[llvm-branch-commits] [cfe-branch] r151016 [1/2] - in /cfe/branches/tooling: ./ INPUTS/ bindings/python/clang/ bindings/python/tests/cindex/ docs/ include/clang-c/ include/clang/AST/ include/clang/ASTMatchers/ include/clang/Analysis/Analyses/ include/clang/Basic/ include/clang/Driver/ include/clang/Frontend/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/AST/ lib/Analysis/ lib/Basic/ lib/CodeGen/ lib/Driver/ lib/Fron...

Manuel Klimek klimek at google.com
Mon Feb 20 17:34:26 PST 2012


Author: klimek
Date: Mon Feb 20 19:34:24 2012
New Revision: 151016

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

Added:
    cfe/branches/tooling/include/clang/Basic/AllDiagnostics.h
      - copied unchanged from r150926, cfe/trunk/include/clang/Basic/AllDiagnostics.h
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
      - copied unchanged from r150926, cfe/trunk/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
    cfe/branches/tooling/test/Analysis/malloc-plist.c
      - copied unchanged from r150926, cfe/trunk/test/Analysis/malloc-plist.c
    cfe/branches/tooling/test/Analysis/malloc.mm
      - copied unchanged from r150926, cfe/trunk/test/Analysis/malloc.mm
    cfe/branches/tooling/test/CXX/class/class.union/p2-0x.cpp
      - copied unchanged from r150926, cfe/trunk/test/CXX/class/class.union/p2-0x.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
      - copied unchanged from r150926, cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
      - copied unchanged from r150926, cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
      - copied unchanged from r150926, cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
    cfe/branches/tooling/test/CodeGen/redefine_extname.c
      - copied unchanged from r150926, cfe/trunk/test/CodeGen/redefine_extname.c
    cfe/branches/tooling/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
      - copied unchanged from r150926, cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
    cfe/branches/tooling/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
      - copied unchanged from r150926, cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
    cfe/branches/tooling/test/CodeGenCXX/init-invariant.cpp
      - copied unchanged from r150926, cfe/trunk/test/CodeGenCXX/init-invariant.cpp
    cfe/branches/tooling/test/CodeGenCXX/static-mutable.cpp
      - copied unchanged from r150926, cfe/trunk/test/CodeGenCXX/static-mutable.cpp
    cfe/branches/tooling/test/CodeGenObjC/arc-no-arc-exceptions.m
      - copied unchanged from r150926, cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m
    cfe/branches/tooling/test/Driver/gcc-toolchain.cpp
      - copied unchanged from r150926, cfe/trunk/test/Driver/gcc-toolchain.cpp
    cfe/branches/tooling/test/Index/complete-lambdas.cpp
      - copied unchanged from r150926, cfe/trunk/test/Index/complete-lambdas.cpp
    cfe/branches/tooling/test/Index/cxx11-lambdas.cpp
      - copied unchanged from r150926, cfe/trunk/test/Index/cxx11-lambdas.cpp
    cfe/branches/tooling/test/PCH/cxx11-lambdas.cpp
      - copied unchanged from r150926, cfe/trunk/test/PCH/cxx11-lambdas.cpp
    cfe/branches/tooling/test/Sema/MicrosoftCompatibility.c
      - copied unchanged from r150926, cfe/trunk/test/Sema/MicrosoftCompatibility.c
    cfe/branches/tooling/test/Sema/complex-imag.c
      - copied unchanged from r150926, cfe/trunk/test/Sema/complex-imag.c
    cfe/branches/tooling/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp
      - copied unchanged from r150926, cfe/trunk/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp
    cfe/branches/tooling/test/SemaCXX/constexpr-turing.cpp
      - copied unchanged from r150926, cfe/trunk/test/SemaCXX/constexpr-turing.cpp
    cfe/branches/tooling/test/SemaCXX/defaulted-private-dtor.cpp
      - copied unchanged from r150926, cfe/trunk/test/SemaCXX/defaulted-private-dtor.cpp
    cfe/branches/tooling/test/SemaCXX/dr1301.cpp
      - copied unchanged from r150926, cfe/trunk/test/SemaCXX/dr1301.cpp
    cfe/branches/tooling/test/SemaCXX/warn-empty-body.cpp
      - copied unchanged from r150926, cfe/trunk/test/SemaCXX/warn-empty-body.cpp
    cfe/branches/tooling/test/SemaTemplate/constexpr-instantiate.cpp
      - copied unchanged from r150926, cfe/trunk/test/SemaTemplate/constexpr-instantiate.cpp
Removed:
    cfe/branches/tooling/test/Frontend/diagnostic-name.c
    cfe/branches/tooling/test/SemaCXX/if-empty-body.cpp
Modified:
    cfe/branches/tooling/   (props changed)
    cfe/branches/tooling/CMakeLists.txt
    cfe/branches/tooling/INPUTS/all-std-headers.cpp
    cfe/branches/tooling/bindings/python/clang/cindex.py
    cfe/branches/tooling/bindings/python/tests/cindex/test_type.py
    cfe/branches/tooling/docs/LanguageExtensions.html
    cfe/branches/tooling/docs/ReleaseNotes.html
    cfe/branches/tooling/docs/UsersManual.html
    cfe/branches/tooling/include/clang-c/Index.h
    cfe/branches/tooling/include/clang/AST/APValue.h
    cfe/branches/tooling/include/clang/AST/ASTContext.h
    cfe/branches/tooling/include/clang/AST/CanonicalType.h
    cfe/branches/tooling/include/clang/AST/DeclCXX.h
    cfe/branches/tooling/include/clang/AST/Expr.h
    cfe/branches/tooling/include/clang/AST/ExprCXX.h
    cfe/branches/tooling/include/clang/AST/OperationKinds.h
    cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h
    cfe/branches/tooling/include/clang/AST/Stmt.h
    cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchers.h
    cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchersInternal.h
    cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h
    cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h
    cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
    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/Parse/Parser.h
    cfe/branches/tooling/include/clang/Sema/DeclSpec.h
    cfe/branches/tooling/include/clang/Sema/Initialization.h
    cfe/branches/tooling/include/clang/Sema/Scope.h
    cfe/branches/tooling/include/clang/Sema/ScopeInfo.h
    cfe/branches/tooling/include/clang/Sema/Sema.h
    cfe/branches/tooling/include/clang/Sema/TypoCorrection.h
    cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
    cfe/branches/tooling/lib/AST/APValue.cpp
    cfe/branches/tooling/lib/AST/DeclCXX.cpp
    cfe/branches/tooling/lib/AST/Expr.cpp
    cfe/branches/tooling/lib/AST/ExprCXX.cpp
    cfe/branches/tooling/lib/AST/ExprConstant.cpp
    cfe/branches/tooling/lib/AST/ItaniumMangle.cpp
    cfe/branches/tooling/lib/AST/ParentMap.cpp
    cfe/branches/tooling/lib/AST/StmtPrinter.cpp
    cfe/branches/tooling/lib/AST/StmtProfile.cpp
    cfe/branches/tooling/lib/AST/Type.cpp
    cfe/branches/tooling/lib/AST/TypePrinter.cpp
    cfe/branches/tooling/lib/Analysis/FormatString.cpp
    cfe/branches/tooling/lib/Analysis/PrintfFormatString.cpp
    cfe/branches/tooling/lib/Analysis/ScanfFormatString.cpp
    cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp
    cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp
    cfe/branches/tooling/lib/Basic/Targets.cpp
    cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp
    cfe/branches/tooling/lib/CodeGen/CGCXX.cpp
    cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp
    cfe/branches/tooling/lib/CodeGen/CGCXXABI.h
    cfe/branches/tooling/lib/CodeGen/CGCall.cpp
    cfe/branches/tooling/lib/CodeGen/CGCall.h
    cfe/branches/tooling/lib/CodeGen/CGClass.cpp
    cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
    cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h
    cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
    cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
    cfe/branches/tooling/lib/CodeGen/CGException.cpp
    cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.h
    cfe/branches/tooling/lib/CodeGen/CGVTables.cpp
    cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp
    cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
    cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
    cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
    cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp
    cfe/branches/tooling/lib/CodeGen/CodeGenTypes.h
    cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp
    cfe/branches/tooling/lib/CodeGen/TargetInfo.h
    cfe/branches/tooling/lib/Driver/Driver.cpp
    cfe/branches/tooling/lib/Driver/ToolChains.cpp
    cfe/branches/tooling/lib/Driver/ToolChains.h
    cfe/branches/tooling/lib/Driver/Tools.cpp
    cfe/branches/tooling/lib/Driver/Tools.h
    cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
    cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp
    cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp
    cfe/branches/tooling/lib/Frontend/TextDiagnosticPrinter.cpp
    cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp
    cfe/branches/tooling/lib/Parse/ParseDecl.cpp
    cfe/branches/tooling/lib/Parse/ParseExpr.cpp
    cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
    cfe/branches/tooling/lib/Parse/ParseInit.cpp
    cfe/branches/tooling/lib/Parse/ParseObjc.cpp
    cfe/branches/tooling/lib/Parse/ParsePragma.cpp
    cfe/branches/tooling/lib/Parse/ParsePragma.h
    cfe/branches/tooling/lib/Parse/ParseStmt.cpp
    cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
    cfe/branches/tooling/lib/Parse/Parser.cpp
    cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp
    cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp
    cfe/branches/tooling/lib/Sema/Scope.cpp
    cfe/branches/tooling/lib/Sema/Sema.cpp
    cfe/branches/tooling/lib/Sema/SemaAccess.cpp
    cfe/branches/tooling/lib/Sema/SemaCast.cpp
    cfe/branches/tooling/lib/Sema/SemaChecking.cpp
    cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
    cfe/branches/tooling/lib/Sema/SemaDecl.cpp
    cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp
    cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
    cfe/branches/tooling/lib/Sema/SemaExpr.cpp
    cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
    cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp
    cfe/branches/tooling/lib/Sema/SemaInit.cpp
    cfe/branches/tooling/lib/Sema/SemaLambda.cpp
    cfe/branches/tooling/lib/Sema/SemaLookup.cpp
    cfe/branches/tooling/lib/Sema/SemaOverload.cpp
    cfe/branches/tooling/lib/Sema/SemaStmt.cpp
    cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/branches/tooling/lib/Sema/SemaType.cpp
    cfe/branches/tooling/lib/Sema/TreeTransform.h
    cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
    cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp
    cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
    cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
    cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerContext.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineC.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/MemRegion.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/SymbolManager.cpp
    cfe/branches/tooling/test/Analysis/malloc-annotations.c
    cfe/branches/tooling/test/Analysis/malloc.c
    cfe/branches/tooling/test/Analysis/misc-ps-region-store.mm
    cfe/branches/tooling/test/Analysis/misc-ps.m
    cfe/branches/tooling/test/Analysis/new.cpp
    cfe/branches/tooling/test/Analysis/plist-output.m
    cfe/branches/tooling/test/Analysis/properties.m
    cfe/branches/tooling/test/Analysis/retain-release.m
    cfe/branches/tooling/test/Analysis/stack-addr-ps.c
    cfe/branches/tooling/test/CXX/class/class.union/p1.cpp
    cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
    cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
    cfe/branches/tooling/test/CXX/expr/expr.const/p2-0x.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
    cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
    cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp
    cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp
    cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp
    cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp
    cfe/branches/tooling/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
    cfe/branches/tooling/test/CodeGenCXX/debug-info-limit.cpp
    cfe/branches/tooling/test/CodeGenCXX/exceptions.cpp
    cfe/branches/tooling/test/CodeGenCXX/lambda-expressions.cpp
    cfe/branches/tooling/test/CodeGenCXX/member-function-pointers.cpp
    cfe/branches/tooling/test/CodeGenCXX/new.cpp
    cfe/branches/tooling/test/CodeGenCXX/pr11676.cpp
    cfe/branches/tooling/test/CodeGenCXX/static-data-member.cpp
    cfe/branches/tooling/test/CodeGenObjC/arc-ivar-layout.m
    cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m
    cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m
    cfe/branches/tooling/test/CodeGenObjC/image-info.m
    cfe/branches/tooling/test/CodeGenObjC/objc-align.m
    cfe/branches/tooling/test/CodeGenObjC/variadic-sends.m
    cfe/branches/tooling/test/CodeGenObjCXX/copy.mm
    cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp
    cfe/branches/tooling/test/FixIt/fixit.c
    cfe/branches/tooling/test/Index/complete-stmt.c
    cfe/branches/tooling/test/Index/index-refs.cpp
    cfe/branches/tooling/test/Lexer/has_feature_cxx0x.cpp
    cfe/branches/tooling/test/Misc/warning-flags.c
    cfe/branches/tooling/test/Parser/attributes.c
    cfe/branches/tooling/test/Parser/cxx-condition.cpp
    cfe/branches/tooling/test/Parser/cxx-using-directive.cpp
    cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp
    cfe/branches/tooling/test/Parser/statements.c
    cfe/branches/tooling/test/Sema/MicrosoftExtensions.c
    cfe/branches/tooling/test/Sema/c89.c
    cfe/branches/tooling/test/Sema/default.c
    cfe/branches/tooling/test/Sema/format-strings-fixit.c
    cfe/branches/tooling/test/Sema/format-strings-scanf.c
    cfe/branches/tooling/test/Sema/format-strings.c
    cfe/branches/tooling/test/Sema/gnu89.c
    cfe/branches/tooling/test/Sema/statements.c
    cfe/branches/tooling/test/Sema/switch.c
    cfe/branches/tooling/test/SemaCXX/MicrosoftExtensions.cpp
    cfe/branches/tooling/test/SemaCXX/attr-sentinel.cpp
    cfe/branches/tooling/test/SemaCXX/condition.cpp
    cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp
    cfe/branches/tooling/test/SemaCXX/cxx0x-cursory-default-delete.cpp
    cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
    cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp
    cfe/branches/tooling/test/SemaCXX/cxx0x-nontrivial-union.cpp
    cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp
    cfe/branches/tooling/test/SemaCXX/deleted-function.cpp
    cfe/branches/tooling/test/SemaCXX/implicit-exception-spec.cpp
    cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp
    cfe/branches/tooling/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
    cfe/branches/tooling/test/SemaCXX/new-delete-cxx0x.cpp
    cfe/branches/tooling/test/SemaCXX/new-delete.cpp
    cfe/branches/tooling/test/SemaCXX/nullptr.cpp
    cfe/branches/tooling/test/SemaCXX/switch.cpp
    cfe/branches/tooling/test/SemaCXX/typo-correction.cpp
    cfe/branches/tooling/test/SemaCXX/value-initialization.cpp
    cfe/branches/tooling/test/SemaCXX/warn-thread-safety-analysis.cpp
    cfe/branches/tooling/test/SemaCXX/warn-thread-safety-parsing.cpp
    cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp   (props changed)
    cfe/branches/tooling/test/SemaObjC/illegal-nonarc-bridged-cast.m
    cfe/branches/tooling/test/SemaObjCXX/properties.mm
    cfe/branches/tooling/test/SemaTemplate/enum-forward.cpp
    cfe/branches/tooling/tools/diagtool/ListWarnings.cpp
    cfe/branches/tooling/tools/libclang/CIndex.cpp
    cfe/branches/tooling/tools/libclang/CXCursor.cpp
    cfe/branches/tooling/tools/libclang/CXCursor.h
    cfe/branches/tooling/tools/libclang/CXType.cpp
    cfe/branches/tooling/tools/libclang/CursorVisitor.h
    cfe/branches/tooling/tools/libclang/IndexBody.cpp
    cfe/branches/tooling/tools/libclang/IndexDecl.cpp
    cfe/branches/tooling/tools/libclang/IndexTypeSourceInfo.cpp
    cfe/branches/tooling/tools/libclang/Indexing.cpp
    cfe/branches/tooling/tools/libclang/IndexingContext.cpp
    cfe/branches/tooling/tools/libclang/IndexingContext.h
    cfe/branches/tooling/unittests/ASTMatchers/ASTMatchersTest.cpp
    cfe/branches/tooling/utils/TableGen/ClangDiagnosticsEmitter.cpp
    cfe/branches/tooling/utils/analyzer/SATestBuild.py
    cfe/branches/tooling/www/cxx_status.html

Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 20 19:34:24 2012
@@ -1,3 +1,3 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-150469
+/cfe/trunk:146581-150926
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/tooling/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/CMakeLists.txt?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/CMakeLists.txt (original)
+++ cfe/branches/tooling/CMakeLists.txt Mon Feb 20 19:34:24 2012
@@ -234,7 +234,7 @@
   PATTERN "*.inc"
   )
 
-add_definitions( -D_GNU_SOURCE -DHAVE_CLANG_CONFIG_H )
+add_definitions( -D_GNU_SOURCE )
 
 # Clang version information
 set(CLANG_EXECUTABLE_VERSION

Modified: cfe/branches/tooling/INPUTS/all-std-headers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/INPUTS/all-std-headers.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/INPUTS/all-std-headers.cpp (original)
+++ cfe/branches/tooling/INPUTS/all-std-headers.cpp Mon Feb 20 19:34:24 2012
@@ -49,3 +49,36 @@
 #include <utility>
 #include <valarray>
 #include <vector>
+
+#if __cplusplus >= 201103
+#include <array>
+#if __has_include(<atomic>)
+#include <atomic>
+#endif
+#include <chrono>
+#if __has_include(<codecvt>)
+#include <codecvt>
+#endif
+#include <condition_variable>
+#include <forward_list>
+#if __has_include(<future>)
+#include <future>
+#endif
+#include <initializer_list>
+#include <mutex>
+#include <random>
+#include <ratio>
+#include <regex>
+#if __has_include(<scoped_allocator>)
+#include <scoped_allocator>
+#endif
+#include <system_error>
+#include <thread>
+#include <tuple>
+#include <type_traits>
+#if __has_include(<typeindex>)
+#include <typeindex>
+#endif
+#include <unordered_map>
+#include <unordered_set>
+#endif

Modified: cfe/branches/tooling/bindings/python/clang/cindex.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/clang/cindex.py?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/clang/cindex.py (original)
+++ cfe/branches/tooling/bindings/python/clang/cindex.py Mon Feb 20 19:34:24 2012
@@ -1137,6 +1137,33 @@
         """Return the kind of this type."""
         return TypeKind.from_id(self._kind_id)
 
+    @property
+    def element_type(self):
+        """Retrieve the Type of elements within this Type.
+
+        If accessed on a type that is not an array, complex, or vector type, an
+        exception will be raised.
+        """
+        result = Type_get_element_type(self)
+        if result.kind == TypeKind.INVALID:
+            raise Exception('Element type not available on this type.')
+
+        return result
+
+    @property
+    def element_count(self):
+        """Retrieve the number of elements in this type.
+
+        Returns an int.
+
+        If the Type is not an array or vector, this raises.
+        """
+        result = Type_get_num_elements(self)
+        if result < 0:
+            raise Exception('Type does not have elements.')
+
+        return result
+
     @staticmethod
     def from_result(res, fn, args):
         assert isinstance(res, Type)
@@ -1881,6 +1908,15 @@
 Type_get_result.restype = Type
 Type_get_result.errcheck = Type.from_result
 
+Type_get_element_type = lib.clang_getElementType
+Type_get_element_type.argtypes = [Type]
+Type_get_element_type.restype = Type
+Type_get_element_type.errcheck = Type.from_result
+
+Type_get_num_elements = lib.clang_getNumElements
+Type_get_num_elements.argtypes = [Type]
+Type_get_num_elements.restype = c_longlong
+
 Type_get_array_element = lib.clang_getArrayElementType
 Type_get_array_element.argtypes = [Type]
 Type_get_array_element.restype = Type

Modified: cfe/branches/tooling/bindings/python/tests/cindex/test_type.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/tests/cindex/test_type.py?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/tests/cindex/test_type.py (original)
+++ cfe/branches/tooling/bindings/python/tests/cindex/test_type.py Mon Feb 20 19:34:24 2012
@@ -1,4 +1,8 @@
-from clang.cindex import Index, CursorKind, TypeKind
+from clang.cindex import CursorKind
+from clang.cindex import Index
+from clang.cindex import TypeKind
+from nose.tools import ok_
+from nose.tools import raises
 
 kInput = """\
 
@@ -115,3 +119,53 @@
 
     assert i.type.is_pod()
     assert not f.type.is_pod()
+
+def test_element_type():
+    index = Index.create()
+    tu = index.parse('t.c', unsaved_files=[('t.c', 'int i[5];')])
+    assert tu is not None
+
+    for cursor in tu.cursor.get_children():
+        if cursor.spelling == 'i':
+            i = cursor
+            break
+
+    assert i.type.kind == TypeKind.CONSTANTARRAY
+    assert i.type.element_type.kind == TypeKind.INT
+
+ at raises(Exception)
+def test_invalid_element_type():
+    """Ensure Type.element_type raises if type doesn't have elements."""
+    index = Index.create()
+    tu = index.parse('t.c', unsaved_files=[('t.c', 'int i;')])
+
+    i = None
+    for cursor in tu.cursor.get_children():
+        if cursor.spelling == 'i':
+            i = cursor
+            break
+
+    ok_(i is not None)
+    i.element_type
+
+def test_element_count():
+    index = Index.create()
+    tu = index.parse('t.c', unsaved_files=[('t.c', 'int i[5]; int j;')])
+    assert tu is not None
+
+    for cursor in tu.cursor.get_children():
+        if cursor.spelling == 'i':
+            i = cursor
+        elif cursor.spelling == 'j':
+            j = cursor
+
+    assert i is not None
+    assert j is not None
+
+    assert i.type.element_count == 5
+
+    try:
+        j.type.element_count
+        assert False
+    except:
+        assert True

Modified: cfe/branches/tooling/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/LanguageExtensions.html?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/docs/LanguageExtensions.html (original)
+++ cfe/branches/tooling/docs/LanguageExtensions.html Mon Feb 20 19:34:24 2012
@@ -668,7 +668,7 @@
 
 <p>Use <tt>__has_feature(cxx_constexpr)</tt> to determine if support
 for generalized constant expressions (e.g., <tt>constexpr</tt>) is
-enabled. Clang does not currently implement this feature.</p> 
+enabled.</p>
 
 <h4 id="cxx_decltype">C++11 <tt>decltype()</tt></h4>
 

Modified: cfe/branches/tooling/docs/ReleaseNotes.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/ReleaseNotes.html?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/docs/ReleaseNotes.html (original)
+++ cfe/branches/tooling/docs/ReleaseNotes.html Mon Feb 20 19:34:24 2012
@@ -2,7 +2,7 @@
           "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-<title>Clang 3.0 Release Notes</title>
+<title>Clang 3.1 Release Notes</title>
 <link type="text/css" rel="stylesheet" href="../menu.css">
 <link type="text/css" rel="stylesheet" href="../content.css">
 <style type="text/css">
@@ -17,18 +17,18 @@
 
 <div id="content">
 
-<h1>Clang 3.0 Release Notes</h1>
+<h1>Clang 3.1 Release Notes</h1>
 
 <img style="float:right" src="http://llvm.org/img/DragonSmall.png"
      width="136" height="136" alt="LLVM Dragon Logo">
 
 <ul>
   <li><a href="#intro">Introduction</a></li>
-  <li><a href="#whatsnew">What's New in Clang 3.0?</a>
+  <li><a href="#whatsnew">What's New in Clang 3.1?</a>
     <ul>
       <li><a href="#majorfeatures">Major New Features</a></li>
       <li><a href="#cchanges">C Language Changes</a></li>
-      <li><a href="#cxxhanges">C++ Language Changes</a></li>
+      <li><a href="#cxxchanges">C++ Language Changes</a></li>
       <li><a href="#objchanges">Objective-C Language Changes</a></li>
       <li><a href="#apichanges">Internal API Changes</a></li>
     </ul>
@@ -41,20 +41,18 @@
   <p>Written by the <a href="http://llvm.org/">LLVM Team</a></p>
 </div>
 
-<!--
-<h1 style="color:red">These are in-progress notes for the upcoming LLVM 3.0
+<h1 style="color:red">These are in-progress notes for the upcoming Clang 3.1
 release.<br>
 You may prefer the
-<a href="http://llvm.org/releases/2.9/docs/ReleaseNotes.html">LLVM 2.9
+<a href="http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html">Clang 3.0
 Release Notes</a>.</h1>
- -->
 
 <!-- ======================================================================= -->
 <h2 id="intro">Introduction</h2>
 <!-- ======================================================================= -->
 
 <p>This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 3.0.  Here we
+frontend, part of the LLVM Compiler Infrastructure, release 3.1.  Here we
 describe the status of Clang in some detail, including major improvements from
 the previous release and new feature work. For the general LLVM release notes,
 see <a href="http://llvm.org/docs/ReleaseNotes.html">the LLVM
@@ -72,7 +70,7 @@
 <a href="http://llvm.org/releases/">releases page</a>.</p>
 
 <!-- ======================================================================= -->
-<h2 id="whatsnew">What's New in Clang 3.0?</h2>
+<h2 id="whatsnew">What's New in Clang 3.1?</h2>
 <!-- ======================================================================= -->
 
 <p>Some of the major new features and improvements to Clang are listed here.
@@ -84,270 +82,70 @@
 <h3 id="majorfeatures">Major New Features</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 
-<h4 id="diagnostics">A multitude of improvements to Clang's diagnostics</h4>
-Clang's diagnostics are constantly being improved to catch more issues, explain
-them more clearly, and provide more accurate source information about them.
-A few improvements since the 2.9 release that have a particularly high impact:
-<ul>
-  <li>Substantially shorter messages due to better recovery, fewer include
-  stacks, and tuning verbose features such as 'a.k.a.' type printing.</li>
-  <li>
-    Able to recover and correct from misspelled type names at the beging of
-    statements. For example, Clang now emits:
-<pre><b>t.c:6:3: <span class="error">error:</span> use of undeclared identifier 'integer'; did you mean 'Integer'?</b>
-  integer *i = 0;
-  <span class="caret">^~~~~~~</span>
-  Integer
-<b>t.c:1:13: note:</b> 'Integer' declared here
-typedef int Integer;
-            <span class="caret">^</span></pre>
-  </li>
-  <li>Expanded typo correction to (among other improvements) look across
-  namespaces and suggest namespace qualifiers in addition to misspellings of the
-  identifier itself.</li>
-  <li>More rich macro expansion backtraces and some (limited) fix-it hints when
-  diagnostics stem from macro arguments.</li>
-  <li>Many new warnings have been added to catch common, bug-prone code
-  patterns.</li>
-  <li>Uninitialized values Clang warning was rewritten to be more accurate,
-  faster, and able to differentiate between the <em>possibility</em> of an
-  uninitialized use and the <em>certainty</em> of an uninitialized use.</li>
-</ul>
-
-<h4 id="libclang">This release saw significant improvements to <code>libclang</code></h4>
-<ul>
-  <li>A broader set of the <code>libclang</code> API is exposed in the Python
-  bindings.</li>
-  <li>Much more of the Clang AST is exposed through <code>libclang</code>'s APIs
-  and cursors.</li>
-  <li>Cursors can now walk more effectively through macros, especially arguments
-  to function-style macros, and resolve to the underlying AST.</li>
-  <li>Improved code completion surrounding macros, macro arguments, and
-  token pasting.</li>
-  <li>Improved code completion for in-class member functions.</li>
-  <li>Crash recovery for <code>libclang</code> clients.</li>
-  <!-- Doug or Ted may want to flesh this out if there are relevant details I'm
-  glossing over... -->
-</ul>
-
-<h4 id="driver">The Clang GCC-compatible command-line driver improved dramatically</h4>
-A great deal of work went into the GCC-compatible driver for the 3.0 release
-making it support more operating systems, emulate GCC behavior more accurately,
-and support a much broader range of Linux distributions out of the box.
-<ul>
-  <li>More accurate support for hardware architecture pre-defined macros (e.g.,
-  __i686__).</li>
-  <li>Robust library and header search paths for the vast majority of x86 and
-  x86-64 Linux distributions.</li>
-  <li>Improved support for newer Darwin platforms.</li>
-  <li>Partial support for <code>--sysroot=...</code> based cross-compiling on
-  Linux (and similar) host systems.</li>
-  <li>Improved support for locating and using libcxx when installed, especially
-  on Darwin.</li>
-  <!-- There are likely more Darwin-specific improvements to mention here? -->
-  <!-- What support was added for FreeBSD? NetBSD? Anything noteworthy? -->
-  <li>Automatic detection of Clang crashes in the driver and preparation of
-  reproduction steps for filing bug reports.</li><!-- Chad, feel free to add
-  more details here. -->
-</ul>
-
-<h4 id="ppcallbacks">Expanded support for instrumenting the preprocessor through
-  callbacks</h4>
-Several enhancements were made to the <code>PPCallbacks</code> interface to
-expand the information available to tools and library users of Clang that wish
-to introspect the preprocessing.
-<ul>
-  <li>The exact text used between the <code>""</code>s or <code><></code>s is reported.</li>
-  <li>The header search path used to locate the header is reported.</li>
-  <li>Missing files during including headers reported.</li>
-  <li>The exact source range for expanded macros can be retrieved.</li>
-</ul>
+<h4 id="majorfeature1">Feature 1</h4>
+...
 
-<h4 id="windows">Clang is building and tested regularly on Windows and can
-  compile limited subsets of code on Windows</h4>
-Clang is regularly built and tested on a variety of Windows platforms including
-MinGW 32-bit and 64-bit, Cygwin, and natively with MSVC. In addition, Clang can
-be used as a compiler in a few Windows contexts.
-<ul>
-  <li>Normal compilation supported for the MinGW target platform, in both 32-bit
-  and 64-bit, and the Cygwin target platform.</li>
-  <li>Parsing and AST support for Windows Structured Exception Handling.</li>
-  <li>New -fms-compatibility flag to handle MSVC constructs that could change 
-  the meaning of an otherwise well formed program</li>
-  <li>clang can now parse all the MSVC 2010 standard C++ header files
-  in the nominal case, (still need to specifiy -nobuiltininc for some headers).</li>
-  <li>Improved support for MFC code parsing, (still a work in progress).</li>
-  <li>Add support for function template specialization at class scope (-fms-extensions mode).</li>
-  <li>Add support for Microsoft __if_exists/__if_not_exists statements (-fms-extensions mode).</li>
-</ul>
+<h4 id="diagnostics">New and better diagnostics</h4>
 
-<h4 id="availability">New availability attribute to detect and warn about API
-usage across OS X and iOS versions</h4>
-Clang now supports an attribute which documents the availability of an API
-across various platforms and releases, allowing interfaces to include
-information about what OS versions support the relevant features. Based on the
-targeted version of a compile, warnings for deprecated and unavailable
-interfaces will automatically be provided by Clang.
-
-<h4 id="threadsafety">Thread Safety annotations and analysis-based warnings</h4>
-A set of annotations were introduced to Clang to describe the various
-thread-safety concerns of a program, and an accompanying set of analysis based
-warnings will diagnose clearly unsafe code patterns. The annotations are
-described in the
-<a href="http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety">extension specification</a>,
-and the warnings currently supported include:
-<ul>
-  <li>Calling functions without the required locks</li>
-  <li>Reading variables without the required locks</li>
-  <li>Writing to variables without an exclusive lock (even if holding a shared
-  lock)</li>
-  <li>Imbalance between locks and unlocks across loop entries and exits</li>
-  <li>Acquiring or releasing locks out of order</li>
-</ul>
+<p>New: <code>-Wdangling-else</code>, <code>-Wstrncat-size</code>, ...</p>
 
-<h4 id="incompleteast">Improved support for partially constructed and/or
-incomplete ASTs</h4>
-For users such as LLDB that are dynamically forming C++ ASTs, sometimes it is
-either necessary or useful to form a partial or incomplete AST. Support for
-these use cases have improved through the introduction of "unknown" types and
-other AST constructs designed specifically for use cases without complete
-information about the C++ construct being formed.
-
-<h4 id="opencl">Initial work to support compiling OpenCL C with Clang</h4>
-<p>Clang has some (limited) support for compiling OpenCL C.  The 3.0
-release adds support for the <tt>vec_step</tt> operator, address space
-qualifiers (<tt>__private</tt>, <tt>__global</tt>, <tt>__local</tt> and
-<tt>__constant</tt>), improved vector literal support and code generation
-support for the <a href="http://llvm.org/docs/ReleaseNotes.html#PTX">PTX
-target</a>.</p>
-
-<p>Using the <a href="http://www.pcc.me.uk/~peter/libclc/">libclc library</a>
-to supply OpenCL C built-ins, you can use Clang to compile OpenCL C code
-into PTX and execute it by loading the resulting PTX as a binary blob using
-the nVidia OpenCL library.  It has been tested with several OpenCL programs,
-including some from the nVidia GPU Computing SDK, and the performance is on
-par with the nVidia compiler.</p>
+<p>Improved: <code>-Wformat</code>, <code>-Wempty-body</code>, ...</p>
 
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 <h3 id="cchanges">C Language Changes in Clang</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 
-<h4 id="c1xchanges">C1X Feature Support</h4>
+<h4 id="c11changes">C11 Feature Support</h4>
 
-<p>Clang 3.0 adds support for the
-<a href="http://clang.llvm.org/docs/LanguageExtensions.html#c1x">
-<code>_Alignas</code>, <code>_Generic</code>, and <code>_Static_assert</code>
-keywords</a>, drafted for inclusion in the next C standard, which is
-provisionally known as C1X. Use <code>-std=c1x</code> or <code>-std=gnu1x</code>
-to enable support for the new language standard. These features are
+<p>Clang 3.1 adds support for anonymous structs and anonymous unions, added in
+the latest ISO C standard. Use <code>-std=c11</code> or <code>-std=gnu11</code>
+to enable support for the new language standard. The new C11 features are
 backwards-compatible and are available as an extension in all language
 modes.</p>
 
+<p>All warning and language selection flags which previously accepted
+<code>c1x</code> have been updated to accept <code>c11</code>. The old
+<code>c1x</code> forms have been removed.
+
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 <h3 id="cxxchanges">C++ Language Changes in Clang</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 
 <h4 id="cxx11changes">C++11 Feature Support</h4>
-<p>Clang 3.0 adds support for
+<p>Clang 3.1 adds support for
 <a href="http://clang.llvm.org/cxx_status.html#cxx11">more of the language
 features</a> added in the latest ISO C++ standard,
 <a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372">C++ 2011</a>.
 Use <code>-std=c++11</code> or <code>-std=gnu++11</code> to enable support for
-these features. The following are now considered to be of production quality:
+these features. In addition to the features supported by Clang 3.0, the
+following are now considered to be of production quality:
 <ul>
-  <li>Range-based <code>for</code> loops</li>
-  <li>Alias declarations (a new syntax for <code>typedef</code> declarations),
-  including their <code>template</code> forms</li>
-  <li>Specifying default values for class data members within a class
-  definition</li>
-  <li>Constructors delegating to other constructors of the same class</li>
-  <li>The <code>override</code> context-sensitive keyword for virtual member
-  function declarations</li>
-  <li>Explicitly generating default function definitions with
-  <code>= default</code></li>
-  <li>The <code>nullptr</code> keyword, and the corresponding type</li>
-  <li>Raw string literals with arbitary delimiters (for instance,
-  <code>R"delim(str"ing)delim"</code>)</li>
-  <li>Unicode string literals (for instance, <code>U"\u1234"</code>) and the
-  <code>char16_t</code> and <code>char32_t</code> built-in types
-  <li><code>noexcept</code> expressions and the <code>noexcept</code> specifier
-  on function declarations</li>
-  <li><code>alignof</code> expressions and the <code>alignas</code> specifier on
-  variable declarations</li>
-  <li>A full set of <a href="http://clang.llvm.org/docs/LanguageExtensions.html#checking_type_traits">type traits</a>,
-  sufficient to support C++11 standard libraries</li>
+  <li>Generalized constant expressions</li>
+  <!--
+  <li>Lambda expressions</li>
+  <li>Generalized initializers</li>
+  -->
 </ul>
-All warning and language selection flags which previously accepted
-<code>c++0x</code> now accept <code>c++11</code>. The old <code>c++0x</code>
-form remains as an alias.
 
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 <h3 id="objcchanges">Objective-C Language Changes in Clang</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
-Clang 3.0 introduces several new Objective-C language features and improvements.
+Clang 3.1 introduces several new Objective-C language features and improvements.
 
-<h4 id="objc_arc">Objective-C Automatic Reference Counting</h4>
-<!-- This is really just a stub for John to flesh out regarding ARC. -->
-ARC provides automated memory management for Objective-C programs that is
-compatible with existing retain/release code.  ARC is carefully built to
-be a reliable programming model that errs on the side of producing a
-compiler error instead of silently producing a runtime memory problem.
-ARC automates Objective-C objects, not malloc data, file descriptors,
-CoreFoundation datatypes or anything else. For more details, see the
-<a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html">full specification</a>.
-
-<h4 id="objc_instancetype">Objective-C Related Result Types / Instance
-Types</h4>
-Allows declaring new methods which follow the Cocoa conventions for methods
-such as <code>init</code> which always return objects that are an instance of
-the receiving class's type. For more details, see the
-<a href="http://clang.llvm.org/docs/LanguageExtensions.html#objc_instancetype">language extension documentation</a>.
+<h4 id="objcwformat">Format string checking for NSString literals</h4>
 
-<!--
-This is a stub for David Chisnall to fill out.
-
-<h4 id="objc_gnuruntime">Improved support for the GNU Runtime</h4>
-....
--->
+<code>-Wformat</code> now checks <code>@"nsstring literals"</code>.
 
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 <h3 id="apichanges">Internal API Changes</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 
-These are major API changes that have happened since the 2.9 release of Clang.
+These are major API changes that have happened since the 3.0 release of Clang.
 If upgrading an external codebase that uses Clang as a library, this section
 should help get you past the largest hurdles of upgrading.
 
-<h4 id="macroexpansion">Switched terminology from "instantiation" to "expansion"
-  for macros</h4>
-A great deal of comments and code changes fell out of this, but also every API
-relating to macros with the word "instantiation" (or some variant thereof) was
-renamed. An incomplete list of the most note-worthy ones is here:
-<ul>
-  <li><code>MacroInstantiation</code> became <code>MacroExpansion</code></li>
-  <li><code>SourceManager::getInstantiationLoc</code> became
-  <code>SourceManager::getExpansionLoc</code></li>
-  <li><code>SourceManager::getInstantiationRange</code> became
-  <code>SourceManager::getExpansionRange</code></li>
-  <li><code>SourceManager::getImmediateInstantiationRange</code> became
-  <code>SourceManager::getImmediateExpansionRange</code></li>
-  <li><code>SourceManager::getDecomposedInstantiationLoc</code> became
-  <code>SourceManager::getDecomposedExpansionLoc</code></li>
-  <li><code>SourceManager::getInstantiationColumnNumber</code> became
-  <code>SourceManager::getExpansionColumnNumber</code></li>
-  <li><code>SourceManager::getInstantiationLineNumber</code> became
-  <code>SourceManager::getExpansionLineNumber</code></li>
-  <!-- TODO: Make this more complete! -->
-</ul>
-
-<h4 id="diagnosticrename">Diagnostic class names were shuffled</h4>
-<ul>
-  <li><code>Diagnostic</code> became <code>DiagnosticEngine</code></li>
-  <li><code>DiagnosticClient</code> became <code>DiagnosticConsumer</code></li>
-  <li><code>DiagnosticInfo</code> became <code>Diagnostic</code></li>
-</ul>
-Subclasses of <code>DiagnosticConsumer</code> were also then renamed to end with
-<code>Consumer</code>.
+<h4 id="api1">API change 1</h4>
+...
 
 <!-- ======================================================================= -->
 <h2 id="knownproblems">Significant Known Problems</h2>

Modified: cfe/branches/tooling/docs/UsersManual.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/UsersManual.html?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/docs/UsersManual.html (original)
+++ cfe/branches/tooling/docs/UsersManual.html Mon Feb 20 19:34:24 2012
@@ -535,8 +535,6 @@
 <li>A categorization of the diagnostic as a note, warning, error, or fatal
     error.</li>
 <li>A text string that describes what the problem is.</li>
-<li>An option that indicates whether to print the diagnostic name [<a
-    href="#opt_fdiagnostics-show-name">-fdiagnostics-show-name</a>].</li>
 <li>An option that indicates how to control the diagnostic (for diagnostics that
     support it) [<a 
    href="#opt_fdiagnostics-show-option">-fdiagnostics-show-option</a>].</li>

Modified: cfe/branches/tooling/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang-c/Index.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang-c/Index.h (original)
+++ cfe/branches/tooling/include/clang-c/Index.h Mon Feb 20 19:34:24 2012
@@ -1500,7 +1500,13 @@
    */
   CXCursor_OverloadedDeclRef             = 49,
   
-  CXCursor_LastRef                       = CXCursor_OverloadedDeclRef,
+  /**
+   * \brief A reference to a variable that occurs in some non-expression 
+   * context, e.g., a C++ lambda capture list.
+   */
+  CXCursor_VariableRef                   = 50,
+  
+  CXCursor_LastRef                       = CXCursor_VariableRef,
 
   /* Error conditions */
   CXCursor_FirstInvalid                  = 70,
@@ -1746,7 +1752,21 @@
    */
   CXCursor_SizeOfPackExpr                = 143,
 
-  CXCursor_LastExpr                      = CXCursor_SizeOfPackExpr,
+  /* \brief Represents a C++ lambda expression that produces a local function
+   * object.
+   *
+   * \code
+   * void abssort(float *x, unsigned N) {
+   *   std::sort(x, x + N,
+   *             [](float a, float b) {
+   *               return std::abs(a) < std::abs(b);
+   *             });
+   * }
+   * \endcode
+   */
+  CXCursor_LambdaExpr                    = 144,
+  
+  CXCursor_LastExpr                      = CXCursor_LambdaExpr,
 
   /* Statements */
   CXCursor_FirstStmt                     = 200,
@@ -4461,7 +4481,13 @@
    * \brief Function-local symbols should be indexed. If this is not set
    * function-local symbols will be ignored.
    */
-  CXIndexOpt_IndexFunctionLocalSymbols = 0x2
+  CXIndexOpt_IndexFunctionLocalSymbols = 0x2,
+
+  /**
+   * \brief Implicit function/class template instantiations should be indexed.
+   * If this is not set, implicit instantiations will be ignored.
+   */
+  CXIndexOpt_IndexImplicitTemplateInstantiations = 0x4
 } CXIndexOptFlags;
 
 /**

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/APValue.h (original)
+++ cfe/branches/tooling/include/clang/AST/APValue.h Mon Feb 20 19:34:24 2012
@@ -138,14 +138,14 @@
   APValue(const APValue &RHS) : Kind(Uninitialized) {
     *this = RHS;
   }
-  APValue(LValueBase B, const CharUnits &O, NoLValuePath N)
+  APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
       : Kind(Uninitialized) {
-    MakeLValue(); setLValue(B, O, N);
+    MakeLValue(); setLValue(B, O, N, CallIndex);
   }
   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
-          bool OnePastTheEnd)
+          bool OnePastTheEnd, unsigned CallIndex)
       : Kind(Uninitialized) {
-    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd);
+    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
   }
   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
     MakeArray(InitElts, Size);
@@ -246,6 +246,7 @@
   bool isLValueOnePastTheEnd() const;
   bool hasLValuePath() const;
   ArrayRef<LValuePathEntry> getLValuePath() const;
+  unsigned getLValueCallIndex() const;
 
   APValue &getVectorElt(unsigned I) {
     assert(isVector() && "Invalid accessor");
@@ -365,9 +366,11 @@
     ((ComplexAPFloat*)(char*)Data)->Real = R;
     ((ComplexAPFloat*)(char*)Data)->Imag = I;
   }
-  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath);
+  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+                 unsigned CallIndex);
   void setLValue(LValueBase B, const CharUnits &O,
-                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd);
+                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
+                 unsigned CallIndex);
   void setUnion(const FieldDecl *Field, const APValue &Value) {
     assert(isUnion() && "Invalid accessor");
     ((UnionData*)(char*)Data)->Field = Field;

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTContext.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTContext.h Mon Feb 20 19:34:24 2012
@@ -55,6 +55,7 @@
   class CXXABI;
   // Decls
   class DeclContext;
+  class CXXConversionDecl;
   class CXXMethodDecl;
   class CXXRecordDecl;
   class Decl;
@@ -321,6 +322,12 @@
   typedef UsuallyTinyPtrVector<const CXXMethodDecl> CXXMethodVector;
   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
 
+  /// \brief Mapping from lambda-to-block-pointer conversion functions to the
+  /// expression used to copy the lambda object.
+  llvm::DenseMap<const CXXConversionDecl *, Expr *> LambdaBlockPointerInits;
+  
+  friend class CXXConversionDecl;
+  
   /// \brief Mapping that stores parameterIndex values for ParmVarDecls
   /// when that value exceeds the bitfield size of
   /// ParmVarDeclBits.ParameterIndex.

Modified: cfe/branches/tooling/include/clang/AST/CanonicalType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/CanonicalType.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/CanonicalType.h (original)
+++ cfe/branches/tooling/include/clang/AST/CanonicalType.h Mon Feb 20 19:34:24 2012
@@ -108,6 +108,8 @@
   /// or a derived class thereof, a NULL canonical type.
   template<typename U> CanProxy<U> getAs() const;
 
+  template<typename U> CanProxy<U> castAs() const;
+
   /// \brief Overloaded arrow operator that produces a canonical type
   /// proxy.
   CanProxy<T> operator->() const;
@@ -753,6 +755,13 @@
 }
 
 template<typename T>
+template<typename U>
+CanProxy<U> CanQual<T>::castAs() const {
+  assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
+  return CanQual<U>::CreateUnsafe(Stored);
+}
+
+template<typename T>
 CanProxy<T> CanQual<T>::operator->() const {
   return CanProxy<T>(*this);
 }

Modified: cfe/branches/tooling/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclCXX.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclCXX.h Mon Feb 20 19:34:24 2012
@@ -1122,6 +1122,13 @@
   // (C++ [class.dtor]p3)
   bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
 
+  // hasIrrelevantDestructor - Whether this class has a destructor which has no
+  // semantic effect. Any such destructor will be trivial, public, defaulted
+  // and not deleted.
+  bool hasIrrelevantDestructor() const {
+    return hasTrivialDestructor() && !hasUserDeclaredDestructor();
+  }
+
   // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or
   // volatile type non-static data member or base class.
   bool hasNonLiteralTypeFieldsOrBases() const {
@@ -1565,6 +1572,15 @@
 
   bool hasInlineBody() const;
 
+  /// \brief Determine whether this is a lambda closure type's static member
+  /// function that is used for the result of the lambda's conversion to
+  /// function pointer (for a lambda with no captures).
+  ///
+  /// The function itself, if used, will have a placeholder body that will be
+  /// supplied by IR generation to either forward to the function call operator
+  /// or clone the function call operator.
+  bool isLambdaStaticInvoker() const;
+  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const CXXMethodDecl *D) { return true; }
@@ -2180,6 +2196,19 @@
     return getType()->getAs<FunctionType>()->getResultType();
   }
 
+  /// \brief Determine whether this conversion function is a conversion from
+  /// a lambda closure type to a block pointer.
+  bool isLambdaToBlockPointerConversion() const;
+  
+  /// \brief For an implicit conversion function that converts a lambda
+  /// closure type to a block pointer, retrieve the expression used to
+  /// copy the closure object into the block.
+  Expr *getLambdaToBlockPointerCopyInit() const;
+  
+  /// \brief Set the copy-initialization expression to be used when converting
+  /// a lambda object to a block pointer.
+  void setLambdaToBlockPointerCopyInit(Expr *Init);
+  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const CXXConversionDecl *D) { return true; }

Modified: cfe/branches/tooling/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Expr.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Expr.h (original)
+++ cfe/branches/tooling/include/clang/AST/Expr.h Mon Feb 20 19:34:24 2012
@@ -423,6 +423,10 @@
                              bool isEvaluated = true) const;
   bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const;
 
+  /// isCXX98IntegralConstantExpr - Return true if this expression is an
+  /// integral constant expression in C++98. Can only be used in C++.
+  bool isCXX98IntegralConstantExpr(ASTContext &Ctx) const;
+
   /// isCXX11ConstantExpr - Return true if this expression is a constant
   /// expression in C++11. Can only be used in C++.
   ///
@@ -3479,10 +3483,6 @@
   ///  field within the union will be initialized.
   llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
 
-  /// Whether this initializer list originally had a GNU array-range
-  /// designator in it. This is a temporary marker used by CodeGen.
-  bool HadArrayRangeDesignator;
-
 public:
   InitListExpr(ASTContext &C, SourceLocation lbraceloc,
                Expr **initexprs, unsigned numinits,
@@ -3581,9 +3581,18 @@
   InitListExpr *getSyntacticForm() const { return SyntacticForm; }
   void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
 
-  bool hadArrayRangeDesignator() const { return HadArrayRangeDesignator; }
+  bool hadArrayRangeDesignator() const {
+    return InitListExprBits.HadArrayRangeDesignator != 0;
+  }
   void sawArrayRangeDesignator(bool ARD = true) {
-    HadArrayRangeDesignator = ARD;
+    InitListExprBits.HadArrayRangeDesignator = ARD;
+  }
+
+  bool initializesStdInitializerList() const {
+    return InitListExprBits.InitializesStdInitializerList != 0;
+  }
+  void setInitializesStdInitializerList(bool ISIL = true) {
+    InitListExprBits.InitializesStdInitializerList = ISIL;
   }
 
   SourceRange getSourceRange() const;
@@ -4229,7 +4238,7 @@
   }
 
   /// getFunctionType - Return the underlying function type for this block.
-  const FunctionType *getFunctionType() const;
+  const FunctionProtoType *getFunctionType() const;
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == BlockExprClass;

Modified: cfe/branches/tooling/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ExprCXX.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ExprCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/ExprCXX.h Mon Feb 20 19:34:24 2012
@@ -1168,6 +1168,14 @@
              ArrayRef<unsigned> ArrayIndexStarts,
              SourceLocation ClosingBrace);
 
+  /// \brief Construct an empty lambda expression.
+  LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
+    : Expr(LambdaExprClass, Empty),
+      NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
+      ExplicitResultType(false), HasArrayIndexVars(true) { 
+    getStoredStmts()[NumCaptures] = 0;
+  }
+  
   Stmt **getStoredStmts() const {
     return reinterpret_cast<Stmt **>(const_cast<LambdaExpr *>(this) + 1);
   }
@@ -1198,6 +1206,11 @@
                             ArrayRef<unsigned> ArrayIndexStarts,
                             SourceLocation ClosingBrace);
 
+  /// \brief Construct a new lambda expression that will be deserialized from
+  /// an external source.
+  static LambdaExpr *CreateDeserialized(ASTContext &C, unsigned NumCaptures,
+                                        unsigned NumArrayIndexVars);
+  
   /// \brief Determine the default capture kind for this lambda.
   LambdaCaptureDefault getCaptureDefault() const {
     return static_cast<LambdaCaptureDefault>(CaptureDefault);
@@ -1271,9 +1284,7 @@
   CXXMethodDecl *getCallOperator() const;
 
   /// \brief Retrieve the body of the lambda.
-  CompoundStmt *getBody() const {
-    return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
-  }
+  CompoundStmt *getBody() const;
 
   /// \brief Determine whether the lambda is mutable, meaning that any
   /// captures values can be modified.
@@ -1348,34 +1359,24 @@
 class CXXNewExpr : public Expr {
   // Was the usage ::new, i.e. is the global new to be used?
   bool GlobalNew : 1;
-  // Is there an initializer? If not, built-ins are uninitialized, else they're
-  // value-initialized.
-  bool Initializer : 1;
   // Do we allocate an array? If so, the first SubExpr is the size expression.
   bool Array : 1;
   // If this is an array allocation, does the usual deallocation
   // function for the allocated type want to know the allocated size?
   bool UsualArrayDeleteWantsSize : 1;
-  // Whether the referred constructor (if any) was resolved from an
-  // overload set having size greater than 1.
-  bool HadMultipleCandidates : 1;
   // The number of placement new arguments.
   unsigned NumPlacementArgs : 13;
-  // The number of constructor arguments. This may be 1 even for non-class
-  // types; use the pseudo copy constructor.
-  unsigned NumConstructorArgs : 14;
-  // Contains an optional array size expression, any number of optional
-  // placement arguments, and any number of optional constructor arguments,
-  // in that order.
+  // What kind of initializer do we have? Could be none, parens, or braces.
+  // In storage, we distinguish between "none, and no initializer expr", and
+  // "none, but an implicit initializer expr".
+  unsigned StoredInitializationStyle : 2;
+  // Contains an optional array size expression, an optional initialization
+  // expression, and any number of optional placement arguments, in that order.
   Stmt **SubExprs;
   // Points to the allocation function used.
   FunctionDecl *OperatorNew;
   // Points to the deallocation function used in case of error. May be null.
   FunctionDecl *OperatorDelete;
-  // Points to the constructor used. Cannot be null if AllocType is a record;
-  // it would still point at the default constructor (even an implicit one).
-  // Must be null for all other types.
-  CXXConstructorDecl *Constructor;
 
   /// \brief The allocated type-source information, as written in the source.
   TypeSourceInfo *AllocatedTypeInfo;
@@ -1384,29 +1385,33 @@
   /// the source range covering the parenthesized type-id.
   SourceRange TypeIdParens;
 
+  /// \brief Location of the first token.
   SourceLocation StartLoc;
-  SourceLocation EndLoc;
-  SourceLocation ConstructorLParen;
-  SourceLocation ConstructorRParen;
+
+  /// \brief Source-range of a paren-delimited initializer.
+  SourceRange DirectInitRange;
 
   friend class ASTStmtReader;
+  friend class ASTStmtWriter;
 public:
+  enum InitializationStyle {
+    NoInit,   ///< New-expression has no initializer as written.
+    CallInit, ///< New-expression has a C++98 paren-delimited initializer.
+    ListInit  ///< New-expression has a C++11 list-initializer.
+  };
+
   CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-             Expr **placementArgs, unsigned numPlaceArgs,
-             SourceRange TypeIdParens,
-             Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
-             Expr **constructorArgs, unsigned numConsArgs,
-             bool HadMultipleCandidates,
              FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
+             Expr **placementArgs, unsigned numPlaceArgs,
+             SourceRange typeIdParens, Expr *arraySize,
+             InitializationStyle initializationStyle, Expr *initializer,
              QualType ty, TypeSourceInfo *AllocatedTypeInfo,
-             SourceLocation startLoc, SourceLocation endLoc,
-             SourceLocation constructorLParen,
-             SourceLocation constructorRParen);
+             SourceLocation startLoc, SourceRange directInitRange);
   explicit CXXNewExpr(EmptyShell Shell)
     : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
 
   void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
-                         unsigned numConsArgs);
+                         bool hasInitializer);
 
   QualType getAllocatedType() const {
     assert(getType()->isPointerType());
@@ -1432,8 +1437,6 @@
   void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
   void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
-  CXXConstructorDecl *getConstructor() const { return Constructor; }
-  void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
 
   bool isArray() const { return Array; }
   Expr *getArraySize() {
@@ -1445,23 +1448,40 @@
 
   unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
   Expr **getPlacementArgs() {
-    return reinterpret_cast<Expr **>(SubExprs + Array);
+    return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
   }
 
   Expr *getPlacementArg(unsigned i) {
     assert(i < NumPlacementArgs && "Index out of range");
-    return cast<Expr>(SubExprs[Array + i]);
+    return getPlacementArgs()[i];
   }
   const Expr *getPlacementArg(unsigned i) const {
     assert(i < NumPlacementArgs && "Index out of range");
-    return cast<Expr>(SubExprs[Array + i]);
+    return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
   }
 
   bool isParenTypeId() const { return TypeIdParens.isValid(); }
   SourceRange getTypeIdParens() const { return TypeIdParens; }
 
   bool isGlobalNew() const { return GlobalNew; }
-  bool hasInitializer() const { return Initializer; }
+
+  /// \brief Whether this new-expression has any initializer at all.
+  bool hasInitializer() const { return StoredInitializationStyle > 0; }
+
+  /// \brief The kind of initializer this new-expression has.
+  InitializationStyle getInitializationStyle() const {
+    if (StoredInitializationStyle == 0)
+      return NoInit;
+    return static_cast<InitializationStyle>(StoredInitializationStyle-1);
+  }
+
+  /// \brief The initializer of this new-expression.
+  Expr *getInitializer() {
+    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+  }
+  const Expr *getInitializer() const {
+    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+  }
 
   /// Answers whether the usual array deallocation function for the
   /// allocated type expects the size of the allocation as a
@@ -1470,71 +1490,39 @@
     return UsualArrayDeleteWantsSize;
   }
 
-  unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
-
-  Expr **getConstructorArgs() {
-    return reinterpret_cast<Expr **>(SubExprs + Array + NumPlacementArgs);
-  }
-
-  Expr *getConstructorArg(unsigned i) {
-    assert(i < NumConstructorArgs && "Index out of range");
-    return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
-  }
-  const Expr *getConstructorArg(unsigned i) const {
-    assert(i < NumConstructorArgs && "Index out of range");
-    return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
-  }
-
-  /// \brief Whether the new expression refers a constructor that was
-  /// resolved from an overloaded set having size greater than 1.
-  bool hadMultipleCandidates() const { return HadMultipleCandidates; }
-  void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
-
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
 
   arg_iterator placement_arg_begin() {
-    return SubExprs + Array;
+    return SubExprs + Array + hasInitializer();
   }
   arg_iterator placement_arg_end() {
-    return SubExprs + Array + getNumPlacementArgs();
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
   }
   const_arg_iterator placement_arg_begin() const {
-    return SubExprs + Array;
+    return SubExprs + Array + hasInitializer();
   }
   const_arg_iterator placement_arg_end() const {
-    return SubExprs + Array + getNumPlacementArgs();
-  }
-
-  arg_iterator constructor_arg_begin() {
-    return SubExprs + Array + getNumPlacementArgs();
-  }
-  arg_iterator constructor_arg_end() {
-    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
-  }
-  const_arg_iterator constructor_arg_begin() const {
-    return SubExprs + Array + getNumPlacementArgs();
-  }
-  const_arg_iterator constructor_arg_end() const {
-    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
   }
 
   typedef Stmt **raw_arg_iterator;
   raw_arg_iterator raw_arg_begin() { return SubExprs; }
   raw_arg_iterator raw_arg_end() {
-    return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
   }
   const_arg_iterator raw_arg_begin() const { return SubExprs; }
-  const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
+  const_arg_iterator raw_arg_end() const {
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+  }
 
   SourceLocation getStartLoc() const { return StartLoc; }
-  SourceLocation getEndLoc() const { return EndLoc; }
+  SourceLocation getEndLoc() const;
 
-  SourceLocation getConstructorLParen() const { return ConstructorLParen; }
-  SourceLocation getConstructorRParen() const { return ConstructorRParen; }
+  SourceRange getDirectInitRange() const { return DirectInitRange; }
 
   SourceRange getSourceRange() const {
-    return SourceRange(StartLoc, EndLoc);
+    return SourceRange(getStartLoc(), getEndLoc());
   }
 
   static bool classof(const Stmt *T) {
@@ -1544,9 +1532,7 @@
 
   // Iterators
   child_range children() {
-    return child_range(&SubExprs[0],
-                       &SubExprs[0] + Array + getNumPlacementArgs()
-                         + getNumConstructorArgs());
+    return child_range(raw_arg_begin(), raw_arg_end());
   }
 };
 

Modified: cfe/branches/tooling/include/clang/AST/OperationKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/OperationKinds.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/OperationKinds.h (original)
+++ cfe/branches/tooling/include/clang/AST/OperationKinds.h Mon Feb 20 19:34:24 2012
@@ -117,6 +117,15 @@
   /// against the null member pointer.
   CK_MemberPointerToBoolean,
 
+  /// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a
+  /// different kind of member pointer.  C++ forbids this from
+  /// crossing between function and object types, but otherwise does
+  /// not restrict it.  However, the only operation that is permitted
+  /// on a "punned" member pointer is casting it back to the original
+  /// type, which is required to be a lossless operation (although
+  /// many ABIs do not guarantee this on all possible intermediate types).
+  CK_ReinterpretMemberPointer,
+
   /// CK_UserDefinedConversion - Conversion using a user defined type
   /// conversion function.
   ///    struct A { operator int(); }; int i = int(A());

Modified: cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h Mon Feb 20 19:34:24 2012
@@ -228,6 +228,11 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
 
+  /// \brief Recursively visit a lambda capture.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaCapture(LambdaExpr::Capture C);
+  
   // ---- Methods on Stmts ----
 
   // Declare Traverse*() for all concrete Stmt classes.
@@ -675,6 +680,10 @@
   return true;
 }
 
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr::Capture C){
+  return true;
+}
 
 // ----------------- Type traversal -----------------
 
@@ -1654,7 +1663,9 @@
 template<typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
   TRY_TO(TraverseDeclaratorHelper(D));
-  TRY_TO(TraverseStmt(D->getInit()));
+  // Default params are taken care of when we traverse the ParmVarDecl.
+  if (!isa<ParmVarDecl>(D))
+    TRY_TO(TraverseStmt(D->getInit()));
   return true;
 }
 
@@ -1953,9 +1964,36 @@
     TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
   })
 
-DEF_TRAVERSE_STMT(LambdaExpr, {
-    TRY_TO(TraverseStmt(S->getBody()));
-  })
+// Walk only the visible parts of lambda expressions.  
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+  for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
+                                 CEnd = S->explicit_capture_end();
+       C != CEnd; ++C) {
+    TRY_TO(TraverseLambdaCapture(*C));
+  }
+
+  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+      // Visit the whole type.
+      TRY_TO(TraverseTypeLoc(TL));
+    } else if (isa<FunctionProtoTypeLoc>(TL)) {
+      FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+      if (S->hasExplicitParameters()) {
+        // Visit parameters.
+        for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getArg(I)));
+        }
+      } else {
+        TRY_TO(TraverseTypeLoc(Proto.getResultLoc()));
+      }        
+    }
+  }
+
+  TRY_TO(TraverseStmt(S->getBody()));
+  return true;
+}
 
 DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
     // This is called for code like 'T()', where T is a template argument.

Modified: cfe/branches/tooling/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Stmt.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Stmt.h (original)
+++ cfe/branches/tooling/include/clang/AST/Stmt.h Mon Feb 20 19:34:24 2012
@@ -213,6 +213,20 @@
     unsigned ShouldCopy : 1;
   };
 
+  class InitListExprBitfields {
+    friend class InitListExpr;
+
+    unsigned : NumExprBits;
+
+    /// Whether this initializer list originally had a GNU array-range
+    /// designator in it. This is a temporary marker used by CodeGen.
+    unsigned HadArrayRangeDesignator : 1;
+
+    /// Whether this initializer list initializes a std::initializer_list
+    /// object.
+    unsigned InitializesStdInitializerList : 1;
+  };
+
   union {
     // FIXME: this is wasteful on 64-bit platforms.
     void *Aligner;
@@ -226,6 +240,7 @@
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
     PseudoObjectExprBitfields PseudoObjectExprBits;
     ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
+    InitListExprBitfields InitListExprBits;
   };
 
   friend class ASTStmtReader;

Modified: cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchers.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchers.h Mon Feb 20 19:34:24 2012
@@ -923,17 +923,6 @@
   return Node.getNumArgs() == N;
 }
 
-/// \brief Checks that a new expression has a specific number of constructor
-/// arguments (including absent default arguments).
-///
-/// Given
-///   new X(1, 2);
-/// NewExpression(ConstructorArgumentCountIs(2))
-///   matches 'new X(1, 2)'.
-AST_MATCHER_P(clang::CXXNewExpr, ConstructorArgumentCountIs, unsigned, N) {
-  return Node.getNumConstructorArgs() == N;
-}
-
 /// \brief Matches the n'th argument of a call expression or a constructor
 /// call expression.
 ///
@@ -951,24 +940,6 @@
               *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
 }
 
-/// \brief Matches the n'th constructor argument of new expression.
-///
-/// Given
-///   int x;
-///   new X(1, y);
-/// NewExpression(HasConstructorArgument(1, DeclarationReference()))
-///   matches 'new X(1, y)',
-/// with DeclarationReference()
-///   matching 'y'.
-AST_MATCHER_P2(
-    clang::CXXNewExpr, HasConstructorArgument, unsigned, N,
-    internal::Matcher<clang::Expr>, InnerMatcher) {
-  return (N < Node.getNumConstructorArgs() &&
-          InnerMatcher.Matches(
-              *Node.getConstructorArg(N)->IgnoreParenImpCasts(),
-              Finder, Builder));
-}
-
 /// \brief Matches a constructor initializer.
 ///
 /// Given

Modified: cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/branches/tooling/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Feb 20 19:34:24 2012
@@ -304,16 +304,6 @@
       InnerMatcher.Matches(*NodeAsDecl, Finder, Builder);
   }
 
-  /// \brief Extracts the Decl of the constructor ran by the new expression and
-  /// returns whether the inner matcher matches on it.
-  bool MatchesSpecialized(const clang::CXXNewExpr& Node,
-                          ASTMatchFinder* Finder,
-                          BoundNodesTreeBuilder* Builder) const {
-    const clang::Decl* NodeAsDecl = Node.getConstructor();
-    return NodeAsDecl != NULL &&
-        InnerMatcher.Matches(*NodeAsDecl, Finder, Builder);
-  }
-
   const Matcher<clang::Decl> InnerMatcher;
 };
 

Modified: cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h Mon Feb 20 19:34:24 2012
@@ -66,7 +66,8 @@
     AsChar,       // 'hh'
     AsShort,      // 'h'
     AsLong,       // 'l'
-    AsLongLong,   // 'll', 'q' (BSD, deprecated)
+    AsLongLong,   // 'll'
+    AsQuad,       // 'q' (BSD, deprecated, for 64-bit integer types)
     AsIntMax,     // 'j'
     AsSizeT,      // 'z'
     AsPtrDiff,    // 't'
@@ -467,10 +468,11 @@
   const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
   bool usesPositionalArg() const { return UsesPositionalArg; }
 
-    /// Changes the specifier and length according to a QualType, retaining any
-    /// flags or options. Returns true on success, or false when a conversion
-    /// was not successful.
-  bool fixType(QualType QT, const LangOptions &LangOpt);
+  /// Changes the specifier and length according to a QualType, retaining any
+  /// flags or options. Returns true on success, or false when a conversion
+  /// was not successful.
+  bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
+               bool IsObjCLiteral);
 
   void toString(raw_ostream &os) const;
 
@@ -567,7 +569,7 @@
 
   ScanfArgTypeResult getArgType(ASTContext &Ctx) const;
 
-  bool fixType(QualType QT, const LangOptions &LangOpt);
+  bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
 
   void toString(raw_ostream &os) const;
 

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td Mon Feb 20 19:34:24 2012
@@ -35,9 +35,7 @@
   "non-literal type %0 cannot be used in a constant expression">;
 def note_constexpr_non_global : Note<
   "%select{pointer|reference}0 to %select{|subobject of }1"
-  "%select{temporary|%4}2 %select{is not a constant expression|"
-  "cannot be returned from a constexpr function|"
-  "cannot be used to initialize a member in a constant expression}3">;
+  "%select{temporary|%3}2 is not a constant expression">;
 def note_constexpr_array_index : Note<"cannot refer to element %0 of "
   "%select{array of %2 elements|non-array object}1 in a constant expression">;
 def note_constexpr_float_arithmetic : Note<
@@ -60,12 +58,14 @@
   "%select{temporary|%2}1 is not a constant expression">;
 def note_constexpr_past_end_subobject : Note<
   "cannot %select{access base class of|access derived class of|access field of|"
-  "access array element of|ERROR|call member function on}0 "
+  "access array element of|ERROR|call member function on|"
+  "access real component of|access imaginary component of}0 "
   "pointer past the end of object">;
 def note_constexpr_null_subobject : Note<
   "cannot %select{access base class of|access derived class of|access field of|"
   "access array element of|perform pointer arithmetic on|"
-  "call member function on}0 null pointer">;
+  "call member function on|access real component of|"
+  "access imaginary component of}0 null pointer">;
 def note_constexpr_var_init_non_constant : Note<
   "initializer of %0 is not a constant expression">;
 def note_constexpr_typeid_polymorphic : Note<
@@ -74,8 +74,15 @@
 def note_constexpr_void_comparison : Note<
   "comparison between unequal pointers to void has unspecified result">;
 def note_constexpr_temporary_here : Note<"temporary created here">;
+def note_constexpr_conditional_never_const : Note<
+  "both arms of conditional operator are unable to produce a "
+  "constant expression">;
 def note_constexpr_depth_limit_exceeded : Note<
   "constexpr evaluation exceeded maximum depth of %0 calls">;
+def note_constexpr_call_limit_exceeded : Note<
+  "constexpr evaluation hit maximum call limit">;
+def note_constexpr_lifetime_ended : Note<
+  "read of %select{temporary|variable}0 whose lifetime has ended">;
 def note_constexpr_ltor_volatile_type : Note<
   "read of volatile-qualified type %0 is not allowed in a constant expression">;
 def note_constexpr_ltor_volatile_obj : Note<

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td Mon Feb 20 19:34:24 2012
@@ -104,6 +104,7 @@
                                       [CXX98CompatLocalTypeTemplateArgs]>;
 def MalformedWarningCheck : DiagGroup<"malformed-warning-check">;
 def Main : DiagGroup<"main">;
+def MainReturnType : DiagGroup<"main-return-type">;
 def MissingBraces : DiagGroup<"missing-braces">;
 def MissingDeclarations: DiagGroup<"missing-declarations">;
 def : DiagGroup<"missing-format-attribute">;
@@ -182,6 +183,7 @@
 def : DiagGroup<"strict-overflow">;
 
 def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
+def LambdaExtensions : DiagGroup<"lambda-extensions">;
 def : DiagGroup<"strict-prototypes">;
 def StrictSelector : DiagGroup<"strict-selector-match">;
 def MethodDuplicate : DiagGroup<"duplicate-method-match">;
@@ -332,7 +334,9 @@
 // Thread Safety warnings 
 def ThreadSafety : DiagGroup<"thread-safety">;
 
-// -Wall is -Wmost -Wparentheses -Wdangling-else -Wswitch
+// Note that putting warnings in -Wall will not disable them by default. If a
+// warning should be active _only_ when -Wall is passed in, mark it as
+// DefaultIgnore in addition to putting it here.
 def : DiagGroup<"all", [Most, Parentheses, Switch]>;
 
 // Aliases.
@@ -360,6 +364,8 @@
 
 // A warning group for warnings about GCC extensions.
 def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
+// A warning group for warnings about code that clang accepts but gcc doesn't.
+def GccCompat : DiagGroup<"gcc-compat">;
 
 // A warning group for warnings about Microsoft extensions.
 def Microsoft : DiagGroup<"microsoft">;

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h Mon Feb 20 19:34:24 2012
@@ -223,31 +223,6 @@
   /// are not SFINAE errors.
   static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
 
-  /// getName - Given a diagnostic ID, return its name
-  static StringRef getName(unsigned DiagID);
-  
-  /// getIdFromName - Given a diagnostic name, return its ID, or 0
-  static unsigned getIdFromName(StringRef Name);
-  
-  /// Iterator class used for traversing all statically declared
-  /// diagnostics.
-  class diag_iterator {
-    const void *impl;
-
-    friend class DiagnosticIDs;    
-    diag_iterator(const void *im) : impl(im) {}
-  public:
-    diag_iterator &operator++();
-    bool operator==(const diag_iterator &x) const { return impl == x.impl; }
-    bool operator!=(const diag_iterator &x) const { return impl != x.impl; }
-    
-    llvm::StringRef getDiagName() const;
-    unsigned getDiagID() const;    
-  };
-
-  static diag_iterator diags_begin();
-  static diag_iterator diags_end();
-
   /// \brief Get the set of all diagnostic IDs in the group with the given name.
   ///
   /// \param Diags [out] - On return, the diagnostics in the group.

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td Mon Feb 20 19:34:24 2012
@@ -151,6 +151,9 @@
 
 def err_expected_fn_body : Error<
   "expected function body after function declarator">;
+def warn_attribute_on_function_definition : Warning<
+  "GCC does not allow %0 attribute in this position on a function definition">, 
+  InGroup<GccCompat>;
 def err_expected_method_body : Error<"expected method body">;
 def err_invalid_token_after_toplevel_declarator : Error<
   "expected ';' after top level declarator">;
@@ -327,8 +330,8 @@
 def err_arc_bridge_retain : Error<
   "unknown cast annotation __bridge_retain; did you mean __bridge_retained?">;
 // To be default mapped to an error later.
-def err_arc_bridge_cast_nonarc : Warning<
-  "'%0' casts are only allowed when using ARC">,
+def warn_arc_bridge_cast_nonarc : Warning<
+  "'%0' casts have no effect when not using ARC">,
   InGroup<DiagGroup<"arc-bridge-casts-disallowed-in-nonarc">>;
 }
   
@@ -599,6 +602,8 @@
 def warn_cxx98_compat_lambda : Warning<
   "lambda expressions are incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
+def err_lambda_missing_parens : Error<
+  "lambda requires '()' before %select{'mutable'|return type}0">;
 
 // Availability attribute
 def err_expected_version : Error<

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td Mon Feb 20 19:34:24 2012
@@ -346,6 +346,8 @@
   "'main' is not allowed to be declared constexpr">;
 def err_main_template_decl : Error<"'main' cannot be a template">;
 def err_main_returns_nonint : Error<"'main' must return 'int'">;
+def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
+    InGroup<MainReturnType>;
 def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
     "must be 0, 2, or 3">;
 def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
@@ -971,8 +973,13 @@
   "because type %0 has a user-declared %select{constructor|copy constructor|"
   "move constructor|copy assignment operator|move assignment operator|"
   "destructor}1">;
-def err_static_data_member_not_allowed_in_union_or_anon_struct : Error<
-  "static data member %0 not allowed in %select{anonymous struct|union}1">; 
+def err_static_data_member_not_allowed_in_anon_struct : Error<
+  "static data member %0 not allowed in anonymous struct">;
+def ext_static_data_member_in_union : ExtWarn<
+  "static data member %0 in union is a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_static_data_member_in_union : Warning<
+  "static data member %0 in union is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_union_member_of_reference_type : Error<
   "union member %0 has reference type %1">;
 def ext_anonymous_struct_union_qualified : Extension<
@@ -1139,24 +1146,24 @@
   "no viable constructor %select{copying variable|copying parameter|"
   "returning object|throwing object|copying member subobject|copying array "
   "element|allocating object|copying temporary|initializing base subobject|"
-  "initializing vector element}0 of type %1">;
+  "initializing vector element|capturing value}0 of type %1">;
 def ext_rvalue_to_reference_temp_copy_no_viable : ExtWarn<
   "no viable constructor %select{copying variable|copying parameter|"
   "returning object|throwing object|copying member subobject|copying array "
   "element|allocating object|copying temporary|initializing base subobject|"
-  "initializing vector element}0 of type %1; C++98 requires a copy "
+  "initializing vector element|capturing value}0 of type %1; C++98 requires a copy "
   "constructor when binding a reference to a temporary">,
   InGroup<BindToTemporaryCopy>;
 def err_temp_copy_ambiguous : Error<
   "ambiguous constructor call when %select{copying variable|copying "
   "parameter|returning object|throwing object|copying member subobject|copying "
   "array element|allocating object|copying temporary|initializing base subobject|"
-  "initializing vector element}0 of type %1">;
+  "initializing vector element|capturing value}0 of type %1">;
 def err_temp_copy_deleted : Error<
   "%select{copying variable|copying parameter|returning object|throwing "
   "object|copying member subobject|copying array element|allocating object|"
-  "copying temporary|initializing base subobject|initializing vector element}0 "
-  "of type %1 invokes deleted constructor">;
+  "copying temporary|initializing base subobject|initializing vector element|"
+  "capturing value}0 of type %1 invokes deleted constructor">;
 def err_temp_copy_incomplete : Error<
   "copying a temporary object of incomplete type %0">;
 def warn_cxx98_compat_temp_copy : Warning<
@@ -2102,6 +2109,10 @@
   "reference initialization of type %0 with initializer of type %1 is ambiguous">;
 def err_ovl_deleted_init : Error<
   "call to %select{unavailable|deleted}0 constructor of %1">;
+def err_ovl_deleted_special_init : Error<
+  "call to implicitly-deleted %select{default constructor|copy constructor|"
+  "move constructor|copy assignment operator|move assignment operator|"
+  "destructor|function}0 of %1">;
 def err_ovl_ambiguous_oper_unary : Error<
   "use of overloaded operator '%0' is ambiguous (operand type %1)">;
 def err_ovl_ambiguous_oper_binary : Error<
@@ -2109,6 +2120,10 @@
 def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
 def err_ovl_deleted_oper : Error<
   "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
+def err_ovl_deleted_special_oper : Error<
+  "overload resolution selected implicitly-deleted %select{default constructor|"
+  "copy constructor|move constructor|copy assignment operator|move assignment "
+  "operator|destructor|'%1'}0%2">;
 def err_ovl_no_viable_subscript :
     Error<"no viable overloaded operator[] for type %0">;
 def err_ovl_no_oper :
@@ -3540,7 +3555,11 @@
   "cannot initialize array of type %0 with non-constant array of type %1">;
 def ext_array_init_copy : Extension<
   "initialization of an array of type %0 from a compound literal of type %1 is "
-  "a GNU extension">;
+  "a GNU extension">, InGroup<GNU>;
+// This is intentionally not disabled by -Wno-gnu.
+def ext_array_init_parens : ExtWarn<
+  "parenthesized initialization of a member array is a GNU extension">,
+  InGroup<DiagGroup<"gnu-array-member-paren-init">>, DefaultError;
 def warn_deprecated_string_literal_conversion : Warning<
   "conversion from string literal to %0 is deprecated">, InGroup<DeprecatedWritableStr>;
 def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
@@ -3997,41 +4016,70 @@
 def err_return_in_constructor_handler : Error<
   "return in the catch of a function try block of a constructor is illegal">;
 
-def err_capture_more_than_once : Error<
-  "%0 can appear only once in a capture list">;
-def err_reference_capture_with_reference_default : Error<
-  "'&' cannot precede a capture when the capture default is '&'">;
-def err_this_capture_with_copy_default : Error<
-  "'this' cannot be explicitly captured when the capture default is '='">;
-def err_copy_capture_with_copy_default : Error<
-  "'&' must precede a capture when the capture default is '='">;
-def err_capture_does_not_name_variable : Error<
-  "%0 in capture list does not name a variable">;
-def err_capture_non_automatic_variable : Error<
-  "%0 cannot be captured because it does not have automatic storage duration">;
-def err_this_capture : Error<
-  "'this' cannot be %select{implicitly |}0captured in this context">;
-def err_lambda_capture_block : Error<
-  "__block variable %0 cannot be captured in a lambda expression">;
-def err_lambda_capture_anonymous_var : Error<
-  "unnamed variable cannot be implicitly captured in a lambda expression">;
-def err_lambda_capture_vm_type : Error<
-  "variable %0 with variably modified type cannot be captured in "
-  "a lambda expression">;
-def err_lambda_impcap : Error<
-  "variable %0 cannot be implicitly captured in a lambda with no "
-  "capture-default specified">;
-def note_lambda_decl : Note<"lambda expression begins here">;
-def err_lambda_unevaluated_operand : Error<
-  "lambda expression in an unevaluated operand">;
-def ext_lambda_implies_void_return : ExtWarn<
-  "C++11 requires lambda with omitted result type to consist of a single "
-  "return statement">,
-  InGroup<DiagGroup<"lambda-return">>;
-def err_lambda_return_init_list : Error<
-  "cannot deduce lambda return type from initializer list">;
-def err_lambda_capture_default_arg : Error<
-  "lambda expression in default argument cannot capture any entity">;
+let CategoryName = "Lambda Issue" in {
+  def err_capture_more_than_once : Error<
+    "%0 can appear only once in a capture list">;
+  def err_reference_capture_with_reference_default : Error<
+    "'&' cannot precede a capture when the capture default is '&'">;
+  def err_this_capture_with_copy_default : Error<
+    "'this' cannot be explicitly captured when the capture default is '='">;
+  def err_copy_capture_with_copy_default : Error<
+    "'&' must precede a capture when the capture default is '='">;
+  def err_capture_does_not_name_variable : Error<
+    "%0 in capture list does not name a variable">;
+  def err_capture_non_automatic_variable : Error<
+    "%0 cannot be captured because it does not have automatic storage "
+    "duration">;
+  def err_this_capture : Error<
+    "'this' cannot be %select{implicitly |}0captured in this context">;
+  def err_lambda_capture_block : Error<
+    "__block variable %0 cannot be captured in a lambda expression">;
+  def err_lambda_capture_anonymous_var : Error<
+    "unnamed variable cannot be implicitly captured in a lambda expression">;
+  def err_lambda_capture_vm_type : Error<
+    "variable %0 with variably modified type cannot be captured in "
+    "a lambda expression">;
+  def err_lambda_impcap : Error<
+    "variable %0 cannot be implicitly captured in a lambda with no "
+    "capture-default specified">;
+  def note_lambda_decl : Note<"lambda expression begins here">;
+  def err_lambda_unevaluated_operand : Error<
+    "lambda expression in an unevaluated operand">;
+  def ext_lambda_implies_void_return : ExtWarn<
+    "C++11 requires lambda with omitted result type to consist of a single "
+    "return statement">,
+    InGroup<LambdaExtensions>;
+  def err_lambda_return_init_list : Error<
+    "cannot deduce lambda return type from initializer list">;
+  def err_lambda_capture_default_arg : Error<
+    "lambda expression in default argument cannot capture any entity">;
+  def err_lambda_unexpanded_pack : Error<
+    "unexpanded function parameter pack capture is unsupported">;
+  def err_lambda_incomplete_result : Error<
+    "incomplete result type %0 in lambda expression">;
+  def err_lambda_objc_object_result : Error<
+    "non-pointer Objective-C class type %0 in lambda expression result">;
+  def ext_lambda_default_arguments : ExtWarn<
+    "C++11 forbids default arguments for lambda expressions">,
+    InGroup<LambdaExtensions>;
+  def err_noreturn_lambda_has_return_expr : Error<
+    "lambda declared 'noreturn' should not return">;
+  def warn_maybe_falloff_nonvoid_lambda : Warning<
+    "control may reach end of non-void lambda">,
+    InGroup<ReturnType>;
+  def warn_falloff_nonvoid_lambda : Warning<
+    "control reaches end of non-void lambda">,
+    InGroup<ReturnType>;
+  def err_access_lambda_capture : Error<
+    // The ERRORs represent other special members that aren't constructors, in
+    // hopes that someone will bother noticing and reporting if they appear
+    "capture of variable '%0' as type %1 calls %select{private|protected}3 "
+    "%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}2constructor">,
+    AccessControl;
+  def note_lambda_to_block_conv : Note<
+    "implicit capture of lambda object due to conversion to block pointer "
+    "here">;
+}
 
 def err_operator_arrow_circular : Error<
   "circular pointer delegation detected">;
@@ -4128,8 +4176,8 @@
   "%select{none|const|restrict|const and restrict|volatile|const and volatile|"
   "volatile and restrict|const, volatile, and restrict}6)}4">;
 def err_typecheck_missing_return_type_incompatible : Error<
-  "return type %0 must match previous return type %1 when block"
-  " literal has unspecified explicit return type">;
+  "return type %0 must match previous return type %1 when %select{block "
+  "literal|lambda expression}2 has unspecified explicit return type">;
 
 def warn_incompatible_qualified_id : Warning<
   "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
@@ -4279,6 +4327,8 @@
   "expected at most %1, have %2">;
 def note_callee_decl : Note<
   "%0 declared here">;
+def note_defined_here : Note<"%0 defined here">;
+
 def warn_call_wrong_number_of_arguments : Warning<
   "too %select{few|many}0 arguments in call to %1">;
 def err_atomic_builtin_must_be_pointer : Error<
@@ -4955,8 +5005,20 @@
   "switch condition type %0 requires explicit conversion to %1">;
 def err_switch_incomplete_class_type : Error<
   "switch condition has incomplete class type %0">;
+
 def warn_empty_if_body : Warning<
   "if statement has empty body">, InGroup<EmptyBody>;
+def warn_empty_for_body : Warning<
+  "for loop has empty body">, InGroup<EmptyBody>;
+def warn_empty_range_based_for_body : Warning<
+  "range-based for loop has empty body">, InGroup<EmptyBody>;
+def warn_empty_while_body : Warning<
+  "while loop has empty body">, InGroup<EmptyBody>;
+def warn_empty_switch_body : Warning<
+  "switch statement has empty body">, InGroup<EmptyBody>;
+def note_empty_body_on_separate_line : Note<
+  "put the semicolon on a separate line to silence this warning">,
+  InGroup<EmptyBody>;
 
 def err_va_start_used_in_non_variadic_function : Error<
   "'va_start' used in function with fixed args">;

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/CC1Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/CC1Options.td Mon Feb 20 19:34:24 2012
@@ -290,8 +290,6 @@
   HelpText<"Print source range spans in numeric form">;
 def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">,
   HelpText<"Print fix-its in machine parseable form">;
-def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">,
-  HelpText<"Print diagnostic name">;
 def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
   HelpText<"Print option name with mappable diagnostics">;
 def fdiagnostics_format : Separate<"-fdiagnostics-format">,

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/Options.td Mon Feb 20 19:34:24 2012
@@ -301,7 +301,6 @@
 def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_clang_Group>;
 def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Group<f_clang_Group>;
 def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
-def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">, Group<f_Group>;
 def fdiagnostics_show_note_include_stack : Flag<"-fdiagnostics-show-note-include-stack">, Group<f_Group>;
 def fdiagnostics_format_EQ : Joined<"-fdiagnostics-format=">, Group<f_clang_Group>;
 def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_clang_Group>;
@@ -402,7 +401,6 @@
 def fno_cxx_exceptions: Flag<"-fno-cxx-exceptions">, Group<f_Group>;
 def fno_cxx_modules : Flag <"-fno-cxx-modules">, Group<f_Group>, Flags<[NoForward]>;
 def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
-def fno_diagnostics_show_name : Flag<"-fno-diagnostics-show-name">, Group<f_Group>;
 def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
 def fno_diagnostics_show_note_include_stack : Flag<"-fno-diagnostics-show-note-include-stack">, Group<f_Group>;
 def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
@@ -758,6 +756,8 @@
 def s : Flag<"-s">;
 def target : Separate<"-target">, Flags<[DriverOption]>,
   HelpText<"Generate code for the given target">;
+def gcc_toolchain : Separate<"-gcc-toolchain">, Flags<[DriverOption]>,
+  HelpText<"Use the gcc toolchain at the given directory">;
 // We should deprecate the use of -ccc-host-triple, and then remove.
 def ccc_host_triple : Separate<"-ccc-host-triple">, Alias<target>;
 def time : Flag<"-time">,

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h Mon Feb 20 19:34:24 2012
@@ -31,7 +31,6 @@
   unsigned ShowFixits : 1;       /// Show fixit information.
   unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form.
   unsigned ShowParseableFixits : 1; /// Show machine parseable fix-its.
-  unsigned ShowNames : 1;        /// Show the diagnostic name
   unsigned ShowOptionNames : 1;  /// Show the option name for mappable
                                  /// diagnostics.
   unsigned ShowNoteIncludeStack : 1; /// Show include stacks for notes.
@@ -91,7 +90,6 @@
     ShowColumn = 1;
     ShowFixits = 1;
     ShowLocation = 1;
-    ShowNames = 0;
     ShowOptionNames = 0;
     ShowCategories = 0;
     Format = Clang;

Modified: cfe/branches/tooling/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Parse/Parser.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Parse/Parser.h (original)
+++ cfe/branches/tooling/include/clang/Parse/Parser.h Mon Feb 20 19:34:24 2012
@@ -162,6 +162,7 @@
   OwningPtr<PragmaHandler> MSStructHandler;
   OwningPtr<PragmaHandler> UnusedHandler;
   OwningPtr<PragmaHandler> WeakHandler;
+  OwningPtr<PragmaHandler> RedefineExtnameHandler;
   OwningPtr<PragmaHandler> FPContractHandler;
   OwningPtr<PragmaHandler> OpenCLExtensionHandler;
 
@@ -1157,7 +1158,10 @@
                                 ExprResult& Init);
   void ParseCXXNonStaticMemberInitializer(Decl *VarD);
   void ParseLexedAttributes(ParsingClass &Class);
-  void ParseLexedAttribute(LateParsedAttribute &LA);
+  void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
+                               bool EnterScope, bool OnDefinition);
+  void ParseLexedAttribute(LateParsedAttribute &LA,
+                           bool EnterScope, bool OnDefinition);
   void ParseLexedMethodDeclarations(ParsingClass &Class);
   void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
   void ParseLexedMethodDefs(ParsingClass &Class);
@@ -1196,7 +1200,8 @@
                                                   AccessSpecifier AS = AS_none);
 
   Decl *ParseFunctionDefinition(ParsingDeclarator &D,
-                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                 LateParsedAttrList *LateParsedAttrs = 0);
   void ParseKNRParamDeclarations(Declarator &D);
   // EndLoc, if non-NULL, is filled with the location of the last token of
   // the simple-asm.
@@ -1469,6 +1474,7 @@
       return ParseAssignmentExpression();
     return ParseBraceInitializer();
   }
+  bool MayBeDesignationStart();
   ExprResult ParseBraceInitializer();
   ExprResult ParseInitializerWithPotentialDesignator();
 
@@ -1642,7 +1648,7 @@
                                 ForRangeInit *FRI = 0);
   Decl *ParseDeclarationAfterDeclarator(Declarator &D,
                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
-  bool ParseAttributesAfterDeclarator(Declarator &D);
+  bool ParseAsmAttributesAfterDeclarator(Declarator &D);
   Decl *ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
   Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);

Modified: cfe/branches/tooling/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/DeclSpec.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/DeclSpec.h (original)
+++ cfe/branches/tooling/include/clang/Sema/DeclSpec.h Mon Feb 20 19:34:24 2012
@@ -1923,10 +1923,12 @@
   LambdaCaptureKind Kind;
   SourceLocation Loc;
   IdentifierInfo* Id;
-
+  SourceLocation EllipsisLoc;
+  
   LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
-                IdentifierInfo* Id = 0)
-    : Kind(Kind), Loc(Loc), Id(Id)
+                IdentifierInfo* Id = 0,
+                SourceLocation EllipsisLoc = SourceLocation())
+    : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc)
   {}
 };
 
@@ -1943,8 +1945,9 @@
   /// addCapture - Append a capture in a lambda introducer.
   void addCapture(LambdaCaptureKind Kind,
                   SourceLocation Loc,
-                  IdentifierInfo* Id = 0) {
-    Captures.push_back(LambdaCapture(Kind, Loc, Id));
+                  IdentifierInfo* Id = 0, 
+                  SourceLocation EllipsisLoc = SourceLocation()) {
+    Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc));
   }
 
 };

Modified: cfe/branches/tooling/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Initialization.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Initialization.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Initialization.h Mon Feb 20 19:34:24 2012
@@ -70,7 +70,10 @@
     EK_BlockElement,
     /// \brief The entity being initialized is the real or imaginary part of a
     /// complex number.
-    EK_ComplexElement
+    EK_ComplexElement,
+    /// \brief The entity being initialized is the field that captures a 
+    /// variable in a lambda.
+    EK_LambdaCapture
   };
   
 private:
@@ -85,7 +88,7 @@
   QualType Type;
   
   union {
-    /// \brief When Kind == EK_Variable or EK_Member, the VarDecl or
+    /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
     /// FieldDecl, respectively.
     DeclaratorDecl *VariableOrMember;
 
@@ -98,7 +101,7 @@
     TypeSourceInfo *TypeInfo;
     
     struct {
-      /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the
+      /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
       /// location of the 'return', 'throw', or 'new' keyword,
       /// respectively. When Kind == EK_Temporary, the location where
       /// the temporary is being created.
@@ -118,6 +121,14 @@
     /// EK_ComplexElement, the index of the array or vector element being
     /// initialized. 
     unsigned Index;
+    
+    struct {
+      /// \brief The variable being captured by an EK_LambdaCapture.
+      VarDecl *Var;
+      
+      /// \brief The source location at which the capture occurs.
+      unsigned Location;
+    } Capture;
   };
 
   InitializedEntity() { }
@@ -147,6 +158,14 @@
   InitializedEntity(ASTContext &Context, unsigned Index, 
                     const InitializedEntity &Parent);
 
+  /// \brief Create the initialization entity for a lambda capture.
+  InitializedEntity(VarDecl *Var, FieldDecl *Field, SourceLocation Loc)
+    : Kind(EK_LambdaCapture), Parent(0), Type(Field->getType()) 
+  {
+    Capture.Var = Var;
+    Capture.Location = Loc.getRawEncoding();
+  }
+  
 public:
   /// \brief Create the initialization entity for a variable.
   static InitializedEntity InitializeVariable(VarDecl *Var) {
@@ -246,6 +265,13 @@
     return InitializedEntity(Context, Index, Parent);
   }
 
+  /// \brief Create the initialization entity for a lambda capture.
+  static InitializedEntity InitializeLambdaCapture(VarDecl *Var,
+                                                   FieldDecl *Field,
+                                                   SourceLocation Loc) {
+    return InitializedEntity(Var, Field, Loc);
+  }
+                                                   
   /// \brief Determine the kind of initialization.
   EntityKind getKind() const { return Kind; }
   
@@ -317,6 +343,19 @@
            EK_ComplexElement);
     this->Index = Index;
   }
+
+  /// \brief Retrieve the variable for a captured variable in a lambda.
+  VarDecl *getCapturedVar() const {
+    assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
+    return Capture.Var;
+  }
+  
+  /// \brief Determine the location of the capture when initializing
+  /// field from a captured variable in a lambda.
+  SourceLocation getCaptureLoc() const {
+    assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
+    return SourceLocation::getFromRawEncoding(Capture.Location);
+  }
 };
   
 /// \brief Describes the kind of initialization being performed, along with 
@@ -553,6 +592,9 @@
     /// \brief Array initialization (from an array rvalue).
     /// This is a GNU C extension.
     SK_ArrayInit,
+    /// \brief Array initialization from a parenthesized initializer list.
+    /// This is a GNU C++ extension.
+    SK_ParenthesizedArrayInit,
     /// \brief Pass an object by indirect copy-and-restore.
     SK_PassByIndirectCopyRestore,
     /// \brief Pass an object by indirect restore.
@@ -873,6 +915,9 @@
   /// \brief Add an array initialization step.
   void AddArrayInitStep(QualType T);
 
+  /// \brief Add a parenthesized array initialization step.
+  void AddParenthesizedArrayInitStep(QualType T);
+
   /// \brief Add a step to pass an object by indirect copy-restore.
   void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy);
 

Modified: cfe/branches/tooling/include/clang/Sema/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Scope.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Scope.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Scope.h Mon Feb 20 19:34:24 2012
@@ -57,7 +57,7 @@
     /// BlockScope - This is a scope that corresponds to a block/closure object.
     /// Blocks serve as top-level scopes for some objects like labels, they
     /// also prevent things like break and continue.  BlockScopes always have
-    /// the FnScope, BreakScope, ContinueScope, and DeclScope flags set as well.
+    /// the FnScope and DeclScope flags set as well.
     BlockScope = 0x40,
 
     /// TemplateParamScope - This is a scope that corresponds to the
@@ -114,16 +114,12 @@
   /// pointer is non-null and points to it.  This is used for label processing.
   Scope *FnParent;
 
-  /// BreakParent/ContinueParent - This is a direct link to the immediately
-  /// preceding BreakParent/ContinueParent if this scope is not one, or null if
-  /// there is no containing break/continue scope.
+  /// BreakParent/ContinueParent - This is a direct link to the innermost
+  /// BreakScope/ContinueScope which contains the contents of this scope
+  /// for control flow purposes (and might be this scope itself), or null
+  /// if there is no such scope.
   Scope *BreakParent, *ContinueParent;
 
-  /// ControlParent - This is a direct link to the immediately
-  /// preceding ControlParent if this scope is not one, or null if
-  /// there is no containing control scope.
-  Scope *ControlParent;
-
   /// BlockParent - This is a direct link to the immediately containing
   /// BlockScope if this scope is not one, or null if there is none.
   Scope *BlockParent;
@@ -180,12 +176,9 @@
   Scope *getFnParent() { return FnParent; }
 
   /// getContinueParent - Return the closest scope that a continue statement
-  /// would be affected by.  If the closest scope is a closure scope, we know
-  /// that there is no loop *inside* the closure.
+  /// would be affected by.
   Scope *getContinueParent() {
-    if (ContinueParent && !ContinueParent->isBlockScope())
-      return ContinueParent;
-    return 0;
+    return ContinueParent;
   }
 
   const Scope *getContinueParent() const {
@@ -193,20 +186,14 @@
   }
 
   /// getBreakParent - Return the closest scope that a break statement
-  /// would be affected by.  If the closest scope is a block scope, we know
-  /// that there is no loop *inside* the block.
+  /// would be affected by.
   Scope *getBreakParent() {
-    if (BreakParent && !BreakParent->isBlockScope())
-      return BreakParent;
-    return 0;
+    return BreakParent;
   }
   const Scope *getBreakParent() const {
     return const_cast<Scope*>(this)->getBreakParent();
   }
 
-  Scope *getControlParent() { return ControlParent; }
-  const Scope *getControlParent() const { return ControlParent; }
-
   Scope *getBlockParent() { return BlockParent; }
   const Scope *getBlockParent() const { return BlockParent; }
 

Modified: cfe/branches/tooling/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/ScopeInfo.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/branches/tooling/include/clang/Sema/ScopeInfo.h Mon Feb 20 19:34:24 2012
@@ -32,6 +32,22 @@
 
 namespace sema {
 
+/// \brief Contains information about the compound statement currently being
+/// parsed.
+class CompoundScopeInfo {
+public:
+  CompoundScopeInfo()
+    : HasEmptyLoopBodies(false) { }
+
+  /// \brief Whether this compound stamement contains `for' or `while' loops
+  /// with empty bodies.
+  bool HasEmptyLoopBodies;
+
+  void setHasEmptyLoopBodies() {
+    HasEmptyLoopBodies = true;
+  }
+};
+
 class PossiblyUnreachableDiag {
 public:
   PartialDiagnostic PD;
@@ -79,7 +95,11 @@
   /// block, if there is any chance of applying the named return value
   /// optimization.
   SmallVector<ReturnStmt*, 4> Returns;
-  
+
+  /// \brief The stack of currently active compound stamement scopes in the
+  /// function.
+  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
+
   /// \brief A list of PartialDiagnostics created but delayed within the
   /// current function scope.  These diagnostics are vetted for reachability
   /// prior to being emitted.
@@ -151,16 +171,26 @@
     /// \brief The source location at which the first capture occurred..
     SourceLocation Loc;
     
+    /// \brief The location of the ellipsis that expands a parameter pack.
+    SourceLocation EllipsisLoc;
+    
+    /// \brief The type as it was captured, which is in effect the type of the
+    /// non-static data member that would hold the capture.
+    QualType CaptureType;
+    
   public:
     Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 
-            SourceLocation Loc, Expr *Cpy)
+            SourceLocation Loc, SourceLocation EllipsisLoc, 
+            QualType CaptureType, Expr *Cpy)
       : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
-        CopyExprAndNested(Cpy, isNested) {}
+        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
+        CaptureType(CaptureType){}
 
     enum IsThisCapture { ThisCapture };
-    Capture(IsThisCapture, bool isNested, SourceLocation Loc, Expr *Cpy)
-      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc) {
-    }
+    Capture(IsThisCapture, bool isNested, SourceLocation Loc, 
+            QualType CaptureType, Expr *Cpy)
+      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
+        EllipsisLoc(), CaptureType(CaptureType) { }
 
     bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
     bool isVariableCapture() const { return !isThisCapture(); }
@@ -176,6 +206,15 @@
     /// \brief Retrieve the location at which this variable was captured.
     SourceLocation getLocation() const { return Loc; }
     
+    /// \brief Retrieve the source location of the ellipsis, whose presence
+    /// indicates that the capture is a pack expansion.
+    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+    
+    /// \brief Retrieve the capture type for this capture, which is effectively
+    /// the type of the non-static data member in the lambda/block structure
+    /// that would store this capture.
+    QualType getCaptureType() const { return CaptureType; }
+    
     Expr *getCopyExpr() const {
       return CopyExprAndNested.getPointer();
     }
@@ -204,14 +243,18 @@
   /// or null if unknown.
   QualType ReturnType;
 
-  void AddCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
-                  SourceLocation Loc, Expr *Cpy) {
-    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, Cpy));
+  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
+                  SourceLocation Loc, SourceLocation EllipsisLoc, 
+                  QualType CaptureType, Expr *Cpy) {
+    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 
+                               EllipsisLoc, CaptureType, Cpy));
     CaptureMap[Var] = Captures.size();
   }
 
-  void AddThisCapture(bool isNested, SourceLocation Loc, Expr *Cpy) {
-    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, Cpy));
+  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
+                      Expr *Cpy) {
+    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
+                               Cpy));
     CXXThisCaptureIndex = Captures.size();
   }
 

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Sema.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Sema.h Mon Feb 20 19:34:24 2012
@@ -163,6 +163,7 @@
 namespace sema {
   class AccessedEntity;
   class BlockScopeInfo;
+  class CompoundScopeInfo;
   class DelayedDiagnostic;
   class FunctionScopeInfo;
   class LambdaScopeInfo;
@@ -468,6 +469,13 @@
   /// identifier, declared or undeclared
   llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
 
+  /// ExtnameUndeclaredIdentifiers - Identifiers contained in
+  /// #pragma redefine_extname before declared.  Used in Solaris system headers
+  /// to define functions that occur in multiple standards to call the version
+  /// in the currently selected standard.
+  llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers;
+
+
   /// \brief Load weak undeclared identifiers from the external source.
   void LoadExternalWeakUndeclaredIdentifiers();
 
@@ -744,6 +752,11 @@
     return FunctionScopes.back();
   }
 
+  void PushCompoundScope();
+  void PopCompoundScope();
+
+  sema::CompoundScopeInfo &getCurCompoundScope() const;
+
   bool hasAnyUnrecoverableErrorsInThisFunction() const;
 
   /// \brief Retrieve the current block, if any.
@@ -1696,9 +1709,6 @@
     ForRedeclaration
   };
 
-private:
-  bool CppLookupName(LookupResult &R, Scope *S);
-
   SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
                                                    CXXSpecialMember SM,
                                                    bool ConstArg,
@@ -1707,6 +1717,9 @@
                                                    bool ConstThis,
                                                    bool VolatileThis);
 
+private:
+  bool CppLookupName(LookupResult &R, Scope *S);
+
   // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls.
   //
   // The boolean value will be true to indicate that the namespace was loaded
@@ -2053,9 +2066,28 @@
 
   StmtResult ActOnNullStmt(SourceLocation SemiLoc,
                            bool HasLeadingEmptyMacro = false);
+
+  void ActOnStartOfCompoundStmt();
+  void ActOnFinishOfCompoundStmt();
   StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                                        MultiStmtArg Elts,
                                        bool isStmtExpr);
+
+  /// \brief A RAII object to enter scope of a compound statement.
+  class CompoundScopeRAII {
+  public:
+    CompoundScopeRAII(Sema &S): S(S) {
+      S.ActOnStartOfCompoundStmt();
+    }
+
+    ~CompoundScopeRAII() {
+      S.ActOnFinishOfCompoundStmt();
+    }
+
+  private:
+    Sema &S;
+  };
+
   StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc);
@@ -2204,6 +2236,21 @@
   void DiagnoseUnusedExprResult(const Stmt *S);
   void DiagnoseUnusedDecl(const NamedDecl *ND);
 
+  /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
+  /// statement as a \p Body, and it is located on the same line.
+  ///
+  /// This helps prevent bugs due to typos, such as:
+  ///     if (condition);
+  ///       do_stuff();
+  void DiagnoseEmptyStmtBody(SourceLocation StmtLoc,
+                             const Stmt *Body,
+                             unsigned DiagID);
+
+  /// Warn if a for/while loop statement \p S, which is followed by
+  /// \p PossibleBody, has a suspicious null statement as a body.
+  void DiagnoseEmptyLoopBody(const Stmt *S,
+                             const Stmt *PossibleBody);
+
   ParsingDeclState PushParsingDeclaration() {
     return DelayedDiagnostics.pushParsingDecl();
   }
@@ -2266,40 +2313,51 @@
   void UpdateMarkingForLValueToRValue(Expr *E);
   void CleanupVarDeclMarking();
 
-  /// \brief Determine whether we can capture the given variable in
-  /// the given scope.
-  ///
-  /// \param Explicit Whether this is an explicit capture (vs. an
-  /// implicit capture).
-  ///
-  /// \param Diagnose Diagnose errors that occur when attempting to perform
-  /// the capture.
-  ///
-  /// \param Var The variable to check for capture.
-  ///
-  /// \param Type Will be set to the type used to perform the capture.
-  ///
-  /// \param FunctionScopesIndex Will be set to the index of the first 
-  /// scope in which capture will need to be performed.
-  ///
-  /// \param Nested Whether this will be a nested capture.
-  bool canCaptureVariable(VarDecl *Var, SourceLocation Loc, bool Explicit,
-                          bool Diagnose, QualType &Type, 
-                          unsigned &FunctionScopesIndex, bool &Nested);
-
-  /// \brief Determine the type of the field that will capture the
-  /// given variable in a lambda expression.
-  ///
-  /// \param T The type of the variable being captured.
-  /// \param ByRef Whether we are capturing by reference or by value.
-  QualType getLambdaCaptureFieldType(QualType T, bool ByRef);
-
   enum TryCaptureKind {
     TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
   };
-  void TryCaptureVar(VarDecl *var, SourceLocation loc,
-                     TryCaptureKind Kind = TryCapture_Implicit);
 
+  /// \brief Try to capture the given variable.
+  ///
+  /// \param Var The variable to capture.
+  ///
+  /// \param Loc The location at which the capture occurs.
+  ///
+  /// \param Kind The kind of capture, which may be implicit (for either a 
+  /// block or a lambda), or explicit by-value or by-reference (for a lambda).
+  ///
+  /// \param EllipsisLoc The location of the ellipsis, if one is provided in
+  /// an explicit lambda capture.
+  ///
+  /// \param BuildAndDiagnose Whether we are actually supposed to add the 
+  /// captures or diagnose errors. If false, this routine merely check whether
+  /// the capture can occur without performing the capture itself or complaining
+  /// if the variable cannot be captured.
+  ///
+  /// \param CaptureType Will be set to the type of the field used to capture
+  /// this variable in the innermost block or lambda. Only valid when the
+  /// variable can be captured.
+  ///
+  /// \param DeclRefType Will be set to the type of a refernce to the capture
+  /// from within the current scope. Only valid when the variable can be 
+  /// captured.
+  ///
+  /// \returns true if an error occurred (i.e., the variable cannot be
+  /// captured) and false if the capture succeeded.
+  bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
+                          SourceLocation EllipsisLoc, bool BuildAndDiagnose, 
+                          QualType &CaptureType,
+                          QualType &DeclRefType);
+
+  /// \brief Try to capture the given variable.
+  bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
+                          TryCaptureKind Kind = TryCapture_Implicit,
+                          SourceLocation EllipsisLoc = SourceLocation());
+  
+  /// \brief Given a variable, determine the type that a reference to that
+  /// variable will have in the given scope.
+  QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
+  
   void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
   void MarkDeclarationsReferencedInExpr(Expr *E);
 
@@ -2920,17 +2978,6 @@
   /// definition when it is defaulted.
   bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM);
 
-  /// \brief Determine if a defaulted copy assignment operator ought to be
-  /// deleted.
-  bool ShouldDeleteCopyAssignmentOperator(CXXMethodDecl *MD);
-
-  /// \brief Determine if a defaulted move assignment operator ought to be
-  /// deleted.
-  bool ShouldDeleteMoveAssignmentOperator(CXXMethodDecl *MD);
-
-  /// \brief Determine if a defaulted destructor ought to be deleted.
-  bool ShouldDeleteDestructor(CXXDestructorDecl *DD);
-
   /// \brief Declare the implicit default constructor for the given class.
   ///
   /// \param ClassDecl The class declaration into which the implicit
@@ -3027,6 +3074,10 @@
   /// class.
   void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
 
+  /// \brief Determine whether the given function is an implicitly-deleted
+  /// special member function.
+  bool isImplicitlyDeleted(FunctionDecl *FD);
+  
   /// MaybeBindToTemporary - If the passed in expression has a record type with
   /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
   /// it simply returns the passed in expression.
@@ -3149,9 +3200,7 @@
                          MultiExprArg PlacementArgs,
                          SourceLocation PlacementRParen,
                          SourceRange TypeIdParens, Declarator &D,
-                         SourceLocation ConstructorLParen,
-                         MultiExprArg ConstructorArgs,
-                         SourceLocation ConstructorRParen);
+                         Expr *Initializer);
   ExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                          SourceLocation PlacementLParen,
                          MultiExprArg PlacementArgs,
@@ -3160,9 +3209,8 @@
                          QualType AllocType,
                          TypeSourceInfo *AllocTypeInfo,
                          Expr *ArraySize,
-                         SourceLocation ConstructorLParen,
-                         MultiExprArg ConstructorArgs,
-                         SourceLocation ConstructorRParen,
+                         SourceRange DirectInitRange,
+                         Expr *Initializer,
                          bool TypeMayContainAuto = true);
 
   bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
@@ -3474,7 +3522,8 @@
   CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
                                        SourceRange IntroducerRange,
                                        TypeSourceInfo *MethodType,
-                                       SourceLocation EndLoc);
+                                       SourceLocation EndLoc,
+                                       llvm::ArrayRef<ParmVarDecl *> Params);
   
   /// \brief Introduce the scope for a lambda expression.
   sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator,
@@ -3489,8 +3538,7 @@
   void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
   
   /// \brief Introduce the lambda parameters into scope.
-  void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope,
-                           llvm::ArrayRef<ParmVarDecl *> Params);
+  void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
   
   /// ActOnStartOfLambdaDefinition - This is called just before we start
   /// parsing the body of a lambda; it analyzes the explicit captures and 
@@ -3509,6 +3557,26 @@
   ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
                              Scope *CurScope, bool IsInstantiation = false);
 
+  /// \brief Define the "body" of the conversion from a lambda object to a 
+  /// function pointer.
+  ///
+  /// This routine doesn't actually define a sensible body; rather, it fills
+  /// in the initialization expression needed to copy the lambda object into
+  /// the block, and IR generation actually generates the real body of the
+  /// block pointer conversion.
+  void DefineImplicitLambdaToFunctionPointerConversion(
+         SourceLocation CurrentLoc, CXXConversionDecl *Conv);
+
+  /// \brief Define the "body" of the conversion from a lambda object to a 
+  /// block pointer.
+  ///
+  /// This routine doesn't actually define a sensible body; rather, it fills
+  /// in the initialization expression needed to copy the lambda object into
+  /// the block, and IR generation actually generates the real body of the
+  /// block pointer conversion.
+  void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc,
+                                                    CXXConversionDecl *Conv);
+  
   // ParseObjCStringLiteral - Parse Objective-C string literals.
   ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
                                     Expr **Strings,
@@ -5658,6 +5726,14 @@
                          SourceLocation PragmaLoc,
                          SourceLocation WeakNameLoc);
 
+  /// ActOnPragmaRedefineExtname - Called on well formed 
+  /// #pragma redefine_extname oldname newname.
+  void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName,
+                                  IdentifierInfo* AliasName,
+                                  SourceLocation PragmaLoc,
+                                  SourceLocation WeakNameLoc,
+                                  SourceLocation AliasNameLoc);
+
   /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
   void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
                             IdentifierInfo* AliasName,
@@ -6263,6 +6339,8 @@
   void CodeCompleteConstructorInitializer(Decl *Constructor,
                                           CXXCtorInitializer** Initializers,
                                           unsigned NumInitializers);
+  void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
+                                    bool AfterAmpersand);
 
   void CodeCompleteObjCAtDirective(Scope *S);
   void CodeCompleteObjCAtVisibility(Scope *S);

Modified: cfe/branches/tooling/include/clang/Sema/TypoCorrection.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/TypoCorrection.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/TypoCorrection.h (original)
+++ cfe/branches/tooling/include/clang/Sema/TypoCorrection.h Mon Feb 20 19:34:24 2012
@@ -23,32 +23,46 @@
 /// @brief Simple class containing the result of Sema::CorrectTypo
 class TypoCorrection {
 public:
+  // "Distance" for unusable corrections
+  static const unsigned InvalidDistance = ~0U;
+  // The largest distance still considered valid (larger edit distances are
+  // mapped to InvalidDistance by getEditDistance).
+  static const unsigned MaximumDistance = 10000U;
+
+  // Relative weightings of the "edit distance" components. The higher the
+  // weight, the more of a penalty to fitness the component will give (higher
+  // weights mean greater contribution to the total edit distance, with the
+  // best correction candidates having the lowest edit distance).
+  static const unsigned CharDistanceWeight = 100U;
+  static const unsigned QualifierDistanceWeight = 110U;
+  static const unsigned CallbackDistanceWeight = 150U;
+
   TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
-                 NestedNameSpecifier *NNS=0, unsigned distance=0)
-      : CorrectionName(Name),
-        CorrectionNameSpec(NNS),
-        EditDistance(distance) {
+                 NestedNameSpecifier *NNS=0, unsigned CharDistance=0,
+                 unsigned QualifierDistance=0)
+      : CorrectionName(Name), CorrectionNameSpec(NNS),
+      CharDistance(CharDistance), QualifierDistance(QualifierDistance),
+      CallbackDistance(0) {
     if (NameDecl)
       CorrectionDecls.push_back(NameDecl);
   }
 
   TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=0,
-                 unsigned distance=0)
-      : CorrectionName(Name->getDeclName()),
-        CorrectionNameSpec(NNS),
-        EditDistance(distance) {
+                 unsigned CharDistance=0)
+      : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
+      CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0) {
     if (Name)
       CorrectionDecls.push_back(Name);
   }
 
   TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=0,
-                 unsigned distance=0)
-      : CorrectionName(Name),
-        CorrectionNameSpec(NNS),
-        EditDistance(distance) {}
+                 unsigned CharDistance=0)
+      : CorrectionName(Name), CorrectionNameSpec(NNS),
+      CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0) {}
 
   TypoCorrection()
-      : CorrectionNameSpec(0), EditDistance(0) {}
+      : CorrectionNameSpec(0), CharDistance(0), QualifierDistance(0),
+      CallbackDistance(0) {}
 
   /// \brief Gets the DeclarationName of the typo correction
   DeclarationName getCorrection() const { return CorrectionName; }
@@ -64,8 +78,41 @@
     CorrectionNameSpec = NNS;
   }
 
-  /// \brief Gets the "edit distance" of the typo correction from the typo
-  unsigned getEditDistance() const { return EditDistance; }
+  void setQualifierDistance(unsigned ED) {
+    QualifierDistance = ED;
+  }
+
+  void setCallbackDistance(unsigned ED) {
+    CallbackDistance = ED;
+  }
+
+  // Convert the given weighted edit distance to a roughly equivalent number of
+  // single-character edits (typically for comparison to the length of the
+  // string being edited).
+  static unsigned NormalizeEditDistance(unsigned ED) {
+    if (ED > MaximumDistance)
+      return InvalidDistance;
+    return (ED + CharDistanceWeight / 2) / CharDistanceWeight;
+  }
+
+  /// \brief Gets the "edit distance" of the typo correction from the typo.
+  /// If Normalized is true, scale the distance down by the CharDistanceWeight
+  /// to return the edit distance in terms of single-character edits.
+  unsigned getEditDistance(bool Normalized = true) const {
+    if (CharDistance > MaximumDistance || QualifierDistance > MaximumDistance ||
+        CallbackDistance > MaximumDistance)
+      return InvalidDistance;
+    unsigned ED =
+        CharDistance * CharDistanceWeight +
+        QualifierDistance * QualifierDistanceWeight +
+        CallbackDistance * CallbackDistanceWeight;
+    if (ED > MaximumDistance)
+      return InvalidDistance;
+    // Half the CharDistanceWeight is added to ED to simulate rounding since
+    // integer division truncates the value (i.e. round-to-nearest-int instead
+    // of round-to-zero).
+    return Normalized ? NormalizeEditDistance(ED) : ED;
+  }
 
   /// \brief Gets the pointer to the declaration of the typo correction
   NamedDecl* getCorrectionDecl() const {
@@ -143,13 +190,17 @@
   DeclarationName CorrectionName;
   NestedNameSpecifier *CorrectionNameSpec;
   llvm::SmallVector<NamedDecl*, 1> CorrectionDecls;
-  unsigned EditDistance;
+  unsigned CharDistance;
+  unsigned QualifierDistance;
+  unsigned CallbackDistance;
 };
 
 /// @brief Base class for callback objects used by Sema::CorrectTypo to check
 /// the validity of a potential typo correction.
 class CorrectionCandidateCallback {
  public:
+  static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
+
   CorrectionCandidateCallback()
       : WantTypeSpecifiers(true), WantExpressionKeywords(true),
         WantCXXNamedCasts(true), WantRemainingKeywords(true),
@@ -158,10 +209,26 @@
 
   virtual ~CorrectionCandidateCallback() {}
 
+  /// \brief Simple predicate used by the default RankCandidate to
+  /// determine whether to return an edit distance of 0 or InvalidDistance.
+  /// This can be overrided by validators that only need to determine if a
+  /// candidate is viable, without ranking potentially viable candidates.
+  /// Only ValidateCandidate or RankCandidate need to be overriden by a
+  /// callback wishing to check the viability of correction candidates.
   virtual bool ValidateCandidate(const TypoCorrection &candidate) {
     return true;
   }
 
+  /// \brief Method used by Sema::CorrectTypo to assign an "edit distance" rank
+  /// to a candidate (where a lower value represents a better candidate), or
+  /// returning InvalidDistance if the candidate is not at all viable. For
+  /// validation callbacks that only need to determine if a candidate is viable,
+  /// the default RankCandidate returns either 0 or InvalidDistance depending
+  /// whether ValidateCandidate returns true or false.
+  virtual unsigned RankCandidate(const TypoCorrection &candidate) {
+    return ValidateCandidate(candidate) ? 0 : InvalidDistance;
+  }
+
   // Flags for context-dependent keywords.
   // TODO: Expand these to apply to non-keywords or possibly remove them.
   bool WantTypeSpecifiers;

Modified: cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h Mon Feb 20 19:34:24 2012
@@ -1180,7 +1180,8 @@
       // ARC
       EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
       
-      STMT_MS_DEPENDENT_EXISTS    // MSDependentExistsStmt
+      STMT_MS_DEPENDENT_EXISTS,   // MSDependentExistsStmt
+      EXPR_LAMBDA                 // LambdaExpr
     };
 
     /// \brief The kinds of designators that can occur in a

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h Mon Feb 20 19:34:24 2012
@@ -265,9 +265,10 @@
                       ProgramStateRef state,
                       const StoreManager::InvalidatedSymbols *invalidated,
                       ArrayRef<const MemRegion *> Explicits,
-                      ArrayRef<const MemRegion *> Regions) {
+                      ArrayRef<const MemRegion *> Regions,
+                      const CallOrObjCMessage *Call) {
     return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
-                                                          Explicits, Regions);
+                                                      Explicits, Regions, Call);
   }
   template <typename CHECKER>
   static bool _wantsRegionChangeUpdate(void *checker,

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h Mon Feb 20 19:34:24 2012
@@ -52,6 +52,19 @@
 
 template <typename T> class CheckerFn;
 
+template <typename RET, typename P1, typename P2, typename P3, typename P4,
+          typename P5>
+class CheckerFn<RET(P1, P2, P3, P4, P5)> {
+  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
+    return Fn(Checker, p1, p2, p3, p4, p5);
+  }
+};
+
 template <typename RET, typename P1, typename P2, typename P3, typename P4>
 class CheckerFn<RET(P1, P2, P3, P4)> {
   typedef RET (*Func)(void *, P1, P2, P3, P4);
@@ -269,11 +282,14 @@
   ///   For example, in the case of a function call, these would be arguments.
   /// \param Regions The transitive closure of accessible regions,
   ///   i.e. all regions that may have been touched by this change.
+  /// \param The call expression wrapper if the regions are invalidated by a
+  ///   call.
   ProgramStateRef 
   runCheckersForRegionChanges(ProgramStateRef state,
                             const StoreManager::InvalidatedSymbols *invalidated,
                               ArrayRef<const MemRegion *> ExplicitRegions,
-                              ArrayRef<const MemRegion *> Regions);
+                              ArrayRef<const MemRegion *> Regions,
+                              const CallOrObjCMessage *Call);
 
   /// \brief Run checkers for handling assumptions on symbolic values.
   ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
@@ -349,8 +365,9 @@
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
                                 const StoreManager::InvalidatedSymbols *symbols,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                          ArrayRef<const MemRegion *> Regions)>
+                                ArrayRef<const MemRegion *> ExplicitRegions,
+                                ArrayRef<const MemRegion *> Regions,
+                                const CallOrObjCMessage *Call)>
       CheckRegionChangesFunc;
   
   typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Mon Feb 20 19:34:24 2012
@@ -32,6 +32,7 @@
 #include "llvm/Support/Casting.h"
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include <vector>
 
 namespace clang {
 
@@ -241,18 +242,17 @@
   friend class CoreEngine;
 
   // Type definitions.
-  typedef SmallVector<ExplodedNode*,2>    RootsTy;
-  typedef SmallVector<ExplodedNode*,10>   EndNodesTy;
+  typedef std::vector<ExplodedNode *> NodeVector;
 
-  /// Roots - The roots of the simulation graph. Usually there will be only
+  /// The roots of the simulation graph. Usually there will be only
   /// one, but clients are free to establish multiple subgraphs within a single
   /// SimulGraph. Moreover, these subgraphs can often merge when paths from
   /// different roots reach the same state at the same program location.
-  RootsTy Roots;
+  NodeVector Roots;
 
-  /// EndNodes - The nodes in the simulation graph which have been
-  ///  specially marked as the endpoint of an abstract simulation path.
-  EndNodesTy EndNodes;
+  /// The nodes in the simulation graph which have been
+  /// specially marked as the endpoint of an abstract simulation path.
+  NodeVector EndNodes;
 
   /// Nodes - The nodes in the graph.
   llvm::FoldingSet<ExplodedNode> Nodes;
@@ -265,10 +265,10 @@
   unsigned NumNodes;
   
   /// A list of recently allocated nodes that can potentially be recycled.
-  void *recentlyAllocatedNodes;
+  NodeVector ChangedNodes;
   
   /// A list of nodes that can be reused.
-  void *freeNodes;
+  NodeVector FreeNodes;
   
   /// A flag that indicates whether nodes should be recycled.
   bool reclaimNodes;
@@ -315,10 +315,10 @@
   // Iterators.
   typedef ExplodedNode                        NodeTy;
   typedef llvm::FoldingSet<ExplodedNode>      AllNodesTy;
-  typedef NodeTy**                            roots_iterator;
-  typedef NodeTy* const *                     const_roots_iterator;
-  typedef NodeTy**                            eop_iterator;
-  typedef NodeTy* const *                     const_eop_iterator;
+  typedef NodeVector::iterator                roots_iterator;
+  typedef NodeVector::const_iterator          const_roots_iterator;
+  typedef NodeVector::iterator                eop_iterator;
+  typedef NodeVector::const_iterator          const_eop_iterator;
   typedef AllNodesTy::iterator                node_iterator;
   typedef AllNodesTy::const_iterator          const_node_iterator;
 

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon Feb 20 19:34:24 2012
@@ -212,7 +212,8 @@
   processRegionChanges(ProgramStateRef state,
                        const StoreManager::InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
-                       ArrayRef<const MemRegion *> Regions);
+                       ArrayRef<const MemRegion *> Regions,
+                       const CallOrObjCMessage *Call);
 
   /// printState - Called by ProgramStateManager to print checker-specific data.
   void printState(raw_ostream &Out, ProgramStateRef State,

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h Mon Feb 20 19:34:24 2012
@@ -28,70 +28,56 @@
 /// \brief Represents both explicit ObjC message expressions and implicit
 /// messages that are sent for handling properties in dot syntax.
 class ObjCMessage {
-  const Expr *MsgOrPropE;
-  const Expr *OriginE;
-  bool IsPropSetter;
-  SVal SetterArgV;
-
-protected:
-  ObjCMessage(const Expr *E, const Expr *origE, bool isSetter, SVal setArgV)
-    : MsgOrPropE(E), OriginE(origE),
-      IsPropSetter(isSetter), SetterArgV(setArgV) { }
-
+  const ObjCMessageExpr *Msg;
+  const ObjCPropertyRefExpr *PE;
+  const bool IsPropSetter;
 public:
-  ObjCMessage() : MsgOrPropE(0), OriginE(0) { }
+  ObjCMessage() : Msg(0), PE(0), IsPropSetter(false) {}
 
-  ObjCMessage(const ObjCMessageExpr *E)
-    : MsgOrPropE(E), OriginE(E) {
+  ObjCMessage(const ObjCMessageExpr *E, const ObjCPropertyRefExpr *pe = 0,
+              bool isSetter = false)
+    : Msg(E), PE(pe), IsPropSetter(isSetter) {
     assert(E && "should not be initialized with null expression");
   }
 
-  bool isValid() const { return MsgOrPropE != 0; }
-  bool isInvalid() const { return !isValid(); }
+  bool isValid() const { return Msg; }
+  
+  bool isPureMessageExpr() const { return !PE; }
 
-  bool isMessageExpr() const {
-    return isValid() && isa<ObjCMessageExpr>(MsgOrPropE);
-  }
+  bool isPropertyGetter() const { return PE && !IsPropSetter; }
 
-  bool isPropertyGetter() const {
-    return isValid() &&
-           isa<ObjCPropertyRefExpr>(MsgOrPropE) && !IsPropSetter;
+  bool isPropertySetter() const {
+    return IsPropSetter;
   }
 
-  bool isPropertySetter() const {
-    return isValid() &&
-           isa<ObjCPropertyRefExpr>(MsgOrPropE) && IsPropSetter;
+  const Expr *getMessageExpr() const { 
+    return Msg;
   }
-  
-  const Expr *getOriginExpr() const { return OriginE; }
 
-  QualType getType(ASTContext &ctx) const;
+  QualType getType(ASTContext &ctx) const {
+    return Msg->getType();
+  }
 
   QualType getResultType(ASTContext &ctx) const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      if (const ObjCMethodDecl *MD = msgE->getMethodDecl())
-        return MD->getResultType();
+    if (const ObjCMethodDecl *MD = Msg->getMethodDecl())
+      return MD->getResultType();
     return getType(ctx);
   }
 
-  ObjCMethodFamily getMethodFamily() const;
+  ObjCMethodFamily getMethodFamily() const {
+    return Msg->getMethodFamily();
+  }
 
-  Selector getSelector() const;
+  Selector getSelector() const {
+    return Msg->getSelector();
+  }
 
   const Expr *getInstanceReceiver() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return msgE->getInstanceReceiver();
-    const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-    if (propE->isObjectReceiver())
-      return propE->getBase();
-    return 0;
+    return Msg->getInstanceReceiver();
   }
 
   SVal getInstanceReceiverSVal(ProgramStateRef State,
                                const LocationContext *LC) const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
     if (!isInstanceMessage())
       return UndefinedVal();
     if (const Expr *Ex = getInstanceReceiver())
@@ -105,101 +91,66 @@
   }
 
   bool isInstanceMessage() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return msgE->isInstanceMessage();
-    const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-    // FIXME: 'super' may be super class.
-    return propE->isObjectReceiver() || propE->isSuperReceiver();
+    return Msg->isInstanceMessage();
   }
 
-  const ObjCMethodDecl *getMethodDecl() const;
-
-  const ObjCInterfaceDecl *getReceiverInterface() const;
-
-  SourceLocation getSuperLoc() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return msgE->getSuperLoc();
-    return cast<ObjCPropertyRefExpr>(MsgOrPropE)->getReceiverLocation();
+  const ObjCMethodDecl *getMethodDecl() const {
+    return Msg->getMethodDecl();
   }
 
-  const Expr *getMsgOrPropExpr() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    return MsgOrPropE;
+  const ObjCInterfaceDecl *getReceiverInterface() const {
+    return Msg->getReceiverInterface();
   }
 
+  SourceLocation getSuperLoc() const {
+    if (PE)
+      return PE->getReceiverLocation();
+    return Msg->getSuperLoc();
+  }  
+
   SourceRange getSourceRange() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    return MsgOrPropE->getSourceRange();
+    if (PE)
+      return PE->getSourceRange();
+    return Msg->getSourceRange();
   }
 
   unsigned getNumArgs() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return msgE->getNumArgs();
-    return isPropertySetter() ? 1 : 0;
+    return Msg->getNumArgs();
   }
 
   SVal getArgSVal(unsigned i,
                   const LocationContext *LCtx,
                   ProgramStateRef state) const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
     assert(i < getNumArgs() && "Invalid index for argument");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return state->getSVal(msgE->getArg(i), LCtx);
-    assert(isPropertySetter());
-    return SetterArgV;
+    return state->getSVal(Msg->getArg(i), LCtx);
   }
 
   QualType getArgType(unsigned i) const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
     assert(i < getNumArgs() && "Invalid index for argument");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return msgE->getArg(i)->getType();
-    assert(isPropertySetter());
-    return cast<ObjCPropertyRefExpr>(MsgOrPropE)->getType();
+    return Msg->getArg(i)->getType();
   }
 
-  const Expr *getArgExpr(unsigned i) const;
+  const Expr *getArgExpr(unsigned i) const {
+    assert(i < getNumArgs() && "Invalid index for argument");
+    return Msg->getArg(i);
+  }
 
   SourceRange getArgSourceRange(unsigned i) const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    assert(i < getNumArgs() && "Invalid index for argument");
-    if (const Expr *argE = getArgExpr(i))
-      return argE->getSourceRange();
-    return OriginE->getSourceRange();
+    const Expr *argE = getArgExpr(i);
+    return argE->getSourceRange();
   }
 
   SourceRange getReceiverSourceRange() const {
-    assert(isValid() && "This ObjCMessage is uninitialized!");
-    if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-      return msgE->getReceiverRange();
-
-    const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-    if (propE->isObjectReceiver())
-      return propE->getBase()->getSourceRange();
+    if (PE) {
+      if (PE->isObjectReceiver())
+        return PE->getBase()->getSourceRange();
+    }
+    else {
+      return Msg->getReceiverRange();
+    }
 
     // FIXME: This isn't a range.
-    return propE->getReceiverLocation();
-  }
-};
-
-class ObjCPropertyGetter : public ObjCMessage {
-public:
-  ObjCPropertyGetter(const ObjCPropertyRefExpr *propE, const Expr *originE)
-    : ObjCMessage(propE, originE, false, SVal()) {
-    assert(propE && originE &&
-           "should not be initialized with null expressions");
-  }
-};
-
-class ObjCPropertySetter : public ObjCMessage {
-public:
-  ObjCPropertySetter(const ObjCPropertyRefExpr *propE, const Expr *storeE,
-                     SVal argV)
-    : ObjCMessage(propE, storeE, true, argV) {
-    assert(propE && storeE &&"should not be initialized with null expressions");
+    return PE->getReceiverLocation();
   }
 };
 
@@ -252,7 +203,7 @@
 
   const Expr *getOriginExpr() const {
     if (!CallE)
-      return Msg.getOriginExpr();
+      return Msg.getMessageExpr();
     if (const CXXConstructExpr *Ctor =
           CallE.dyn_cast<const CXXConstructExpr *>())
       return Ctor;

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Mon Feb 20 19:34:24 2012
@@ -218,6 +218,7 @@
   ///  from Begin to End. Optionally invalidates global regions as well.
   ProgramStateRef invalidateRegions(ArrayRef<const MemRegion *> Regions,
                                const Expr *E, unsigned BlockCount,
+                               const LocationContext *LCtx,
                                StoreManager::InvalidatedSymbols *IS = 0,
                                const CallOrObjCMessage *Call = 0) const;
 
@@ -378,6 +379,7 @@
   ProgramStateRef 
   invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
                         const Expr *E, unsigned BlockCount,
+                        const LocationContext *LCtx,
                         StoreManager::InvalidatedSymbols &IS,
                         const CallOrObjCMessage *Call) const;
 };

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h Mon Feb 20 19:34:24 2012
@@ -142,15 +142,19 @@
 
   // Forwarding methods to SymbolManager.
 
-  const SymbolConjured* getConjuredSymbol(const Stmt *stmt, QualType type,
+  const SymbolConjured* getConjuredSymbol(const Stmt *stmt,
+					  const LocationContext *LCtx,
+					  QualType type,
                                           unsigned visitCount,
                                           const void *symbolTag = 0) {
-    return SymMgr.getConjuredSymbol(stmt, type, visitCount, symbolTag);
+    return SymMgr.getConjuredSymbol(stmt, LCtx, type, visitCount, symbolTag);
   }
 
-  const SymbolConjured* getConjuredSymbol(const Expr *expr, unsigned visitCount,
+  const SymbolConjured* getConjuredSymbol(const Expr *expr,
+					  const LocationContext *LCtx,
+					  unsigned visitCount,
                                           const void *symbolTag = 0) {
-    return SymMgr.getConjuredSymbol(expr, visitCount, symbolTag);
+    return SymMgr.getConjuredSymbol(expr, LCtx, visitCount, symbolTag);
   }
 
   /// Construct an SVal representing '0' for the specified type.
@@ -166,9 +170,13 @@
   /// preserve the relation between related(or even equivalent) expressions, so
   /// conjured symbols should be used sparingly.
   DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
-                                            const Expr *expr, unsigned count);
+                                            const Expr *expr,
+					    const LocationContext *LCtx,
+					    unsigned count);
   DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
-                                            const Expr *expr, QualType type,
+                                            const Expr *expr,
+					    const LocationContext *LCtx,
+					    QualType type,
                                             unsigned count);
 
   DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Mon Feb 20 19:34:24 2012
@@ -188,6 +188,7 @@
   virtual StoreRef invalidateRegions(Store store,
                                      ArrayRef<const MemRegion *> Regions,
                                      const Expr *E, unsigned Count,
+                                     const LocationContext *LCtx,
                                      InvalidatedSymbols &IS,
                                      const CallOrObjCMessage *Call,
                                      InvalidatedRegions *Invalidated) = 0;

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Mon Feb 20 19:34:24 2012
@@ -97,19 +97,20 @@
   ///  region change should trigger a processRegionChanges update.
   virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
 
-  /// processRegionChanges - Called by ProgramStateManager whenever a change is made
-  ///  to the store. Used to update checkers that track region values.
+  /// processRegionChanges - Called by ProgramStateManager whenever a change is
+  /// made to the store. Used to update checkers that track region values.
   virtual ProgramStateRef 
   processRegionChanges(ProgramStateRef state,
                        const StoreManager::InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
-                       ArrayRef<const MemRegion *> Regions) = 0;
+                       ArrayRef<const MemRegion *> Regions,
+                       const CallOrObjCMessage *Call) = 0;
 
 
   inline ProgramStateRef 
   processRegionChange(ProgramStateRef state,
                       const MemRegion* MR) {
-    return processRegionChanges(state, 0, MR, MR);
+    return processRegionChanges(state, 0, MR, MR, 0);
   }
 
   /// printState - Called by ProgramStateManager to print checker-specific data.

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h Mon Feb 20 19:34:24 2012
@@ -156,12 +156,15 @@
   const Stmt *S;
   QualType T;
   unsigned Count;
+  const LocationContext *LCtx;
   const void *SymbolTag;
 
 public:
-  SymbolConjured(SymbolID sym, const Stmt *s, QualType t, unsigned count,
+  SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx,
+		 QualType t, unsigned count,
                  const void *symbolTag)
     : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count),
+      LCtx(lctx),
       SymbolTag(symbolTag) {}
 
   const Stmt *getStmt() const { return S; }
@@ -173,16 +176,18 @@
   virtual void dumpToStream(raw_ostream &os) const;
 
   static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S,
-                      QualType T, unsigned Count, const void *SymbolTag) {
+                      QualType T, unsigned Count, const LocationContext *LCtx,
+                      const void *SymbolTag) {
     profile.AddInteger((unsigned) ConjuredKind);
     profile.AddPointer(S);
+    profile.AddPointer(LCtx);
     profile.Add(T);
     profile.AddInteger(Count);
     profile.AddPointer(SymbolTag);
   }
 
   virtual void Profile(llvm::FoldingSetNodeID& profile) {
-    Profile(profile, S, T, Count, SymbolTag);
+    Profile(profile, S, T, Count, LCtx, SymbolTag);
   }
 
   // Implement isa<T> support.
@@ -488,13 +493,18 @@
   /// \brief Make a unique symbol for MemRegion R according to its kind.
   const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R);
 
-  const SymbolConjured* getConjuredSymbol(const Stmt *E, QualType T,
+  const SymbolConjured* getConjuredSymbol(const Stmt *E,
+					  const LocationContext *LCtx,
+					  QualType T,
                                           unsigned VisitCount,
                                           const void *SymbolTag = 0);
 
-  const SymbolConjured* getConjuredSymbol(const Expr *E, unsigned VisitCount,
+  const SymbolConjured* getConjuredSymbol(const Expr *E,
+					  const LocationContext *LCtx,
+					  unsigned VisitCount,
                                           const void *SymbolTag = 0) {
-    return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag);
+    return getConjuredSymbol(E, LCtx, E->getType(),
+			     VisitCount, SymbolTag);
   }
 
   const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,

Modified: cfe/branches/tooling/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/APValue.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/APValue.cpp (original)
+++ cfe/branches/tooling/lib/AST/APValue.cpp Mon Feb 20 19:34:24 2012
@@ -28,6 +28,7 @@
     llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
     CharUnits Offset;
     unsigned PathLength;
+    unsigned CallIndex;
   };
 }
 
@@ -166,9 +167,10 @@
   else if (isLValue()) {
     if (RHS.hasLValuePath())
       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
-                RHS.isLValueOnePastTheEnd());
+                RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
     else
-      setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath());
+      setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
+                RHS.getLValueCallIndex());
   } else if (isArray()) {
     for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
       getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
@@ -525,22 +527,31 @@
   return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
 }
 
-void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath) {
+unsigned APValue::getLValueCallIndex() const {
+  assert(isLValue() && "Invalid accessor");
+  return ((const LV*)(const char*)Data)->CallIndex;
+}
+
+void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+                        unsigned CallIndex) {
   assert(isLValue() && "Invalid accessor");
   LV &LVal = *((LV*)(char*)Data);
   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
   LVal.BaseAndIsOnePastTheEnd.setInt(false);
   LVal.Offset = O;
+  LVal.CallIndex = CallIndex;
   LVal.resizePath((unsigned)-1);
 }
 
 void APValue::setLValue(LValueBase B, const CharUnits &O,
-                        ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd) {
+                        ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
+                        unsigned CallIndex) {
   assert(isLValue() && "Invalid accessor");
   LV &LVal = *((LV*)(char*)Data);
   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
   LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
   LVal.Offset = O;
+  LVal.CallIndex = CallIndex;
   LVal.resizePath(Path.size());
   memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
 }

Modified: cfe/branches/tooling/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclCXX.cpp Mon Feb 20 19:34:24 2012
@@ -1455,6 +1455,12 @@
   return CheckFn->hasBody(fn) && !fn->isOutOfLine();
 }
 
+bool CXXMethodDecl::isLambdaStaticInvoker() const {
+  return getParent()->isLambda() && 
+         getIdentifier() && getIdentifier()->getName() == "__invoke";
+}
+
+
 CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
                                        TypeSourceInfo *TInfo, bool IsVirtual,
                                        SourceLocation L, Expr *Init,
@@ -1759,6 +1765,21 @@
                                    EndLocation);
 }
 
+bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
+  return isImplicit() && getParent()->isLambda() &&
+         getConversionType()->isBlockPointerType();
+}
+
+Expr *CXXConversionDecl::getLambdaToBlockPointerCopyInit() const {
+  assert(isLambdaToBlockPointerConversion());
+  return getASTContext().LambdaBlockPointerInits[this];
+}
+
+void CXXConversionDecl::setLambdaToBlockPointerCopyInit(Expr *Init) {
+  assert(isLambdaToBlockPointerConversion());
+  getASTContext().LambdaBlockPointerInits[this] = Init;
+}
+
 void LinkageSpecDecl::anchor() { }
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,

Modified: cfe/branches/tooling/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Expr.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Expr.cpp (original)
+++ cfe/branches/tooling/lib/AST/Expr.cpp Mon Feb 20 19:34:24 2012
@@ -1053,6 +1053,11 @@
     assert(getSubExpr()->getType()->isBlockPointerType());
     goto CheckNoBasePath;
 
+  case CK_ReinterpretMemberPointer:
+    assert(getType()->isMemberPointerType());
+    assert(getSubExpr()->getType()->isMemberPointerType());
+    goto CheckNoBasePath;
+
   case CK_BitCast:
     // Arbitrary casts to C pointer types count as bitcasts.
     // Otherwise, we should only have block and ObjC pointer casts
@@ -1156,6 +1161,8 @@
     return "BaseToDerivedMemberPointer";
   case CK_DerivedToBaseMemberPointer:
     return "DerivedToBaseMemberPointer";
+  case CK_ReinterpretMemberPointer:
+    return "ReinterpretMemberPointer";
   case CK_UserDefinedConversion:
     return "UserDefinedConversion";
   case CK_ConstructorConversion:
@@ -1426,9 +1433,10 @@
   : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
          false, false),
     InitExprs(C, numInits),
-    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
-    HadArrayRangeDesignator(false) 
-{      
+    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0)
+{
+  sawArrayRangeDesignator(false);
+  setInitializesStdInitializerList(false);
   for (unsigned I = 0; I != numInits; ++I) {
     if (initExprs[I]->isTypeDependent())
       ExprBits.TypeDependent = true;
@@ -1505,9 +1513,10 @@
 
 /// getFunctionType - Return the underlying function type for this block.
 ///
-const FunctionType *BlockExpr::getFunctionType() const {
-  return getType()->getAs<BlockPointerType>()->
-                    getPointeeType()->getAs<FunctionType>();
+const FunctionProtoType *BlockExpr::getFunctionType() const {
+  // The block pointer is never sugared, but the function type might be.
+  return cast<BlockPointerType>(getType())
+           ->getPointeeType()->castAs<FunctionProtoType>();
 }
 
 SourceLocation BlockExpr::getCaretLocation() const {
@@ -2034,10 +2043,7 @@
     if (isTypeDependent())
       CT = CT_Dependent;
     else
-      CT = MergeCanThrow(
-        CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()),
-        CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getConstructor(),
-                       /*NullThrows*/false));
+      CT = CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew());
     if (CT == CT_Can)
       return CT;
     return MergeCanThrow(CT, CanSubExprsThrow(C, this));
@@ -2728,11 +2734,18 @@
     return NPCK_NotNull;
 
   // If we have an integer constant expression, we need to *evaluate* it and
-  // test for the value 0.
-  llvm::APSInt Result;
-  bool IsNull = isIntegerConstantExpr(Result, Ctx) && Result == 0;
+  // test for the value 0. Don't use the C++11 constant expression semantics
+  // for this, for now; once the dust settles on core issue 903, we might only
+  // allow a literal 0 here in C++11 mode.
+  if (Ctx.getLangOptions().CPlusPlus0x) {
+    if (!isCXX98IntegralConstantExpr(Ctx))
+      return NPCK_NotNull;
+  } else {
+    if (!isIntegerConstantExpr(Ctx))
+      return NPCK_NotNull;
+  }
 
-  return (IsNull ? NPCK_ZeroInteger : NPCK_NotNull);
+  return (EvaluateKnownConstInt(Ctx) == 0) ? NPCK_ZeroInteger : NPCK_NotNull;
 }
 
 /// \brief If this expression is an l-value for an Objective C

Modified: cfe/branches/tooling/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprCXX.cpp Mon Feb 20 19:34:24 2012
@@ -45,30 +45,26 @@
 
 // CXXNewExpr
 CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-                       Expr **placementArgs, unsigned numPlaceArgs,
-                       SourceRange TypeIdParens, Expr *arraySize,
-                       CXXConstructorDecl *constructor, bool initializer,
-                       Expr **constructorArgs, unsigned numConsArgs,
-                       bool HadMultipleCandidates,
                        FunctionDecl *operatorDelete,
-                       bool usualArrayDeleteWantsSize, QualType ty,
-                       TypeSourceInfo *AllocatedTypeInfo,
-                       SourceLocation startLoc, SourceLocation endLoc,
-                       SourceLocation constructorLParen,
-                       SourceLocation constructorRParen)
+                       bool usualArrayDeleteWantsSize,
+                       Expr **placementArgs, unsigned numPlaceArgs,
+                       SourceRange typeIdParens, Expr *arraySize,
+                       InitializationStyle initializationStyle,
+                       Expr *initializer, QualType ty,
+                       TypeSourceInfo *allocatedTypeInfo,
+                       SourceLocation startLoc, SourceRange directInitRange)
   : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
          ty->isDependentType(), ty->isDependentType(),
          ty->isInstantiationDependentType(),
          ty->containsUnexpandedParameterPack()),
-    GlobalNew(globalNew), Initializer(initializer),
-    UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
-    HadMultipleCandidates(HadMultipleCandidates),
-    SubExprs(0), OperatorNew(operatorNew),
-    OperatorDelete(operatorDelete), Constructor(constructor),
-    AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
-    StartLoc(startLoc), EndLoc(endLoc), ConstructorLParen(constructorLParen),
-    ConstructorRParen(constructorRParen) {
-  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
+    GlobalNew(globalNew), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
+    SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
+    AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
+    StartLoc(startLoc), DirectInitRange(directInitRange) {
+  assert((initializer != 0 || initializationStyle == NoInit) &&
+         "Only NoInit can have no initializer.");
+  StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
+  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, initializer != 0);
   unsigned i = 0;
   if (Array) {
     if (arraySize->isInstantiationDependent())
@@ -80,33 +76,33 @@
     SubExprs[i++] = arraySize;
   }
 
-  for (unsigned j = 0; j < NumPlacementArgs; ++j) {
-    if (placementArgs[j]->isInstantiationDependent())
+  if (initializer) {
+    if (initializer->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-    if (placementArgs[j]->containsUnexpandedParameterPack())
+
+    if (initializer->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = placementArgs[j];
+    SubExprs[i++] = initializer;
   }
 
-  for (unsigned j = 0; j < NumConstructorArgs; ++j) {
-    if (constructorArgs[j]->isInstantiationDependent())
+  for (unsigned j = 0; j < NumPlacementArgs; ++j) {
+    if (placementArgs[j]->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
-    if (constructorArgs[j]->containsUnexpandedParameterPack())
+    if (placementArgs[j]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
-    SubExprs[i++] = constructorArgs[j];
+    SubExprs[i++] = placementArgs[j];
   }
 }
 
 void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
-                                   unsigned numPlaceArgs, unsigned numConsArgs){
+                                   unsigned numPlaceArgs, bool hasInitializer){
   assert(SubExprs == 0 && "SubExprs already allocated");
   Array = isArray;
   NumPlacementArgs = numPlaceArgs;
-  NumConstructorArgs = numConsArgs; 
-  
-  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
+
+  unsigned TotalSize = Array + hasInitializer + NumPlacementArgs;
   SubExprs = new (C) Stmt*[TotalSize];
 }
 
@@ -115,6 +111,18 @@
     castAs<FunctionProtoType>()->isNothrow(Ctx);
 }
 
+SourceLocation CXXNewExpr::getEndLoc() const {
+  switch (getInitializationStyle()) {
+  case NoInit:
+    return AllocatedTypeInfo->getTypeLoc().getEndLoc();
+  case CallInit:
+    return DirectInitRange.getEnd();
+  case ListInit:
+    return getInitializer()->getSourceRange().getEnd();
+  }
+  llvm_unreachable("bogus initialization style");
+}
+
 // CXXDeleteExpr
 QualType CXXDeleteExpr::getDestroyedType() const {
   const Expr *Arg = getArgument();
@@ -832,6 +840,16 @@
                               ClosingBrace);
 }
 
+LambdaExpr *LambdaExpr::CreateDeserialized(ASTContext &C, unsigned NumCaptures,
+                                           unsigned NumArrayIndexVars) {
+  unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (NumCaptures + 1);
+  if (NumArrayIndexVars)
+    Size += sizeof(VarDecl) * NumArrayIndexVars
+          + sizeof(unsigned) * (NumCaptures + 1);
+  void *Mem = C.Allocate(Size);
+  return new (Mem) LambdaExpr(EmptyShell(), NumCaptures, NumArrayIndexVars > 0);
+}
+
 LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
   return getLambdaClass()->getLambdaData().Captures;
 }
@@ -886,6 +904,13 @@
   return Result;
 }
 
+CompoundStmt *LambdaExpr::getBody() const {
+  if (!getStoredStmts()[NumCaptures])
+    getStoredStmts()[NumCaptures] = getCallOperator()->getBody();
+    
+  return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
+}
+
 bool LambdaExpr::isMutable() const {
   return (getCallOperator()->getTypeQualifiers() & Qualifiers::Const) == 0;
 }

Modified: cfe/branches/tooling/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprConstant.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprConstant.cpp Mon Feb 20 19:34:24 2012
@@ -51,26 +51,14 @@
 using llvm::APSInt;
 using llvm::APFloat;
 
-/// EvalInfo - This is a private struct used by the evaluator to capture
-/// information about a subexpression as it is folded.  It retains information
-/// about the AST context, but also maintains information about the folded
-/// expression.
-///
-/// If an expression could be evaluated, it is still possible it is not a C
-/// "integer constant expression" or constant expression.  If not, this struct
-/// captures information about how and why not.
-///
-/// One bit of information passed *into* the request for constant folding
-/// indicates whether the subexpression is "evaluated" or not according to C
-/// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
-/// evaluate the expression regardless of what the RHS is, but C only allows
-/// certain things in certain situations.
+static bool IsGlobalLValue(APValue::LValueBase B);
+
 namespace {
   struct LValue;
   struct CallStackFrame;
   struct EvalInfo;
 
-  QualType getType(APValue::LValueBase B) {
+  static QualType getType(APValue::LValueBase B) {
     if (!B) return QualType();
     if (const ValueDecl *D = B.dyn_cast<const ValueDecl*>())
       return D->getType();
@@ -79,6 +67,7 @@
 
   /// Get an LValue path entry, which is known to not be an array index, as a
   /// field or base class.
+  static
   APValue::BaseOrMemberType getAsBaseOrMember(APValue::LValuePathEntry E) {
     APValue::BaseOrMemberType Value;
     Value.setFromOpaqueValue(E.BaseOrMember);
@@ -87,17 +76,17 @@
 
   /// Get an LValue path entry, which is known to not be an array index, as a
   /// field declaration.
-  const FieldDecl *getAsField(APValue::LValuePathEntry E) {
+  static const FieldDecl *getAsField(APValue::LValuePathEntry E) {
     return dyn_cast<FieldDecl>(getAsBaseOrMember(E).getPointer());
   }
   /// Get an LValue path entry, which is known to not be an array index, as a
   /// base class declaration.
-  const CXXRecordDecl *getAsBaseClass(APValue::LValuePathEntry E) {
+  static const CXXRecordDecl *getAsBaseClass(APValue::LValuePathEntry E) {
     return dyn_cast<CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
   }
   /// Determine whether this LValue path entry for a base class names a virtual
   /// base class.
-  bool isVirtualBaseClass(APValue::LValuePathEntry E) {
+  static bool isVirtualBaseClass(APValue::LValuePathEntry E) {
     return getAsBaseOrMember(E).getInt();
   }
 
@@ -116,6 +105,11 @@
         Type = CAT->getElementType();
         ArraySize = CAT->getSize().getZExtValue();
         MostDerivedLength = I + 1;
+      } else if (Type->isAnyComplexType()) {
+        const ComplexType *CT = Type->castAs<ComplexType>();
+        Type = CT->getElementType();
+        ArraySize = 2;
+        MostDerivedLength = I + 1;
       } else if (const FieldDecl *FD = getAsField(Path[I])) {
         Type = FD->getType();
         ArraySize = 0;
@@ -131,7 +125,7 @@
   // The order of this enum is important for diagnostics.
   enum CheckSubobjectKind {
     CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
-    CSK_This
+    CSK_This, CSK_Real, CSK_Imag
   };
 
   /// A path from a glvalue to a subobject of that glvalue.
@@ -232,6 +226,18 @@
         MostDerivedPathLength = Entries.size();
       }
     }
+    /// Update this designator to refer to the given complex component.
+    void addComplexUnchecked(QualType EltTy, bool Imag) {
+      PathEntry Entry;
+      Entry.ArrayIndex = Imag;
+      Entries.push_back(Entry);
+
+      // This is technically a most-derived object, though in practice this
+      // is unlikely to matter.
+      MostDerivedType = EltTy;
+      MostDerivedArraySize = 2;
+      MostDerivedPathLength = Entries.size();
+    }
     void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E, uint64_t N);
     /// Add N to the address of this subobject.
     void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
@@ -267,9 +273,6 @@
   class CCValue : public APValue {
     typedef llvm::APSInt APSInt;
     typedef llvm::APFloat APFloat;
-    /// If the value is a reference or pointer into a parameter or temporary,
-    /// this is the corresponding call stack frame.
-    CallStackFrame *CallFrame;
     /// If the value is a reference or pointer, this is a description of how the
     /// subobject was specified.
     SubobjectDesignator Designator;
@@ -282,22 +285,19 @@
     CCValue(const APValue *E, unsigned N) : APValue(E, N) {}
     CCValue(const APSInt &R, const APSInt &I) : APValue(R, I) {}
     CCValue(const APFloat &R, const APFloat &I) : APValue(R, I) {}
-    CCValue(const CCValue &V) : APValue(V), CallFrame(V.CallFrame) {}
-    CCValue(LValueBase B, const CharUnits &O, CallStackFrame *F,
+    CCValue(const CCValue &V) : APValue(V), Designator(V.Designator) {}
+    CCValue(LValueBase B, const CharUnits &O, unsigned I,
             const SubobjectDesignator &D) :
-      APValue(B, O, APValue::NoLValuePath()), CallFrame(F), Designator(D) {}
+      APValue(B, O, APValue::NoLValuePath(), I), Designator(D) {}
     CCValue(ASTContext &Ctx, const APValue &V, GlobalValue) :
-      APValue(V), CallFrame(0), Designator(Ctx, V) {}
+      APValue(V), Designator(Ctx, V) {
+    }
     CCValue(const ValueDecl *D, bool IsDerivedMember,
             ArrayRef<const CXXRecordDecl*> Path) :
       APValue(D, IsDerivedMember, Path) {}
     CCValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) :
       APValue(LHSExpr, RHSExpr) {}
 
-    CallStackFrame *getLValueFrame() const {
-      assert(getKind() == LValue);
-      return CallFrame;
-    }
     SubobjectDesignator &getLValueDesignator() {
       assert(getKind() == LValue);
       return Designator;
@@ -305,6 +305,21 @@
     const SubobjectDesignator &getLValueDesignator() const {
       return const_cast<CCValue*>(this)->getLValueDesignator();
     }
+    APValue toAPValue() const {
+      if (!isLValue())
+        return *this;
+
+      if (Designator.Invalid) {
+        // This is not a core constant expression. An appropriate diagnostic
+        // will have already been produced.
+        return APValue(getLValueBase(), getLValueOffset(),
+                       APValue::NoLValuePath(), getLValueCallIndex());
+      }
+
+      return APValue(getLValueBase(), getLValueOffset(),
+                     Designator.Entries, Designator.IsOnePastTheEnd,
+                     getLValueCallIndex());
+    }
   };
 
   /// A stack frame in the constexpr call stack.
@@ -320,6 +335,9 @@
     /// Callee - The function which was called.
     const FunctionDecl *Callee;
 
+    /// Index - The call index of this call.
+    unsigned Index;
+
     /// This - The binding for the this pointer in this call, if any.
     const LValue *This;
 
@@ -372,6 +390,20 @@
     }
   };
 
+  /// EvalInfo - This is a private struct used by the evaluator to capture
+  /// information about a subexpression as it is folded.  It retains information
+  /// about the AST context, but also maintains information about the folded
+  /// expression.
+  ///
+  /// If an expression could be evaluated, it is still possible it is not a C
+  /// "integer constant expression" or constant expression.  If not, this struct
+  /// captures information about how and why not.
+  ///
+  /// One bit of information passed *into* the request for constant folding
+  /// indicates whether the subexpression is "evaluated" or not according to C
+  /// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
+  /// evaluate the expression regardless of what the RHS is, but C only allows
+  /// certain things in certain situations.
   struct EvalInfo {
     ASTContext &Ctx;
 
@@ -384,6 +416,9 @@
     /// CallStackDepth - The number of calls in the call stack right now.
     unsigned CallStackDepth;
 
+    /// NextCallIndex - The next call index to assign.
+    unsigned NextCallIndex;
+
     typedef llvm::DenseMap<const OpaqueValueExpr*, CCValue> MapTy;
     /// OpaqueValues - Values used as the common expression in a
     /// BinaryConditionalOperator.
@@ -413,7 +448,8 @@
 
     EvalInfo(const ASTContext &C, Expr::EvalStatus &S)
       : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0),
-        CallStackDepth(0), BottomFrame(*this, SourceLocation(), 0, 0, 0),
+        CallStackDepth(0), NextCallIndex(1),
+        BottomFrame(*this, SourceLocation(), 0, 0, 0),
         EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false),
         CheckingPotentialConstantExpression(false) {}
 
@@ -435,6 +471,11 @@
       // when checking a potential constant expression.
       if (CheckingPotentialConstantExpression && CallStackDepth > 1)
         return false;
+      if (NextCallIndex == 0) {
+        // NextCallIndex has wrapped around.
+        Diag(Loc, diag::note_constexpr_call_limit_exceeded);
+        return false;
+      }
       if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
         return true;
       Diag(Loc, diag::note_constexpr_depth_limit_exceeded)
@@ -442,6 +483,16 @@
       return false;
     }
 
+    CallStackFrame *getCallFrame(unsigned CallIndex) {
+      assert(CallIndex && "no call index in getCallFrame");
+      // We will eventually hit BottomFrame, which has Index 1, so Frame can't
+      // be null in this loop.
+      CallStackFrame *Frame = CurrentCall;
+      while (Frame->Index > CallIndex)
+        Frame = Frame->Caller;
+      return (Frame->Index == CallIndex) ? Frame : 0;
+    }
+
   private:
     /// Add a diagnostic to the diagnostics list.
     PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId) {
@@ -510,7 +561,8 @@
     /// Should we continue evaluation as much as possible after encountering a
     /// construct which can't be folded?
     bool keepEvaluatingAfterFailure() {
-      return CheckingPotentialConstantExpression && EvalStatus.Diag->empty();
+      return CheckingPotentialConstantExpression &&
+             EvalStatus.Diag && EvalStatus.Diag->empty();
     }
   };
 
@@ -529,6 +581,24 @@
         Info.EvalStatus.Diag->clear();
     }
   };
+
+  /// RAII object used to suppress diagnostics and side-effects from a
+  /// speculative evaluation.
+  class SpeculativeEvaluationRAII {
+    EvalInfo &Info;
+    Expr::EvalStatus Old;
+
+  public:
+    SpeculativeEvaluationRAII(EvalInfo &Info,
+                              llvm::SmallVectorImpl<PartialDiagnosticAt>
+                                *NewDiag = 0)
+      : Info(Info), Old(Info.EvalStatus) {
+      Info.EvalStatus.Diag = NewDiag;
+    }
+    ~SpeculativeEvaluationRAII() {
+      Info.EvalStatus = Old;
+    }
+  };
 }
 
 bool SubobjectDesignator::checkSubobject(EvalInfo &Info, const Expr *E,
@@ -560,7 +630,7 @@
                                const FunctionDecl *Callee, const LValue *This,
                                const CCValue *Arguments)
     : Info(Info), Caller(Info.CurrentCall), CallLoc(CallLoc), Callee(Callee),
-      This(This), Arguments(Arguments) {
+      Index(Info.NextCallIndex++), This(This), Arguments(Arguments) {
   Info.CurrentCall = this;
   ++Info.CallStackDepth;
 }
@@ -591,10 +661,11 @@
     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.
+      // Convert the CCValue to an APValue without checking for constantness.
       APValue Value(Arg.getLValueBase(), Arg.getLValueOffset(),
                     Arg.getLValueDesignator().Entries,
-                    Arg.getLValueDesignator().IsOnePastTheEnd);
+                    Arg.getLValueDesignator().IsOnePastTheEnd,
+                    Arg.getLValueCallIndex());
       Value.printPretty(Out, Frame->Info.Ctx, Param->getType());
     }
 
@@ -679,31 +750,31 @@
   struct LValue {
     APValue::LValueBase Base;
     CharUnits Offset;
-    CallStackFrame *Frame;
+    unsigned CallIndex;
     SubobjectDesignator Designator;
 
     const APValue::LValueBase getLValueBase() const { return Base; }
     CharUnits &getLValueOffset() { return Offset; }
     const CharUnits &getLValueOffset() const { return Offset; }
-    CallStackFrame *getLValueFrame() const { return Frame; }
+    unsigned getLValueCallIndex() const { return CallIndex; }
     SubobjectDesignator &getLValueDesignator() { return Designator; }
     const SubobjectDesignator &getLValueDesignator() const { return Designator;}
 
     void moveInto(CCValue &V) const {
-      V = CCValue(Base, Offset, Frame, Designator);
+      V = CCValue(Base, Offset, CallIndex, Designator);
     }
     void setFrom(const CCValue &V) {
       assert(V.isLValue());
       Base = V.getLValueBase();
       Offset = V.getLValueOffset();
-      Frame = V.getLValueFrame();
+      CallIndex = V.getLValueCallIndex();
       Designator = V.getLValueDesignator();
     }
 
-    void set(APValue::LValueBase B, CallStackFrame *F = 0) {
+    void set(APValue::LValueBase B, unsigned I = 0) {
       Base = B;
       Offset = CharUnits::Zero();
-      Frame = F;
+      CallIndex = I;
       Designator = SubobjectDesignator(getType(B));
     }
 
@@ -738,6 +809,10 @@
       checkSubobject(Info, E, CSK_ArrayToPointer);
       Designator.addArrayUnchecked(CAT);
     }
+    void addComplex(EvalInfo &Info, const Expr *E, QualType EltTy, bool Imag) {
+      checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real);
+      Designator.addComplexUnchecked(EltTy, Imag);
+    }
     void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
       if (!checkNullPointer(Info, E, CSK_ArrayIndex))
         return;
@@ -852,11 +927,10 @@
 }
 
 static bool Evaluate(CCValue &Result, EvalInfo &Info, const Expr *E);
-static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
-                                       const LValue &This, const Expr *E,
-                                       CheckConstantExpressionKind CCEK
-                                        = CCEK_Constant,
-                                       bool AllowNonLiteralTypes = false);
+static bool EvaluateInPlace(APValue &Result, EvalInfo &Info,
+                            const LValue &This, const Expr *E,
+                            CheckConstantExpressionKind CCEK = CCEK_Constant,
+                            bool AllowNonLiteralTypes = false);
 static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info);
 static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info);
 static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
@@ -899,8 +973,10 @@
   switch (E->getStmtClass()) {
   default:
     return false;
-  case Expr::CompoundLiteralExprClass:
-    return cast<CompoundLiteralExpr>(E)->isFileScope();
+  case Expr::CompoundLiteralExprClass: {
+    const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+    return CLE->isFileScope() && CLE->isLValue();
+  }
   // A string literal has static storage duration.
   case Expr::StringLiteralClass:
   case Expr::PredefinedExprClass:
@@ -928,47 +1004,46 @@
   }
 }
 
+static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) {
+  assert(Base && "no location for a null lvalue");
+  const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
+  if (VD)
+    Info.Note(VD->getLocation(), diag::note_declared_at);
+  else
+    Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(),
+              diag::note_constexpr_temporary_here);
+}
+
 /// Check that this reference or pointer core constant expression is a valid
 /// value for an address or reference constant expression. Type T should be
 /// either LValue or CCValue. Return true if we can fold this expression,
 /// whether or not it's a constant expression.
-template<typename T>
-static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E,
-                                          const T &LVal, APValue &Value,
-                                          CheckConstantExpressionKind CCEK) {
+static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
+                                          QualType Type, const LValue &LVal) {
+  bool IsReferenceType = Type->isReferenceType();
+
   APValue::LValueBase Base = LVal.getLValueBase();
   const SubobjectDesignator &Designator = LVal.getLValueDesignator();
 
+  // Check that the object is a global. Note that the fake 'this' object we
+  // manufacture when checking potential constant expressions is conservatively
+  // assumed to be global here.
   if (!IsGlobalLValue(Base)) {
     if (Info.getLangOpts().CPlusPlus0x) {
       const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
-      Info.Diag(E->getExprLoc(), diag::note_constexpr_non_global, 1)
-        << E->isGLValue() << !Designator.Entries.empty()
-        << !!VD << CCEK << VD;
-      if (VD)
-        Info.Note(VD->getLocation(), diag::note_declared_at);
-      else
-        Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(),
-                  diag::note_constexpr_temporary_here);
+      Info.Diag(Loc, diag::note_constexpr_non_global, 1)
+        << IsReferenceType << !Designator.Entries.empty()
+        << !!VD << VD;
+      NoteLValueLocation(Info, Base);
     } else {
-      Info.Diag(E->getExprLoc());
+      Info.Diag(Loc);
     }
     // Don't allow references to temporaries to escape.
     return false;
   }
-
-  bool IsReferenceType = E->isGLValue();
-
-  if (Designator.Invalid) {
-    // This is not a core constant expression. An appropriate diagnostic will
-    // have already been produced.
-    Value = APValue(LVal.getLValueBase(), LVal.getLValueOffset(),
-                    APValue::NoLValuePath());
-    return true;
-  }
-
-  Value = APValue(LVal.getLValueBase(), LVal.getLValueOffset(),
-                  Designator.Entries, Designator.IsOnePastTheEnd);
+  assert((Info.CheckingPotentialConstantExpression ||
+          LVal.getLValueCallIndex() == 0) &&
+         "have call index for global lvalue");
 
   // Allow address constant expressions to be past-the-end pointers. This is
   // an extension: the standard requires them to point to an object.
@@ -978,20 +1053,16 @@
   // A reference constant expression must refer to an object.
   if (!Base) {
     // FIXME: diagnostic
-    Info.CCEDiag(E->getExprLoc());
+    Info.CCEDiag(Loc);
     return true;
   }
 
   // Does this refer one past the end of some object?
   if (Designator.isOnePastTheEnd()) {
     const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>();
-    Info.Diag(E->getExprLoc(), diag::note_constexpr_past_end, 1)
+    Info.Diag(Loc, diag::note_constexpr_past_end, 1)
       << !Designator.Entries.empty() << !!VD << VD;
-    if (VD)
-      Info.Note(VD->getLocation(), diag::note_declared_at);
-    else
-      Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(),
-                diag::note_constexpr_temporary_here);
+    NoteLValueLocation(Info, Base);
   }
 
   return true;
@@ -1013,18 +1084,58 @@
 }
 
 /// Check that this core constant expression value is a valid value for a
-/// constant expression, and if it is, produce the corresponding constant value.
-/// If not, report an appropriate diagnostic. Does not check that the expression
-/// is of literal type.
-static bool CheckConstantExpression(EvalInfo &Info, const Expr *E,
-                                    const CCValue &CCValue, APValue &Value,
-                                    CheckConstantExpressionKind CCEK
-                                      = CCEK_Constant) {
-  if (!CCValue.isLValue()) {
-    Value = CCValue;
-    return true;
+/// constant expression. If not, report an appropriate diagnostic. Does not
+/// check that the expression is of literal type.
+static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
+                                    QualType Type, const APValue &Value) {
+  // Core issue 1454: For a literal constant expression of array or class type,
+  // each subobject of its value shall have been initialized by a constant
+  // expression.
+  if (Value.isArray()) {
+    QualType EltTy = Type->castAsArrayTypeUnsafe()->getElementType();
+    for (unsigned I = 0, N = Value.getArrayInitializedElts(); I != N; ++I) {
+      if (!CheckConstantExpression(Info, DiagLoc, EltTy,
+                                   Value.getArrayInitializedElt(I)))
+        return false;
+    }
+    if (!Value.hasArrayFiller())
+      return true;
+    return CheckConstantExpression(Info, DiagLoc, EltTy,
+                                   Value.getArrayFiller());
+  }
+  if (Value.isUnion() && Value.getUnionField()) {
+    return CheckConstantExpression(Info, DiagLoc,
+                                   Value.getUnionField()->getType(),
+                                   Value.getUnionValue());
+  }
+  if (Value.isStruct()) {
+    RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
+    if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
+      unsigned BaseIndex = 0;
+      for (CXXRecordDecl::base_class_const_iterator I = CD->bases_begin(),
+             End = CD->bases_end(); I != End; ++I, ++BaseIndex) {
+        if (!CheckConstantExpression(Info, DiagLoc, I->getType(),
+                                     Value.getStructBase(BaseIndex)))
+          return false;
+      }
+    }
+    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+         I != E; ++I) {
+      if (!CheckConstantExpression(Info, DiagLoc, (*I)->getType(),
+                                   Value.getStructField((*I)->getFieldIndex())))
+        return false;
+    }
   }
-  return CheckLValueConstantExpression(Info, E, CCValue, Value, CCEK);
+
+  if (Value.isLValue()) {
+    CCValue Val(Info.Ctx, Value, CCValue::GlobalValue());
+    LValue LVal;
+    LVal.setFrom(Val);
+    return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal);
+  }
+
+  // Everything else is fine.
+  return true;
 }
 
 const ValueDecl *GetLValueBaseDecl(const LValue &LVal) {
@@ -1032,7 +1143,7 @@
 }
 
 static bool IsLiteralLValue(const LValue &Value) {
-  return Value.Base.dyn_cast<const Expr*>() && !Value.Frame;
+  return Value.Base.dyn_cast<const Expr*>() && !Value.CallIndex;
 }
 
 static bool IsWeakLValue(const LValue &Value) {
@@ -1291,7 +1402,8 @@
 }
 
 /// Get the size of the given type in char units.
-static bool HandleSizeof(EvalInfo &Info, QualType Type, CharUnits &Size) {
+static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc,
+                         QualType Type, CharUnits &Size) {
   // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
   // extension.
   if (Type->isVoidType() || Type->isFunctionType()) {
@@ -1301,7 +1413,8 @@
 
   if (!Type->isConstantSizeType()) {
     // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
-    // FIXME: Diagnostic.
+    // FIXME: Better diagnostic.
+    Info.Diag(Loc);
     return false;
   }
 
@@ -1319,7 +1432,7 @@
                                         LValue &LVal, QualType EltTy,
                                         int64_t Adjustment) {
   CharUnits SizeOfPointee;
-  if (!HandleSizeof(Info, EltTy, SizeOfPointee))
+  if (!HandleSizeof(Info, E->getExprLoc(), EltTy, SizeOfPointee))
     return false;
 
   // Compute the new offset in the appropriate width.
@@ -1328,6 +1441,24 @@
   return true;
 }
 
+/// Update an lvalue to refer to a component of a complex number.
+/// \param Info - Information about the ongoing evaluation.
+/// \param LVal - The lvalue to be updated.
+/// \param EltTy - The complex number's component type.
+/// \param Imag - False for the real component, true for the imaginary.
+static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
+                                       LValue &LVal, QualType EltTy,
+                                       bool Imag) {
+  if (Imag) {
+    CharUnits SizeOfComponent;
+    if (!HandleSizeof(Info, E->getExprLoc(), EltTy, SizeOfComponent))
+      return false;
+    LVal.Offset += SizeOfComponent;
+  }
+  LVal.addComplex(Info, E, EltTy, Imag);
+  return true;
+}
+
 /// Try to evaluate the initializer for a variable declaration.
 static bool EvaluateVarDeclInit(EvalInfo &Info, const Expr *E,
                                 const VarDecl *VD,
@@ -1412,6 +1543,20 @@
   llvm_unreachable("base class missing from derived class's bases list");
 }
 
+/// Extract the value of a character from a string literal.
+static APSInt ExtractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit,
+                                            uint64_t Index) {
+  // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant
+  const StringLiteral *S = dyn_cast<StringLiteral>(Lit);
+  assert(S && "unexpected string literal expression kind");
+
+  APSInt Value(S->getCharByteWidth() * Info.Ctx.getCharWidth(),
+    Lit->getType()->getArrayElementTypeNoTypeQual()->isUnsignedIntegerType());
+  if (Index < S->getLength())
+    Value = S->getCodeUnit(Index);
+  return Value;
+}
+
 /// Extract the designated sub-object of an rvalue.
 static bool ExtractSubobject(EvalInfo &Info, const Expr *E,
                              CCValue &Obj, QualType ObjType,
@@ -1431,7 +1576,6 @@
     // This object might be initialized later.
     return false;
 
-  assert(!Obj.isLValue() && "extracting subobject of lvalue");
   const APValue *O = &Obj;
   // Walk the designator's path to find the subobject.
   for (unsigned I = 0, N = Sub.Entries.size(); I != N; ++I) {
@@ -1448,11 +1592,38 @@
                     (unsigned)diag::note_invalid_subexpr_in_const_expr);
         return false;
       }
-      if (O->getArrayInitializedElts() > Index)
+      // An array object is represented as either an Array APValue or as an
+      // LValue which refers to a string literal.
+      if (O->isLValue()) {
+        assert(I == N - 1 && "extracting subobject of character?");
+        assert(!O->hasLValuePath() || O->getLValuePath().empty());
+        Obj = CCValue(ExtractStringLiteralCharacter(
+          Info, O->getLValueBase().get<const Expr*>(), Index));
+        return true;
+      } else if (O->getArrayInitializedElts() > Index)
         O = &O->getArrayInitializedElt(Index);
       else
         O = &O->getArrayFiller();
       ObjType = CAT->getElementType();
+    } else if (ObjType->isAnyComplexType()) {
+      // Next subobject is a complex number.
+      uint64_t Index = Sub.Entries[I].ArrayIndex;
+      if (Index > 1) {
+        Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ?
+                    (unsigned)diag::note_constexpr_read_past_end :
+                    (unsigned)diag::note_invalid_subexpr_in_const_expr);
+        return false;
+      }
+      assert(I == N - 1 && "extracting subobject of scalar?");
+      if (O->isComplexInt()) {
+        Obj = CCValue(Index ? O->getComplexIntImag()
+                            : O->getComplexIntReal());
+      } else {
+        assert(O->isComplexFloat());
+        Obj = CCValue(Index ? O->getComplexFloatImag()
+                            : O->getComplexFloatReal());
+      }
+      return true;
     } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
       if (Field->isMutable()) {
         Info.Diag(E->getExprLoc(), diag::note_constexpr_ltor_mutable, 1)
@@ -1515,13 +1686,17 @@
                                        bool &WasArrayIndex) {
   unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
   for (/**/; I != N; ++I) {
-    if (!ObjType.isNull() && ObjType->isArrayType()) {
+    if (!ObjType.isNull() &&
+        (ObjType->isArrayType() || ObjType->isAnyComplexType())) {
       // Next subobject is an array element.
       if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
         WasArrayIndex = true;
         return I;
       }
-      ObjType = ObjType->castAsArrayTypeUnsafe()->getElementType();
+      if (ObjType->isAnyComplexType())
+        ObjType = ObjType->castAs<ComplexType>()->getElementType();
+      else
+        ObjType = ObjType->castAsArrayTypeUnsafe()->getElementType();
     } else {
       if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
         WasArrayIndex = false;
@@ -1583,7 +1758,6 @@
     return false;
 
   const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
-  CallStackFrame *Frame = LVal.Frame;
   SourceLocation Loc = Conv->getExprLoc();
 
   if (!LVal.Base) {
@@ -1592,6 +1766,16 @@
     return false;
   }
 
+  CallStackFrame *Frame = 0;
+  if (LVal.CallIndex) {
+    Frame = Info.getCallFrame(LVal.CallIndex);
+    if (!Frame) {
+      Info.Diag(Loc, diag::note_constexpr_lifetime_ended, 1) << !Base;
+      NoteLValueLocation(Info, LVal.Base);
+      return false;
+    }
+  }
+
   // C++11 DR1311: An lvalue-to-rvalue conversion on a volatile-qualified type
   // is not a constant expression (even if the object is non-volatile). We also
   // apply this rule to C++98, in order to conform to the expected 'volatile'
@@ -1680,7 +1864,17 @@
     assert(RVal.getLValueOffset().isZero() &&
            "offset for lvalue init of non-reference");
     Base = RVal.getLValueBase().get<const Expr*>();
-    Frame = RVal.getLValueFrame();
+
+    if (unsigned CallIndex = RVal.getLValueCallIndex()) {
+      Frame = Info.getCallFrame(CallIndex);
+      if (!Frame) {
+        Info.Diag(Loc, diag::note_constexpr_lifetime_ended, 1) << !Base;
+        NoteLValueLocation(Info, RVal.getLValueBase());
+        return false;
+      }
+    } else {
+      Frame = 0;
+    }
   }
 
   // Volatile temporary objects cannot be read in constant expressions.
@@ -1694,33 +1888,6 @@
     return false;
   }
 
-  // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant
-  if (const StringLiteral *S = dyn_cast<StringLiteral>(Base)) {
-    const SubobjectDesignator &Designator = LVal.Designator;
-    if (Designator.Invalid || Designator.Entries.size() != 1) {
-      Info.Diag(Conv->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
-      return false;
-    }
-
-    assert(Type->isIntegerType() && "string element not integer type");
-    uint64_t Index = Designator.Entries[0].ArrayIndex;
-    const ConstantArrayType *CAT =
-        Info.Ctx.getAsConstantArrayType(S->getType());
-    if (Index >= CAT->getSize().getZExtValue()) {
-      // Note, it should not be possible to form a pointer which points more
-      // than one past the end of the array without producing a prior const expr
-      // diagnostic.
-      Info.Diag(Loc, diag::note_constexpr_read_past_end);
-      return false;
-    }
-    APSInt Value(S->getCharByteWidth() * Info.Ctx.getCharWidth(),
-                 Type->isUnsignedIntegerType());
-    if (Index < S->getLength())
-      Value = S->getCodeUnit(Index);
-    RVal = CCValue(Value);
-    return true;
-  }
-
   if (Frame) {
     // If this is a temporary expression with a nontrivial initializer, grab the
     // value from the relevant stack frame.
@@ -1733,6 +1900,13 @@
     assert(!Info.getLangOpts().CPlusPlus && "lvalue compound literal in c++?");
     if (!Evaluate(RVal, Info, CLE->getInitializer()))
       return false;
+  } else if (isa<StringLiteral>(Base)) {
+    // We represent a string literal array as an lvalue pointing at the
+    // corresponding expression, rather than building an array of chars.
+    // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant
+    RVal = CCValue(Info.Ctx,
+                   APValue(Base, CharUnits::Zero(), APValue::NoLValuePath(), 0),
+                   CCValue::GlobalValue());
   } else {
     Info.Diag(Conv->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
     return false;
@@ -1896,7 +2070,7 @@
 }
 
 // Evaluate a statement.
-static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
+static EvalStmtResult EvaluateStmt(CCValue &Result, EvalInfo &Info,
                                    const Stmt *S) {
   switch (S->getStmtClass()) {
   default:
@@ -1907,11 +2081,8 @@
     return ESR_Succeeded;
 
   case Stmt::ReturnStmtClass: {
-    CCValue CCResult;
     const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
-    if (!Evaluate(CCResult, Info, RetExpr) ||
-        !CheckConstantExpression(Info, RetExpr, CCResult, Result,
-                                 CCEK_ReturnValue))
+    if (!Evaluate(Result, Info, RetExpr))
       return ESR_Failed;
     return ESR_Returned;
   }
@@ -2010,7 +2181,7 @@
 static bool HandleFunctionCall(SourceLocation CallLoc,
                                const FunctionDecl *Callee, const LValue *This,
                                ArrayRef<const Expr*> Args, const Stmt *Body,
-                               EvalInfo &Info, APValue &Result) {
+                               EvalInfo &Info, CCValue &Result) {
   ArgVector ArgValues(Args.size());
   if (!EvaluateArgs(Args, ArgValues, Info))
     return false;
@@ -2045,7 +2216,7 @@
   // If it's a delegating constructor, just delegate.
   if (Definition->isDelegatingConstructor()) {
     CXXConstructorDecl::init_const_iterator I = Definition->init_begin();
-    return EvaluateConstantExpression(Result, Info, This, (*I)->getInit());
+    return EvaluateInPlace(Result, Info, This, (*I)->getInit());
   }
 
   // For a trivial copy or move constructor, perform an APValue copy. This is
@@ -2137,8 +2308,8 @@
       llvm_unreachable("unknown base initializer kind");
     }
 
-    if (!EvaluateConstantExpression(*Value, Info, Subobject, (*I)->getInit(),
-                                    (*I)->isBaseInitializer()
+    if (!EvaluateInPlace(*Value, Info, Subobject, (*I)->getInit(),
+                         (*I)->isBaseInitializer()
                                       ? CCEK_Constant : CCEK_MemberInit)) {
       // If we're checking for a potential constant expression, evaluate all
       // initializers even if some of them fail.
@@ -2248,8 +2419,9 @@
   bool hasError() const { return opaqueValue == 0; }
 
   ~OpaqueValueEvaluation() {
-    // FIXME: This will not work for recursive constexpr functions using opaque
-    // values. Restore the former value.
+    // FIXME: For a recursive constexpr call, an outer stack frame might have
+    // been using this opaque value too, and will now have to re-evaluate the
+    // source expression.
     if (opaqueValue) info.OpaqueValues.erase(opaqueValue);
   }
 };
@@ -2273,6 +2445,45 @@
     return static_cast<Derived*>(this)->ZeroInitialization(E);
   }
 
+  // Check whether a conditional operator with a non-constant condition is a
+  // potential constant expression. If neither arm is a potential constant
+  // expression, then the conditional operator is not either.
+  template<typename ConditionalOperator>
+  void CheckPotentialConstantConditional(const ConditionalOperator *E) {
+    assert(Info.CheckingPotentialConstantExpression);
+
+    // Speculatively evaluate both arms.
+    {
+      llvm::SmallVector<PartialDiagnosticAt, 8> Diag;
+      SpeculativeEvaluationRAII Speculate(Info, &Diag);
+
+      StmtVisitorTy::Visit(E->getFalseExpr());
+      if (Diag.empty())
+        return;
+
+      Diag.clear();
+      StmtVisitorTy::Visit(E->getTrueExpr());
+      if (Diag.empty())
+        return;
+    }
+
+    Error(E, diag::note_constexpr_conditional_never_const);
+  }
+
+
+  template<typename ConditionalOperator>
+  bool HandleConditionalOperator(const ConditionalOperator *E) {
+    bool BoolResult;
+    if (!EvaluateAsBooleanCondition(E->getCond(), BoolResult, Info)) {
+      if (Info.CheckingPotentialConstantExpression)
+        CheckPotentialConstantConditional(E);
+      return false;
+    }
+
+    Expr *EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
+    return StmtVisitorTy::Visit(EvalExpr);
+  }
+
 protected:
   EvalInfo &Info;
   typedef ConstStmtVisitor<Derived, RetTy> StmtVisitorTy;
@@ -2355,15 +2566,12 @@
   }
 
   RetTy VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
+    // Cache the value of the common expression.
     OpaqueValueEvaluation opaque(Info, E->getOpaqueValue(), E->getCommon());
     if (opaque.hasError())
       return false;
 
-    bool cond;
-    if (!EvaluateAsBooleanCondition(E->getCond(), cond, Info))
-      return false;
-
-    return StmtVisitorTy::Visit(cond ? E->getTrueExpr() : E->getFalseExpr());
+    return HandleConditionalOperator(E);
   }
 
   RetTy VisitConditionalOperator(const ConditionalOperator *E) {
@@ -2384,12 +2592,7 @@
 
     FoldConstant Fold(Info);
 
-    bool BoolResult;
-    if (!EvaluateAsBooleanCondition(E->getCond(), BoolResult, Info))
-      return false;
-
-    Expr *EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
-    if (!StmtVisitorTy::Visit(EvalExpr))
+    if (!HandleConditionalOperator(E))
       return false;
 
     if (IsBcpCall)
@@ -2488,14 +2691,14 @@
 
     const FunctionDecl *Definition = 0;
     Stmt *Body = FD->getBody(Definition);
-    APValue Result;
+    CCValue Result;
 
     if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) ||
         !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body,
                             Info, Result))
       return false;
 
-    return DerivedSuccess(CCValue(Info.Ctx, Result, CCValue::GlobalValue()), E);
+    return DerivedSuccess(Result, E);
   }
 
   RetTy VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
@@ -2706,8 +2909,8 @@
 //  * BlockExpr
 //  * CallExpr for a MakeStringConstant builtin
 // - Locals and temporaries
-//  * Any Expr, with a Frame indicating the function in which the temporary was
-//    evaluated.
+//  * Any Expr, with a CallIndex indicating the function in which the temporary
+//    was evaluated.
 // plus an offset in bytes.
 //===----------------------------------------------------------------------===//
 namespace {
@@ -2729,6 +2932,8 @@
   bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
   bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
   bool VisitUnaryDeref(const UnaryOperator *E);
+  bool VisitUnaryReal(const UnaryOperator *E);
+  bool VisitUnaryImag(const UnaryOperator *E);
 
   bool VisitCastExpr(const CastExpr *E) {
     switch (E->getCastKind()) {
@@ -2748,9 +2953,6 @@
       return HandleBaseToDerivedCast(Info, E, Result);
     }
   }
-
-  // FIXME: Missing: __real__, __imag__
-
 };
 } // end anonymous namespace
 
@@ -2777,7 +2979,7 @@
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   if (!VD->getType()->isReferenceType()) {
     if (isa<ParmVarDecl>(VD)) {
-      Result.set(VD, Info.CurrentCall);
+      Result.set(VD, Info.CurrentCall->Index);
       return true;
     }
     return Success(VD);
@@ -2795,9 +2997,9 @@
     if (E->getType()->isRecordType())
       return EvaluateTemporary(E->GetTemporaryExpr(), Result, Info);
 
-    Result.set(E, Info.CurrentCall);
-    return EvaluateConstantExpression(Info.CurrentCall->Temporaries[E], Info,
-                                      Result, E->GetTemporaryExpr());
+    Result.set(E, Info.CurrentCall->Index);
+    return EvaluateInPlace(Info.CurrentCall->Temporaries[E], Info,
+                           Result, E->GetTemporaryExpr());
   }
 
   // Materialization of an lvalue temporary occurs when we need to force a copy
@@ -2808,7 +3010,7 @@
   if (!HandleLValueToRValueConversion(Info, E, E->getType(), Result,
                                       Info.CurrentCall->Temporaries[E]))
     return false;
-  Result.set(E, Info.CurrentCall);
+  Result.set(E, Info.CurrentCall->Index);
   return true;
 }
 
@@ -2874,6 +3076,24 @@
   return EvaluatePointer(E->getSubExpr(), Result, Info);
 }
 
+bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
+  if (!Visit(E->getSubExpr()))
+    return false;
+  // __real is a no-op on scalar lvalues.
+  if (E->getSubExpr()->getType()->isAnyComplexType())
+    HandleLValueComplexElement(Info, E, Result, E->getType(), false);
+  return true;
+}
+
+bool LValueExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
+  assert(E->getSubExpr()->getType()->isAnyComplexType() &&
+         "lvalue __imag__ on scalar?");
+  if (!Visit(E->getSubExpr()))
+    return false;
+  HandleLValueComplexElement(Info, E, Result, E->getType(), true);
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // Pointer Evaluation
 //===----------------------------------------------------------------------===//
@@ -3032,7 +3252,7 @@
       uint64_t N = Value.getInt().extOrTrunc(Size).getZExtValue();
       Result.Base = (Expr*)0;
       Result.Offset = CharUnits::fromQuantity(N);
-      Result.Frame = 0;
+      Result.CallIndex = 0;
       Result.Designator.setInvalid();
       return true;
     } else {
@@ -3046,9 +3266,9 @@
       if (!EvaluateLValue(SubExpr, Result, Info))
         return false;
     } else {
-      Result.set(SubExpr, Info.CurrentCall);
-      if (!EvaluateConstantExpression(Info.CurrentCall->Temporaries[SubExpr],
-                                      Info, Result, SubExpr))
+      Result.set(SubExpr, Info.CurrentCall->Index);
+      if (!EvaluateInPlace(Info.CurrentCall->Temporaries[SubExpr],
+                           Info, Result, SubExpr))
         return false;
     }
     // The result is a pointer to the first element of the array.
@@ -3175,7 +3395,8 @@
       : ExprEvaluatorBaseTy(info), This(This), Result(Result) {}
 
     bool Success(const CCValue &V, const Expr *E) {
-      return CheckConstantExpression(Info, E, V, Result);
+      Result = V;
+      return true;
     }
     bool ZeroInitialization(const Expr *E);
 
@@ -3225,7 +3446,7 @@
     HandleLValueMember(Info, E, Subobject, *I, &Layout);
 
     ImplicitValueInitExpr VIE((*I)->getType());
-    if (!EvaluateConstantExpression(
+    if (!EvaluateInPlace(
           Result.getStructField((*I)->getFieldIndex()), Info, Subobject, &VIE))
       return false;
   }
@@ -3248,8 +3469,12 @@
     HandleLValueMember(Info, E, Subobject, *I);
     Result = APValue(*I);
     ImplicitValueInitExpr VIE((*I)->getType());
-    return EvaluateConstantExpression(Result.getUnionValue(), Info,
-                                      Subobject, &VIE);
+    return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
+  }
+
+  if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
+    Info.Diag(E->getExprLoc(), diag::note_constexpr_virtual_base) << RD;
+    return false;
   }
 
   return HandleClassZeroInitialization(Info, E, RD, This, Result);
@@ -3304,8 +3529,7 @@
 
     LValue Subobject = This;
     HandleLValueMember(Info, InitExpr, Subobject, Field, &Layout);
-    return EvaluateConstantExpression(Result.getUnionValue(), Info,
-                                      Subobject, InitExpr);
+    return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
   }
 
   assert((!isa<CXXRecordDecl>(RD) || !cast<CXXRecordDecl>(RD)->getNumBases()) &&
@@ -3334,7 +3558,7 @@
     // the initializer list.
     ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
 
-    if (!EvaluateConstantExpression(
+    if (!EvaluateInPlace(
           Result.getStructField((*Field)->getFieldIndex()),
           Info, Subobject, HaveInit ? E->getInit(ElementNo++) : &VIE)) {
       if (!Info.keepEvaluatingAfterFailure())
@@ -3410,9 +3634,8 @@
 
   /// Visit an expression which constructs the value of this temporary.
   bool VisitConstructExpr(const Expr *E) {
-    Result.set(E, Info.CurrentCall);
-    return EvaluateConstantExpression(Info.CurrentCall->Temporaries[E], Info,
-                                      Result, E);
+    Result.set(E, Info.CurrentCall->Index);
+    return EvaluateInPlace(Info.CurrentCall->Temporaries[E], Info, Result, E);
   }
 
   bool VisitCastExpr(const CastExpr *E) {
@@ -3639,7 +3862,8 @@
       : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
 
     bool Success(const APValue &V, const Expr *E) {
-      assert(V.isArray() && "Expected array type");
+      assert((V.isArray() || V.isLValue()) &&
+             "expected array or string literal");
       Result = V;
       return true;
     }
@@ -3658,8 +3882,7 @@
       LValue Subobject = This;
       Subobject.addArray(Info, E, CAT);
       ImplicitValueInitExpr VIE(CAT->getElementType());
-      return EvaluateConstantExpression(Result.getArrayFiller(), Info,
-                                        Subobject, &VIE);
+      return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
     }
 
     bool VisitInitListExpr(const InitListExpr *E);
@@ -3685,22 +3908,9 @@
     LValue LV;
     if (!EvaluateLValue(E->getInit(0), LV, Info))
       return false;
-    uint64_t NumElements = CAT->getSize().getZExtValue();
-    Result = APValue(APValue::UninitArray(), NumElements, NumElements);
-
-    // Copy the string literal into the array. FIXME: Do this better.
-    LV.addArray(Info, E, CAT);
-    for (uint64_t I = 0; I < NumElements; ++I) {
-      CCValue Char;
-      if (!HandleLValueToRValueConversion(Info, E->getInit(0),
-                                          CAT->getElementType(), LV, Char) ||
-          !CheckConstantExpression(Info, E->getInit(0), Char,
-                                   Result.getArrayInitializedElt(I)) ||
-          !HandleLValueArrayAdjustment(Info, E->getInit(0), LV,
-                                       CAT->getElementType(), 1))
-        return false;
-    }
-    return true;
+    CCValue Val;
+    LV.moveInto(Val);
+    return Success(Val, E);
   }
 
   bool Success = true;
@@ -3712,8 +3922,8 @@
   unsigned Index = 0;
   for (InitListExpr::const_iterator I = E->begin(), End = E->end();
        I != End; ++I, ++Index) {
-    if (!EvaluateConstantExpression(Result.getArrayInitializedElt(Index),
-                                    Info, Subobject, cast<Expr>(*I)) ||
+    if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
+                         Info, Subobject, cast<Expr>(*I)) ||
         !HandleLValueArrayAdjustment(Info, cast<Expr>(*I), Subobject,
                                      CAT->getElementType(), 1)) {
       if (!Info.keepEvaluatingAfterFailure())
@@ -3728,8 +3938,8 @@
   // but sometimes does:
   //   struct S { constexpr S() : p(&p) {} void *p; };
   //   S s[10] = {};
-  return EvaluateConstantExpression(Result.getArrayFiller(), Info,
-                                    Subobject, E->getArrayFiller()) && Success;
+  return EvaluateInPlace(Result.getArrayFiller(), Info,
+                         Subobject, E->getArrayFiller()) && Success;
 }
 
 bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
@@ -3754,8 +3964,7 @@
       LValue Subobject = This;
       Subobject.addArray(Info, E, CAT);
       ImplicitValueInitExpr VIE(CAT->getElementType());
-      return EvaluateConstantExpression(Result.getArrayFiller(), Info,
-                                        Subobject, &VIE);
+      return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
     }
 
     const CXXRecordDecl *RD = FD->getParent();
@@ -3783,8 +3992,7 @@
 
   if (ZeroInit && !HadZeroInit) {
     ImplicitValueInitExpr VIE(CAT->getElementType());
-    if (!EvaluateConstantExpression(Result.getArrayFiller(), Info, Subobject,
-                                    &VIE))
+    if (!EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE))
       return false;
   }
 
@@ -4257,7 +4465,7 @@
   }
 
   return IsGlobalLValue(A.getLValueBase()) ||
-         A.getLValueFrame() == B.getLValueFrame();
+         A.getLValueCallIndex() == B.getLValueCallIndex();
 }
 
 /// Perform the given integer operation, which is known to need at most BitWidth
@@ -4288,7 +4496,7 @@
 
   if (E->isLogicalOp()) {
     // These need to be handled specially because the operands aren't
-    // necessarily integral
+    // necessarily integral nor evaluated.
     bool lhsResult, rhsResult;
 
     if (EvaluateAsBooleanCondition(E->getLHS(), lhsResult, Info)) {
@@ -4304,19 +4512,17 @@
           return Success(lhsResult && rhsResult, E);
       }
     } else {
-      // FIXME: If both evaluations fail, we should produce the diagnostic from
-      // the LHS. If the LHS is non-constant and the RHS is unevaluatable, it's
-      // less clear how to diagnose this.
+      // Since we weren't able to evaluate the left hand side, it
+      // must have had side effects.
+      Info.EvalStatus.HasSideEffects = true;
+
+      // Suppress diagnostics from this arm.
+      SpeculativeEvaluationRAII Speculative(Info);
       if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
         // We can't evaluate the LHS; however, sometimes the result
         // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
-        if (rhsResult == (E->getOpcode() == BO_LOr)) {
-          // Since we weren't able to evaluate the left hand side, it
-          // must have had side effects.
-          Info.EvalStatus.HasSideEffects = true;
-
+        if (rhsResult == (E->getOpcode() == BO_LOr))
           return Success(rhsResult, E);
-        }
       }
     }
 
@@ -4484,7 +4690,7 @@
         QualType ElementType = Type->getAs<PointerType>()->getPointeeType();
 
         CharUnits ElementSize;
-        if (!HandleSizeof(Info, ElementType, ElementSize))
+        if (!HandleSizeof(Info, E->getExprLoc(), ElementType, ElementSize))
           return false;
 
         // FIXME: LLVM and GCC both compute LHSOffset - RHSOffset at runtime,
@@ -4612,6 +4818,16 @@
     return Success(E->getOpcode() == BO_EQ ? Equal : !Equal, E);
   }
 
+  if (LHSTy->isNullPtrType()) {
+    assert(E->isComparisonOp() && "unexpected nullptr operation");
+    assert(RHSTy->isNullPtrType() && "missing pointer conversion");
+    // C++11 [expr.rel]p4, [expr.eq]p3: If two operands of type std::nullptr_t
+    // are compared, the result is true of the operator is <=, >= or ==, and
+    // false otherwise.
+    BinaryOperator::Opcode Opcode = E->getOpcode();
+    return Success(Opcode == BO_EQ || Opcode == BO_LE || Opcode == BO_GE, E);
+  }
+
   if (!LHSTy->isIntegralOrEnumerationType() ||
       !RHSTy->isIntegralOrEnumerationType()) {
     // We can't continue from here for non-integral types.
@@ -4764,8 +4980,6 @@
 }
 
 CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
-  // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
-  //   the result is the size of the referenced type."
   // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
   //   result shall be the alignment of the referenced type."
   if (const ReferenceType *Ref = T->getAs<ReferenceType>())
@@ -4825,13 +5039,11 @@
     QualType SrcTy = E->getTypeOfArgument();
     // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
     //   the result is the size of the referenced type."
-    // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
-    //   result shall be the alignment of the referenced type."
     if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
       SrcTy = Ref->getPointeeType();
 
     CharUnits Sizeof;
-    if (!HandleSizeof(Info, SrcTy, Sizeof))
+    if (!HandleSizeof(Info, E->getExprLoc(), SrcTy, Sizeof))
       return false;
     return Success(Sizeof, E);
   }
@@ -4964,6 +5176,7 @@
   case CK_NullToMemberPointer:
   case CK_BaseToDerivedMemberPointer:
   case CK_DerivedToBaseMemberPointer:
+  case CK_ReinterpretMemberPointer:
   case CK_ConstructorConversion:
   case CK_IntegralToPointer:
   case CK_ToVoid:
@@ -5440,6 +5653,7 @@
   case CK_BaseToDerivedMemberPointer:
   case CK_DerivedToBaseMemberPointer:
   case CK_MemberPointerToBoolean:
+  case CK_ReinterpretMemberPointer:
   case CK_ConstructorConversion:
   case CK_IntegralToPointer:
   case CK_PointerToIntegral:
@@ -5795,13 +6009,13 @@
     return true;
   } else if (E->getType()->isArrayType()) {
     LValue LV;
-    LV.set(E, Info.CurrentCall);
+    LV.set(E, Info.CurrentCall->Index);
     if (!EvaluateArray(E, LV, Info.CurrentCall->Temporaries[E], Info))
       return false;
     Result = Info.CurrentCall->Temporaries[E];
   } else if (E->getType()->isRecordType()) {
     LValue LV;
-    LV.set(E, Info.CurrentCall);
+    LV.set(E, Info.CurrentCall->Index);
     if (!EvaluateRecord(E, LV, Info.CurrentCall->Temporaries[E], Info))
       return false;
     Result = Info.CurrentCall->Temporaries[E];
@@ -5824,14 +6038,12 @@
   return true;
 }
 
-/// EvaluateConstantExpression - Evaluate an expression as a constant expression
-/// in-place in an APValue. In some cases, the in-place evaluation is essential,
-/// since later initializers for an object can indirectly refer to subobjects
-/// which were initialized earlier.
-static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
-                                       const LValue &This, const Expr *E,
-                                       CheckConstantExpressionKind CCEK,
-                                       bool AllowNonLiteralTypes) {
+/// EvaluateInPlace - Evaluate an expression in-place in an APValue. In some
+/// cases, the in-place evaluation is essential, since later initializers for
+/// an object can indirectly refer to subobjects which were initialized earlier.
+static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
+                            const Expr *E, CheckConstantExpressionKind CCEK,
+                            bool AllowNonLiteralTypes) {
   if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E))
     return false;
 
@@ -5846,8 +6058,10 @@
 
   // For any other type, in-place evaluation is unimportant.
   CCValue CoreConstResult;
-  return Evaluate(CoreConstResult, Info, E) &&
-         CheckConstantExpression(Info, E, CoreConstResult, Result, CCEK);
+  if (!Evaluate(CoreConstResult, Info, E))
+    return false;
+  Result = CoreConstResult.toAPValue();
+  return true;
 }
 
 /// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
@@ -5869,7 +6083,8 @@
 
   // Check this core constant expression is a constant expression, and if so,
   // convert it to one.
-  return CheckConstantExpression(Info, E, Value, Result);
+  Result = Value.toAPValue();
+  return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result);
 }
 
 /// EvaluateAsRValue - Return true if this is a constant which we can fold using
@@ -5923,9 +6138,15 @@
   EvalInfo Info(Ctx, Result);
 
   LValue LV;
-  return EvaluateLValue(this, LV, Info) && !Result.HasSideEffects &&
-         CheckLValueConstantExpression(Info, this, LV, Result.Val,
-                                       CCEK_Constant);
+  if (!EvaluateLValue(this, LV, Info) || Result.HasSideEffects ||
+      !CheckLValueConstantExpression(Info, getExprLoc(),
+                                     Ctx.getLValueReferenceType(getType()), LV))
+    return false;
+
+  CCValue Tmp;
+  LV.moveInto(Tmp);
+  Result.Val = Tmp.toAPValue();
+  return true;
 }
 
 bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
@@ -5953,14 +6174,18 @@
   if (Ctx.getLangOptions().CPlusPlus && !VD->hasLocalStorage() &&
       !VD->getType()->isReferenceType()) {
     ImplicitValueInitExpr VIE(VD->getType());
-    if (!EvaluateConstantExpression(Value, InitInfo, LVal, &VIE, CCEK_Constant,
-                                    /*AllowNonLiteralTypes=*/true))
+    if (!EvaluateInPlace(Value, InitInfo, LVal, &VIE, CCEK_Constant,
+                         /*AllowNonLiteralTypes=*/true))
       return false;
   }
 
-  return EvaluateConstantExpression(Value, InitInfo, LVal, this, CCEK_Constant,
-                                    /*AllowNonLiteralTypes=*/true) &&
-         !EStatus.HasSideEffects;
+  if (!EvaluateInPlace(Value, InitInfo, LVal, this, CCEK_Constant,
+                         /*AllowNonLiteralTypes=*/true) ||
+      EStatus.HasSideEffects)
+    return false;
+
+  return CheckConstantExpression(InitInfo, VD->getLocation(), VD->getType(),
+                                 Value);
 }
 
 /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
@@ -6435,12 +6660,17 @@
   return true;
 }
 
+bool Expr::isCXX98IntegralConstantExpr(ASTContext &Ctx) const {
+  return CheckICE(this, Ctx).Val == 0;
+}
+
 bool Expr::isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result,
                                SourceLocation *Loc) const {
   // We support this checking in C++98 mode in order to diagnose compatibility
   // issues.
   assert(Ctx.getLangOptions().CPlusPlus);
 
+  // Build evaluation settings.
   Expr::EvalStatus Status;
   llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
   Status.Diag = &Diags;
@@ -6482,18 +6712,20 @@
   // is a temporary being used as the 'this' pointer.
   LValue This;
   ImplicitValueInitExpr VIE(RD ? Info.Ctx.getRecordType(RD) : Info.Ctx.IntTy);
-  This.set(&VIE, Info.CurrentCall);
+  This.set(&VIE, Info.CurrentCall->Index);
 
-  APValue Scratch;
   ArrayRef<const Expr*> Args;
 
   SourceLocation Loc = FD->getLocation();
 
   if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
+    APValue Scratch;
     HandleConstructorCall(Loc, This, Args, CD, Info, Scratch);
-  } else
+  } else {
+    CCValue Scratch;
     HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : 0,
                        Args, FD->getBody(), Info, Scratch);
+  }
 
   return Diags.empty();
 }

Modified: cfe/branches/tooling/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ItaniumMangle.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/branches/tooling/lib/AST/ItaniumMangle.cpp Mon Feb 20 19:34:24 2012
@@ -2351,10 +2351,20 @@
     Out << '_';
     mangleType(New->getAllocatedType());
     if (New->hasInitializer()) {
+      // FIXME: Does this mean "parenthesized initializer"?
       Out << "pi";
-      for (CXXNewExpr::const_arg_iterator I = New->constructor_arg_begin(),
-             E = New->constructor_arg_end(); I != E; ++I)
-        mangleExpression(*I);
+      const Expr *Init = New->getInitializer();
+      if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
+        // Directly inline the initializers.
+        for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
+                                                  E = CCE->arg_end();
+             I != E; ++I)
+          mangleExpression(*I);
+      } else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
+        for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
+          mangleExpression(PLE->getExpr(i));
+      } else
+        mangleExpression(Init);
     }
     Out << 'E';
     break;

Modified: cfe/branches/tooling/lib/AST/ParentMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ParentMap.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ParentMap.cpp (original)
+++ cfe/branches/tooling/lib/AST/ParentMap.cpp Mon Feb 20 19:34:24 2012
@@ -26,6 +26,10 @@
       M[*I] = S;
       BuildParentMap(M, *I);
     }
+  
+  // Also include the source expr tree of an OpaqueValueExpr in the map.
+  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
+    BuildParentMap(M, OVE->getSourceExpr());
 }
 
 ParentMap::ParentMap(Stmt* S) : Impl(0) {

Modified: cfe/branches/tooling/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtPrinter.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtPrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtPrinter.cpp Mon Feb 20 19:34:24 2012
@@ -1390,17 +1390,13 @@
   if (E->isParenTypeId())
     OS << ")";
 
-  if (E->hasInitializer()) {
-    OS << "(";
-    unsigned NumCons = E->getNumConstructorArgs();
-    if (NumCons > 0) {
-      PrintExpr(E->getConstructorArg(0));
-      for (unsigned i = 1; i < NumCons; ++i) {
-        OS << ", ";
-        PrintExpr(E->getConstructorArg(i));
-      }
-    }
-    OS << ")";
+  CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
+  if (InitStyle) {
+    if (InitStyle == CXXNewExpr::CallInit)
+      OS << "(";
+    PrintExpr(E->getInitializer());
+    if (InitStyle == CXXNewExpr::CallInit)
+      OS << ")";
   }
 }
 

Modified: cfe/branches/tooling/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtProfile.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtProfile.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtProfile.cpp Mon Feb 20 19:34:24 2012
@@ -825,13 +825,11 @@
   VisitType(S->getAllocatedType());
   VisitDecl(S->getOperatorNew());
   VisitDecl(S->getOperatorDelete());
-  VisitDecl(S->getConstructor());
   ID.AddBoolean(S->isArray());
   ID.AddInteger(S->getNumPlacementArgs());
   ID.AddBoolean(S->isGlobalNew());
   ID.AddBoolean(S->isParenTypeId());
-  ID.AddBoolean(S->hasInitializer());
-  ID.AddInteger(S->getNumConstructorArgs());
+  ID.AddInteger(S->getInitializationStyle());
 }
 
 void

Modified: cfe/branches/tooling/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Type.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Type.cpp (original)
+++ cfe/branches/tooling/lib/AST/Type.cpp Mon Feb 20 19:34:24 2012
@@ -2137,11 +2137,6 @@
   }
 
   llvm_unreachable("unhandled type class");
-
-  // C++ [basic.link]p8:
-  //   Names not covered by these rules have no linkage.
-  NamedDecl::LinkageInfo LV(NoLinkage, DefaultVisibility, false);
-  return CachedProperties(LV, false);
 }
 
 /// \brief Determine the linkage of this type.

Modified: cfe/branches/tooling/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/TypePrinter.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/TypePrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/TypePrinter.cpp Mon Feb 20 19:34:24 2012
@@ -672,8 +672,14 @@
     // Make an unambiguous representation for anonymous types, e.g.
     //   <anonymous enum at /usr/include/string.h:120:9>
     llvm::raw_string_ostream OS(Buffer);
-    OS << "<anonymous";
-
+    
+    if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
+      OS << "<lambda";
+      HasKindDecoration = true;
+    } else {
+      OS << "<anonymous";
+    }
+    
     if (Policy.AnonymousTagLocations) {
       // Suppress the redundant tag keyword if we just printed one.
       // We don't have to worry about ElaboratedTypes here because you can't

Modified: cfe/branches/tooling/lib/Analysis/FormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/FormatString.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/FormatString.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/FormatString.cpp Mon Feb 20 19:34:24 2012
@@ -198,7 +198,7 @@
     case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
     case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
     case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
-    case 'q': lmKind = LengthModifier::AsLongLong;   ++I; break;
+    case 'q': lmKind = LengthModifier::AsQuad;       ++I; break;
     case 'a':
       if (IsScanf && !LO.C99 && !LO.CPlusPlus0x) {
         // For scanf in C90, look at the next character to see if this should
@@ -417,6 +417,8 @@
     return "l";
   case AsLongLong:
     return "ll";
+  case AsQuad:
+    return "q";
   case AsIntMax:
     return "j";
   case AsSizeT:
@@ -506,10 +508,11 @@
     case LengthModifier::None:
       return true;
       
-        // Handle most integer flags
+    // Handle most integer flags
     case LengthModifier::AsChar:
     case LengthModifier::AsShort:
     case LengthModifier::AsLongLong:
+    case LengthModifier::AsQuad:
     case LengthModifier::AsIntMax:
     case LengthModifier::AsSizeT:
     case LengthModifier::AsPtrDiff:
@@ -526,7 +529,7 @@
           return false;
       }
       
-        // Handle 'l' flag
+    // Handle 'l' flag
     case LengthModifier::AsLong:
       switch (CS.getKind()) {
         case ConversionSpecifier::dArg:

Modified: cfe/branches/tooling/lib/Analysis/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/PrintfFormatString.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/PrintfFormatString.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/PrintfFormatString.cpp Mon Feb 20 19:34:24 2012
@@ -266,7 +266,9 @@
       case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy;
       case LengthModifier::AsShort: return Ctx.ShortTy;
       case LengthModifier::AsLong: return Ctx.LongTy;
-      case LengthModifier::AsLongLong: return Ctx.LongLongTy;
+      case LengthModifier::AsLongLong:
+      case LengthModifier::AsQuad:
+        return Ctx.LongLongTy;
       case LengthModifier::AsIntMax:
         return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
       case LengthModifier::AsSizeT:
@@ -288,7 +290,9 @@
       case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
-      case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
+      case LengthModifier::AsLongLong:
+      case LengthModifier::AsQuad:
+        return Ctx.UnsignedLongLongTy;
       case LengthModifier::AsIntMax:
         return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
       case LengthModifier::AsSizeT:
@@ -336,7 +340,8 @@
   return ArgTypeResult();
 }
 
-bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) {
+bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
+                              ASTContext &Ctx, bool IsObjCLiteral) {
   // Handle strings first (char *, wchar_t *)
   if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
     CS.setKind(ConversionSpecifier::sArg);
@@ -432,6 +437,11 @@
     }
   }
 
+  // If fixing the length modifier was enough, we are done.
+  const analyze_printf::ArgTypeResult &ATR = getArgType(Ctx, IsObjCLiteral);
+  if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT))
+    return true;
+
   // Set conversion specifier and disable any flags which do not apply to it.
   // Let typedefs to char fall through to int, as %c is silly for uint8_t.
   if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {
@@ -451,9 +461,7 @@
     HasAlternativeForm = 0;
   }
   else if (QT->isUnsignedIntegerType()) {
-    // Preserve the original formatting, e.g. 'X', 'o'.
-    if (!cast<PrintfConversionSpecifier>(CS).isUIntArg())
-      CS.setKind(ConversionSpecifier::uArg);
+    CS.setKind(ConversionSpecifier::uArg);
     HasAlternativeForm = 0;
     HasPlusPrefix = 0;
   } else {

Modified: cfe/branches/tooling/lib/Analysis/ScanfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/ScanfFormatString.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/ScanfFormatString.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/ScanfFormatString.cpp Mon Feb 20 19:34:24 2012
@@ -210,7 +210,9 @@
           return ArgTypeResult(ArgTypeResult::AnyCharTy);
         case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy);
         case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy);
-        case LengthModifier::AsLongLong: return ArgTypeResult(Ctx.LongLongTy);
+        case LengthModifier::AsLongLong:
+        case LengthModifier::AsQuad:
+          return ArgTypeResult(Ctx.LongLongTy);
         case LengthModifier::AsIntMax:
           return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *");
         case LengthModifier::AsSizeT:
@@ -236,6 +238,7 @@
         case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy);
         case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy);
         case LengthModifier::AsLongLong:
+        case LengthModifier::AsQuad:
           return ArgTypeResult(Ctx.UnsignedLongLongTy);
         case LengthModifier::AsIntMax:
           return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *");
@@ -307,8 +310,8 @@
   return ScanfArgTypeResult();
 }
 
-bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt)
-{
+bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
+                             ASTContext &Ctx) {
   if (!QT->isPointerType())
     return false;
 
@@ -390,17 +393,19 @@
     }
   }
 
+  // If fixing the length modifier was enough, we are done.
+  const analyze_scanf::ScanfArgTypeResult &ATR = getArgType(Ctx);
+  if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT))
+    return true;
+
   // Figure out the conversion specifier.
   if (PT->isRealFloatingType())
     CS.setKind(ConversionSpecifier::fArg);
   else if (PT->isSignedIntegerType())
     CS.setKind(ConversionSpecifier::dArg);
-  else if (PT->isUnsignedIntegerType()) {
-    // Preserve the original formatting, e.g. 'X', 'o'.
-    if (!CS.isUIntArg()) {
-      CS.setKind(ConversionSpecifier::uArg);
-    }
-  } else
+  else if (PT->isUnsignedIntegerType())
+    CS.setKind(ConversionSpecifier::uArg);
+  else
     llvm_unreachable("Unexpected type");
 
   return true;

Modified: cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp Mon Feb 20 19:34:24 2012
@@ -62,11 +62,11 @@
 ///
 /// Clang introduces an additional wrinkle, which is that it is difficult to
 /// derive canonical expressions, or compare expressions directly for equality.
-/// Thus, we identify a mutex not by an Expr, but by the set of named
+/// Thus, we identify a mutex not by an Expr, but by the list of named
 /// declarations that are referenced by the Expr.  In other words,
 /// x->foo->bar.mu will be a four element vector with the Decls for
 /// mu, bar, and foo, and x.  The vector will uniquely identify the expression
-/// for all practical purposes.
+/// for all practical purposes.  Null is used to denote 'this'.
 ///
 /// Note we will need to perform substitution on "this" and function parameter
 /// names when constructing a lock expression.
@@ -122,8 +122,10 @@
     } else if (isa<CXXThisExpr>(Exp)) {
       if (Parent)
         buildMutexID(Parent, D, 0, 0, 0);
-      else
+      else {
+        DeclSeq.push_back(0);  // Use 0 to represent 'this'.
         return;  // mutexID is still valid in this case
+      }
     } else if (UnaryOperator *UOE = dyn_cast<UnaryOperator>(Exp))
       buildMutexID(UOE->getSubExpr(), D, Parent, NumArgs, FunArgs);
     else if (CastExpr *CE = dyn_cast<CastExpr>(Exp))
@@ -233,6 +235,8 @@
   /// We do not want to output the entire expression text for security reasons.
   StringRef getName() const {
     assert(isValid());
+    if (!DeclSeq.front())
+      return "this";  // Use 0 to represent 'this'.
     return DeclSeq.front()->getName();
   }
 
@@ -1428,6 +1432,14 @@
     return;  // Ignore anonymous functions for now.
   if (D->getAttr<NoThreadSafetyAnalysisAttr>())
     return;
+  // FIXME: Do something a bit more intelligent inside constructor and
+  // destructor code.  Constructors and destructors must assume unique access
+  // to 'this', so checks on member variable access is disabled, but we should
+  // still enable checks on other objects.
+  if (isa<CXXConstructorDecl>(D))
+    return;  // Don't check inside constructors.
+  if (isa<CXXDestructorDecl>(D))
+    return;  // Don't check inside destructors.
 
   std::vector<CFGBlockInfo> BlockInfo(CFGraph->getNumBlockIDs(),
     CFGBlockInfo::getEmptyBlockInfo(LocksetFactory, LocalVarMap));
@@ -1445,30 +1457,40 @@
   findBlockLocations(CFGraph, SortedGraph, BlockInfo);
 
   // Add locks from exclusive_locks_required and shared_locks_required
-  // to initial lockset.
+  // to initial lockset. Also turn off checking for lock and unlock functions.
+  // FIXME: is there a more intelligent way to check lock/unlock functions?
   if (!SortedGraph->empty() && D->hasAttrs()) {
     const CFGBlock *FirstBlock = *SortedGraph->begin();
     Lockset &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
     const AttrVec &ArgAttrs = D->getAttrs();
-    for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
+    for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
       Attr *Attr = ArgAttrs[i];
       SourceLocation AttrLoc = Attr->getLocation();
       if (SharedLocksRequiredAttr *SLRAttr
             = dyn_cast<SharedLocksRequiredAttr>(Attr)) {
         for (SharedLocksRequiredAttr::args_iterator
-            SLRIter = SLRAttr->args_begin(),
-            SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
+             SLRIter = SLRAttr->args_begin(),
+             SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
           InitialLockset = addLock(InitialLockset,
                                    *SLRIter, D, LK_Shared,
                                    AttrLoc);
       } else if (ExclusiveLocksRequiredAttr *ELRAttr
                    = dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
         for (ExclusiveLocksRequiredAttr::args_iterator
-            ELRIter = ELRAttr->args_begin(),
-            ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
+             ELRIter = ELRAttr->args_begin(),
+             ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
           InitialLockset = addLock(InitialLockset,
                                    *ELRIter, D, LK_Exclusive,
                                    AttrLoc);
+      } else if (isa<UnlockFunctionAttr>(Attr)) {
+        // Don't try to check unlock functions for now
+        return;
+      } else if (isa<ExclusiveLockFunctionAttr>(Attr)) {
+        // Don't try to check lock functions for now
+        return;
+      } else if (isa<SharedLockFunctionAttr>(Attr)) {
+        // Don't try to check lock functions for now
+        return;
       }
     }
   }

Modified: cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp (original)
+++ cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp Mon Feb 20 19:34:24 2012
@@ -11,17 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/ASTDiagnostic.h"
-#include "clang/Analysis/AnalysisDiagnostic.h"
 #include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/AllDiagnostics.h"
 #include "clang/Basic/DiagnosticCategories.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include "clang/Serialization/SerializationDiagnostic.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -52,21 +45,13 @@
   unsigned WarnShowInSystemHeader : 1;
   unsigned Category : 5;
 
-  uint8_t  NameLen;
-  uint8_t  OptionGroupLen;
+  uint16_t OptionGroupIndex;
 
   uint16_t DescriptionLen;
-
-  const char *NameStr;
-  const char *OptionGroupStr;
-
   const char *DescriptionStr;
 
-  StringRef getName() const {
-    return StringRef(NameStr, NameLen);
-  }
-  StringRef getOptionGroup() const {
-    return StringRef(OptionGroupStr, OptionGroupLen);
+  unsigned getOptionGroupIndex() const {
+    return OptionGroupIndex;
   }
 
   StringRef getDescription() const {
@@ -78,44 +63,15 @@
   }
 };
 
-struct StaticDiagNameIndexRec {
-  const char *NameStr;
-  unsigned short DiagID;
-  uint8_t NameLen;
-
-  StringRef getName() const {
-    return StringRef(NameStr, NameLen);
-  }
-
-  bool operator<(const StaticDiagNameIndexRec &RHS) const {
-    return getName() < RHS.getName();
-  }
-  
-  bool operator==(const StaticDiagNameIndexRec &RHS) const {
-    return getName() == RHS.getName();
-  }
-};
-
-template <size_t SizeOfStr, typename FieldType>
-class StringSizerHelper {
-  char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
-public:
-  enum { Size = SizeOfStr };
-};
-
 } // namespace anonymous
 
-#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str)-1, fieldTy>::Size 
-
 static const StaticDiagInfoRec StaticDiagInfo[] = {
 #define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,               \
              SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,              \
              CATEGORY)                                            \
   { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS,           \
-    NOWERROR, SHOWINSYSHEADER, CATEGORY,                          \
-    STR_SIZE(#ENUM, uint8_t), STR_SIZE(GROUP, uint8_t),           \
-    STR_SIZE(DESC, uint16_t),                                     \
-    #ENUM, GROUP, DESC },
+    NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP,                   \
+    STR_SIZE(DESC, uint16_t), DESC },
 #include "clang/Basic/DiagnosticCommonKinds.inc"
 #include "clang/Basic/DiagnosticDriverKinds.inc"
 #include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -126,23 +82,12 @@
 #include "clang/Basic/DiagnosticSemaKinds.inc"
 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
 #undef DIAG
-  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 };
 
 static const unsigned StaticDiagInfoSize =
   sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
 
-/// To be sorted before first use (since it's splitted among multiple files)
-static const StaticDiagNameIndexRec StaticDiagNameIndex[] = {
-#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
-#include "clang/Basic/DiagnosticIndexName.inc"
-#undef DIAG_NAME_INDEX
-  { 0, 0, 0 }
-};
-
-static const unsigned StaticDiagNameIndexSize =
-  sizeof(StaticDiagNameIndex)/sizeof(StaticDiagNameIndex[0])-1;
-
 /// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
 /// or null if the ID is invalid.
 static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
@@ -164,7 +109,7 @@
 
   // Search the diagnostic table with a binary search.
   StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID),
-                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
   const StaticDiagInfoRec *Found =
     std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
@@ -198,15 +143,6 @@
   return Info;
 }
 
-/// getWarningOptionForDiag - Return the lowest-level warning option that
-/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
-/// the diagnostic, this returns null.
-StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->getOptionGroup();
-  return StringRef();
-}
-
 /// getCategoryNumberForDiag - Return the category number that a specified
 /// DiagID belongs to, or 0 if no category.
 unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
@@ -286,34 +222,6 @@
   return SFINAE_Report;
 }
 
-/// getName - Given a diagnostic ID, return its name
-StringRef DiagnosticIDs::getName(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->getName();
-  return StringRef();
-}
-
-/// getIdFromName - Given a diagnostic name, return its ID, or 0
-unsigned DiagnosticIDs::getIdFromName(StringRef Name) {
-  const StaticDiagNameIndexRec *StaticDiagNameIndexEnd =
-    StaticDiagNameIndex + StaticDiagNameIndexSize;
-  
-  if (Name.empty()) { return diag::DIAG_UPPER_LIMIT; }
-  
-  assert(Name.size() == static_cast<uint8_t>(Name.size()) &&
-         "Name is too long");
-  StaticDiagNameIndexRec Find = { Name.data(), 0,
-                                  static_cast<uint8_t>(Name.size()) };
-  
-  const StaticDiagNameIndexRec *Found =
-    std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find);
-  if (Found == StaticDiagNameIndexEnd ||
-      Found->getName() != Name)
-    return diag::DIAG_UPPER_LIMIT;
-  
-  return Found->DiagID;
-}
-
 /// getBuiltinDiagClass - Return the class field of the diagnostic.
 ///
 static unsigned getBuiltinDiagClass(unsigned DiagID) {
@@ -323,35 +231,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// diag_iterator
-//===----------------------------------------------------------------------===//
-
-llvm::StringRef DiagnosticIDs::diag_iterator::getDiagName() const {
-  return static_cast<const StaticDiagNameIndexRec*>(impl)->getName();
-}
-
-unsigned DiagnosticIDs::diag_iterator::getDiagID() const {
-  return static_cast<const StaticDiagNameIndexRec*>(impl)->DiagID;
-}
-
-DiagnosticIDs::diag_iterator &DiagnosticIDs::diag_iterator::operator++() {
-  const StaticDiagNameIndexRec* ptr =
-    static_cast<const StaticDiagNameIndexRec*>(impl);;
-  ++ptr;
-  impl = ptr;
-  return *this;
-}
-
-DiagnosticIDs::diag_iterator DiagnosticIDs::diags_begin() {
-  return DiagnosticIDs::diag_iterator(StaticDiagNameIndex);
-}
-
-DiagnosticIDs::diag_iterator DiagnosticIDs::diags_end() {
-  return DiagnosticIDs::diag_iterator(StaticDiagNameIndex +
-                                      StaticDiagNameIndexSize);
-}
-
-//===----------------------------------------------------------------------===//
 // Custom Diagnostic information
 //===----------------------------------------------------------------------===//
 
@@ -622,6 +501,15 @@
   return LHS.getName() < RHS.getName();
 }
 
+/// getWarningOptionForDiag - Return the lowest-level warning option that
+/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
+/// the diagnostic, this returns null.
+StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+    return OptionTable[Info->getOptionGroupIndex()].getName();
+  return StringRef();
+}
+
 void DiagnosticIDs::getDiagnosticsInGroup(
   const WarningOption *Group,
   llvm::SmallVectorImpl<diag::kind> &Diags) const

Modified: cfe/branches/tooling/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Targets.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Targets.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Targets.cpp Mon Feb 20 19:34:24 2012
@@ -490,6 +490,10 @@
     Builder.defineMacro("__ELF__");
     Builder.defineMacro("__svr4__");
     Builder.defineMacro("__SVR4");
+    Builder.defineMacro("_XOPEN_SOURCE", "500");
+    Builder.defineMacro("_LARGEFILE_SOURCE");
+    Builder.defineMacro("_LARGEFILE64_SOURCE");
+    Builder.defineMacro("__EXTENSIONS__");
   }
 public:
   SolarisTargetInfo(const std::string& triple)

Modified: cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp Mon Feb 20 19:34:24 2012
@@ -855,11 +855,11 @@
   llvm::Value *Func = Builder.CreateLoad(FuncPtr);
 
   const FunctionType *FuncTy = FnType->castAs<FunctionType>();
-  const CGFunctionInfo &FnInfo = CGM.getTypes().getFunctionInfo(Args, FuncTy);
+  const CGFunctionInfo &FnInfo =
+    CGM.getTypes().arrangeFunctionCall(Args, FuncTy);
 
   // Cast the function pointer to the right type.
-  llvm::Type *BlockFTy =
-    CGM.getTypes().GetFunctionType(FnInfo, false);
+  llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo);
 
   llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
   Func = Builder.CreateBitCast(Func, BlockFTyPtr);
@@ -1013,16 +1013,15 @@
     args.push_back(*i);
 
   // Create the function declaration.
-  const FunctionProtoType *fnType =
-    cast<FunctionProtoType>(blockInfo.getBlockExpr()->getFunctionType());
+  const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType();
   const CGFunctionInfo &fnInfo =
-    CGM.getTypes().getFunctionInfo(fnType->getResultType(), args,
-                                   fnType->getExtInfo());
+    CGM.getTypes().arrangeFunctionDeclaration(fnType->getResultType(), args,
+                                              fnType->getExtInfo(),
+                                              fnType->isVariadic());
   if (CGM.ReturnTypeUsesSRet(fnInfo))
     blockInfo.UsesStret = true;
 
-  llvm::FunctionType *fnLLVMType =
-    CGM.getTypes().GetFunctionType(fnInfo, fnType->isVariadic());
+  llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
 
   MangleBuffer name;
   CGM.getBlockMangledName(GD, name, blockDecl);
@@ -1164,11 +1163,13 @@
   args.push_back(&srcDecl);
 
   const CGFunctionInfo &FI =
-      CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo());
+    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
+                                              FunctionType::ExtInfo(),
+                                              /*variadic*/ false);
 
   // FIXME: it would be nice if these were mergeable with things with
   // identical semantics.
-  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
 
   llvm::Function *Fn =
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
@@ -1279,11 +1280,13 @@
   args.push_back(&srcDecl);
 
   const CGFunctionInfo &FI =
-      CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo());
+    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
+                                              FunctionType::ExtInfo(),
+                                              /*variadic*/ false);
 
   // FIXME: We'd like to put these into a mergable by content, with
   // internal linkage.
-  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
 
   llvm::Function *Fn =
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
@@ -1557,10 +1560,12 @@
   args.push_back(&src);
 
   const CGFunctionInfo &FI =
-    CGF.CGM.getTypes().getFunctionInfo(R, args, FunctionType::ExtInfo());
+    CGF.CGM.getTypes().arrangeFunctionDeclaration(R, args,
+                                                  FunctionType::ExtInfo(),
+                                                  /*variadic*/ false);
 
   CodeGenTypes &Types = CGF.CGM.getTypes();
-  llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+  llvm::FunctionType *LTy = Types.GetFunctionType(FI);
 
   // FIXME: We'd like to put these into a mergable by content, with
   // internal linkage.
@@ -1625,10 +1630,12 @@
   args.push_back(&src);
 
   const CGFunctionInfo &FI =
-    CGF.CGM.getTypes().getFunctionInfo(R, args, FunctionType::ExtInfo());
+    CGF.CGM.getTypes().arrangeFunctionDeclaration(R, args,
+                                                  FunctionType::ExtInfo(),
+                                                  /*variadic*/ false);
 
   CodeGenTypes &Types = CGF.CGM.getTypes();
-  llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+  llvm::FunctionType *LTy = Types.GetFunctionType(FI);
 
   // FIXME: We'd like to put these into a mergable by content, with
   // internal linkage.

Modified: cfe/branches/tooling/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCXX.cpp Mon Feb 20 19:34:24 2012
@@ -196,7 +196,8 @@
                                 GlobalDecl(ctor, Ctor_Base)))
     return;
 
-  const CGFunctionInfo &fnInfo = getTypes().getFunctionInfo(ctor, ctorType);
+  const CGFunctionInfo &fnInfo =
+    getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType);
 
   llvm::Function *fn =
     cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo));
@@ -218,11 +219,10 @@
   if (llvm::GlobalValue *existing = GetGlobalValue(name))
     return existing;
 
-  if (!fnInfo) fnInfo = &getTypes().getFunctionInfo(ctor, ctorType);
+  if (!fnInfo)
+    fnInfo = &getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType);
 
-  const FunctionProtoType *proto = ctor->getType()->castAs<FunctionProtoType>();
-  llvm::FunctionType *fnType =
-    getTypes().GetFunctionType(*fnInfo, proto->isVariadic());
+  llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo);
   return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
                                                       /*ForVTable=*/false));
 }
@@ -260,7 +260,8 @@
   if (dtorType == Dtor_Base && !TryEmitBaseDestructorAsAlias(dtor))
     return;
 
-  const CGFunctionInfo &fnInfo = getTypes().getFunctionInfo(dtor, dtorType);
+  const CGFunctionInfo &fnInfo =
+    getTypes().arrangeCXXDestructor(dtor, dtorType);
 
   llvm::Function *fn =
     cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo));
@@ -282,11 +283,9 @@
   if (llvm::GlobalValue *existing = GetGlobalValue(name))
     return existing;
 
-  if (!fnInfo) fnInfo = &getTypes().getFunctionInfo(dtor, dtorType);
-
-  llvm::FunctionType *fnType =
-    getTypes().GetFunctionType(*fnInfo, false);
+  if (!fnInfo) fnInfo = &getTypes().arrangeCXXDestructor(dtor, dtorType);
 
+  llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo);
   return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
                                                       /*ForVTable=*/false));
 }
@@ -359,12 +358,10 @@
   // -O does that. But need to support -O0 as well.
   if (MD->isVirtual() && Type != Dtor_Base) {
     // Compute the function type we're calling.
-    const CGFunctionInfo *FInfo = 
-    &CGM.getTypes().getFunctionInfo(cast<CXXDestructorDecl>(MD),
-                                    Dtor_Complete);
-    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
-    llvm::Type *Ty
-      = CGM.getTypes().GetFunctionType(*FInfo, FPT->isVariadic());
+    const CGFunctionInfo &FInfo = 
+      CGM.getTypes().arrangeCXXDestructor(cast<CXXDestructorDecl>(MD),
+                                          Dtor_Complete);
+    llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo);
 
     llvm::Value *VTable = CGM.getVTables().GetAddrOfVTable(RD);
     Ty = Ty->getPointerTo()->getPointerTo();

Modified: cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp Mon Feb 20 19:34:24 2012
@@ -49,9 +49,8 @@
     MPT->getPointeeType()->getAs<FunctionProtoType>();
   const CXXRecordDecl *RD = 
     cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
-  llvm::FunctionType *FTy = 
-    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
-                                   FPT->isVariadic());
+  llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
+                              CGM.getTypes().arrangeCXXMethodType(RD, FPT));
   return llvm::Constant::getNullValue(FTy->getPointerTo());
 }
 
@@ -71,6 +70,11 @@
   return GetBogusMemberPointer(CGM, E->getType());
 }
 
+llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
+                                                      llvm::Constant *Src) {
+  return GetBogusMemberPointer(CGM, E->getType());
+}
+
 llvm::Value *
 CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
                                       llvm::Value *L,
@@ -172,3 +176,24 @@
                                bool PerformInit) {
   ErrorUnsupportedABI(CGF, "static local variable initialization");
 }
+
+/// Returns the adjustment, in bytes, required for the given
+/// member-pointer operation.  Returns null if no adjustment is
+/// required.
+llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
+  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
+         E->getCastKind() == CK_BaseToDerivedMemberPointer);
+
+  QualType derivedType;
+  if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
+    derivedType = E->getSubExpr()->getType();
+  else
+    derivedType = E->getType();
+
+  const CXXRecordDecl *derivedClass =
+    derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
+
+  return CGM.GetNonVirtualBaseClassOffset(derivedClass,
+                                          E->path_begin(),
+                                          E->path_end());
+}

Modified: cfe/branches/tooling/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCXXABI.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCXXABI.h Mon Feb 20 19:34:24 2012
@@ -100,12 +100,17 @@
                                                     llvm::Value *MemPtr,
                                             const MemberPointerType *MPT);
 
-  /// Perform a derived-to-base or base-to-derived member pointer
-  /// conversion.
+  /// Perform a derived-to-base, base-to-derived, or bitcast member
+  /// pointer conversion.
   virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
                                                    const CastExpr *E,
                                                    llvm::Value *Src);
 
+  /// Perform a derived-to-base, base-to-derived, or bitcast member
+  /// pointer conversion on a constant value.
+  virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
+                                                      llvm::Constant *Src);
+
   /// Return true if the given member pointer can be zero-initialized
   /// (in the C++ sense) with an LLVM zeroinitializer.
   virtual bool isZeroInitializable(const MemberPointerType *MPT);
@@ -137,6 +142,15 @@
                              llvm::Value *MemPtr,
                              const MemberPointerType *MPT);
 
+protected:
+  /// A utility method for computing the offset required for the given
+  /// base-to-derived or derived-to-base member-pointer conversion.
+  /// Does not handle virtual conversions (in case we ever fully
+  /// support an ABI that allows this).  Returns null if no adjustment
+  /// is required.
+  llvm::Constant *getMemberPointerAdjustment(const CastExpr *E);
+
+public:
   /// Build the signature of the given constructor variant by adding
   /// any required parameters.  For convenience, ResTy has been
   /// initialized to 'void', and ArgTys has been initialized with the

Modified: cfe/branches/tooling/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCall.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCall.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCall.cpp Mon Feb 20 19:34:24 2012
@@ -17,6 +17,7 @@
 #include "ABIInfo.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "TargetInfo.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
@@ -66,29 +67,39 @@
   return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType();
 }
 
+/// Arrange the argument and result information for a value of the
+/// given unprototyped function type.
 const CGFunctionInfo &
-CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP) {
-  return getFunctionInfo(FTNP->getResultType().getUnqualifiedType(),
-                         SmallVector<CanQualType, 16>(),
-                         FTNP->getExtInfo());
+CodeGenTypes::arrangeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
+  // When translating an unprototyped function type, always use a
+  // variadic type.
+  return arrangeFunctionType(FTNP->getResultType().getUnqualifiedType(),
+                             ArrayRef<CanQualType>(),
+                             FTNP->getExtInfo(),
+                             RequiredArgs(0));
 }
 
-/// \param Args - contains any initial parameters besides those
-///   in the formal type
-static const CGFunctionInfo &getFunctionInfo(CodeGenTypes &CGT,
-                                  SmallVectorImpl<CanQualType> &ArgTys,
+/// Arrange the argument and result information for a value of the
+/// given function type, on top of any implicit parameters already
+/// stored.
+static const CGFunctionInfo &arrangeFunctionType(CodeGenTypes &CGT,
+                                  SmallVectorImpl<CanQualType> &argTypes,
                                              CanQual<FunctionProtoType> FTP) {
+  RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size());
   // FIXME: Kill copy.
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FTP->getArgType(i));
-  CanQualType ResTy = FTP->getResultType().getUnqualifiedType();
-  return CGT.getFunctionInfo(ResTy, ArgTys, FTP->getExtInfo());
+    argTypes.push_back(FTP->getArgType(i));
+  CanQualType resultType = FTP->getResultType().getUnqualifiedType();
+  return CGT.arrangeFunctionType(resultType, argTypes,
+                                 FTP->getExtInfo(), required);
 }
 
+/// Arrange the argument and result information for a value of the
+/// given function type.
 const CGFunctionInfo &
-CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP) {
-  SmallVector<CanQualType, 16> ArgTys;
-  return ::getFunctionInfo(*this, ArgTys, FTP);
+CodeGenTypes::arrangeFunctionType(CanQual<FunctionProtoType> FTP) {
+  SmallVector<CanQualType, 16> argTypes;
+  return ::arrangeFunctionType(*this, argTypes, FTP);
 }
 
 static CallingConv getCallingConventionForDecl(const Decl *D) {
@@ -111,82 +122,133 @@
   return CC_C;
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
-                                                 const FunctionProtoType *FTP) {
-  SmallVector<CanQualType, 16> ArgTys;
+/// Arrange the argument and result information for a call to an
+/// unknown C++ non-static member function of the given abstract type.
+/// The member function must be an ordinary function, i.e. not a
+/// constructor or destructor.
+const CGFunctionInfo &
+CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
+                                   const FunctionProtoType *FTP) {
+  SmallVector<CanQualType, 16> argTypes;
 
   // Add the 'this' pointer.
-  ArgTys.push_back(GetThisType(Context, RD));
+  argTypes.push_back(GetThisType(Context, RD));
 
-  return ::getFunctionInfo(*this, ArgTys,
+  return ::arrangeFunctionType(*this, argTypes,
               FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
-  SmallVector<CanQualType, 16> ArgTys;
-
+/// Arrange the argument and result information for a declaration or
+/// definition of the given C++ non-static member function.  The
+/// member function must be an ordinary function, i.e. not a
+/// constructor or destructor.
+const CGFunctionInfo &
+CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) {
   assert(!isa<CXXConstructorDecl>(MD) && "wrong method for contructors!");
   assert(!isa<CXXDestructorDecl>(MD) && "wrong method for destructors!");
 
-  // Add the 'this' pointer unless this is a static method.
-  if (MD->isInstance())
-    ArgTys.push_back(GetThisType(Context, MD->getParent()));
+  CanQual<FunctionProtoType> prototype = GetFormalType(MD);
+
+  if (MD->isInstance()) {
+    // The abstract case is perfectly fine.
+    return arrangeCXXMethodType(MD->getParent(), prototype.getTypePtr());
+  }
 
-  return ::getFunctionInfo(*this, ArgTys, GetFormalType(MD));
+  return arrangeFunctionType(prototype);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D,
-                                                    CXXCtorType Type) {
-  SmallVector<CanQualType, 16> ArgTys;
-  ArgTys.push_back(GetThisType(Context, D->getParent()));
-  CanQualType ResTy = Context.VoidTy;
+/// Arrange the argument and result information for a declaration
+/// or definition to the given constructor variant.
+const CGFunctionInfo &
+CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D,
+                                               CXXCtorType ctorKind) {
+  SmallVector<CanQualType, 16> argTypes;
+  argTypes.push_back(GetThisType(Context, D->getParent()));
+  CanQualType resultType = Context.VoidTy;
 
-  TheCXXABI.BuildConstructorSignature(D, Type, ResTy, ArgTys);
+  TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes);
 
   CanQual<FunctionProtoType> FTP = GetFormalType(D);
 
+  RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size());
+
   // Add the formal parameters.
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FTP->getArgType(i));
+    argTypes.push_back(FTP->getArgType(i));
 
-  return getFunctionInfo(ResTy, ArgTys, FTP->getExtInfo());
+  return arrangeFunctionType(resultType, argTypes, FTP->getExtInfo(), required);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D,
-                                                    CXXDtorType Type) {
-  SmallVector<CanQualType, 2> ArgTys;
-  ArgTys.push_back(GetThisType(Context, D->getParent()));
-  CanQualType ResTy = Context.VoidTy;
+/// Arrange the argument and result information for a declaration,
+/// definition, or call to the given destructor variant.  It so
+/// happens that all three cases produce the same information.
+const CGFunctionInfo &
+CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D,
+                                   CXXDtorType dtorKind) {
+  SmallVector<CanQualType, 2> argTypes;
+  argTypes.push_back(GetThisType(Context, D->getParent()));
+  CanQualType resultType = Context.VoidTy;
 
-  TheCXXABI.BuildDestructorSignature(D, Type, ResTy, ArgTys);
+  TheCXXABI.BuildDestructorSignature(D, dtorKind, resultType, argTypes);
 
   CanQual<FunctionProtoType> FTP = GetFormalType(D);
   assert(FTP->getNumArgs() == 0 && "dtor with formal parameters");
 
-  return getFunctionInfo(ResTy, ArgTys, FTP->getExtInfo());
+  return arrangeFunctionType(resultType, argTypes, FTP->getExtInfo(),
+                             RequiredArgs::All);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
+/// Arrange the argument and result information for the declaration or
+/// definition of the given function.
+const CGFunctionInfo &
+CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
     if (MD->isInstance())
-      return getFunctionInfo(MD);
+      return arrangeCXXMethodDeclaration(MD);
 
   CanQualType FTy = FD->getType()->getCanonicalTypeUnqualified();
+
   assert(isa<FunctionType>(FTy));
-  if (isa<FunctionNoProtoType>(FTy))
-    return getFunctionInfo(FTy.getAs<FunctionNoProtoType>());
+
+  // When declaring a function without a prototype, always use a
+  // non-variadic type.
+  if (isa<FunctionNoProtoType>(FTy)) {
+    CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>();
+    return arrangeFunctionType(noProto->getResultType(),
+                               ArrayRef<CanQualType>(),
+                               noProto->getExtInfo(),
+                               RequiredArgs::All);
+  }
+
   assert(isa<FunctionProtoType>(FTy));
-  return getFunctionInfo(FTy.getAs<FunctionProtoType>());
+  return arrangeFunctionType(FTy.getAs<FunctionProtoType>());
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
-  SmallVector<CanQualType, 16> ArgTys;
-  ArgTys.push_back(Context.getCanonicalParamType(MD->getSelfDecl()->getType()));
-  ArgTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
+/// Arrange the argument and result information for the declaration or
+/// definition of an Objective-C method.
+const CGFunctionInfo &
+CodeGenTypes::arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD) {
+  // It happens that this is the same as a call with no optional
+  // arguments, except also using the formal 'self' type.
+  return arrangeObjCMessageSendSignature(MD, MD->getSelfDecl()->getType());
+}
+
+/// Arrange the argument and result information for the function type
+/// through which to perform a send to the given Objective-C method,
+/// using the given receiver type.  The receiver type is not always
+/// the 'self' type of the method or even an Objective-C pointer type.
+/// This is *not* the right method for actually performing such a
+/// message send, due to the possibility of optional arguments.
+const CGFunctionInfo &
+CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
+                                              QualType receiverType) {
+  SmallVector<CanQualType, 16> argTys;
+  argTys.push_back(Context.getCanonicalParamType(receiverType));
+  argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
   // FIXME: Kill copy?
   for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
          e = MD->param_end(); i != e; ++i) {
-    ArgTys.push_back(Context.getCanonicalParamType((*i)->getType()));
+    argTys.push_back(Context.getCanonicalParamType((*i)->getType()));
   }
 
   FunctionType::ExtInfo einfo;
@@ -196,77 +258,114 @@
       MD->hasAttr<NSReturnsRetainedAttr>())
     einfo = einfo.withProducesResult(true);
 
-  return getFunctionInfo(GetReturnType(MD->getResultType()), ArgTys, einfo);
+  RequiredArgs required =
+    (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
+
+  return arrangeFunctionType(GetReturnType(MD->getResultType()), argTys,
+                             einfo, required);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(GlobalDecl GD) {
+const CGFunctionInfo &
+CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) {
   // FIXME: Do we need to handle ObjCMethodDecl?
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
 
   if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
-    return getFunctionInfo(CD, GD.getCtorType());
+    return arrangeCXXConstructorDeclaration(CD, GD.getCtorType());
 
   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD))
-    return getFunctionInfo(DD, GD.getDtorType());
+    return arrangeCXXDestructor(DD, GD.getDtorType());
 
-  return getFunctionInfo(FD);
+  return arrangeFunctionDeclaration(FD);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
-                                                    const CallArgList &Args,
-                                            const FunctionType::ExtInfo &Info) {
+/// Figure out the rules for calling a function with the given formal
+/// type using the given arguments.  The arguments are necessary
+/// because the function might be unprototyped, in which case it's
+/// target-dependent in crazy ways.
+const CGFunctionInfo &
+CodeGenTypes::arrangeFunctionCall(const CallArgList &args,
+                                  const FunctionType *fnType) {
+  RequiredArgs required = RequiredArgs::All;
+  if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
+    if (proto->isVariadic())
+      required = RequiredArgs(proto->getNumArgs());
+  } else if (CGM.getTargetCodeGenInfo()
+               .isNoProtoCallVariadic(args, cast<FunctionNoProtoType>(fnType))) {
+    required = RequiredArgs(0);
+  }
+
+  return arrangeFunctionCall(fnType->getResultType(), args,
+                             fnType->getExtInfo(), required);
+}
+
+const CGFunctionInfo &
+CodeGenTypes::arrangeFunctionCall(QualType resultType,
+                                  const CallArgList &args,
+                                  const FunctionType::ExtInfo &info,
+                                  RequiredArgs required) {
   // FIXME: Kill copy.
-  SmallVector<CanQualType, 16> ArgTys;
-  for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
+  SmallVector<CanQualType, 16> argTypes;
+  for (CallArgList::const_iterator i = args.begin(), e = args.end();
        i != e; ++i)
-    ArgTys.push_back(Context.getCanonicalParamType(i->Ty));
-  return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info);
+    argTypes.push_back(Context.getCanonicalParamType(i->Ty));
+  return arrangeFunctionType(GetReturnType(resultType), argTypes, info,
+                             required);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
-                                                    const FunctionArgList &Args,
-                                            const FunctionType::ExtInfo &Info) {
+const CGFunctionInfo &
+CodeGenTypes::arrangeFunctionDeclaration(QualType resultType,
+                                         const FunctionArgList &args,
+                                         const FunctionType::ExtInfo &info,
+                                         bool isVariadic) {
   // FIXME: Kill copy.
-  SmallVector<CanQualType, 16> ArgTys;
-  for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
+  SmallVector<CanQualType, 16> argTypes;
+  for (FunctionArgList::const_iterator i = args.begin(), e = args.end();
        i != e; ++i)
-    ArgTys.push_back(Context.getCanonicalParamType((*i)->getType()));
-  return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info);
+    argTypes.push_back(Context.getCanonicalParamType((*i)->getType()));
+
+  RequiredArgs required =
+    (isVariadic ? RequiredArgs(args.size()) : RequiredArgs::All);
+  return arrangeFunctionType(GetReturnType(resultType), argTypes, info,
+                             required);
 }
 
-const CGFunctionInfo &CodeGenTypes::getNullaryFunctionInfo() {
-  SmallVector<CanQualType, 1> args;
-  return getFunctionInfo(getContext().VoidTy, args, FunctionType::ExtInfo());
+const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
+  return arrangeFunctionType(getContext().VoidTy, ArrayRef<CanQualType>(),
+                             FunctionType::ExtInfo(), RequiredArgs::All);
 }
 
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy,
-                           const SmallVectorImpl<CanQualType> &ArgTys,
-                                            const FunctionType::ExtInfo &Info) {
+/// Arrange the argument and result information for an abstract value
+/// of a given function type.  This is the method which all of the
+/// above functions ultimately defer to.
+const CGFunctionInfo &
+CodeGenTypes::arrangeFunctionType(CanQualType resultType,
+                                  ArrayRef<CanQualType> argTypes,
+                                  const FunctionType::ExtInfo &info,
+                                  RequiredArgs required) {
 #ifndef NDEBUG
-  for (SmallVectorImpl<CanQualType>::const_iterator
-         I = ArgTys.begin(), E = ArgTys.end(); I != E; ++I)
+  for (ArrayRef<CanQualType>::const_iterator
+         I = argTypes.begin(), E = argTypes.end(); I != E; ++I)
     assert(I->isCanonicalAsParam());
 #endif
 
-  unsigned CC = ClangCallConvToLLVMCallConv(Info.getCC());
+  unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
 
   // Lookup or create unique function info.
   llvm::FoldingSetNodeID ID;
-  CGFunctionInfo::Profile(ID, Info, ResTy, ArgTys.begin(), ArgTys.end());
+  CGFunctionInfo::Profile(ID, info, required, resultType, argTypes);
 
-  void *InsertPos = 0;
-  CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos);
+  void *insertPos = 0;
+  CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
   if (FI)
     return *FI;
 
-  // Construct the function info.
-  FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getProducesResult(),
-                          Info.getHasRegParm(), Info.getRegParm(), ResTy,
-                          ArgTys.data(), ArgTys.size());
-  FunctionInfos.InsertNode(FI, InsertPos);
+  // Construct the function info.  We co-allocate the ArgInfos.
+  FI = CGFunctionInfo::create(CC, info, resultType, argTypes, required);
+  FunctionInfos.InsertNode(FI, insertPos);
 
-  bool Inserted = FunctionsBeingProcessed.insert(FI); (void)Inserted;
-  assert(Inserted && "Recursively being processed?");
+  bool inserted = FunctionsBeingProcessed.insert(FI); (void)inserted;
+  assert(inserted && "Recursively being processed?");
   
   // Compute ABI information.
   getABIInfo().computeInfo(*FI);
@@ -274,39 +373,42 @@
   // Loop over all of the computed argument and return value info.  If any of
   // them are direct or extend without a specified coerce type, specify the
   // default now.
-  ABIArgInfo &RetInfo = FI->getReturnInfo();
-  if (RetInfo.canHaveCoerceToType() && RetInfo.getCoerceToType() == 0)
-    RetInfo.setCoerceToType(ConvertType(FI->getReturnType()));
+  ABIArgInfo &retInfo = FI->getReturnInfo();
+  if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == 0)
+    retInfo.setCoerceToType(ConvertType(FI->getReturnType()));
 
   for (CGFunctionInfo::arg_iterator I = FI->arg_begin(), E = FI->arg_end();
        I != E; ++I)
     if (I->info.canHaveCoerceToType() && I->info.getCoerceToType() == 0)
       I->info.setCoerceToType(ConvertType(I->type));
 
-  bool Erased = FunctionsBeingProcessed.erase(FI); (void)Erased;
-  assert(Erased && "Not in set?");
+  bool erased = FunctionsBeingProcessed.erase(FI); (void)erased;
+  assert(erased && "Not in set?");
   
   return *FI;
 }
 
-CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
-                               bool _NoReturn, bool returnsRetained,
-                               bool _HasRegParm, unsigned _RegParm,
-                               CanQualType ResTy,
-                               const CanQualType *ArgTys,
-                               unsigned NumArgTys)
-  : CallingConvention(_CallingConvention),
-    EffectiveCallingConvention(_CallingConvention),
-    NoReturn(_NoReturn), ReturnsRetained(returnsRetained),
-    HasRegParm(_HasRegParm), RegParm(_RegParm)
-{
-  NumArgs = NumArgTys;
-
-  // FIXME: Coallocate with the CGFunctionInfo object.
-  Args = new ArgInfo[1 + NumArgTys];
-  Args[0].type = ResTy;
-  for (unsigned i = 0; i != NumArgTys; ++i)
-    Args[1 + i].type = ArgTys[i];
+CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
+                                       const FunctionType::ExtInfo &info,
+                                       CanQualType resultType,
+                                       ArrayRef<CanQualType> argTypes,
+                                       RequiredArgs required) {
+  void *buffer = operator new(sizeof(CGFunctionInfo) +
+                              sizeof(ArgInfo) * (argTypes.size() + 1));
+  CGFunctionInfo *FI = new(buffer) CGFunctionInfo();
+  FI->CallingConvention = llvmCC;
+  FI->EffectiveCallingConvention = llvmCC;
+  FI->ASTCallingConvention = info.getCC();
+  FI->NoReturn = info.getNoReturn();
+  FI->ReturnsRetained = info.getProducesResult();
+  FI->Required = required;
+  FI->HasRegParm = info.getHasRegParm();
+  FI->RegParm = info.getRegParm();
+  FI->NumArgs = argTypes.size();
+  FI->getArgsBuffer()[0].type = resultType;
+  for (unsigned i = 0, e = argTypes.size(); i != e; ++i)
+    FI->getArgsBuffer()[i + 1].type = argTypes[i];
+  return FI;
 }
 
 /***/
@@ -623,19 +725,12 @@
 }
 
 llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) {
-  const CGFunctionInfo &FI = getFunctionInfo(GD);
-
-  // For definition purposes, don't consider a K&R function variadic.
-  bool Variadic = false;
-  if (const FunctionProtoType *FPT =
-        cast<FunctionDecl>(GD.getDecl())->getType()->getAs<FunctionProtoType>())
-    Variadic = FPT->isVariadic();
-
-  return GetFunctionType(FI, Variadic);
+  const CGFunctionInfo &FI = arrangeGlobalDeclaration(GD);
+  return GetFunctionType(FI);
 }
 
 llvm::FunctionType *
-CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic) {
+CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
   
   bool Inserted = FunctionsBeingProcessed.insert(&FI); (void)Inserted;
   assert(Inserted && "Recursively being processed?");
@@ -711,7 +806,7 @@
   bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased;
   assert(Erased && "Not in set?");
   
-  return llvm::FunctionType::get(resultType, argTypes, isVariadic);
+  return llvm::FunctionType::get(resultType, argTypes, FI.isVariadic());
 }
 
 llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) {
@@ -723,10 +818,10 @@
     
   const CGFunctionInfo *Info;
   if (isa<CXXDestructorDecl>(MD))
-    Info = &getFunctionInfo(cast<CXXDestructorDecl>(MD), GD.getDtorType());
+    Info = &arrangeCXXDestructor(cast<CXXDestructorDecl>(MD), GD.getDtorType());
   else
-    Info = &getFunctionInfo(MD);
-  return GetFunctionType(*Info, FPT->isVariadic());
+    Info = &arrangeCXXMethodDeclaration(MD);
+  return GetFunctionType(*Info);
 }
 
 void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
@@ -1593,6 +1688,16 @@
   args.add(EmitAnyExprToTemp(E), type);
 }
 
+// In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
+// optimizer it can aggressively ignore unwind edges.
+void
+CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
+  if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
+      !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
+    Inst->setMetadata("clang.arc.no_objc_arc_exceptions",
+                      CGM.getNoObjCARCExceptionsMetadata());
+}
+
 /// Emits a call or invoke instruction to the given function, depending
 /// on the current state of the EH stack.
 llvm::CallSite
@@ -1600,14 +1705,22 @@
                                   ArrayRef<llvm::Value *> Args,
                                   const Twine &Name) {
   llvm::BasicBlock *InvokeDest = getInvokeDest();
+
+  llvm::Instruction *Inst;
   if (!InvokeDest)
-    return Builder.CreateCall(Callee, Args, Name);
+    Inst = Builder.CreateCall(Callee, Args, Name);
+  else {
+    llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
+    Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, Name);
+    EmitBlock(ContBB);
+  }
 
-  llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
-  llvm::InvokeInst *Invoke = Builder.CreateInvoke(Callee, ContBB, InvokeDest,
-                                                  Args, Name);
-  EmitBlock(ContBB);
-  return Invoke;
+  // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
+  // optimizer it can aggressively ignore unwind edges.
+  if (CGM.getLangOptions().ObjCAutoRefCount)
+    AddObjCARCExceptionMetadata(Inst);
+
+  return Inst;
 }
 
 llvm::CallSite
@@ -1916,6 +2029,11 @@
   CS.setAttributes(Attrs);
   CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
 
+  // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
+  // optimizer it can aggressively ignore unwind edges.
+  if (CGM.getLangOptions().ObjCAutoRefCount)
+    AddObjCARCExceptionMetadata(CS.getInstruction());
+
   // If the call doesn't return, finish the basic block and clear the
   // insertion point; this allows the rest of IRgen to discard
   // unreachable code.

Modified: cfe/branches/tooling/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCall.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCall.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCall.h Mon Feb 20 19:34:24 2012
@@ -98,6 +98,55 @@
     SmallVector<Writeback, 1> Writebacks;
   };
 
+  /// A class for recording the number of arguments that a function
+  /// signature requires.
+  class RequiredArgs {
+    /// The number of required arguments, or ~0 if the signature does
+    /// not permit optional arguments.
+    unsigned NumRequired;
+  public:
+    enum All_t { All };
+
+    RequiredArgs(All_t _) : NumRequired(~0U) {}
+    explicit RequiredArgs(unsigned n) : NumRequired(n) {
+      assert(n != ~0U);
+    }
+
+    /// Compute the arguments required by the given formal prototype,
+    /// given that there may be some additional, non-formal arguments
+    /// in play.
+    static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
+                                         unsigned additional) {
+      if (!prototype->isVariadic()) return All;
+      return RequiredArgs(prototype->getNumArgs() + additional);
+    }
+
+    static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
+      return forPrototypePlus(prototype, 0);
+    }
+
+    static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
+      return forPrototype(prototype.getTypePtr());
+    }
+
+    static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
+                                         unsigned additional) {
+      return forPrototypePlus(prototype.getTypePtr(), additional);
+    }
+
+    bool allowsOptionalArgs() const { return NumRequired != ~0U; }
+    bool getNumRequiredArgs() const {
+      assert(allowsOptionalArgs());
+      return NumRequired;
+    }
+
+    unsigned getOpaqueData() const { return NumRequired; }
+    static RequiredArgs getFromOpaqueData(unsigned value) {
+      if (value == ~0U) return All;
+      return RequiredArgs(value);
+    }
+  };
+
   /// FunctionArgList - Type for representing both the decl and type
   /// of parameters to a function. The decl must be either a
   /// ParmVarDecl or ImplicitParamDecl.
@@ -114,50 +163,71 @@
 
     /// The LLVM::CallingConv to use for this function (as specified by the
     /// user).
-    unsigned CallingConvention;
+    unsigned CallingConvention : 8;
 
     /// The LLVM::CallingConv to actually use for this function, which may
     /// depend on the ABI.
-    unsigned EffectiveCallingConvention;
+    unsigned EffectiveCallingConvention : 8;
+
+    /// The clang::CallingConv that this was originally created with.
+    unsigned ASTCallingConvention : 8;
 
     /// Whether this function is noreturn.
-    bool NoReturn;
+    unsigned NoReturn : 1;
 
     /// Whether this function is returns-retained.
-    bool ReturnsRetained;
+    unsigned ReturnsRetained : 1;
+
+    /// How many arguments to pass inreg.
+    unsigned HasRegParm : 1;
+    unsigned RegParm : 4;
+
+    RequiredArgs Required;
 
     unsigned NumArgs;
-    ArgInfo *Args;
+    ArgInfo *getArgsBuffer() {
+      return reinterpret_cast<ArgInfo*>(this+1);
+    }
+    const ArgInfo *getArgsBuffer() const {
+      return reinterpret_cast<const ArgInfo*>(this + 1);
+    }
 
-    /// How many arguments to pass inreg.
-    bool HasRegParm;
-    unsigned RegParm;
+    CGFunctionInfo() : Required(RequiredArgs::All) {}
 
   public:
+    static CGFunctionInfo *create(unsigned llvmCC,
+                                  const FunctionType::ExtInfo &extInfo,
+                                  CanQualType resultType,
+                                  ArrayRef<CanQualType> argTypes,
+                                  RequiredArgs required);
+
     typedef const ArgInfo *const_arg_iterator;
     typedef ArgInfo *arg_iterator;
 
-    CGFunctionInfo(unsigned CallingConvention, bool NoReturn,
-                   bool ReturnsRetained, bool HasRegParm, unsigned RegParm,
-                   CanQualType ResTy,
-                   const CanQualType *ArgTys, unsigned NumArgTys);
-    ~CGFunctionInfo() { delete[] Args; }
-
-    const_arg_iterator arg_begin() const { return Args + 1; }
-    const_arg_iterator arg_end() const { return Args + 1 + NumArgs; }
-    arg_iterator arg_begin() { return Args + 1; }
-    arg_iterator arg_end() { return Args + 1 + NumArgs; }
+    const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
+    const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
+    arg_iterator arg_begin() { return getArgsBuffer() + 1; }
+    arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
 
     unsigned  arg_size() const { return NumArgs; }
 
+    bool isVariadic() const { return Required.allowsOptionalArgs(); }
+    RequiredArgs getRequiredArgs() const { return Required; }
+
     bool isNoReturn() const { return NoReturn; }
 
-    /// In ARR, whether this function retains its return value.  This
+    /// In ARC, whether this function retains its return value.  This
     /// is not always reliable for call sites.
     bool isReturnsRetained() const { return ReturnsRetained; }
 
-    /// getCallingConvention - Return the user specified calling
+    /// getASTCallingConvention() - Return the AST-specified calling
     /// convention.
+    CallingConv getASTCallingConvention() const {
+      return CallingConv(ASTCallingConvention);
+    }
+
+    /// getCallingConvention - Return the user specified calling
+    /// convention, which has been translated into an LLVM CC.
     unsigned getCallingConvention() const { return CallingConvention; }
 
     /// getEffectiveCallingConvention - Return the actual calling convention to
@@ -172,36 +242,44 @@
     bool getHasRegParm() const { return HasRegParm; }
     unsigned getRegParm() const { return RegParm; }
 
-    CanQualType getReturnType() const { return Args[0].type; }
+    FunctionType::ExtInfo getExtInfo() const {
+      return FunctionType::ExtInfo(isNoReturn(),
+                                   getHasRegParm(), getRegParm(),
+                                   getASTCallingConvention(),
+                                   isReturnsRetained());
+    }
+
+    CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
 
-    ABIArgInfo &getReturnInfo() { return Args[0].info; }
-    const ABIArgInfo &getReturnInfo() const { return Args[0].info; }
+    ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
+    const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
 
     void Profile(llvm::FoldingSetNodeID &ID) {
-      ID.AddInteger(getCallingConvention());
+      ID.AddInteger(getASTCallingConvention());
       ID.AddBoolean(NoReturn);
       ID.AddBoolean(ReturnsRetained);
       ID.AddBoolean(HasRegParm);
       ID.AddInteger(RegParm);
+      ID.AddInteger(Required.getOpaqueData());
       getReturnType().Profile(ID);
       for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
         it->type.Profile(ID);
     }
-    template<class Iterator>
     static void Profile(llvm::FoldingSetNodeID &ID,
-                        const FunctionType::ExtInfo &Info,
-                        CanQualType ResTy,
-                        Iterator begin,
-                        Iterator end) {
-      ID.AddInteger(Info.getCC());
-      ID.AddBoolean(Info.getNoReturn());
-      ID.AddBoolean(Info.getProducesResult());
-      ID.AddBoolean(Info.getHasRegParm());
-      ID.AddInteger(Info.getRegParm());
-      ResTy.Profile(ID);
-      for (; begin != end; ++begin) {
-        CanQualType T = *begin; // force iterator to be over canonical types
-        T.Profile(ID);
+                        const FunctionType::ExtInfo &info,
+                        RequiredArgs required,
+                        CanQualType resultType,
+                        ArrayRef<CanQualType> argTypes) {
+      ID.AddInteger(info.getCC());
+      ID.AddBoolean(info.getNoReturn());
+      ID.AddBoolean(info.getProducesResult());
+      ID.AddBoolean(info.getHasRegParm());
+      ID.AddInteger(info.getRegParm());
+      ID.AddInteger(required.getOpaqueData());
+      resultType.Profile(ID);
+      for (ArrayRef<CanQualType>::iterator
+             i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
+        i->Profile(ID);
       }
     }
   };

Modified: cfe/branches/tooling/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGClass.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGClass.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGClass.cpp Mon Feb 20 19:34:24 2012
@@ -1289,7 +1289,7 @@
     EmitCallArg(Args, *Arg, ArgType);
   }
   
-  EmitCall(CGM.getTypes().getFunctionInfo(Args, FPT), Callee,
+  EmitCall(CGM.getTypes().arrangeFunctionCall(Args, FPT), Callee,
            ReturnValueSlot(), Args, D);
 }
 
@@ -1325,7 +1325,7 @@
     EmitDelegateCallArg(DelegateArgs, param);
   }
 
-  EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType),
+  EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType),
            CGM.GetAddrOfCXXConstructor(Ctor, CtorType), 
            ReturnValueSlot(), DelegateArgs, Ctor);
 }
@@ -1710,13 +1710,72 @@
 CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,
                                              const CXXMethodDecl *MD,
                                              llvm::Value *This) {
-  const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
-  llvm::Type *Ty =
-    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
-                                   FPT->isVariadic());
+  llvm::FunctionType *fnType =
+    CGM.getTypes().GetFunctionType(
+                             CGM.getTypes().arrangeCXXMethodDeclaration(MD));
 
   if (UseVirtualCall(getContext(), E, MD))
-    return BuildVirtualCall(MD, This, Ty);
+    return BuildVirtualCall(MD, This, fnType);
 
-  return CGM.GetAddrOfFunction(MD, Ty);
+  return CGM.GetAddrOfFunction(MD, fnType);
+}
+
+void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) {
+  CGM.ErrorUnsupported(CurFuncDecl, "lambda conversion to block");
+}
+
+void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
+  const CXXRecordDecl *Lambda = MD->getParent();
+  DeclarationName Name
+    = getContext().DeclarationNames.getCXXOperatorName(OO_Call);
+  DeclContext::lookup_const_result Calls = Lambda->lookup(Name);
+  CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(*Calls.first++);
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  QualType ResultType = FPT->getResultType();
+
+  // Start building arguments for forwarding call
+  CallArgList CallArgs;
+
+  QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
+  llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType));
+  CallArgs.add(RValue::get(ThisPtr), ThisType);
+
+  // Add the rest of the parameters.
+  for (FunctionDecl::param_const_iterator I = MD->param_begin(),
+       E = MD->param_end(); I != E; ++I) {
+    ParmVarDecl *param = *I;
+    EmitDelegateCallArg(CallArgs, param);
+  }
+
+  // Get the address of the call operator.
+  GlobalDecl GD(CallOperator);
+  const CGFunctionInfo &CalleeFnInfo =
+    CGM.getTypes().arrangeFunctionCall(ResultType, CallArgs, FPT->getExtInfo(),
+                                       RequiredArgs::forPrototypePlus(FPT, 1));
+  llvm::Type *Ty = CGM.getTypes().GetFunctionType(CalleeFnInfo);
+  llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty);
+
+  // Determine whether we have a return value slot to use.
+  ReturnValueSlot Slot;
+  if (!ResultType->isVoidType() &&
+      CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+      hasAggregateLLVMType(CurFnInfo->getReturnType()))
+    Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
+  
+  // Now emit our call.
+  RValue RV = EmitCall(CalleeFnInfo, Callee, Slot, CallArgs, CallOperator);
+
+  // Forward the returned value
+  if (!ResultType->isVoidType() && Slot.isNull())
+    EmitReturnOfRValue(RV, ResultType);
+}
+
+void CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) {
+  if (MD->isVariadic()) {
+    // FIXME: Making this work correctly is nasty because it requires either
+    // cloning the body of the call operator or making the call operator forward.
+    CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
+  }
+
+  EmitLambdaDelegatingInvokeBody(MD);
 }

Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp Mon Feb 20 19:34:24 2012
@@ -502,8 +502,7 @@
     llvm_unreachable("Unknown RecordDecl type!");
 
   // Create the type.
-  return DBuilder.createForwardDecl(Tag, RDName, DefUnit,
-				    Line);
+  return DBuilder.createForwardDecl(Tag, RDName, DefUnit, Line);
 }
 
 // Walk up the context chain and create forward decls for record decls,
@@ -524,11 +523,8 @@
 
   if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) {
     if (!RD->isDependentType()) {
-      llvm::DIDescriptor FDContext =
-        createContextChain(cast<Decl>(RD->getDeclContext()));
-      llvm::DIType Ty = createRecordFwdDecl(RD, FDContext);
-
-      RegionMap[Context] = llvm::WeakVH(Ty);
+      llvm::DIType Ty = getOrCreateLimitedType(CGM.getContext().getTypeDeclType(RD),
+					       getOrCreateMainFile());
       return llvm::DIDescriptor(Ty);
     }
   }
@@ -654,10 +650,11 @@
   // declared.
   unsigned Line = getLineNumber(Ty->getDecl()->getLocation());
   const TypedefNameDecl *TyDecl = Ty->getDecl();
+  
   llvm::DIDescriptor TypedefContext =
     getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext()));
-
-  return  
+  
+  return
     DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);
 }
 
@@ -1133,8 +1130,6 @@
 
   // Get overall information about the record type for the debug info.
   llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
-  unsigned Line = getLineNumber(RD->getLocation());
-  StringRef RDName = RD->getName();
 
   // Records and classes and unions can all be recursive.  To handle them, we
   // first generate a debug descriptor for the struct as a forward declaration.
@@ -1143,28 +1138,21 @@
   // may refer to the forward decl if the struct is recursive) and replace all
   // uses of the forward declaration with the final definition.
 
-  llvm::DIDescriptor RDContext;
-  if (CGM.getCodeGenOpts().LimitDebugInfo)
-    RDContext = createContextChain(cast<Decl>(RD->getDeclContext()));
-  else
-    RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));
-
-  // If this is just a forward declaration, construct an appropriately
-  // marked node and just return it.
-  if (!RD->getDefinition())
-    return createRecordFwdDecl(RD, RDContext);
-
-  llvm::DIType FwdDecl = DBuilder.createTemporaryType(DefUnit);
+  llvm::DIType FwdDecl = getOrCreateLimitedType(QualType(Ty, 0), DefUnit);
 
+  if (FwdDecl.isForwardDecl())
+    return FwdDecl;
+  
   llvm::MDNode *MN = FwdDecl;
   llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
-  // Otherwise, insert it into the TypeCache so that recursive uses will find
-  // it.
-  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
+  
   // Push the struct on region stack.
   LexicalBlockStack.push_back(FwdDeclNode);
   RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
 
+  // Add this to the completed types cache since we're completing it.
+  CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
+
   // Convert all the elements.
   SmallVector<llvm::Value *, 16> EltTys;
 
@@ -1196,50 +1184,20 @@
   if (RI != RegionMap.end())
     RegionMap.erase(RI);
 
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
   llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-  llvm::MDNode *RealDecl = NULL;
-
+  // FIXME: Magic numbers ahoy! These should be changed when we
+  // get some enums in llvm/Analysis/DebugInfo.h to refer to
+  // them.
   if (RD->isUnion())
-    RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line,
-                                        Size, Align, 0, Elements);
+    MN->replaceOperandWith(10, Elements);
   else if (CXXDecl) {
-    RDName = getClassName(RD);
-     // A class's primary base or the class itself contains the vtable.
-    llvm::MDNode *ContainingType = NULL;
-    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-    if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
-      // Seek non virtual primary base root.
-      while (1) {
-        const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
-        const CXXRecordDecl *PBT = BRL.getPrimaryBase();
-        if (PBT && !BRL.isPrimaryBaseVirtual())
-          PBase = PBT;
-        else 
-          break;
-      }
-      ContainingType = 
-        getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit);
-    }
-    else if (CXXDecl->isDynamicClass()) 
-      ContainingType = FwdDecl;
-
-    // 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);
+    MN->replaceOperandWith(10, Elements);
+    MN->replaceOperandWith(13, TParamsArray);
   } else
-    RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
-                                         Size, Align, 0, Elements);
+    MN->replaceOperandWith(10, Elements);
 
-  // Now that we have a real decl for the struct, replace anything using the
-  // old decl with the new one.  This will recursively update the debug info.
-  llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl);
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
-  return llvm::DIType(RealDecl);
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(MN);
+  return llvm::DIType(MN);
 }
 
 /// CreateType - get objective-c object type.
@@ -1274,22 +1232,28 @@
   }
   ID = Def;
 
-  // To handle a recursive interface, we first generate a debug descriptor
-  // for the struct as a forward declaration. Then (if it is a definition)
-  // we go through and get debug info for all of its members.  Finally, we
-  // create a descriptor for the complete type (which may refer to the
-  // forward decl if the struct is recursive) and replace all uses of the
-  // forward declaration with the final definition.
-  llvm::DIType FwdDecl = DBuilder.createTemporaryType(DefUnit);
+  // Bit size, align and offset of the type.
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+
+  unsigned Flags = 0;
+  if (ID->getImplementation())
+    Flags |= llvm::DIDescriptor::FlagObjcClassComplete;
 
-  llvm::MDNode *MN = FwdDecl;
-  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
+  llvm::DIType RealDecl =
+    DBuilder.createStructType(Unit, ID->getName(), DefUnit,
+                              Line, Size, Align, Flags,
+                              llvm::DIArray(), RuntimeLang);
+  
   // Otherwise, insert it into the TypeCache so that recursive uses will find
   // it.
-  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;
   // Push the struct on region stack.
+  llvm::MDNode *MN = RealDecl;
+  llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
+
   LexicalBlockStack.push_back(FwdDeclNode);
-  RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
 
   // Convert all the elements.
   SmallVector<llvm::Value *, 16> EltTys;
@@ -1302,7 +1266,7 @@
       return llvm::DIType();
     
     llvm::DIType InhTag =
-      DBuilder.createInheritance(FwdDecl, SClassTy, 0, 0);
+      DBuilder.createInheritance(RealDecl, SClassTy, 0, 0);
     EltTys.push_back(InhTag);
   }
 
@@ -1381,31 +1345,9 @@
   }
 
   llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-
+  RealDecl->replaceOperandWith(10, Elements);
+  
   LexicalBlockStack.pop_back();
-  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator RI = 
-    RegionMap.find(Ty->getDecl());
-  if (RI != RegionMap.end())
-    RegionMap.erase(RI);
-
-  // Bit size, align and offset of the type.
-  uint64_t Size = CGM.getContext().getTypeSize(Ty);
-  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
-
-  unsigned Flags = 0;
-  if (ID->getImplementation())
-    Flags |= llvm::DIDescriptor::FlagObjcClassComplete;
-
-  llvm::DIType RealDecl =
-    DBuilder.createStructType(Unit, ID->getName(), DefUnit,
-                                  Line, Size, Align, Flags,
-                                  Elements, RuntimeLang);
-
-  // Now that we have a real decl for the struct, replace anything using the
-  // old decl with the new one.  This will recursively update the debug info.
-  llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl);
-  RegionMap[ID] = llvm::WeakVH(RealDecl);
-
   return RealDecl;
 }
 
@@ -1637,6 +1579,26 @@
   return llvm::DIType();
 }
 
+/// getCompletedTypeOrNull - Get the type from the cache or return null if it
+/// doesn't exist.
+llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
+
+  // Unwrap the type as needed for debug information.
+  Ty = UnwrapTypeForDebugInfo(Ty);
+
+  // Check for existing entry.
+  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
+    CompletedTypeCache.find(Ty.getAsOpaquePtr());
+  if (it != CompletedTypeCache.end()) {
+    // Verify that the debug info still exists.
+    if (&*it->second)
+      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) {
@@ -1646,14 +1608,22 @@
   // Unwrap the type as needed for debug information.
   Ty = UnwrapTypeForDebugInfo(Ty);
   
-  llvm::DIType T = getTypeOrNull(Ty);
+  llvm::DIType T = getCompletedTypeOrNull(Ty);
+
   if (T.Verify()) return T;
 
   // Otherwise create the type.
   llvm::DIType Res = CreateTypeNode(Ty, Unit);
 
+  llvm::DIType TC = getTypeOrNull(Ty);
+  if (TC.Verify() && TC.isForwardDecl())
+    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(), TC));
+  
   // And update the type cache.
-  TypeCache[Ty.getAsOpaquePtr()] = Res;  
+  TypeCache[Ty.getAsOpaquePtr()] = Res;
+
+  if (!Res.isForwardDecl())
+    CompletedTypeCache[Ty.getAsOpaquePtr()] = Res;
   return Res;
 }
 
@@ -1737,6 +1707,123 @@
   return llvm::DIType();
 }
 
+/// getOrCreateLimitedType - Get the type from the cache or create a new
+/// limited type if necessary.
+llvm::DIType CGDebugInfo::getOrCreateLimitedType(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);
+
+  // We may have cached a forward decl when we could have created
+  // a non-forward decl. Go ahead and create a non-forward decl
+  // now.
+  if (T.Verify() && !T.isForwardDecl()) return T;
+
+  // Otherwise create the type.
+  llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);
+
+  if (T.Verify() && T.isForwardDecl())
+    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(), T));
+
+  // And update the type cache.
+  TypeCache[Ty.getAsOpaquePtr()] = Res;
+  return Res;
+}
+
+// TODO: Currently used for context chains when limiting debug info.
+llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
+  RecordDecl *RD = Ty->getDecl();
+  
+  // Get overall information about the record type for the debug info.
+  llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
+  unsigned Line = getLineNumber(RD->getLocation());
+  StringRef RDName = RD->getName();
+
+  llvm::DIDescriptor RDContext;
+  if (CGM.getCodeGenOpts().LimitDebugInfo)
+    RDContext = createContextChain(cast<Decl>(RD->getDeclContext()));
+  else
+    RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));
+
+  // If this is just a forward declaration, construct an appropriately
+  // marked node and just return it.
+  if (!RD->getDefinition())
+    return createRecordFwdDecl(RD, RDContext);
+
+  uint64_t Size = CGM.getContext().getTypeSize(Ty);
+  uint64_t Align = CGM.getContext().getTypeAlign(Ty);
+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
+  llvm::MDNode *RealDecl = NULL;
+  
+  if (RD->isUnion())
+    RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line,
+					Size, Align, 0, llvm::DIArray());
+  else if (CXXDecl) {
+    RDName = getClassName(RD);
+    
+    // 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(),
+					llvm::DIArray(), NULL,
+					llvm::DIArray());
+  } else
+    RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
+					 Size, Align, 0, llvm::DIArray());
+
+  RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = llvm::DIType(RealDecl);
+
+  if (CXXDecl) {
+    // A class's primary base or the class itself contains the vtable.
+    llvm::MDNode *ContainingType = NULL;
+    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
+    if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
+      // Seek non virtual primary base root.
+      while (1) {
+	const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
+	const CXXRecordDecl *PBT = BRL.getPrimaryBase();
+	if (PBT && !BRL.isPrimaryBaseVirtual())
+	  PBase = PBT;
+	else
+	  break;
+      }
+      ContainingType =
+	getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit);
+    }
+    else if (CXXDecl->isDynamicClass())
+      ContainingType = RealDecl;
+
+    RealDecl->replaceOperandWith(12, ContainingType);
+  }
+  return llvm::DIType(RealDecl);
+}
+
+/// CreateLimitedTypeNode - Create a new debug type node, but only forward
+/// declare composite types that haven't been processed yet.
+llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) {
+
+  // Work out details of type.
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+        #include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Dependent types cannot show up in debug information");
+
+  case Type::Record:
+    return CreateLimitedType(cast<RecordType>(Ty));
+  default:
+    return CreateTypeNode(Ty, Unit);
+  }
+}
+
 /// CreateMemberType - Create new member and increase Offset by FType's size.
 llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,
                                            StringRef Name,
@@ -2477,16 +2564,24 @@
   return NS;
 }
 
-/// UpdateCompletedType - Update type cache because the type is now
-/// translated.
-void CGDebugInfo::UpdateCompletedType(const TagDecl *TD) {
-  QualType Ty = CGM.getContext().getTagDeclType(TD);
-
-  // If the type exist in type cache then remove it from the cache.
-  // There is no need to prepare debug info for the completed type
-  // right now. It will be generated on demand lazily.
-  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-    TypeCache.find(Ty.getAsOpaquePtr());
-  if (it != TypeCache.end()) 
-    TypeCache.erase(it);
+void CGDebugInfo::finalize(void) {
+  for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI
+         = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {
+    llvm::DIType Ty, RepTy;
+    // Verify that the debug info still exists.
+    if (&*VI->second)
+      Ty = llvm::DIType(cast<llvm::MDNode>(VI->second));
+    
+    llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
+      TypeCache.find(VI->first);
+    if (it != TypeCache.end()) {
+      // Verify that the debug info still exists.
+      if (&*it->second)
+        RepTy = llvm::DIType(cast<llvm::MDNode>(it->second));
+    }
+    
+    if (Ty.Verify() && RepTy.Verify())
+      Ty.replaceAllUsesWith(RepTy);
+  }
+  DBuilder.finalize();
 }

Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h Mon Feb 20 19:34:24 2012
@@ -53,6 +53,13 @@
   /// TypeCache - Cache of previously constructed Types.
   llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
 
+  /// CompleteTypeCache - Cache of previously constructed complete RecordTypes.
+  llvm::DenseMap<void *, llvm::WeakVH> CompletedTypeCache;
+
+  /// ReplaceMap - Cache of forward declared types to RAUW at the end of
+  /// compilation.
+  std::vector<std::pair<void *, llvm::WeakVH> >ReplaceMap;
+
   bool BlockLiteralGenericSet;
   llvm::DIType BlockLiteralGeneric;
 
@@ -84,6 +91,7 @@
   llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const RecordType *Ty);
+  llvm::DIType CreateLimitedType(const RecordType *Ty);
   llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
@@ -94,6 +102,7 @@
   llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
   llvm::DIType CreateEnumType(const EnumDecl *ED);
   llvm::DIType getTypeOrNull(const QualType);
+  llvm::DIType getCompletedTypeOrNull(const QualType);
   llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
                                      llvm::DIFile F);
   llvm::DIType getOrCreateFunctionType(const Decl *D, QualType FnType,
@@ -155,7 +164,8 @@
 public:
   CGDebugInfo(CodeGenModule &CGM);
   ~CGDebugInfo();
-  void finalize() { DBuilder.finalize(); }
+
+  void finalize(void);
 
   /// setLocation - Update the current source location. If \arg loc is
   /// invalid it is ignored.
@@ -173,10 +183,6 @@
   /// EmitFunctionEnd - Constructs the debug code for exiting a function.
   void EmitFunctionEnd(CGBuilderTy &Builder);
 
-  /// UpdateCompletedType - Update type cache because the type is now
-  /// translated.
-  void UpdateCompletedType(const TagDecl *TD);
-
   /// EmitLexicalBlockStart - Emit metadata to indicate the beginning of a
   /// new lexical block and push the block onto the stack.
   void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc);
@@ -257,9 +263,17 @@
   /// necessary.
   llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);
 
+  /// getOrCreateLimitedType - Get the type from the cache or create a new
+  /// partial type if necessary.
+  llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F);
+
   /// CreateTypeNode - Create type metadata for a source language type.
   llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
 
+  /// CreateLimitedTypeNode - Create type metadata for a source language
+  /// type, but only partial types for records.
+  llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F);
+
   /// CreateMemberType - Create new member and increase Offset by FType's size.
   llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,
                                 StringRef Name, uint64_t *Offset);

Modified: cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDecl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDecl.cpp Mon Feb 20 19:34:24 2012
@@ -255,14 +255,13 @@
     OldGV->eraseFromParent();
   }
 
+  GV->setConstant(CGM.isTypeConstant(D.getType(), true));
   GV->setInitializer(Init);
 
   if (hasNontrivialDestruction(D.getType())) {
     // We have a constant initializer, but a nontrivial destructor. We still
     // need to perform a guarded "initialization" in order to register the
-    // destructor. Since we're running a destructor on this variable, it can't
-    // be a constant even if it's const.
-    GV->setConstant(false);
+    // destructor.
     EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
   }
 
@@ -775,7 +774,7 @@
       // If this value is a POD array or struct with a statically
       // determinable constant initializer, there are optimizations we can do.
       //
-      // TODO: we should constant-evaluate any variable of literal type
+      // TODO: We should constant-evaluate the initializer of any variable,
       // as long as it is initialized by a constant expression. Currently,
       // isConstantInitializer produces wrong answers for structs with
       // reference or bitfield members, and a few other cases, and checking
@@ -789,17 +788,13 @@
         // If the variable's a const type, and it's neither an NRVO
         // candidate nor a __block variable and has no mutable members,
         // emit it as a global instead.
-        if (CGM.getCodeGenOpts().MergeAllConstants && Ty.isConstQualified() &&
-            !NRVO && !isByRef && Ty->isLiteralType()) {
-          CXXRecordDecl *RD =
-            Ty->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
-          if (!RD || !RD->hasMutableFields()) {
-            EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
-
-            emission.Address = 0; // signal this condition to later callbacks
-            assert(emission.wasEmittedAsGlobal());
-            return emission;
-          }
+        if (CGM.getCodeGenOpts().MergeAllConstants && !NRVO && !isByRef &&
+            CGM.isTypeConstant(Ty, true)) {
+          EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
+
+          emission.Address = 0; // signal this condition to later callbacks
+          assert(emission.wasEmittedAsGlobal());
+          return emission;
         }
 
         // Otherwise, tell the initialization code that we're in this case.
@@ -1098,6 +1093,7 @@
                                               AggValueSlot::IsDestructed,
                                          AggValueSlot::DoesNotNeedGCBarriers,
                                               AggValueSlot::IsNotAliased));
+    MaybeEmitStdInitializerListCleanup(lvalue, init);
   }
 }
 
@@ -1184,7 +1180,7 @@
     llvm::Constant *F = CGM.GetAddrOfFunction(FD);
     assert(F && "Could not find function!");
 
-    const CGFunctionInfo &Info = CGM.getTypes().getFunctionInfo(FD);
+    const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD);
     EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D);
   }
 
@@ -1525,7 +1521,7 @@
 
         if (lt == Qualifiers::OCL_Weak) {
           EmitARCInitWeak(DeclPtr, Arg);
-          doStore = false; // The weak init is a store, no need to do two
+          doStore = false; // The weak init is a store, no need to do two.
         }
       }
 

Modified: cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp Mon Feb 20 19:34:24 2012
@@ -101,6 +101,23 @@
   CGF.EmitCXXGlobalDtorRegistration(function, argument);
 }
 
+/// Emit code to cause the variable at the given address to be considered as
+/// constant from this point onwards.
+static void EmitDeclInvariant(CodeGenFunction &CGF, llvm::Constant *Addr) {
+  // Don't emit the intrinsic if we're not optimizing.
+  if (!CGF.CGM.getCodeGenOpts().OptimizationLevel)
+    return;
+
+  // Grab the llvm.invariant.start intrinsic.
+  llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
+  llvm::Constant *InvariantStart = CGF.CGM.getIntrinsic(InvStartID);
+
+  // Emit a call, with size -1 signifying the whole object.
+  llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(CGF.Int64Ty, -1),
+                           llvm::ConstantExpr::getBitCast(Addr, CGF.Int8PtrTy)};
+  CGF.Builder.CreateCall(InvariantStart, Args);
+}
+
 void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
                                                llvm::Constant *DeclPtr,
                                                bool PerformInit) {
@@ -111,7 +128,10 @@
   if (!T->isReferenceType()) {
     if (PerformInit)
       EmitDeclInit(*this, D, DeclPtr);
-    EmitDeclDestroy(*this, D, DeclPtr);
+    if (CGM.isTypeConstant(D.getType(), true))
+      EmitDeclInvariant(*this, DeclPtr);
+    else
+      EmitDeclDestroy(*this, D, DeclPtr);
     return;
   }
 
@@ -277,7 +297,7 @@
                                                  llvm::GlobalVariable *Addr,
                                                        bool PerformInit) {
   StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
-                getTypes().getNullaryFunctionInfo(),
+                getTypes().arrangeNullaryFunction(),
                 FunctionArgList(), SourceLocation());
 
   // Use guarded initialization if the global variable is weak. This
@@ -297,7 +317,7 @@
                                                 llvm::Constant **Decls,
                                                 unsigned NumDecls) {
   StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
-                getTypes().getNullaryFunctionInfo(),
+                getTypes().arrangeNullaryFunction(),
                 FunctionArgList(), SourceLocation());
 
   RunCleanupsScope Scope(*this);
@@ -322,7 +342,7 @@
                   const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
                                                 &DtorsAndObjects) {
   StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
-                getTypes().getNullaryFunctionInfo(),
+                getTypes().arrangeNullaryFunction(),
                 FunctionArgList(), SourceLocation());
 
   // Emit the dtors, in reverse order from construction.
@@ -350,9 +370,10 @@
   args.push_back(&dst);
   
   const CGFunctionInfo &FI = 
-    CGM.getTypes().getFunctionInfo(getContext().VoidTy, args, 
-                                   FunctionType::ExtInfo());
-  llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
+    CGM.getTypes().arrangeFunctionDeclaration(getContext().VoidTy, args,
+                                              FunctionType::ExtInfo(),
+                                              /*variadic*/ false);
+  llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
   llvm::Function *fn = 
     CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
 

Modified: cfe/branches/tooling/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGException.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGException.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGException.cpp Mon Feb 20 19:34:24 2012
@@ -1204,14 +1204,10 @@
     if (nextIsEnd) {
       CGF.Builder.restoreIP(savedIP);
       return;
-
-    // Otherwise we need to emit and continue at that block.
-    } else {
-      CGF.EmitBlock(nextBlock);
     }
+    // Otherwise we need to emit and continue at that block.
+    CGF.EmitBlock(nextBlock);
   }
-
-  llvm_unreachable("fell out of loop!");
 }
 
 void CodeGenFunction::popCatchScope() {

Modified: cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExpr.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExpr.cpp Mon Feb 20 19:34:24 2012
@@ -1181,11 +1181,9 @@
       // FIXME: since we're shuffling with undef, can we just use the indices
       //        into that?  This could be simpler.
       SmallVector<llvm::Constant*, 4> ExtMask;
-      unsigned i;
-      for (i = 0; i != NumSrcElts; ++i)
+      for (unsigned i = 0; i != NumSrcElts; ++i)
         ExtMask.push_back(Builder.getInt32(i));
-      for (; i != NumDstElts; ++i)
-        ExtMask.push_back(llvm::UndefValue::get(Int32Ty));
+      ExtMask.resize(NumDstElts, llvm::UndefValue::get(Int32Ty));
       llvm::Value *ExtMaskV = llvm::ConstantVector::get(ExtMask);
       llvm::Value *ExtSrcVal =
         Builder.CreateShuffleVector(SrcVal,
@@ -1467,9 +1465,10 @@
     assert(LV.isSimple() && "real/imag on non-ordinary l-value");
     llvm::Value *Addr = LV.getAddress();
 
-    // real and imag are valid on scalars.  This is a faster way of
-    // testing that.
-    if (!cast<llvm::PointerType>(Addr->getType())
+    // __real is valid on scalars.  This is a faster way of testing that.
+    // __imag can only produce an rvalue on scalars.
+    if (E->getOpcode() == UO_Real &&
+        !cast<llvm::PointerType>(Addr->getType())
            ->getElementType()->isStructTy()) {
       assert(E->getSubExpr()->getType()->isArithmeticType());
       return LV;
@@ -2092,6 +2091,7 @@
   case CK_DerivedToBaseMemberPointer:
   case CK_BaseToDerivedMemberPointer:
   case CK_MemberPointerToBoolean:
+  case CK_ReinterpretMemberPointer:
   case CK_AnyPointerToBlockPointerCast:
   case CK_ARCProduceObject:
   case CK_ARCConsumeObject:
@@ -2455,7 +2455,8 @@
   CallArgList Args;
   EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
 
-  const CGFunctionInfo &FnInfo = CGM.getTypes().getFunctionInfo(Args, FnType);
+  const CGFunctionInfo &FnInfo =
+    CGM.getTypes().arrangeFunctionCall(Args, FnType);
 
   // C99 6.5.2.2p6:
   //   If the expression that denotes the called function has a type
@@ -2474,11 +2475,8 @@
   // through an unprototyped function type works like a *non-variadic*
   // call.  The way we make this work is to cast to the exact type
   // of the promoted arguments.
-  if (isa<FunctionNoProtoType>(FnType) &&
-      !getTargetHooks().isNoProtoCallVariadic(FnInfo)) {
-    assert(cast<llvm::FunctionType>(Callee->getType()->getContainedType(0))
-             ->isVarArg());
-    llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo, false);
+  if (isa<FunctionNoProtoType>(FnType) && !FnInfo.isVariadic()) {
+    llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo);
     CalleeTy = CalleeTy->getPointerTo();
     Callee = Builder.CreateBitCast(Callee, CalleeTy, "callee.knr.cast");
   }
@@ -2679,7 +2677,8 @@
     Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)),
              getContext().getSizeType());
     const CGFunctionInfo &FuncInfo =
-        CGM.getTypes().getFunctionInfo(RetTy, Args, FunctionType::ExtInfo());
+        CGM.getTypes().arrangeFunctionCall(RetTy, Args, FunctionType::ExtInfo(),
+                                           /*variadic*/ false);
     llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo, false);
     llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
     RValue Res = EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);

Modified: cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp Mon Feb 20 19:34:24 2012
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/StmtVisitor.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
@@ -79,6 +80,10 @@
 
   void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
 
+  void EmitStdInitializerList(llvm::Value *DestPtr, InitListExpr *InitList);
+  void EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
+                     QualType elementType, InitListExpr *E);
+
   AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
     if (CGF.getLangOptions().getGC() && TypeRequiresGCollection(T))
       return AggValueSlot::NeedsGCBarriers;
@@ -271,6 +276,225 @@
   EmitFinalDestCopy(E, Src.asAggregateRValue(), Ignore, Alignment.getQuantity());
 }
 
+static QualType GetStdInitializerListElementType(QualType T) {
+  // Just assume that this is really std::initializer_list.
+  ClassTemplateSpecializationDecl *specialization =
+      cast<ClassTemplateSpecializationDecl>(T->castAs<RecordType>()->getDecl());
+  return specialization->getTemplateArgs()[0].getAsType();
+}
+
+/// \brief Prepare cleanup for the temporary array.
+static void EmitStdInitializerListCleanup(CodeGenFunction &CGF,
+                                          QualType arrayType,
+                                          llvm::Value *addr,
+                                          const InitListExpr *initList) {
+  QualType::DestructionKind dtorKind = arrayType.isDestructedType();
+  if (!dtorKind)
+    return; // Type doesn't need destroying.
+  if (dtorKind != QualType::DK_cxx_destructor) {
+    CGF.ErrorUnsupported(initList, "ObjC ARC type in initializer_list");
+    return;
+  }
+
+  CodeGenFunction::Destroyer *destroyer = CGF.getDestroyer(dtorKind);
+  CGF.pushDestroy(NormalAndEHCleanup, addr, arrayType, destroyer,
+                  /*EHCleanup=*/true);
+}
+
+/// \brief Emit the initializer for a std::initializer_list initialized with a
+/// real initializer list.
+void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr,
+                                            InitListExpr *initList) {
+  // We emit an array containing the elements, then have the init list point
+  // at the array.
+  ASTContext &ctx = CGF.getContext();
+  unsigned numInits = initList->getNumInits();
+  QualType element = GetStdInitializerListElementType(initList->getType());
+  llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits);
+  QualType array = ctx.getConstantArrayType(element, size, ArrayType::Normal,0);
+  llvm::Type *LTy = CGF.ConvertTypeForMem(array);
+  llvm::AllocaInst *alloc = CGF.CreateTempAlloca(LTy);
+  alloc->setAlignment(ctx.getTypeAlignInChars(array).getQuantity());
+  alloc->setName(".initlist.");
+
+  EmitArrayInit(alloc, cast<llvm::ArrayType>(LTy), element, initList);
+
+  // FIXME: The diagnostics are somewhat out of place here.
+  RecordDecl *record = initList->getType()->castAs<RecordType>()->getDecl();
+  RecordDecl::field_iterator field = record->field_begin();
+  if (field == record->field_end()) {
+    CGF.ErrorUnsupported(initList, "weird std::initializer_list");
+  }
+
+  QualType elementPtr = ctx.getPointerType(element.withConst());
+
+  // Start pointer.
+  if (!ctx.hasSameType(field->getType(), elementPtr)) {
+    CGF.ErrorUnsupported(initList, "weird std::initializer_list");
+  }
+  LValue start = CGF.EmitLValueForFieldInitialization(destPtr, *field, 0);
+  llvm::Value *arrayStart = Builder.CreateStructGEP(alloc, 0, "arraystart");
+  CGF.EmitStoreThroughLValue(RValue::get(arrayStart), start);
+  ++field;
+
+  if (field == record->field_end()) {
+    CGF.ErrorUnsupported(initList, "weird std::initializer_list");
+  }
+  LValue endOrLength = CGF.EmitLValueForFieldInitialization(destPtr, *field, 0);
+  if (ctx.hasSameType(field->getType(), elementPtr)) {
+    // End pointer.
+    llvm::Value *arrayEnd = Builder.CreateStructGEP(alloc,numInits, "arrayend");
+    CGF.EmitStoreThroughLValue(RValue::get(arrayEnd), endOrLength);
+  } else if(ctx.hasSameType(field->getType(), ctx.getSizeType())) {
+    // Length.
+    CGF.EmitStoreThroughLValue(RValue::get(Builder.getInt(size)), endOrLength);
+  } else {
+    CGF.ErrorUnsupported(initList, "weird std::initializer_list");
+  }
+
+  if (!Dest.isExternallyDestructed())
+    EmitStdInitializerListCleanup(CGF, array, alloc, initList);
+}
+
+/// \brief Emit initialization of an array from an initializer list.
+void AggExprEmitter::EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
+                                   QualType elementType, InitListExpr *E) {
+  uint64_t NumInitElements = E->getNumInits();
+
+  uint64_t NumArrayElements = AType->getNumElements();
+  assert(NumInitElements <= NumArrayElements);
+
+  // DestPtr is an array*.  Construct an elementType* by drilling
+  // down a level.
+  llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
+  llvm::Value *indices[] = { zero, zero };
+  llvm::Value *begin =
+    Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin");
+
+  // Exception safety requires us to destroy all the
+  // already-constructed members if an initializer throws.
+  // For that, we'll need an EH cleanup.
+  QualType::DestructionKind dtorKind = elementType.isDestructedType();
+  llvm::AllocaInst *endOfInit = 0;
+  EHScopeStack::stable_iterator cleanup;
+  llvm::Instruction *cleanupDominator = 0;
+  if (CGF.needsEHCleanup(dtorKind)) {
+    // In principle we could tell the cleanup where we are more
+    // directly, but the control flow can get so varied here that it
+    // would actually be quite complex.  Therefore we go through an
+    // alloca.
+    endOfInit = CGF.CreateTempAlloca(begin->getType(),
+                                     "arrayinit.endOfInit");
+    cleanupDominator = Builder.CreateStore(begin, endOfInit);
+    CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
+                                         CGF.getDestroyer(dtorKind));
+    cleanup = CGF.EHStack.stable_begin();
+
+  // Otherwise, remember that we didn't need a cleanup.
+  } else {
+    dtorKind = QualType::DK_none;
+  }
+
+  llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
+
+  // The 'current element to initialize'.  The invariants on this
+  // variable are complicated.  Essentially, after each iteration of
+  // the loop, it points to the last initialized element, except
+  // that it points to the beginning of the array before any
+  // elements have been initialized.
+  llvm::Value *element = begin;
+
+  // Emit the explicit initializers.
+  for (uint64_t i = 0; i != NumInitElements; ++i) {
+    // Advance to the next element.
+    if (i > 0) {
+      element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");
+
+      // Tell the cleanup that it needs to destroy up to this
+      // element.  TODO: some of these stores can be trivially
+      // observed to be unnecessary.
+      if (endOfInit) Builder.CreateStore(element, endOfInit);
+    }
+
+    // If these are nested std::initializer_list inits, do them directly,
+    // because they are conceptually the same "location".
+    InitListExpr *initList = dyn_cast<InitListExpr>(E->getInit(i));
+    if (initList && initList->initializesStdInitializerList()) {
+      EmitStdInitializerList(element, initList);
+    } else {
+      LValue elementLV = CGF.MakeAddrLValue(element, elementType);
+      EmitInitializationToLValue(E->getInit(i), elementLV);
+    }
+  }
+
+  // Check whether there's a non-trivial array-fill expression.
+  // Note that this will be a CXXConstructExpr even if the element
+  // type is an array (or array of array, etc.) of class type.
+  Expr *filler = E->getArrayFiller();
+  bool hasTrivialFiller = true;
+  if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
+    assert(cons->getConstructor()->isDefaultConstructor());
+    hasTrivialFiller = cons->getConstructor()->isTrivial();
+  }
+
+  // Any remaining elements need to be zero-initialized, possibly
+  // using the filler expression.  We can skip this if the we're
+  // emitting to zeroed memory.
+  if (NumInitElements != NumArrayElements &&
+      !(Dest.isZeroed() && hasTrivialFiller &&
+        CGF.getTypes().isZeroInitializable(elementType))) {
+
+    // Use an actual loop.  This is basically
+    //   do { *array++ = filler; } while (array != end);
+
+    // Advance to the start of the rest of the array.
+    if (NumInitElements) {
+      element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start");
+      if (endOfInit) Builder.CreateStore(element, endOfInit);
+    }
+
+    // Compute the end of the array.
+    llvm::Value *end = Builder.CreateInBoundsGEP(begin,
+                      llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
+                                                 "arrayinit.end");
+
+    llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
+    llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
+
+    // Jump into the body.
+    CGF.EmitBlock(bodyBB);
+    llvm::PHINode *currentElement =
+      Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");
+    currentElement->addIncoming(element, entryBB);
+
+    // Emit the actual filler expression.
+    LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
+    if (filler)
+      EmitInitializationToLValue(filler, elementLV);
+    else
+      EmitNullInitializationToLValue(elementLV);
+
+    // Move on to the next element.
+    llvm::Value *nextElement =
+      Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next");
+
+    // Tell the EH cleanup that we finished with the last element.
+    if (endOfInit) Builder.CreateStore(nextElement, endOfInit);
+
+    // Leave the loop if we're done.
+    llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
+                                             "arrayinit.done");
+    llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
+    Builder.CreateCondBr(done, endBB, bodyBB);
+    currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
+
+    CGF.EmitBlock(endBB);
+  }
+
+  // Leave the partial-array cleanup if we entered one.
+  if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
+}
+
 //===----------------------------------------------------------------------===//
 //                            Visitor Methods
 //===----------------------------------------------------------------------===//
@@ -360,6 +584,7 @@
   case CK_BaseToDerivedMemberPointer:
   case CK_DerivedToBaseMemberPointer:
   case CK_MemberPointerToBoolean:
+  case CK_ReinterpretMemberPointer:
   case CK_IntegralToPointer:
   case CK_PointerToIntegral:
   case CK_PointerToBoolean:
@@ -656,17 +881,15 @@
   if (E->hadArrayRangeDesignator())
     CGF.ErrorUnsupported(E, "GNU array range designator extension");
 
+  if (E->initializesStdInitializerList()) {
+    EmitStdInitializerList(Dest.getAddr(), E);
+    return;
+  }
+
   llvm::Value *DestPtr = Dest.getAddr();
 
   // Handle initialization of an array.
   if (E->getType()->isArrayType()) {
-    llvm::PointerType *APType =
-      cast<llvm::PointerType>(DestPtr->getType());
-    llvm::ArrayType *AType =
-      cast<llvm::ArrayType>(APType->getElementType());
-
-    uint64_t NumInitElements = E->getNumInits();
-
     if (E->getNumInits() > 0) {
       QualType T1 = E->getType();
       QualType T2 = E->getInit(0)->getType();
@@ -676,137 +899,17 @@
       }
     }
 
-    uint64_t NumArrayElements = AType->getNumElements();
-    assert(NumInitElements <= NumArrayElements);
-
     QualType elementType = E->getType().getCanonicalType();
     elementType = CGF.getContext().getQualifiedType(
                     cast<ArrayType>(elementType)->getElementType(),
                     elementType.getQualifiers() + Dest.getQualifiers());
 
-    // DestPtr is an array*.  Construct an elementType* by drilling
-    // down a level.
-    llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
-    llvm::Value *indices[] = { zero, zero };
-    llvm::Value *begin =
-      Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin");
-
-    // Exception safety requires us to destroy all the
-    // already-constructed members if an initializer throws.
-    // For that, we'll need an EH cleanup.
-    QualType::DestructionKind dtorKind = elementType.isDestructedType();
-    llvm::AllocaInst *endOfInit = 0;
-    EHScopeStack::stable_iterator cleanup;
-    llvm::Instruction *cleanupDominator = 0;
-    if (CGF.needsEHCleanup(dtorKind)) {
-      // In principle we could tell the cleanup where we are more
-      // directly, but the control flow can get so varied here that it
-      // would actually be quite complex.  Therefore we go through an
-      // alloca.
-      endOfInit = CGF.CreateTempAlloca(begin->getType(),
-                                       "arrayinit.endOfInit");
-      cleanupDominator = Builder.CreateStore(begin, endOfInit);
-      CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
-                                           CGF.getDestroyer(dtorKind));
-      cleanup = CGF.EHStack.stable_begin();
-
-    // Otherwise, remember that we didn't need a cleanup.
-    } else {
-      dtorKind = QualType::DK_none;
-    }
-
-    llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
-
-    // The 'current element to initialize'.  The invariants on this
-    // variable are complicated.  Essentially, after each iteration of
-    // the loop, it points to the last initialized element, except
-    // that it points to the beginning of the array before any
-    // elements have been initialized.
-    llvm::Value *element = begin;
-
-    // Emit the explicit initializers.
-    for (uint64_t i = 0; i != NumInitElements; ++i) {
-      // Advance to the next element.
-      if (i > 0) {
-        element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");
-
-        // Tell the cleanup that it needs to destroy up to this
-        // element.  TODO: some of these stores can be trivially
-        // observed to be unnecessary.
-        if (endOfInit) Builder.CreateStore(element, endOfInit);
-      }
-
-      LValue elementLV = CGF.MakeAddrLValue(element, elementType);
-      EmitInitializationToLValue(E->getInit(i), elementLV);
-    }
-
-    // Check whether there's a non-trivial array-fill expression.
-    // Note that this will be a CXXConstructExpr even if the element
-    // type is an array (or array of array, etc.) of class type.
-    Expr *filler = E->getArrayFiller();
-    bool hasTrivialFiller = true;
-    if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
-      assert(cons->getConstructor()->isDefaultConstructor());
-      hasTrivialFiller = cons->getConstructor()->isTrivial();
-    }
-
-    // Any remaining elements need to be zero-initialized, possibly
-    // using the filler expression.  We can skip this if the we're
-    // emitting to zeroed memory.
-    if (NumInitElements != NumArrayElements &&
-        !(Dest.isZeroed() && hasTrivialFiller &&
-          CGF.getTypes().isZeroInitializable(elementType))) {
-
-      // Use an actual loop.  This is basically
-      //   do { *array++ = filler; } while (array != end);
-
-      // Advance to the start of the rest of the array.
-      if (NumInitElements) {
-        element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start");
-        if (endOfInit) Builder.CreateStore(element, endOfInit);
-      }
-
-      // Compute the end of the array.
-      llvm::Value *end = Builder.CreateInBoundsGEP(begin,
-                        llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
-                                                   "arrayinit.end");
-
-      llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
-      llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
-
-      // Jump into the body.
-      CGF.EmitBlock(bodyBB);
-      llvm::PHINode *currentElement =
-        Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");
-      currentElement->addIncoming(element, entryBB);
-
-      // Emit the actual filler expression.
-      LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
-      if (filler)
-        EmitInitializationToLValue(filler, elementLV);
-      else
-        EmitNullInitializationToLValue(elementLV);
-
-      // Move on to the next element.
-      llvm::Value *nextElement =
-        Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next");
-
-      // Tell the EH cleanup that we finished with the last element.
-      if (endOfInit) Builder.CreateStore(nextElement, endOfInit);
-
-      // Leave the loop if we're done.
-      llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
-                                               "arrayinit.done");
-      llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
-      Builder.CreateCondBr(done, endBB, bodyBB);
-      currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
-
-      CGF.EmitBlock(endBB);
-    }
-
-    // Leave the partial-array cleanup if we entered one.
-    if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
+    llvm::PointerType *APType =
+      cast<llvm::PointerType>(DestPtr->getType());
+    llvm::ArrayType *AType =
+      cast<llvm::ArrayType>(APType->getElementType());
 
+    EmitArrayInit(DestPtr, AType, elementType, E);
     return;
   }
 
@@ -1159,3 +1262,60 @@
                                               TypeInfo.first.getQuantity()),
                        Alignment, isVolatile);
 }
+
+void CodeGenFunction::MaybeEmitStdInitializerListCleanup(LValue lvalue,
+                                                    const Expr *init) {
+  const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(init);
+  if (!cleanups)
+    return; // Nothing interesting here.
+  init = cleanups->getSubExpr();
+
+  if (isa<InitListExpr>(init) &&
+      cast<InitListExpr>(init)->initializesStdInitializerList()) {
+    // We initialized this std::initializer_list with an initializer list.
+    // A backing array was created. Push a cleanup for it.
+    EmitStdInitializerListCleanup(lvalue.getAddress(),
+                                  cast<InitListExpr>(init));
+  }
+}
+
+static void EmitRecursiveStdInitializerListCleanup(CodeGenFunction &CGF,
+                                                   llvm::Value *arrayStart,
+                                                   const InitListExpr *init) {
+  // Check if there are any recursive cleanups to do, i.e. if we have
+  //   std::initializer_list<std::initializer_list<obj>> list = {{obj()}};
+  // then we need to destroy the inner array as well.
+  for (unsigned i = 0, e = init->getNumInits(); i != e; ++i) {
+    const InitListExpr *subInit = dyn_cast<InitListExpr>(init->getInit(i));
+    if (!subInit || !subInit->initializesStdInitializerList())
+      continue;
+
+    // This one needs to be destroyed. Get the address of the std::init_list.
+    llvm::Value *offset = llvm::ConstantInt::get(CGF.SizeTy, i);
+    llvm::Value *loc = CGF.Builder.CreateInBoundsGEP(arrayStart, offset,
+                                                 "std.initlist");
+    CGF.EmitStdInitializerListCleanup(loc, subInit);
+  }
+}
+
+void CodeGenFunction::EmitStdInitializerListCleanup(llvm::Value *loc,
+                                                    const InitListExpr *init) {
+  ASTContext &ctx = getContext();
+  QualType element = GetStdInitializerListElementType(init->getType());
+  unsigned numInits = init->getNumInits();
+  llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits);
+  QualType array =ctx.getConstantArrayType(element, size, ArrayType::Normal, 0);
+  QualType arrayPtr = ctx.getPointerType(array);
+  llvm::Type *arrayPtrType = ConvertType(arrayPtr);
+
+  // lvalue is the location of a std::initializer_list, which as its first
+  // element has a pointer to the array we want to destroy.
+  llvm::Value *startPointer = Builder.CreateStructGEP(loc, 0, "startPointer");
+  llvm::Value *startAddress = Builder.CreateLoad(startPointer, "startAddress");
+
+  ::EmitRecursiveStdInitializerListCleanup(*this, startAddress, init);
+
+  llvm::Value *arrayAddress =
+      Builder.CreateBitCast(startAddress, arrayPtrType, "arrayAddress");
+  ::EmitStdInitializerListCleanup(*this, array, arrayAddress, init);
+}

Modified: cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp Mon Feb 20 19:34:24 2012
@@ -33,8 +33,6 @@
   assert(MD->isInstance() &&
          "Trying to emit a member call expr on a static method!");
 
-  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
-
   CallArgList Args;
 
   // Push the this ptr.
@@ -45,13 +43,16 @@
     QualType T = getContext().getPointerType(getContext().VoidPtrTy);
     Args.add(RValue::get(VTT), T);
   }
+
+  const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
+  RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size());
   
-  // And the rest of the call args
+  // And the rest of the call args.
   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
 
-  QualType ResultType = FPT->getResultType();
-  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args,
-                                                 FPT->getExtInfo()),
+  return EmitCall(CGM.getTypes().arrangeFunctionCall(FPT->getResultType(), Args,
+                                                     FPT->getExtInfo(),
+                                                     required),
                   Callee, ReturnValue, Args, MD);
 }
 
@@ -229,17 +230,16 @@
   // Compute the function type we're calling.
   const CGFunctionInfo *FInfo = 0;
   if (isa<CXXDestructorDecl>(MD))
-    FInfo = &CGM.getTypes().getFunctionInfo(cast<CXXDestructorDecl>(MD),
-                                           Dtor_Complete);
+    FInfo = &CGM.getTypes().arrangeCXXDestructor(cast<CXXDestructorDecl>(MD),
+                                                 Dtor_Complete);
   else if (isa<CXXConstructorDecl>(MD))
-    FInfo = &CGM.getTypes().getFunctionInfo(cast<CXXConstructorDecl>(MD),
-                                            Ctor_Complete);
+    FInfo = &CGM.getTypes().arrangeCXXConstructorDeclaration(
+                                                 cast<CXXConstructorDecl>(MD),
+                                                 Ctor_Complete);
   else
-    FInfo = &CGM.getTypes().getFunctionInfo(MD);
+    FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(MD);
 
-  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
-  llvm::Type *Ty
-    = CGM.getTypes().GetFunctionType(*FInfo, FPT->isVariadic());
+  llvm::Type *Ty = CGM.getTypes().GetFunctionType(*FInfo);
 
   // C++ [class.virtual]p12:
   //   Explicit qualification with the scope operator (5.1) suppresses the
@@ -322,7 +322,7 @@
   
   // And the rest of the call args
   EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end());
-  return EmitCall(CGM.getTypes().getFunctionInfo(Args, FPT), Callee, 
+  return EmitCall(CGM.getTypes().arrangeFunctionCall(Args, FPT), Callee, 
                   ReturnValue, Args);
 }
 
@@ -743,11 +743,8 @@
 
 static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,
                                     llvm::Value *NewPtr) {
-  
-  assert(E->getNumConstructorArgs() == 1 &&
-         "Can only have one argument to initializer of POD type.");
-  
-  const Expr *Init = E->getConstructorArg(0);
+
+  const Expr *Init = E->getInitializer();
   QualType AllocType = E->getAllocatedType();
 
   CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);
@@ -773,9 +770,8 @@
                                          QualType elementType,
                                          llvm::Value *beginPtr,
                                          llvm::Value *numElements) {
-  // We have a POD type.
-  if (E->getNumConstructorArgs() == 0)
-    return;
+  if (!E->hasInitializer())
+    return; // We have a POD type.
 
   // Check if the number of elements is constant.
   bool checkZero = true;
@@ -858,13 +854,15 @@
                                llvm::Value *NewPtr,
                                llvm::Value *NumElements,
                                llvm::Value *AllocSizeWithoutCookie) {
+  const Expr *Init = E->getInitializer();
   if (E->isArray()) {
-    if (CXXConstructorDecl *Ctor = E->getConstructor()) {
+    if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){
+      CXXConstructorDecl *Ctor = CCE->getConstructor();
       bool RequiresZeroInitialization = false;
       if (Ctor->getParent()->hasTrivialDefaultConstructor()) {
         // If new expression did not specify value-initialization, then there
         // is no initialization.
-        if (!E->hasInitializer() || Ctor->getParent()->isEmpty())
+        if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
           return;
       
         if (CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
@@ -877,43 +875,24 @@
         RequiresZeroInitialization = true;
       }
 
-      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr, 
-                                     E->constructor_arg_begin(), 
-                                     E->constructor_arg_end(),
+      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
+                                     CCE->arg_begin(),  CCE->arg_end(),
                                      RequiresZeroInitialization);
       return;
-    } else if (E->getNumConstructorArgs() == 1 &&
-               isa<ImplicitValueInitExpr>(E->getConstructorArg(0)) &&
+    } else if (Init && isa<ImplicitValueInitExpr>(Init) &&
                CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
       // Optimization: since zero initialization will just set the memory
       // to all zeroes, generate a single memset to do it in one shot.
       EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
       return;
-    } else {
-      CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
-      return;
     }
-  }
-
-  if (CXXConstructorDecl *Ctor = E->getConstructor()) {
-    // Per C++ [expr.new]p15, if we have an initializer, then we're performing
-    // direct initialization. C++ [dcl.init]p5 requires that we 
-    // zero-initialize storage if there are no user-declared constructors.
-    if (E->hasInitializer() && 
-        !Ctor->getParent()->hasUserDeclaredConstructor() &&
-        !Ctor->getParent()->isEmpty())
-      CGF.EmitNullInitialization(NewPtr, ElementType);
-      
-    CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false, 
-                               NewPtr, E->constructor_arg_begin(),
-                               E->constructor_arg_end());
-
+    CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
     return;
   }
-  // We have a POD type.
-  if (E->getNumConstructorArgs() == 0)
+
+  if (!Init)
     return;
-  
+
   StoreAnyExprIntoOneUnit(CGF, E, NewPtr);
 }
 
@@ -966,7 +945,7 @@
         DeleteArgs.add(getPlacementArgs()[I], *AI++);
 
       // Call 'operator delete'.
-      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(DeleteArgs, FPT),
+      CGF.EmitCall(CGF.CGM.getTypes().arrangeFunctionCall(DeleteArgs, FPT),
                    CGF.CGM.GetAddrOfFunction(OperatorDelete),
                    ReturnValueSlot(), DeleteArgs, OperatorDelete);
     }
@@ -1027,7 +1006,7 @@
       }
 
       // Call 'operator delete'.
-      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(DeleteArgs, FPT),
+      CGF.EmitCall(CGF.CGM.getTypes().arrangeFunctionCall(DeleteArgs, FPT),
                    CGF.CGM.GetAddrOfFunction(OperatorDelete),
                    ReturnValueSlot(), DeleteArgs, OperatorDelete);
     }
@@ -1134,7 +1113,8 @@
     // TODO: kill any unnecessary computations done for the size
     // argument.
   } else {
-    RV = EmitCall(CGM.getTypes().getFunctionInfo(allocatorArgs, allocatorType),
+    RV = EmitCall(CGM.getTypes().arrangeFunctionCall(allocatorArgs,
+                                                     allocatorType),
                   CGM.GetAddrOfFunction(allocator), ReturnValueSlot(),
                   allocatorArgs, allocator);
   }
@@ -1145,7 +1125,7 @@
   // CXXNewExpr::shouldNullCheckAllocation()) and we have an
   // interesting initializer.
   bool nullCheck = allocatorType->isNothrow(getContext()) &&
-    !(allocType.isPODType(getContext()) && !E->hasInitializer());
+    (!allocType.isPODType(getContext()) || E->hasInitializer());
 
   llvm::BasicBlock *nullCheckBB = 0;
   llvm::BasicBlock *contBB = 0;
@@ -1211,7 +1191,7 @@
     DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
     cleanupDominator->eraseFromParent();
   }
-  
+
   if (nullCheck) {
     conditional.end(*this);
 
@@ -1257,7 +1237,7 @@
     DeleteArgs.add(RValue::get(Size), SizeTy);
 
   // Emit the call to delete.
-  EmitCall(CGM.getTypes().getFunctionInfo(DeleteArgs, DeleteFTy),
+  EmitCall(CGM.getTypes().arrangeFunctionCall(DeleteArgs, DeleteFTy),
            CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(), 
            DeleteArgs, DeleteFD);
 }
@@ -1304,9 +1284,8 @@
         }
         
         llvm::Type *Ty =
-          CGF.getTypes().GetFunctionType(CGF.getTypes().getFunctionInfo(Dtor,
-                                                               Dtor_Complete),
-                                         /*isVariadic=*/false);
+          CGF.getTypes().GetFunctionType(
+                         CGF.getTypes().arrangeCXXDestructor(Dtor, Dtor_Complete));
           
         llvm::Value *Callee
           = CGF.BuildVirtualCall(Dtor, 
@@ -1414,7 +1393,7 @@
       }
 
       // Emit the call to delete.
-      CGF.EmitCall(CGF.getTypes().getFunctionInfo(Args, DeleteFTy),
+      CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(Args, DeleteFTy),
                    CGF.CGM.GetAddrOfFunction(OperatorDelete),
                    ReturnValueSlot(), Args, OperatorDelete);
     }

Modified: cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp Mon Feb 20 19:34:24 2012
@@ -388,6 +388,7 @@
   case CK_BaseToDerivedMemberPointer:
   case CK_DerivedToBaseMemberPointer:
   case CK_MemberPointerToBoolean:
+  case CK_ReinterpretMemberPointer:
   case CK_ConstructorConversion:
   case CK_IntegralToPointer:
   case CK_PointerToIntegral:

Modified: cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp Mon Feb 20 19:34:24 2012
@@ -620,6 +620,11 @@
 
     case CK_Dependent: llvm_unreachable("saw dependent cast!");
 
+    case CK_ReinterpretMemberPointer:
+    case CK_DerivedToBaseMemberPointer:
+    case CK_BaseToDerivedMemberPointer:
+      return CGM.getCXXABI().EmitMemberPointerConversion(E, C);
+
     // These will never be supported.
     case CK_ObjCObjectLValueCast:
     case CK_ARCProduceObject:
@@ -630,18 +635,16 @@
 
     // These don't need to be handled here because Evaluate knows how to
     // evaluate them in the cases where they can be folded.
+    case CK_BitCast:
     case CK_ToVoid:
     case CK_Dynamic:
     case CK_LValueBitCast:
     case CK_NullToMemberPointer:
-    case CK_DerivedToBaseMemberPointer:
-    case CK_BaseToDerivedMemberPointer:
     case CK_UserDefinedConversion:
     case CK_ConstructorConversion:
     case CK_CPointerToObjCPointerCast:
     case CK_BlockPointerToObjCPointerCast:
     case CK_AnyPointerToBlockPointerCast:
-    case CK_BitCast:
     case CK_ArrayToPointerDecay:
     case CK_FunctionToPointerDecay:
     case CK_BaseToDerived:
@@ -701,9 +704,9 @@
     // Copy initializer elements.
     std::vector<llvm::Constant*> Elts;
     Elts.reserve(NumInitableElts + NumElements);
-    unsigned i = 0;
+
     bool RewriteType = false;
-    for (; i < NumInitableElts; ++i) {
+    for (unsigned i = 0; i < NumInitableElts; ++i) {
       Expr *Init = ILE->getInit(i);
       llvm::Constant *C = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
       if (!C)
@@ -722,8 +725,7 @@
     if (!fillC)
       return 0;
     RewriteType |= (fillC->getType() != ElemTy);
-    for (; i < NumElements; ++i)
-      Elts.push_back(fillC);
+    Elts.resize(NumElements, fillC);
 
     if (RewriteType) {
       // FIXME: Try to avoid packing the array

Modified: cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp Mon Feb 20 19:34:24 2012
@@ -895,8 +895,7 @@
           if (CurIdx == 0) {
             // insert into undef -> shuffle (src, undef)
             Args.push_back(C);
-            for (unsigned j = 1; j != ResElts; ++j)
-              Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
+            Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
 
             LHS = EI->getVectorOperand();
             RHS = V;
@@ -907,9 +906,8 @@
             for (unsigned j = 0; j != CurIdx; ++j)
               Args.push_back(getMaskElt(SVV, j, 0, CGF.Int32Ty));
             Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
-            for (unsigned j = CurIdx + 1; j != ResElts; ++j)
-              Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
-            
+            Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
+
             LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
             RHS = EI->getVectorOperand();
             VIsUndefShuffle = false;
@@ -953,8 +951,7 @@
         }
         for (unsigned j = 0, je = InitElts; j != je; ++j)
           Args.push_back(getMaskElt(SVI, j, Offset, CGF.Int32Ty));
-        for (unsigned j = CurIdx + InitElts; j != ResElts; ++j)
-          Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
+        Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
 
         if (VIsUndefShuffle)
           V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
@@ -968,8 +965,7 @@
     if (Args.empty()) {
       for (unsigned j = 0; j != InitElts; ++j)
         Args.push_back(Builder.getInt32(j));
-      for (unsigned j = InitElts; j != ResElts; ++j)
-        Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
+      Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
       llvm::Constant *Mask = llvm::ConstantVector::get(Args);
       Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
                                          Mask, "vext");
@@ -979,8 +975,7 @@
         Args.push_back(Builder.getInt32(j));
       for (unsigned j = 0; j != InitElts; ++j)
         Args.push_back(Builder.getInt32(j+Offset));
-      for (unsigned j = CurIdx + InitElts; j != ResElts; ++j)
-        Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
+      Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
     }
 
     // If V is undef, make sure it ends up on the RHS of the shuffle to aid
@@ -1127,6 +1122,7 @@
     return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
   }
 
+  case CK_ReinterpretMemberPointer:
   case CK_BaseToDerivedMemberPointer:
   case CK_DerivedToBaseMemberPointer: {
     Value *Src = Visit(E);
@@ -1646,7 +1642,10 @@
 
   // __imag on a scalar returns zero.  Emit the subexpr to ensure side
   // effects are evaluated, but not the actual value.
-  CGF.EmitScalarExpr(Op, true);
+  if (Op->isGLValue())
+    CGF.EmitLValue(Op);
+  else
+    CGF.EmitScalarExpr(Op, true);
   return llvm::Constant::getNullValue(ConvertType(E->getType()));
 }
 

Modified: cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjC.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjC.cpp Mon Feb 20 19:34:24 2012
@@ -307,7 +307,7 @@
 
   llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
 
-  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
   CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
 
   args.push_back(OMD->getSelfDecl());
@@ -369,8 +369,9 @@
   args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
 
   llvm::Value *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
-  CGF.EmitCall(CGF.getTypes().getFunctionInfo(Context.VoidTy, args,
-                                              FunctionType::ExtInfo()),
+  CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(Context.VoidTy, args,
+                                                  FunctionType::ExtInfo(),
+                                                  RequiredArgs::All),
                fn, ReturnValueSlot(), args);
 }
 
@@ -624,8 +625,9 @@
   
   llvm::Value *copyCppAtomicObjectFn = 
   CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
-  CGF.EmitCall(CGF.getTypes().getFunctionInfo(CGF.getContext().VoidTy, args,
-                                              FunctionType::ExtInfo()),
+  CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(CGF.getContext().VoidTy, args,
+                                                  FunctionType::ExtInfo(),
+                                                  RequiredArgs::All),
                copyCppAtomicObjectFn, ReturnValueSlot(), args);
 }
 
@@ -710,8 +712,9 @@
 
     // FIXME: We shouldn't need to get the function info here, the
     // runtime already should have computed it to build the function.
-    RValue RV = EmitCall(getTypes().getFunctionInfo(propType, args,
-                                                    FunctionType::ExtInfo()),
+    RValue RV = EmitCall(getTypes().arrangeFunctionCall(propType, args,
+                                                        FunctionType::ExtInfo(),
+                                                        RequiredArgs::All),
                          getPropertyFn, ReturnValueSlot(), args);
 
     // We need to fix the type here. Ivars with copy & retain are
@@ -811,8 +814,9 @@
   args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
 
   llvm::Value *copyStructFn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
-  CGF.EmitCall(CGF.getTypes().getFunctionInfo(CGF.getContext().VoidTy, args,
-                                              FunctionType::ExtInfo()),
+  CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(CGF.getContext().VoidTy, args,
+                                                  FunctionType::ExtInfo(),
+                                                  RequiredArgs::All),
                copyStructFn, ReturnValueSlot(), args);
 }
 
@@ -847,8 +851,9 @@
   
   llvm::Value *copyCppAtomicObjectFn = 
     CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
-  CGF.EmitCall(CGF.getTypes().getFunctionInfo(CGF.getContext().VoidTy, args,
-                                              FunctionType::ExtInfo()),
+  CGF.EmitCall(CGF.getTypes().arrangeFunctionCall(CGF.getContext().VoidTy, args,
+                                                  FunctionType::ExtInfo(),
+                                                  RequiredArgs::All),
                copyCppAtomicObjectFn, ReturnValueSlot(), args);
   
 
@@ -961,8 +966,9 @@
              getContext().BoolTy);
     // FIXME: We shouldn't need to get the function info here, the runtime
     // already should have computed it to build the function.
-    EmitCall(getTypes().getFunctionInfo(getContext().VoidTy, args,
-                                        FunctionType::ExtInfo()),
+    EmitCall(getTypes().arrangeFunctionCall(getContext().VoidTy, args,
+                                            FunctionType::ExtInfo(),
+                                            RequiredArgs::All),
              setPropertyFn, ReturnValueSlot(), args);
     return;
   }
@@ -1321,8 +1327,9 @@
   Args2.add(RValue::get(V), getContext().getObjCIdType());
   // FIXME: We shouldn't need to get the function info here, the runtime already
   // should have computed it to build the function.
-  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
-                                          FunctionType::ExtInfo()),
+  EmitCall(CGM.getTypes().arrangeFunctionCall(getContext().VoidTy, Args2,
+                                              FunctionType::ExtInfo(),
+                                              RequiredArgs::All),
            EnumerationMutationFn, ReturnValueSlot(), Args2);
 
   // Otherwise, or if the mutation function returns, just continue.
@@ -2556,7 +2563,7 @@
 void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
   // We just use an inline assembly.
   llvm::FunctionType *extenderType
-    = llvm::FunctionType::get(VoidTy, VoidPtrTy, /*variadic*/ false);
+    = llvm::FunctionType::get(VoidTy, VoidPtrTy, RequiredArgs::All);
   llvm::Value *extender
     = llvm::InlineAsm::get(extenderType,
                            /* assembly */ "",
@@ -2614,9 +2621,11 @@
   args.push_back(&srcDecl);
   
   const CGFunctionInfo &FI =
-    CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo());
+    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
+                                              FunctionType::ExtInfo(),
+                                              RequiredArgs::All);
   
-  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
   
   llvm::Function *Fn =
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
@@ -2702,9 +2711,11 @@
   args.push_back(&srcDecl);
   
   const CGFunctionInfo &FI =
-  CGM.getTypes().getFunctionInfo(C.VoidTy, args, FunctionType::ExtInfo());
+  CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
+                                            FunctionType::ExtInfo(),
+                                            RequiredArgs::All);
   
-  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI, false);
+  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
   
   llvm::Function *Fn =
   llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,

Modified: cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp Mon Feb 20 19:34:24 2012
@@ -103,8 +103,6 @@
 /// GNUstep).
 class CGObjCGNU : public CGObjCRuntime {
 protected:
-  /// The module that is using this class
-  CodeGenModule &CGM;
   /// The LLVM module into which output is inserted
   llvm::Module &TheModule;
   /// strut objc_super.  Used for sending messages to super.  This structure
@@ -688,9 +686,9 @@
 
 CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
     unsigned protocolClassVersion)
-  : CGM(cgm), TheModule(CGM.getModule()), VMContext(cgm.getLLVMContext()),
-  ClassPtrAlias(0), MetaClassPtrAlias(0), RuntimeVersion(runtimeABIVersion),
-  ProtocolVersion(protocolClassVersion) {
+  : CGObjCRuntime(cgm), TheModule(CGM.getModule()),
+    VMContext(cgm.getLLVMContext()), ClassPtrAlias(0), MetaClassPtrAlias(0),
+    RuntimeVersion(runtimeABIVersion), ProtocolVersion(protocolClassVersion) {
 
   msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
 
@@ -1037,9 +1035,7 @@
   ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType());
   ActualArgs.addFrom(CallArgs);
 
-  CodeGenTypes &Types = CGM.getTypes();
-  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
-                                                       FunctionType::ExtInfo());
+  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
 
   llvm::Value *ReceiverClass = 0;
   if (isCategoryImpl) {
@@ -1092,12 +1088,10 @@
   Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
 
   ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
-  llvm::FunctionType *impType =
-    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
 
   // Get the IMP
   llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd);
-  imp = EnforceType(Builder, imp, llvm::PointerType::getUnqual(impType));
+  imp = EnforceType(Builder, imp, MSI.MessengerType);
 
   llvm::Value *impMD[] = {
       llvm::MDString::get(VMContext, Sel.getAsString()),
@@ -1107,8 +1101,7 @@
   llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
 
   llvm::Instruction *call;
-  RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
-      0, &call);
+  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, 0, &call);
   call->setMetadata(msgSendMDKind, node);
   return msgRet;
 }
@@ -1181,13 +1174,13 @@
    };
   llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
 
-  CodeGenTypes &Types = CGM.getTypes();
   CallArgList ActualArgs;
   ActualArgs.add(RValue::get(Receiver), ASTIdTy);
   ActualArgs.add(RValue::get(cmd), CGF.getContext().getObjCSelType());
   ActualArgs.addFrom(CallArgs);
-  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
-                                                       FunctionType::ExtInfo());
+
+  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
+
   // Get the IMP to call
   llvm::Value *imp;
 
@@ -1203,7 +1196,7 @@
       if (CGM.ReturnTypeUsesFPRet(ResultType)) {
         imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
                                   "objc_msgSend_fpret");
-      } else if (CGM.ReturnTypeUsesSRet(FnInfo)) {
+      } else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
         // The actual types here don't matter - we're going to bitcast the
         // function anyway
         imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
@@ -1217,12 +1210,10 @@
   // Reset the receiver in case the lookup modified it
   ActualArgs[0] = CallArg(RValue::get(Receiver), ASTIdTy, false);
 
-  llvm::FunctionType *impType =
-    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
-  imp = EnforceType(Builder, imp, llvm::PointerType::getUnqual(impType));
+  imp = EnforceType(Builder, imp, MSI.MessengerType);
 
   llvm::Instruction *call;
-  RValue msgRet = CGF.EmitCall(FnInfo, imp, Return, ActualArgs,
+  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
       0, &call);
   call->setMetadata(msgSendMDKind, node);
 
@@ -2418,7 +2409,7 @@
 
   CodeGenTypes &Types = CGM.getTypes();
   llvm::FunctionType *MethodTy =
-    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
+    Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
   std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
       MethodName, isClassMethod);
 

Modified: cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp Mon Feb 20 19:34:24 2012
@@ -241,9 +241,9 @@
     Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
     Params.push_back(Ctx.BoolTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
-                                                  FunctionType::ExtInfo()),
-                            false);
+      Types.GetFunctionType(Types.arrangeFunctionType(IdType, Params,
+                                                      FunctionType::ExtInfo(),
+                                                      RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
   }
 
@@ -261,9 +261,9 @@
     Params.push_back(Ctx.BoolTy);
     Params.push_back(Ctx.BoolTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
-                                                  FunctionType::ExtInfo()),
-                            false);
+      Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
+                                                      FunctionType::ExtInfo(),
+                                                      RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
   }
 
@@ -279,9 +279,9 @@
     Params.push_back(Ctx.BoolTy);
     Params.push_back(Ctx.BoolTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
-                                                  FunctionType::ExtInfo()),
-                            false);
+      Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
+                                                      FunctionType::ExtInfo(),
+                                                      RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
   }
   
@@ -298,9 +298,9 @@
     Params.push_back(Ctx.VoidPtrTy);
     Params.push_back(Ctx.VoidPtrTy);
     llvm::FunctionType *FTy =
-    Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
-                                                FunctionType::ExtInfo()),
-                          false);
+      Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
+                                                      FunctionType::ExtInfo(),
+                                                      RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
   }
   
@@ -311,9 +311,9 @@
     SmallVector<CanQualType,1> Params;
     Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
-                                                  FunctionType::ExtInfo()),
-                            false);
+      Types.GetFunctionType(Types.arrangeFunctionType(Ctx.VoidTy, Params,
+                                                      FunctionType::ExtInfo(),
+                                                      RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
   }
 
@@ -719,7 +719,6 @@
   };
 
 protected:
-  CodeGen::CodeGenModule &CGM;
   llvm::LLVMContext &VMContext;
   // FIXME! May not be needing this after all.
   unsigned ObjCABI;
@@ -904,7 +903,7 @@
 
 public:
   CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
-    CGM(cgm), VMContext(cgm.getLLVMContext()) { }
+    CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
 
   virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
 
@@ -1675,11 +1674,8 @@
   ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
   ActualArgs.addFrom(CallArgs);
 
-  CodeGenTypes &Types = CGM.getTypes();
-  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
-                                                       FunctionType::ExtInfo());
-  llvm::FunctionType *FTy =
-    Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
+  // If we're calling a method, use the formal signature.
+  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
 
   if (Method)
     assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
@@ -1689,7 +1685,7 @@
   NullReturnState nullReturn;
 
   llvm::Constant *Fn = NULL;
-  if (CGM.ReturnTypeUsesSRet(FnInfo)) {
+  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
     if (!IsSuper) nullReturn.init(CGF, Arg0);
     Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
       : ObjCTypes.getSendStretFn(IsSuper);
@@ -1717,8 +1713,8 @@
       }
     }
   
-  Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
-  RValue rvalue = CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
+  Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
+  RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
   return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
                              requiresnullCheck ? Method : 0);
 }
@@ -1730,6 +1726,10 @@
   if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
     return Qualifiers::Weak;
   
+  // check for __unsafe_unretained
+  if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
+    return Qualifiers::GCNone;
+  
   if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
     return Qualifiers::Strong;
   
@@ -2679,7 +2679,7 @@
 
   CodeGenTypes &Types = CGM.getTypes();
   llvm::FunctionType *MethodTy =
-    Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
+    Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
   llvm::Function *Method =
     llvm::Function::Create(MethodTy,
                            llvm::GlobalValue::InternalLinkage,
@@ -3564,33 +3564,48 @@
 
 void CGObjCCommonMac::EmitImageInfo() {
   unsigned version = 0; // Version is unused?
-  unsigned flags = 0;
-
-  // FIXME: Fix and continue?
-  if (CGM.getLangOptions().getGC() != LangOptions::NonGC)
-    flags |= eImageInfo_GarbageCollected;
-  if (CGM.getLangOptions().getGC() == LangOptions::GCOnly)
-    flags |= eImageInfo_GCOnly;
-
-  // We never allow @synthesize of a superclass property.
-  flags |= eImageInfo_CorrectedSynthesize;
-
-  // Emitted as int[2];
-  uint32_t Values[2] = { version, flags };
-
-  const char *Section;
-  if (ObjCABI == 1)
-    Section = "__OBJC, __image_info,regular";
-  else
-    Section = "__DATA, __objc_imageinfo, regular, no_dead_strip";
-  llvm::GlobalVariable *GV =
-    CreateMetadataVar("\01L_OBJC_IMAGE_INFO",
-                      llvm::ConstantDataArray::get(VMContext, Values),
-                      Section, 0, true);
-  GV->setConstant(true);
+  const char *Section = (ObjCABI == 1) ?
+    "__OBJC, __image_info,regular" :
+    "__DATA, __objc_imageinfo, regular, no_dead_strip";
+
+  // Generate module-level named metadata to convey this information to the
+  // linker and code-gen.
+  llvm::Module &Mod = CGM.getModule();
+
+  // Add the ObjC ABI version to the module flags.
+  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
+  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
+                    version);
+  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
+                    llvm::MDString::get(VMContext,Section));
+
+  if (CGM.getLangOptions().getGC() == LangOptions::NonGC) {
+    // Non-GC overrides those files which specify GC.
+    Mod.addModuleFlag(llvm::Module::Override,
+                      "Objective-C Garbage Collection", (uint32_t)0);
+  } else {
+    // Add the ObjC garbage collection value.
+    Mod.addModuleFlag(llvm::Module::Error,
+                      "Objective-C Garbage Collection",
+                      eImageInfo_GarbageCollected);
+
+    if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) {
+      // Add the ObjC GC Only value.
+      Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
+                        eImageInfo_GCOnly);
+
+      // Require that GC be specified and set to eImageInfo_GarbageCollected.
+      llvm::Value *Ops[2] = {
+        llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
+        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                               eImageInfo_GarbageCollected)
+      };
+      Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
+                        llvm::MDNode::get(VMContext, Ops));
+    }
+  }
 }
 
-
 // struct objc_module {
 //   unsigned long version;
 //   unsigned long size;
@@ -5747,9 +5762,7 @@
 
   args.insert(args.end(), formalArgs.begin(), formalArgs.end());
 
-  const CGFunctionInfo &fnInfo =
-    CGM.getTypes().getFunctionInfo(resultType, args,
-                                   FunctionType::ExtInfo());
+  MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
 
   NullReturnState nullReturn;
 
@@ -5762,7 +5775,7 @@
   // FIXME: don't use this for that.
   llvm::Constant *fn = 0;
   std::string messageRefName("\01l_");
-  if (CGM.ReturnTypeUsesSRet(fnInfo)) {
+  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
     if (isSuper) {
       fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
       messageRefName += "objc_msgSendSuper2_stret_fixup";
@@ -5830,13 +5843,9 @@
   llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
   callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
 
-  bool variadic = method ? method->isVariadic() : false;
-  llvm::FunctionType *fnType = 
-    CGF.getTypes().GetFunctionType(fnInfo, variadic);
-  callee = CGF.Builder.CreateBitCast(callee,
-                                     llvm::PointerType::getUnqual(fnType));
+  callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
 
-  RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args);
+  RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
   return nullReturn.complete(CGF, result, resultType, formalArgs, 
                              requiresnullCheck ? method : 0);
 }

Modified: cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp Mon Feb 20 19:34:24 2012
@@ -327,3 +327,48 @@
   // Emit the body of the statement.
   CGF.EmitStmt(S.getSynchBody());
 }
+
+/// Compute the pointer-to-function type to which a message send
+/// should be casted in order to correctly call the given method
+/// with the given arguments.
+///
+/// \param method - may be null
+/// \param resultType - the result type to use if there's no method
+/// \param argInfo - the actual arguments, including implicit ones
+CGObjCRuntime::MessageSendInfo
+CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
+                                  QualType resultType,
+                                  CallArgList &callArgs) {
+  // If there's a method, use information from that.
+  if (method) {
+    const CGFunctionInfo &signature =
+      CGM.getTypes().arrangeObjCMessageSendSignature(method, callArgs[0].Ty);
+
+    llvm::PointerType *signatureType =
+      CGM.getTypes().GetFunctionType(signature)->getPointerTo();
+
+    // If that's not variadic, there's no need to recompute the ABI
+    // arrangement.
+    if (!signature.isVariadic())
+      return MessageSendInfo(signature, signatureType);
+
+    // Otherwise, there is.
+    FunctionType::ExtInfo einfo = signature.getExtInfo();
+    const CGFunctionInfo &argsInfo =
+      CGM.getTypes().arrangeFunctionCall(resultType, callArgs, einfo,
+                                         signature.getRequiredArgs());
+
+    return MessageSendInfo(argsInfo, signatureType);
+  }
+
+  // There's no method;  just use a default CC.
+  const CGFunctionInfo &argsInfo =
+    CGM.getTypes().arrangeFunctionCall(resultType, callArgs, 
+                                       FunctionType::ExtInfo(),
+                                       RequiredArgs::All);
+
+  // Derive the signature to call from that.
+  llvm::PointerType *signatureType =
+    CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo();
+  return MessageSendInfo(argsInfo, signatureType);
+}

Modified: cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.h Mon Feb 20 19:34:24 2012
@@ -63,6 +63,9 @@
 /// Implements runtime-specific code generation functions.
 class CGObjCRuntime {
 protected:
+  CodeGen::CodeGenModule &CGM;
+  CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {}
+
   // Utility functions for unified ivar access. These need to
   // eventually be folded into other places (the structure layout
   // code).
@@ -255,6 +258,19 @@
   virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
                                   const CodeGen::CGBlockInfo &blockInfo) = 0;
   virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
+
+  struct MessageSendInfo {
+    const CGFunctionInfo &CallInfo;
+    llvm::PointerType *MessengerType;
+
+    MessageSendInfo(const CGFunctionInfo &callInfo,
+                    llvm::PointerType *messengerType)
+      : CallInfo(callInfo), MessengerType(messengerType) {}
+  };
+
+  MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
+                                     QualType resultType,
+                                     CallArgList &callArgs);
 };
 
 /// Creates an instance of an Objective-C runtime class.

Modified: cfe/branches/tooling/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGVTables.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGVTables.cpp Mon Feb 20 19:34:24 2012
@@ -242,8 +242,8 @@
   QualType ResultType = FPT->getResultType();
 
   // Get the original function
-  llvm::Type *Ty =
-    CGM.getTypes().GetFunctionType(FnInfo, /*IsVariadic*/true);
+  assert(FnInfo.isVariadic());
+  llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo);
   llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
   llvm::Function *BaseFn = cast<llvm::Function>(Callee);
 
@@ -351,13 +351,13 @@
 
   // Get our callee.
   llvm::Type *Ty =
-    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(GD),
-                                   FPT->isVariadic());
+    CGM.getTypes().GetFunctionType(CGM.getTypes().arrangeGlobalDeclaration(GD));
   llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
 
 #ifndef NDEBUG
   const CGFunctionInfo &CallFnInfo = 
-    CGM.getTypes().getFunctionInfo(ResultType, CallArgs, FPT->getExtInfo());
+    CGM.getTypes().arrangeFunctionCall(ResultType, CallArgs, FPT->getExtInfo(),
+                                       RequiredArgs::forPrototypePlus(FPT, 1));
   assert(CallFnInfo.getRegParm() == FnInfo.getRegParm() &&
          CallFnInfo.isNoReturn() == FnInfo.isNoReturn() &&
          CallFnInfo.getCallingConvention() == FnInfo.getCallingConvention());
@@ -398,7 +398,7 @@
 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk, 
                                bool UseAvailableExternallyLinkage)
 {
-  const CGFunctionInfo &FnInfo = CGM.getTypes().getFunctionInfo(GD);
+  const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD);
 
   // FIXME: re-use FnInfo in this computation.
   llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk);

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp Mon Feb 20 19:34:24 2012
@@ -428,9 +428,8 @@
   if (isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance())
     CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args);
 
-  if (FD->getNumParams())
-    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
-      Args.push_back(FD->getParamDecl(i));
+  for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
+    Args.push_back(FD->getParamDecl(i));
 
   SourceRange BodyRange;
   if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
@@ -447,6 +446,17 @@
            !CGM.getCodeGenOpts().CUDAIsDevice &&
            FD->hasAttr<CUDAGlobalAttr>())
     CGM.getCUDARuntime().EmitDeviceStubBody(*this, Args);
+  else if (isa<CXXConversionDecl>(FD) &&
+           cast<CXXConversionDecl>(FD)->isLambdaToBlockPointerConversion()) {
+    // The lambda conversion to block pointer is special; the semantics can't be
+    // expressed in the AST, so IRGen needs to special-case it.
+    EmitLambdaToBlockPointerBody(Args);
+  } else if (isa<CXXMethodDecl>(FD) &&
+             cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
+    // The lambda "__invoke" function is special, because it forwards or
+    // clones the body of the function call operator (but is actually static).
+    EmitLambdaStaticInvokeFunction(cast<CXXMethodDecl>(FD));
+  }
   else
     EmitFunctionBody(Args);
 

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h Mon Feb 20 19:34:24 2012
@@ -1376,6 +1376,10 @@
   void EmitDestructorBody(FunctionArgList &Args);
   void EmitFunctionBody(FunctionArgList &Args);
 
+  void EmitLambdaToBlockPointerBody(FunctionArgList &Args);
+  void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
+  void EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD);
+
   /// EmitReturnBlock - Emit the unified return block, trying to avoid its
   /// emission when possible.
   void EmitReturnBlock();
@@ -1807,6 +1811,10 @@
   llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
   llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
 
+  void MaybeEmitStdInitializerListCleanup(LValue lvalue, const Expr *init);
+  void EmitStdInitializerListCleanup(llvm::Value *loc,
+                                     const InitListExpr *init);
+
   void EmitCheck(llvm::Value *, unsigned Size);
 
   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
@@ -2566,6 +2574,8 @@
   CodeGenModule::ByrefHelpers *
   buildByrefHelpers(llvm::StructType &byrefType,
                     const AutoVarEmission &emission);
+
+  void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);
 };
 
 /// Helper class with most of the code for saving a value for a

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp Mon Feb 20 19:34:24 2012
@@ -66,10 +66,11 @@
   : Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
     TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
     ABI(createCXXABI(*this)), 
-    Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI, CGO),
+    Types(*this),
     TBAA(0),
     VTables(*this), ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0),
-    DebugInfo(0), ARCData(0), RRData(0), CFConstantStringClassRef(0),
+    DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0),
+    RRData(0), CFConstantStringClassRef(0),
     ConstantStringClassRef(0), NSConstantStringType(0),
     VMContext(M.getContext()),
     NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
@@ -172,8 +173,6 @@
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
   // Make sure that this type is translated.
   Types.UpdateCompletedType(TD);
-  if (DebugInfo)
-    DebugInfo->UpdateCompletedType(TD);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) {
@@ -579,7 +578,7 @@
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
 
   if (!IsIncompleteFunction)
-    SetLLVMFunctionAttributes(FD, getTypes().getFunctionInfo(GD), F);
+    SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F);
 
   // Only a few attributes are set on declarations; these may later be
   // overridden by a definition.
@@ -1100,19 +1099,23 @@
                                  ExtraAttrs);
 }
 
-static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D,
-                                 bool ConstantInit) {
-  if (!D->getType().isConstant(Context) && !D->getType()->isReferenceType())
+/// isTypeConstant - Determine whether an object of this type can be emitted
+/// as a constant.
+///
+/// If ExcludeCtor is true, the duration when the object's constructor runs
+/// will not be considered. The caller will need to verify that the object is
+/// not written to during its construction.
+bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
+  if (!Ty.isConstant(Context) && !Ty->isReferenceType())
     return false;
-  
+
   if (Context.getLangOptions().CPlusPlus) {
-    if (const RecordType *Record 
-          = Context.getBaseElementType(D->getType())->getAs<RecordType>())
-      return ConstantInit && 
-             cast<CXXRecordDecl>(Record->getDecl())->isPOD() &&
-             !cast<CXXRecordDecl>(Record->getDecl())->hasMutableFields();
+    if (const CXXRecordDecl *Record
+          = Context.getBaseElementType(Ty)->getAsCXXRecordDecl())
+      return ExcludeCtor && !Record->hasMutableFields() &&
+             Record->hasTrivialDestructor();
   }
-  
+
   return true;
 }
 
@@ -1169,7 +1172,7 @@
   if (D) {
     // FIXME: This code is overly simple and should be merged with other global
     // handling.
-    GV->setConstant(DeclIsConstantGlobal(Context, D, false));
+    GV->setConstant(isTypeConstant(D->getType(), false));
 
     // Set linkage and visibility in case we never see a definition.
     NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
@@ -1450,13 +1453,11 @@
   GV->setInitializer(Init);
 
   // If it is safe to mark the global 'constant', do so now.
-  GV->setConstant(false);
-  if (!NeedsGlobalCtor && !NeedsGlobalDtor &&
-      DeclIsConstantGlobal(Context, D, true))
-    GV->setConstant(true);
+  GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
+                  isTypeConstant(D->getType(), true));
 
   GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
-  
+
   // Set the llvm linkage type as appropriate.
   llvm::GlobalValue::LinkageTypes Linkage = 
     GetLLVMLinkageVarDefinition(D, GV);
@@ -1599,11 +1600,8 @@
   const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
 
   // Compute the function info and LLVM type.
-  const CGFunctionInfo &FI = getTypes().getFunctionInfo(GD);
-  bool variadic = false;
-  if (const FunctionProtoType *fpt = D->getType()->getAs<FunctionProtoType>())
-    variadic = fpt->isVariadic();
-  llvm::FunctionType *Ty = getTypes().GetFunctionType(FI, variadic);
+  const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
+  llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
 
   // Get or create the prototype for the function.
   llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.h Mon Feb 20 19:34:24 2012
@@ -233,6 +233,7 @@
   CGCUDARuntime* CUDARuntime;
   CGDebugInfo* DebugInfo;
   ARCEntrypoints *ARCData;
+  llvm::MDNode *NoObjCARCExceptionsMetadata;
   RREntrypoints *RRData;
 
   // WeakRefReferences - A set of references that have only been seen via
@@ -421,6 +422,14 @@
 
   CGDebugInfo *getModuleDebugInfo() { return DebugInfo; }
 
+  llvm::MDNode *getNoObjCARCExceptionsMetadata() {
+    if (!NoObjCARCExceptionsMetadata)
+      NoObjCARCExceptionsMetadata =
+        llvm::MDNode::get(getLLVMContext(),
+                          SmallVector<llvm::Value*,1>());
+    return NoObjCARCExceptionsMetadata;
+  }
+
   ASTContext &getContext() const { return Context; }
   const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
   const LangOptions &getLangOptions() const { return Features; }
@@ -439,6 +448,8 @@
 
   llvm::MDNode *getTBAAInfo(QualType QTy);
 
+  bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
+
   static void DecorateInstruction(llvm::Instruction *Inst,
                                   llvm::MDNode *TBAAInfo);
 

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp Mon Feb 20 19:34:24 2012
@@ -15,6 +15,7 @@
 #include "CGCall.h"
 #include "CGCXXABI.h"
 #include "CGRecordLayout.h"
+#include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclCXX.h"
@@ -26,11 +27,12 @@
 using namespace clang;
 using namespace CodeGen;
 
-CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
-                           const llvm::TargetData &TD, const ABIInfo &Info,
-                           CGCXXABI &CXXABI, const CodeGenOptions &CGO)
-  : Context(Ctx), Target(Ctx.getTargetInfo()), TheModule(M), TheTargetData(TD),
-    TheABIInfo(Info), TheCXXABI(CXXABI), CodeGenOpts(CGO) {
+CodeGenTypes::CodeGenTypes(CodeGenModule &CGM)
+  : Context(CGM.getContext()), Target(Context.getTargetInfo()),
+    TheModule(CGM.getModule()), TheTargetData(CGM.getTargetData()),
+    TheABIInfo(CGM.getTargetCodeGenInfo().getABIInfo()),
+    TheCXXABI(CGM.getCXXABI()),
+    CodeGenOpts(CGM.getCodeGenOpts()), CGM(CGM) {
   SkippedLayout = false;
 }
 
@@ -473,16 +475,13 @@
     // The function type can be built; call the appropriate routines to
     // build it.
     const CGFunctionInfo *FI;
-    bool isVariadic;
     if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
-      FI = &getFunctionInfo(
+      FI = &arrangeFunctionType(
                    CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)));
-      isVariadic = FPT->isVariadic();
     } else {
       const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT);
-      FI = &getFunctionInfo(
+      FI = &arrangeFunctionType(
                 CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0)));
-      isVariadic = true;
     }
     
     // If there is something higher level prodding our CGFunctionInfo, then
@@ -494,7 +493,7 @@
     } else {
 
       // Otherwise, we're good to go, go ahead and convert it.
-      ResultType = GetFunctionType(*FI, isVariadic);
+      ResultType = GetFunctionType(*FI);
     }
 
     RecordsBeingLaidOut.erase(Ty);

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenTypes.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenTypes.h Mon Feb 20 19:34:24 2012
@@ -52,10 +52,13 @@
 namespace CodeGen {
   class CGCXXABI;
   class CGRecordLayout;
+  class CodeGenModule;
+  class RequiredArgs;
 
 /// CodeGenTypes - This class organizes the cross-module state that is used
 /// while lowering AST types to LLVM types.
 class CodeGenTypes {
+  // Some of this stuff should probably be left on the CGM.
   ASTContext &Context;
   const TargetInfo &Target;
   llvm::Module &TheModule;
@@ -63,6 +66,7 @@
   const ABIInfo &TheABIInfo;
   CGCXXABI &TheCXXABI;
   const CodeGenOptions &CodeGenOpts;
+  CodeGenModule &CGM;
 
   /// The opaque type map for Objective-C interfaces. All direct
   /// manipulation is done by the runtime interfaces, which are
@@ -101,9 +105,7 @@
   llvm::DenseMap<const Type *, llvm::Type *> TypeCache;
 
 public:
-  CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD,
-               const ABIInfo &Info, CGCXXABI &CXXABI,
-               const CodeGenOptions &Opts);
+  CodeGenTypes(CodeGenModule &CGM);
   ~CodeGenTypes();
 
   const llvm::TargetData &getTargetData() const { return TheTargetData; }
@@ -124,8 +126,7 @@
   llvm::Type *ConvertTypeForMem(QualType T);
 
   /// GetFunctionType - Get the LLVM function type for \arg Info.
-  llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info,
-                                      bool IsVariadic);
+  llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);
 
   llvm::FunctionType *GetFunctionType(GlobalDecl GD);
 
@@ -148,50 +149,66 @@
 
   /// getNullaryFunctionInfo - Get the function info for a void()
   /// function with standard CC.
-  const CGFunctionInfo &getNullaryFunctionInfo();
+  const CGFunctionInfo &arrangeNullaryFunction();
 
-  /// getFunctionInfo - Get the function info for the specified function decl.
-  const CGFunctionInfo &getFunctionInfo(GlobalDecl GD);
-
-  const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD);
-  const CGFunctionInfo &getFunctionInfo(const CXXMethodDecl *MD);
-  const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD);
-  const CGFunctionInfo &getFunctionInfo(const CXXConstructorDecl *D,
-                                        CXXCtorType Type);
-  const CGFunctionInfo &getFunctionInfo(const CXXDestructorDecl *D,
-                                        CXXDtorType Type);
-
-  const CGFunctionInfo &getFunctionInfo(const CallArgList &Args,
-                                        const FunctionType *Ty) {
-    return getFunctionInfo(Ty->getResultType(), Args,
-                           Ty->getExtInfo());
-  }
-
-  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty);
-  const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty);
-
-  /// getFunctionInfo - Get the function info for a member function of
-  /// the given type.  This is used for calls through member function
-  /// pointers.
-  const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD,
-                                        const FunctionProtoType *FTP);
-
-  /// getFunctionInfo - Get the function info for a function described by a
-  /// return type and argument types. If the calling convention is not
-  /// specified, the "C" calling convention will be used.
-  const CGFunctionInfo &getFunctionInfo(QualType ResTy,
-                                        const CallArgList &Args,
-                                        const FunctionType::ExtInfo &Info);
-  const CGFunctionInfo &getFunctionInfo(QualType ResTy,
-                                        const FunctionArgList &Args,
-                                        const FunctionType::ExtInfo &Info);
+  // The arrangement methods are split into three families:
+  //   - those meant to drive the signature and prologue/epilogue
+  //     of a function declaration or definition,
+  //   - those meant for the computation of the LLVM type for an abstract
+  //     appearance of a function, and
+  //   - those meant for performing the IR-generation of a call.
+  // They differ mainly in how they deal with optional (i.e. variadic)
+  // arguments, as well as unprototyped functions.
+  //
+  // Key points:
+  // - The CGFunctionInfo for emitting a specific call site must include
+  //   entries for the optional arguments.
+  // - The function type used at the call site must reflect the formal
+  //   signature of the declaration being called, or else the call will
+  //   go awry.
+  // - For the most part, unprototyped functions are called by casting to
+  //   a formal signature inferred from the specific argument types used
+  //   at the call-site.  However, some targets (e.g. x86-64) screw with
+  //   this for compatibility reasons.
+
+  const CGFunctionInfo &arrangeGlobalDeclaration(GlobalDecl GD);
+  const CGFunctionInfo &arrangeFunctionDeclaration(const FunctionDecl *FD);
+  const CGFunctionInfo &arrangeFunctionDeclaration(QualType ResTy,
+                                                   const FunctionArgList &Args,
+                                             const FunctionType::ExtInfo &Info,
+                                                   bool isVariadic);
+
+  const CGFunctionInfo &arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD);
+  const CGFunctionInfo &arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
+                                                        QualType receiverType);
+
+  const CGFunctionInfo &arrangeCXXMethodDeclaration(const CXXMethodDecl *MD);
+  const CGFunctionInfo &arrangeCXXConstructorDeclaration(
+                                                    const CXXConstructorDecl *D,
+                                                    CXXCtorType Type);
+  const CGFunctionInfo &arrangeCXXDestructor(const CXXDestructorDecl *D,
+                                             CXXDtorType Type);
+
+  const CGFunctionInfo &arrangeFunctionCall(const CallArgList &Args,
+                                            const FunctionType *Ty);
+  const CGFunctionInfo &arrangeFunctionCall(QualType ResTy,
+                                            const CallArgList &args,
+                                            const FunctionType::ExtInfo &info,
+                                            RequiredArgs required);
+
+  const CGFunctionInfo &arrangeFunctionType(CanQual<FunctionProtoType> Ty);
+  const CGFunctionInfo &arrangeFunctionType(CanQual<FunctionNoProtoType> Ty);
+  const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
+                                             const FunctionProtoType *FTP);
 
   /// Retrieves the ABI information for the given function signature.
+  /// This is the "core" routine to which all the others defer.
   ///
-  /// \param ArgTys - must all actually be canonical as params
-  const CGFunctionInfo &getFunctionInfo(CanQualType RetTy,
-                               const SmallVectorImpl<CanQualType> &ArgTys,
-                                        const FunctionType::ExtInfo &Info);
+  /// \param argTypes - must all actually be canonical as params
+  const CGFunctionInfo &arrangeFunctionType(CanQualType returnType,
+                                            ArrayRef<CanQualType> argTypes,
+                                            const FunctionType::ExtInfo &info,
+                                            RequiredArgs args);
 
   /// \brief Compute a new LLVM record layout object for the given record.
   CGRecordLayout *ComputeRecordLayout(const RecordDecl *D,

Modified: cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp Mon Feb 20 19:34:24 2012
@@ -73,6 +73,8 @@
   llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
                                            const CastExpr *E,
                                            llvm::Value *Src);
+  llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
+                                              llvm::Constant *Src);
 
   llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
 
@@ -216,8 +218,8 @@
     cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
 
   llvm::FunctionType *FTy = 
-    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
-                                   FPT->isVariadic());
+    CGM.getTypes().GetFunctionType(
+      CGM.getTypes().arrangeCXXMethodType(RD, FPT));
 
   llvm::IntegerType *ptrdiff = getPtrDiffTy();
   llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1);
@@ -312,7 +314,10 @@
   return Builder.CreateBitCast(Addr, PType);
 }
 
-/// Perform a derived-to-base or base-to-derived member pointer conversion.
+/// Perform a bitcast, derived-to-base, or base-to-derived member pointer
+/// conversion.
+///
+/// Bitcast conversions are always a no-op under Itanium.
 ///
 /// Obligatory offset/adjustment diagram:
 ///         <-- offset -->          <-- adjustment -->
@@ -335,64 +340,105 @@
 llvm::Value *
 ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
                                            const CastExpr *E,
-                                           llvm::Value *Src) {
+                                           llvm::Value *src) {
   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
-         E->getCastKind() == CK_BaseToDerivedMemberPointer);
+         E->getCastKind() == CK_BaseToDerivedMemberPointer ||
+         E->getCastKind() == CK_ReinterpretMemberPointer);
 
-  CGBuilderTy &Builder = CGF.Builder;
+  // Under Itanium, reinterprets don't require any additional processing.
+  if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
 
-  const MemberPointerType *SrcTy =
-    E->getSubExpr()->getType()->getAs<MemberPointerType>();
-  const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
-
-  const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
-  const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
-
-  bool DerivedToBase =
-    E->getCastKind() == CK_DerivedToBaseMemberPointer;
-
-  const CXXRecordDecl *DerivedDecl;
-  if (DerivedToBase)
-    DerivedDecl = SrcDecl;
-  else
-    DerivedDecl = DestDecl;
+  // Use constant emission if we can.
+  if (isa<llvm::Constant>(src))
+    return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
 
-  llvm::Constant *Adj = 
-    CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
-                                         E->path_begin(),
-                                         E->path_end());
-  if (!Adj) return Src;
+  llvm::Constant *adj = getMemberPointerAdjustment(E);
+  if (!adj) return src;
+
+  CGBuilderTy &Builder = CGF.Builder;
+  bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
+
+  const MemberPointerType *destTy =
+    E->getType()->castAs<MemberPointerType>();
 
   // For member data pointers, this is just a matter of adding the
   // offset if the source is non-null.
-  if (SrcTy->isMemberDataPointer()) {
-    llvm::Value *Dst;
-    if (DerivedToBase)
-      Dst = Builder.CreateNSWSub(Src, Adj, "adj");
+  if (destTy->isMemberDataPointer()) {
+    llvm::Value *dst;
+    if (isDerivedToBase)
+      dst = Builder.CreateNSWSub(src, adj, "adj");
     else
-      Dst = Builder.CreateNSWAdd(Src, Adj, "adj");
+      dst = Builder.CreateNSWAdd(src, adj, "adj");
 
     // Null check.
-    llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType());
-    llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull");
-    return Builder.CreateSelect(IsNull, Src, Dst);
+    llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
+    llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");
+    return Builder.CreateSelect(isNull, src, dst);
+  }
+
+  // The this-adjustment is left-shifted by 1 on ARM.
+  if (IsARM) {
+    uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
+    offset <<= 1;
+    adj = llvm::ConstantInt::get(adj->getType(), offset);
+  }
+
+  llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");
+  llvm::Value *dstAdj;
+  if (isDerivedToBase)
+    dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");
+  else
+    dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");
+
+  return Builder.CreateInsertValue(src, dstAdj, 1);
+}
+
+llvm::Constant *
+ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
+                                           llvm::Constant *src) {
+  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
+         E->getCastKind() == CK_BaseToDerivedMemberPointer ||
+         E->getCastKind() == CK_ReinterpretMemberPointer);
+
+  // Under Itanium, reinterprets don't require any additional processing.
+  if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
+
+  // If the adjustment is trivial, we don't need to do anything.
+  llvm::Constant *adj = getMemberPointerAdjustment(E);
+  if (!adj) return src;
+
+  bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
+
+  const MemberPointerType *destTy =
+    E->getType()->castAs<MemberPointerType>();
+
+  // For member data pointers, this is just a matter of adding the
+  // offset if the source is non-null.
+  if (destTy->isMemberDataPointer()) {
+    // null maps to null.
+    if (src->isAllOnesValue()) return src;
+
+    if (isDerivedToBase)
+      return llvm::ConstantExpr::getNSWSub(src, adj);
+    else
+      return llvm::ConstantExpr::getNSWAdd(src, adj);
   }
 
   // The this-adjustment is left-shifted by 1 on ARM.
   if (IsARM) {
-    uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue();
-    Offset <<= 1;
-    Adj = llvm::ConstantInt::get(Adj->getType(), Offset);
+    uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
+    offset <<= 1;
+    adj = llvm::ConstantInt::get(adj->getType(), offset);
   }
 
-  llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj");
-  llvm::Value *DstAdj;
-  if (DerivedToBase)
-    DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj");
+  llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
+  llvm::Constant *dstAdj;
+  if (isDerivedToBase)
+    dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
   else
-    DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj");
+    dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
 
-  return Builder.CreateInsertValue(Src, DstAdj, 1);
+  return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
 }
 
 llvm::Constant *
@@ -465,8 +511,7 @@
     // Check whether the function has a computable LLVM signature.
     if (Types.isFuncTypeConvertible(FPT)) {
       // The function has a computable LLVM signature; use the correct type.
-      Ty = Types.GetFunctionType(Types.getFunctionInfo(MD),
-                                 FPT->isVariadic());
+      Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
     } else {
       // Use an arbitrary non-function type to tell GetAddrOfFunction that the
       // function type is incomplete.

Modified: cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp Mon Feb 20 19:34:24 2012
@@ -98,8 +98,8 @@
   return 32;
 }
 
-bool TargetCodeGenInfo::isNoProtoCallVariadic(
-                                       const CodeGen::CGFunctionInfo &) const {
+bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args,
+                                     const FunctionNoProtoType *fnType) const {
   // The following conventions are known to require this to be false:
   //   x86_stdcall
   //   MIPS
@@ -935,6 +935,17 @@
   X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, bool hasavx) :
       ABIInfo(CGT), HasAVX(hasavx) {}
 
+  bool isPassedUsingAVXType(QualType type) const {
+    unsigned neededInt, neededSSE;
+    ABIArgInfo info = classifyArgumentType(type, neededInt, neededSSE);
+    if (info.isDirect()) {
+      llvm::Type *ty = info.getCoerceToType();
+      if (llvm::VectorType *vectorTy = dyn_cast_or_null<llvm::VectorType>(ty))
+        return (vectorTy->getBitWidth() > 128);
+    }
+    return false;
+  }
+
   virtual void computeInfo(CGFunctionInfo &FI) const;
 
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -960,6 +971,10 @@
   X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX)
     : TargetCodeGenInfo(new X86_64ABIInfo(CGT, HasAVX)) {}
 
+  const X86_64ABIInfo &getABIInfo() const {
+    return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
+  }
+
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
     return 7;
   }
@@ -980,33 +995,29 @@
     return X86AdjustInlineAsmType(CGF, Constraint, Ty);
   }
 
-  bool isNoProtoCallVariadic(const CodeGen::CGFunctionInfo &FI) const {
+  bool isNoProtoCallVariadic(const CallArgList &args,
+                             const FunctionNoProtoType *fnType) const {
     // The default CC on x86-64 sets %al to the number of SSA
     // registers used, and GCC sets this when calling an unprototyped
     // function, so we override the default behavior.  However, don't do
     // that when AVX types are involved: the ABI explicitly states it is
     // undefined, and it doesn't work in practice because of how the ABI
     // defines varargs anyway.
-    if (FI.getCallingConvention() == llvm::CallingConv::C) {
+    if (fnType->getCallConv() == CC_Default || fnType->getCallConv() == CC_C) {
       bool HasAVXType = false;
-      for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
-                                              ie = FI.arg_end();
-           it != ie; ++it) {
-        if (it->info.isDirect()) {
-          llvm::Type *Ty = it->info.getCoerceToType();
-          if (llvm::VectorType *VTy = dyn_cast_or_null<llvm::VectorType>(Ty)) {
-            if (VTy->getBitWidth() > 128) {
-              HasAVXType = true;
-              break;
-            }
-          }
+      for (CallArgList::const_iterator
+             it = args.begin(), ie = args.end(); it != ie; ++it) {
+        if (getABIInfo().isPassedUsingAVXType(it->Ty)) {
+          HasAVXType = true;
+          break;
         }
       }
+
       if (!HasAVXType)
         return true;
     }
 
-    return TargetCodeGenInfo::isNoProtoCallVariadic(FI);
+    return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType);
   }
 
 };

Modified: cfe/branches/tooling/lib/CodeGen/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/TargetInfo.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/TargetInfo.h (original)
+++ cfe/branches/tooling/lib/CodeGen/TargetInfo.h Mon Feb 20 19:34:24 2012
@@ -30,6 +30,7 @@
   class Decl;
 
   namespace CodeGen {
+    class CallArgList;
     class CodeGenModule;
     class CodeGenFunction;
     class CGFunctionInfo;
@@ -161,7 +162,8 @@
     /// same way and some out-of-band information is passed for the
     /// benefit of variadic callees, as is the case for x86-64.
     /// In this case the ABI should be consulted.
-    virtual bool isNoProtoCallVariadic(const CodeGen::CGFunctionInfo &) const;
+    virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args,
+                                       const FunctionNoProtoType *fnType) const;
   };
 }
 

Modified: cfe/branches/tooling/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Driver.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Driver.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Driver.cpp Mon Feb 20 19:34:24 2012
@@ -36,13 +36,10 @@
 #include "InputInfo.h"
 #include "ToolChains.h"
 
-#ifdef HAVE_CLANG_CONFIG_H
-# include "clang/Config/config.h"
-#endif
-#include "llvm/Config/config.h"
-
 #include <map>
 
+#include "clang/Config/config.h"
+
 using namespace clang::driver;
 using namespace clang;
 
@@ -1632,7 +1629,7 @@
   if (!TC) {
     switch (Target.getOS()) {
     case llvm::Triple::AuroraUX:
-      TC = new toolchains::AuroraUX(*this, Target);
+      TC = new toolchains::AuroraUX(*this, Target, Args);
       break;
     case llvm::Triple::Darwin:
     case llvm::Triple::MacOSX:
@@ -1643,28 +1640,31 @@
           Target.getArch() == llvm::Triple::thumb)
         TC = new toolchains::DarwinClang(*this, Target);
       else
-        TC = new toolchains::Darwin_Generic_GCC(*this, Target);
+        TC = new toolchains::Darwin_Generic_GCC(*this, Target, Args);
       break;
     case llvm::Triple::DragonFly:
-      TC = new toolchains::DragonFly(*this, Target);
+      TC = new toolchains::DragonFly(*this, Target, Args);
       break;
     case llvm::Triple::OpenBSD:
-      TC = new toolchains::OpenBSD(*this, Target);
+      TC = new toolchains::OpenBSD(*this, Target, Args);
       break;
     case llvm::Triple::NetBSD:
-      TC = new toolchains::NetBSD(*this, Target);
+      TC = new toolchains::NetBSD(*this, Target, Args);
       break;
     case llvm::Triple::FreeBSD:
-      TC = new toolchains::FreeBSD(*this, Target);
+      TC = new toolchains::FreeBSD(*this, Target, Args);
       break;
     case llvm::Triple::Minix:
-      TC = new toolchains::Minix(*this, Target);
+      TC = new toolchains::Minix(*this, Target, Args);
       break;
     case llvm::Triple::Linux:
       if (Target.getArch() == llvm::Triple::hexagon)
         TC = new toolchains::Hexagon_TC(*this, Target);
       else
-        TC = new toolchains::Linux(*this, Target);
+        TC = new toolchains::Linux(*this, Target, Args);
+      break;
+    case llvm::Triple::Solaris:
+      TC = new toolchains::Solaris(*this, Target, Args);
       break;
     case llvm::Triple::Win32:
       TC = new toolchains::Windows(*this, Target);
@@ -1678,7 +1678,7 @@
         break;
       }
 
-      TC = new toolchains::Generic_GCC(*this, Target);
+      TC = new toolchains::Generic_GCC(*this, Target, Args);
       break;
     }
   }

Modified: cfe/branches/tooling/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChains.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChains.cpp (original)
+++ cfe/branches/tooling/lib/Driver/ToolChains.cpp Mon Feb 20 19:34:24 2012
@@ -33,11 +33,7 @@
 
 #include <cstdlib> // ::getenv
 
-#ifdef HAVE_CLANG_CONFIG_H
-# include "clang/Config/config.h"
-#endif
-
-#include "llvm/Config/config.h" // for GCC_INSTALL_PREFIX
+#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -1091,6 +1087,13 @@
   return false;
 }
 
+static StringRef getGCCToolchainDir(const ArgList &Args) {
+  const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
+  if (A)
+    return A->getValue(Args);
+  return GCC_INSTALL_PREFIX;
+}
+
 /// \brief Construct a GCCInstallationDetector from the driver.
 ///
 /// This performs all of the autodetection and sets up the various paths.
@@ -1102,7 +1105,8 @@
 /// triple.
 Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
     const Driver &D,
-    const llvm::Triple &TargetTriple)
+    const llvm::Triple &TargetTriple,
+    const ArgList &Args)
     : IsValid(false) {
   llvm::Triple MultiarchTriple
     = TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
@@ -1122,12 +1126,12 @@
   SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
                                        D.PrefixDirs.end());
 
-  SmallString<128> CxxInstallRoot(GCC_INSTALL_PREFIX);
-  if (CxxInstallRoot != "") {
-    if (CxxInstallRoot.back() == '/')
-      llvm::sys::path::remove_filename(CxxInstallRoot); // remove the /
+  StringRef GCCToolchainDir = getGCCToolchainDir(Args);
+  if (GCCToolchainDir != "") {
+    if (GCCToolchainDir.back() == '/')
+      GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
 
-    Prefixes.push_back(CxxInstallRoot.str());
+    Prefixes.push_back(GCCToolchainDir);
   } else {
     Prefixes.push_back(D.SysRoot);
     Prefixes.push_back(D.SysRoot + "/usr");
@@ -1360,8 +1364,9 @@
   }
 }
 
-Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple)
-  : ToolChain(D, Triple), GCCInstallation(getDriver(), Triple) {
+Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
+                         const ArgList &Args)
+  : ToolChain(D, Triple), GCCInstallation(getDriver(), Triple, Args) {
   getProgramPaths().push_back(getDriver().getInstalledDir());
   if (getDriver().getInstalledDir() != getDriver().Dir)
     getProgramPaths().push_back(getDriver().Dir);
@@ -1554,8 +1559,8 @@
 
 /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
 
-OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple)
-  : Generic_ELF(D, Triple) {
+OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
   getFilePaths().push_back(getDriver().Dir + "/../lib");
   getFilePaths().push_back("/usr/lib");
 }
@@ -1594,8 +1599,8 @@
 
 /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
 
-FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple)
-  : Generic_ELF(D, Triple) {
+FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
 
   // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
   // back to '/usr/lib' if it doesn't exist.
@@ -1640,8 +1645,8 @@
 
 /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
 
-NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple)
-  : Generic_ELF(D, Triple) {
+NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
 
   if (getDriver().UseStdLib) {
     // When targeting a 32-bit platform, try the special directory used on
@@ -1690,8 +1695,8 @@
 
 /// Minix - Minix tool chain which can call as(1) and ld(1) directly.
 
-Minix::Minix(const Driver &D, const llvm::Triple& Triple)
-  : Generic_ELF(D, Triple) {
+Minix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
   getFilePaths().push_back(getDriver().Dir + "/../lib");
   getFilePaths().push_back("/usr/lib");
 }
@@ -1721,8 +1726,9 @@
 
 /// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
 
-AuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple)
-  : Generic_GCC(D, Triple) {
+AuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple,
+                   const ArgList &Args)
+  : Generic_GCC(D, Triple, Args) {
 
   getProgramPaths().push_back(getDriver().getInstalledDir());
   if (getDriver().getInstalledDir() != getDriver().Dir)
@@ -1759,6 +1765,42 @@
   return *T;
 }
 
+/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
+
+Solaris::Solaris(const Driver &D, const llvm::Triple& Triple,
+                 const ArgList &Args)
+  : Generic_GCC(D, Triple, Args) {
+
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+}
+
+Tool &Solaris::SelectTool(const Compilation &C, const JobAction &JA,
+                           const ActionList &Inputs) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::AssembleJobClass:
+      T = new tools::solaris::Assemble(*this); break;
+    case Action::LinkJobClass:
+      T = new tools::solaris::Link(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA, Inputs);
+    }
+  }
+
+  return *T;
+}
 
 /// Linux toolchain (very bare-bones at the moment).
 
@@ -1927,8 +1969,8 @@
   if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
 }
 
-Linux::Linux(const Driver &D, const llvm::Triple &Triple)
-  : Generic_ELF(D, Triple) {
+Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
   llvm::Triple::ArchType Arch = Triple.getArch();
   const std::string &SysRoot = getDriver().SysRoot;
 
@@ -2213,8 +2255,8 @@
 
 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
 
-DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple)
-  : Generic_ELF(D, Triple) {
+DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
 
   // Path mangling to find libexec
   getProgramPaths().push_back(getDriver().getInstalledDir());

Modified: cfe/branches/tooling/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChains.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChains.h (original)
+++ cfe/branches/tooling/lib/Driver/ToolChains.h Mon Feb 20 19:34:24 2012
@@ -79,7 +79,8 @@
     GCCVersion Version;
 
   public:
-    GCCInstallationDetector(const Driver &D, const llvm::Triple &TargetTriple);
+    GCCInstallationDetector(const Driver &D, const llvm::Triple &TargetTriple,
+                            const ArgList &Args);
 
     /// \brief Check whether we detected a valid GCC install.
     bool isValid() const { return IsValid; }
@@ -119,7 +120,7 @@
   mutable llvm::DenseMap<unsigned, Tool*> Tools;
 
 public:
-  Generic_GCC(const Driver &D, const llvm::Triple& Triple);
+  Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
   ~Generic_GCC();
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
@@ -419,8 +420,8 @@
 /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
 class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC {
 public:
-  Darwin_Generic_GCC(const Driver &D, const llvm::Triple& Triple)
-    : Generic_GCC(D, Triple) {}
+  Darwin_Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+    : Generic_GCC(D, Triple, Args) {}
 
   std::string ComputeEffectiveClangTriple(const ArgList &Args,
                                           types::ID InputType) const;
@@ -431,8 +432,8 @@
 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
   virtual void anchor();
 public:
-  Generic_ELF(const Driver &D, const llvm::Triple& Triple)
-    : Generic_GCC(D, Triple) {}
+  Generic_ELF(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+    : Generic_GCC(D, Triple, Args) {}
 
   virtual bool IsIntegratedAssemblerDefault() const {
     // Default integrated assembler to on for x86.
@@ -443,15 +444,26 @@
 
 class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
 public:
-  AuroraUX(const Driver &D, const llvm::Triple& Triple);
+  AuroraUX(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
 };
 
+class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
+public:
+  Solaris(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+                           const ActionList &Inputs) const;
+
+  virtual bool IsIntegratedAssemblerDefault() const { return true; }
+};
+
+
 class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
 public:
-  OpenBSD(const Driver &D, const llvm::Triple& Triple);
+  OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -459,7 +471,7 @@
 
 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
 public:
-  FreeBSD(const Driver &D, const llvm::Triple& Triple);
+  FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -467,7 +479,7 @@
 
 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
 public:
-  NetBSD(const Driver &D, const llvm::Triple& Triple);
+  NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -475,7 +487,7 @@
 
 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF {
 public:
-  Minix(const Driver &D, const llvm::Triple& Triple);
+  Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -483,7 +495,7 @@
 
 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
 public:
-  DragonFly(const Driver &D, const llvm::Triple& Triple);
+  DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -491,7 +503,7 @@
 
 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
 public:
-  Linux(const Driver &D, const llvm::Triple& Triple);
+  Linux(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
   virtual bool HasNativeLLVMSupport() const;
 

Modified: cfe/branches/tooling/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Tools.cpp Mon Feb 20 19:34:24 2012
@@ -2079,6 +2079,7 @@
     !Args.hasFlag(options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
                   getToolChain().getTriple().getOS() != llvm::Triple::Cygwin &&
                   getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 &&
+                  getToolChain().getTriple().getOS() != llvm::Triple::Solaris &&
                   getToolChain().getTriple().getArch() !=
                   llvm::Triple::hexagon))
     CmdArgs.push_back("-fno-use-cxa-atexit");
@@ -2350,11 +2351,6 @@
                     options::OPT_fno_diagnostics_fixit_info))
     CmdArgs.push_back("-fno-diagnostics-fixit-info");
 
-  // Enable -fdiagnostics-show-name by default.
-  if (Args.hasFlag(options::OPT_fdiagnostics_show_name,
-                   options::OPT_fno_diagnostics_show_name, false))
-    CmdArgs.push_back("-fdiagnostics-show-name");
-
   // Enable -fdiagnostics-show-option by default.
   if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
                    options::OPT_fno_diagnostics_show_option))
@@ -4170,6 +4166,126 @@
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
+void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+                                      const InputInfo &Output,
+                                      const InputInfoList &Inputs,
+                                      const ArgList &Args,
+                                      const char *LinkingOutput) const {
+  ArgStringList CmdArgs;
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                       options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (InputInfoList::const_iterator
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+    const InputInfo &II = *it;
+    CmdArgs.push_back(II.getFilename());
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+
+void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+  // FIXME: Find a real GCC, don't hard-code versions here
+  std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/";
+  const llvm::Triple &T = getToolChain().getTriple();
+  std::string LibPath = "/usr/lib/";
+  llvm::Triple::ArchType Arch = T.getArch();
+  switch (Arch) {
+        case llvm::Triple::x86:
+          GCCLibPath += ("i386-" + T.getVendorName() + "-" +
+              T.getOSName()).str() + "/4.5.2/";
+          break;
+        case llvm::Triple::x86_64:
+          GCCLibPath += ("i386-" + T.getVendorName() + "-" +
+              T.getOSName()).str();
+          GCCLibPath += "/4.5.2/amd64/";
+          LibPath += "amd64/";
+          break;
+        default:
+          assert(0 && "Unsupported architecture");
+  }
+
+  ArgStringList CmdArgs;
+
+  if ((!Args.hasArg(options::OPT_nostdlib)) &&
+      (!Args.hasArg(options::OPT_shared))) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("_start");
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+    CmdArgs.push_back("-dn");
+  } else {
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("--dynamic-linker");
+      CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
+    }
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o"));
+      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
+      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
+    } else {
+      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
+    }
+  }
+
+  CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath));
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    CmdArgs.push_back("-lgcc");
+    CmdArgs.push_back("-lgcc_s");
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back("-lc");
+
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
+  }
+  CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
+
+  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
 void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
                                       const InputInfo &Output,
                                       const InputInfoList &Inputs,

Modified: cfe/branches/tooling/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.h (original)
+++ cfe/branches/tooling/lib/Driver/Tools.h Mon Feb 20 19:34:24 2012
@@ -483,6 +483,35 @@
   };
 } // end namespace minix
 
+  /// solaris -- Directly call Solaris assembler and linker
+namespace solaris {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("solaris::Assemble", "assembler",
+                                         TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("solaris::Link", "linker", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace solaris
+
   /// auroraux -- Directly call GNU Binutils assembler and linker
 namespace auroraux {
   class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {

Modified: cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp Mon Feb 20 19:34:24 2012
@@ -322,8 +322,6 @@
     Res.push_back("-fcolor-diagnostics");
   if (Opts.VerifyDiagnostics)
     Res.push_back("-verify");
-  if (Opts.ShowNames)
-    Res.push_back("-fdiagnostics-show-name");
   if (Opts.ShowOptionNames)
     Res.push_back("-fdiagnostics-show-option");
   if (Opts.ShowCategories == 1)
@@ -1217,7 +1215,6 @@
                                  /*Default=*/true);
   Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
   Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
-  Opts.ShowNames = Args.hasArg(OPT_fdiagnostics_show_name);
   Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
 
   // Default behavior is to not to show note include stacks.

Modified: cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp Mon Feb 20 19:34:24 2012
@@ -26,11 +26,8 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Path.h"
 
-#ifdef HAVE_CLANG_CONFIG_H
-# include "clang/Config/config.h"
-#endif
+#include "clang/Config/config.h" // C_INCLUDE_DIRS
 
-#include "llvm/Config/config.h"
 using namespace clang;
 using namespace clang::frontend;
 
@@ -418,6 +415,15 @@
                                 "", "", "", triple);
     break;
   case llvm::Triple::Solaris:
+    AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/",
+                                "i386-pc-solaris2.11", "", "", triple);
+    AddGnuCPlusPlusIncludePaths(
+        "/usr/gcc/4.5/lib/gcc/i386-pc-solaris2.11/4.5.2/include",
+        "", "", "", triple);
+    AddGnuCPlusPlusIncludePaths(
+        "/usr/gcc/4.5/lib/gcc/i386-pc-solaris2.11/4.5.2/include-fixed",
+        "", "", "", triple);
+
     // Solaris - Fall though..
   case llvm::Triple::AuroraUX:
     // AuroraUX

Modified: cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp Mon Feb 20 19:34:24 2012
@@ -333,6 +333,9 @@
   Builder.defineMacro("__ATOMIC_ACQ_REL", "4");
   Builder.defineMacro("__ATOMIC_SEQ_CST", "5");
 
+  // Support for #pragma redefine_extname (Sun compatibility)
+  Builder.defineMacro("__PRAGMA_REDEFINE_EXTNAME", "1");
+
   // As sad as it is, enough software depends on the __VERSION__ for version
   // checks that it is necessary to report 4.2.1 (the base GCC version we claim
   // compatibility with) first.

Modified: cfe/branches/tooling/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/TextDiagnosticPrinter.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/TextDiagnosticPrinter.cpp Mon Feb 20 19:34:24 2012
@@ -46,16 +46,6 @@
   TextDiag.reset(0);
 }
 
-/// \brief Print the diagnostic name to a raw_ostream.
-///
-/// This prints the diagnostic name to a raw_ostream if it has one. It formats
-/// the name according to the expected diagnostic message formatting:
-///   " [diagnostic_name_here]"
-static void printDiagnosticName(raw_ostream &OS, const Diagnostic &Info) {
-  if (!DiagnosticIDs::isBuiltinNote(Info.getID()))
-    OS << " [" << DiagnosticIDs::getName(Info.getID()) << "]";
-}
-
 /// \brief Print any diagnostic option information to a raw_ostream.
 ///
 /// This implements all of the logic for adding diagnostic options to a message
@@ -136,8 +126,6 @@
   Info.FormatDiagnostic(OutStr);
 
   llvm::raw_svector_ostream DiagMessageStream(OutStr);
-  if (DiagOpts->ShowNames)
-    printDiagnosticName(DiagMessageStream, Info);
   printDiagnosticOptions(DiagMessageStream, Level, Info, *DiagOpts);
 
   // Keeps track of the the starting position of the location

Modified: cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp Mon Feb 20 19:34:24 2012
@@ -638,7 +638,7 @@
            .Case("cxx_atomic", LangOpts.CPlusPlus0x)
            .Case("cxx_attributes", LangOpts.CPlusPlus0x)
            .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
-         //.Case("cxx_constexpr", false);
+           .Case("cxx_constexpr", LangOpts.CPlusPlus0x)
            .Case("cxx_decltype", LangOpts.CPlusPlus0x)
            .Case("cxx_default_function_template_args", LangOpts.CPlusPlus0x)
            .Case("cxx_defaulted_functions", LangOpts.CPlusPlus0x)

Modified: cfe/branches/tooling/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseDecl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseDecl.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseDecl.cpp Mon Feb 20 19:34:24 2012
@@ -132,14 +132,15 @@
 
       if (Tok.is(tok::l_paren)) {
         // handle "parameterized" attributes
-        if (LateAttrs && !ClassStack.empty() &&
-            isAttributeLateParsed(*AttrName)) {
-          // Delayed parsing is only available for attributes that occur
-          // in certain locations within a class scope.
+        if (LateAttrs && isAttributeLateParsed(*AttrName)) {
           LateParsedAttribute *LA =
             new LateParsedAttribute(this, *AttrName, AttrNameLoc);
           LateAttrs->push_back(LA);
-          getCurrentClass().LateParsedDeclarations.push_back(LA);
+
+          // Attributes in a class are parsed at the end of the class, along
+          // with other late-parsed declarations.
+          if (!ClassStack.empty())
+            getCurrentClass().LateParsedDeclarations.push_back(LA);
 
           // consume everything up to and including the matching right parens
           ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
@@ -711,7 +712,7 @@
 }
 
 void Parser::LateParsedAttribute::ParseLexedAttributes() {
-  Self->ParseLexedAttribute(*this);
+  Self->ParseLexedAttribute(*this, true, false);
 }
 
 /// Wrapper class which calls ParseLexedAttribute, after setting up the
@@ -736,12 +737,25 @@
   }
 }
 
+
+/// \brief Parse all attributes in LAs, and attach them to Decl D.
+void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
+                                     bool EnterScope, bool OnDefinition) {
+  for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
+    LAs[i]->setDecl(D);
+    ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
+  }
+  LAs.clear();
+}
+
+
 /// \brief Finish parsing an attribute for which parsing was delayed.
 /// This will be called at the end of parsing a class declaration
 /// for each LateParsedAttribute. We consume the saved tokens and
 /// create an attribute with the arguments filled in. We add this 
 /// to the Attribute list for the decl.
-void Parser::ParseLexedAttribute(LateParsedAttribute &LA) {
+void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
+                                 bool EnterScope, bool OnDefinition) {
   // Save the current token position.
   SourceLocation OrigLoc = Tok.getLocation();
 
@@ -752,17 +766,23 @@
   // Consume the previously pushed token.
   ConsumeAnyToken();
 
+  if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
+    Diag(Tok, diag::warn_attribute_on_function_definition)
+      << LA.AttrName.getName();
+  }
+
   ParsedAttributes Attrs(AttrFactory);
   SourceLocation endLoc;
 
   // If the Decl is templatized, add template parameters to scope.
-  bool HasTemplateScope = LA.D && LA.D->isTemplateDecl();
+  bool HasTemplateScope = EnterScope && LA.D && LA.D->isTemplateDecl();
   ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
   if (HasTemplateScope)
     Actions.ActOnReenterTemplateScope(Actions.CurScope, LA.D);
 
   // If the Decl is on a function, add function parameters to the scope.
-  bool HasFunctionScope = LA.D && LA.D->isFunctionOrFunctionTemplate();
+  bool HasFunctionScope = EnterScope && LA.D &&
+                          LA.D->isFunctionOrFunctionTemplate();
   ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope);
   if (HasFunctionScope)
     Actions.ActOnReenterFunctionContext(Actions.CurScope, LA.D);
@@ -1064,6 +1084,12 @@
     return DeclGroupPtrTy();
   }
 
+  // Save late-parsed attributes for now; they need to be parsed in the
+  // appropriate function scope after the function Decl has been constructed.
+  LateParsedAttrList LateParsedAttrs;
+  if (D.isFunctionDeclarator())
+    MaybeParseGNUAttributes(D, &LateParsedAttrs);
+
   // Check to see if we have a function *definition* which must have a body.
   if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
       // Look at the next token to make sure that this isn't a function
@@ -1079,7 +1105,8 @@
         DS.ClearStorageClassSpecs();
       }
 
-      Decl *TheDecl = ParseFunctionDefinition(D);
+      Decl *TheDecl =
+        ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
       return Actions.ConvertDeclToDeclGroup(TheDecl);
     }
     
@@ -1096,7 +1123,7 @@
     }
   }
 
-  if (ParseAttributesAfterDeclarator(D))
+  if (ParseAsmAttributesAfterDeclarator(D))
     return DeclGroupPtrTy();
 
   // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
@@ -1117,6 +1144,8 @@
 
   SmallVector<Decl *, 8> DeclsInGroup;
   Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
+  if (LateParsedAttrs.size() > 0)
+    ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
   D.complete(FirstDecl);
   if (FirstDecl)
     DeclsInGroup.push_back(FirstDecl);
@@ -1185,7 +1214,7 @@
 
 /// Parse an optional simple-asm-expr and attributes, and attach them to a
 /// declarator. Returns true on an error.
-bool Parser::ParseAttributesAfterDeclarator(Declarator &D) {
+bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
   // If a simple-asm-expr is present, parse it.
   if (Tok.is(tok::kw_asm)) {
     SourceLocation Loc;
@@ -1227,7 +1256,7 @@
 ///
 Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
                                      const ParsedTemplateInfo &TemplateInfo) {
-  if (ParseAttributesAfterDeclarator(D))
+  if (ParseAsmAttributesAfterDeclarator(D))
     return 0;
 
   return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);

Modified: cfe/branches/tooling/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExpr.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExpr.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExpr.cpp Mon Feb 20 19:34:24 2012
@@ -726,7 +726,9 @@
          (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
       ConsumeToken();
       
-      if (Tok.isNot(tok::identifier)) {
+      // Allow either an identifier or the keyword 'class' (in C++).
+      if (Tok.isNot(tok::identifier) && 
+          !(getLang().CPlusPlus && Tok.is(tok::kw_class))) {
         Diag(Tok, diag::err_expected_property_name);
         return ExprError();
       }
@@ -1406,11 +1408,23 @@
       // FIXME: Add support for explicit call of template constructor.
       SourceLocation TemplateKWLoc;
       UnqualifiedId Name;
-      if (ParseUnqualifiedId(SS, 
-                             /*EnteringContext=*/false, 
-                             /*AllowDestructorName=*/true,
-                             /*AllowConstructorName=*/ getLang().MicrosoftExt, 
-                             ObjectType, TemplateKWLoc, Name))
+      if (getLang().ObjC2 && OpKind == tok::period && Tok.is(tok::kw_class)) {
+        // Objective-C++:
+        //   After a '.' in a member access expression, treat the keyword
+        //   'class' as if it were an identifier.
+        //
+        // This hack allows property access to the 'class' method because it is
+        // such a common method name. For other C++ keywords that are 
+        // Objective-C method names, one must use the message send syntax.
+        IdentifierInfo *Id = Tok.getIdentifierInfo();
+        SourceLocation Loc = ConsumeToken();
+        Name.setIdentifier(Id, Loc);
+      } else if (ParseUnqualifiedId(SS, 
+                                    /*EnteringContext=*/false, 
+                                    /*AllowDestructorName=*/true,
+                                    /*AllowConstructorName=*/
+                                      getLang().MicrosoftExt, 
+                                    ObjectType, TemplateKWLoc, Name))
         LHS = ExprError();
       
       if (!LHS.isInvalid())
@@ -1852,7 +1866,7 @@
     StringRef BridgeCastName = Tok.getName();
     SourceLocation BridgeKeywordLoc = ConsumeToken();
     if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
-      Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_nonarc)
+      Diag(BridgeKeywordLoc, diag::warn_arc_bridge_cast_nonarc)
         << BridgeCastName
         << FixItHint::CreateReplacement(BridgeKeywordLoc, "");
     BridgeCast = false;
@@ -2276,7 +2290,6 @@
   // allows determining whether a variable reference inside the block is
   // within or outside of the block.
   ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
-                              Scope::BreakScope | Scope::ContinueScope |
                               Scope::DeclScope);
 
   // Inform sema that we are starting a block.

Modified: cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp Mon Feb 20 19:34:24 2012
@@ -615,7 +615,7 @@
 /// ParseLambdaExpression - Parse a lambda introducer.
 ///
 /// Returns a DiagnosticID if it hit something unexpected.
-llvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) {
+llvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro){
   typedef llvm::Optional<unsigned> DiagResult;
 
   assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
@@ -640,18 +640,39 @@
 
   while (Tok.isNot(tok::r_square)) {
     if (!first) {
-      if (Tok.isNot(tok::comma))
+      if (Tok.isNot(tok::comma)) {
+        if (Tok.is(tok::code_completion)) {
+          Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
+                                               /*AfterAmpersand=*/false);
+          ConsumeCodeCompletionToken();
+          break;
+        }
+
         return DiagResult(diag::err_expected_comma_or_rsquare);
+      }
       ConsumeToken();
     }
 
-    first = false;
+    if (Tok.is(tok::code_completion)) {
+      // If we're in Objective-C++ and we have a bare '[', then this is more
+      // likely to be a message receiver.
+      if (getLang().ObjC1 && first)
+        Actions.CodeCompleteObjCMessageReceiver(getCurScope());
+      else
+        Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
+                                             /*AfterAmpersand=*/false);
+      ConsumeCodeCompletionToken();
+      break;
+    }
 
+    first = false;
+    
     // Parse capture.
     LambdaCaptureKind Kind = LCK_ByCopy;
     SourceLocation Loc;
     IdentifierInfo* Id = 0;
-
+    SourceLocation EllipsisLoc;
+    
     if (Tok.is(tok::kw_this)) {
       Kind = LCK_This;
       Loc = ConsumeToken();
@@ -659,11 +680,21 @@
       if (Tok.is(tok::amp)) {
         Kind = LCK_ByRef;
         ConsumeToken();
+
+        if (Tok.is(tok::code_completion)) {
+          Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
+                                               /*AfterAmpersand=*/true);
+          ConsumeCodeCompletionToken();
+          break;
+        }
       }
 
       if (Tok.is(tok::identifier)) {
         Id = Tok.getIdentifierInfo();
         Loc = ConsumeToken();
+        
+        if (Tok.is(tok::ellipsis))
+          EllipsisLoc = ConsumeToken();
       } else if (Tok.is(tok::kw_this)) {
         // FIXME: If we want to suggest a fixit here, will need to return more
         // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be
@@ -674,7 +705,7 @@
       }
     }
 
-    Intro.addCapture(Kind, Loc, Id);
+    Intro.addCapture(Kind, Loc, Id, EllipsisLoc);
   }
 
   T.consumeClose();
@@ -683,7 +714,7 @@
   return DiagResult();
 }
 
-/// TryParseLambdaExpression - Tentatively parse a lambda introducer.
+/// TryParseLambdaIntroducer - Tentatively parse a lambda introducer.
 ///
 /// Returns true if it hit something unexpected.
 bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
@@ -789,12 +820,57 @@
                                            DeclLoc, DeclEndLoc, D,
                                            TrailingReturnType),
                   Attr, DeclEndLoc);
+  } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow)) {
+    // It's common to forget that one needs '()' before 'mutable' or the 
+    // result type. Deal with this.
+    Diag(Tok, diag::err_lambda_missing_parens)
+      << Tok.is(tok::arrow)
+      << FixItHint::CreateInsertion(Tok.getLocation(), "() ");
+    SourceLocation DeclLoc = Tok.getLocation();
+    SourceLocation DeclEndLoc = DeclLoc;
+    
+    // Parse 'mutable', if it's there.
+    SourceLocation MutableLoc;
+    if (Tok.is(tok::kw_mutable)) {
+      MutableLoc = ConsumeToken();
+      DeclEndLoc = MutableLoc;
+    }
+    
+    // Parse the return type, if there is one.
+    ParsedType TrailingReturnType;
+    if (Tok.is(tok::arrow)) {
+      SourceRange Range;
+      TrailingReturnType = ParseTrailingReturnType(Range).get();
+      if (Range.getEnd().isValid())
+        DeclEndLoc = Range.getEnd();      
+    }
+
+    ParsedAttributes Attr(AttrFactory);
+    D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
+                     /*isVariadic=*/false,
+                     /*EllipsisLoc=*/SourceLocation(),
+                     /*Params=*/0, /*NumParams=*/0,
+                     /*TypeQuals=*/0,
+                     /*RefQualifierIsLValueRef=*/true,
+                     /*RefQualifierLoc=*/SourceLocation(),
+                     /*ConstQualifierLoc=*/SourceLocation(),
+                     /*VolatileQualifierLoc=*/SourceLocation(),
+                     MutableLoc,
+                     EST_None, 
+                     /*ESpecLoc=*/SourceLocation(),
+                     /*Exceptions=*/0,
+                     /*ExceptionRanges=*/0,
+                     /*NumExceptions=*/0,
+                     /*NoexceptExpr=*/0,
+                     DeclLoc, DeclEndLoc, D,
+                     TrailingReturnType),
+                  Attr, DeclEndLoc);
   }
+  
 
   // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
   // it.
   ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
-                             Scope::BreakScope | Scope::ContinueScope |
                              Scope::DeclScope);
 
   Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
@@ -2162,10 +2238,11 @@
     return ExprError();
   }
 
-  ExprVector ConstructorArgs(Actions);
-  SourceLocation ConstructorLParen, ConstructorRParen;
+  ExprResult Initializer;
 
   if (Tok.is(tok::l_paren)) {
+    SourceLocation ConstructorLParen, ConstructorRParen;
+    ExprVector ConstructorArgs(Actions);
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.consumeOpen();
     ConstructorLParen = T.getOpenLocation();
@@ -2182,19 +2259,20 @@
       SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
       return ExprError();
     }
+    Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
+                                             ConstructorRParen,
+                                             move_arg(ConstructorArgs));
   } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) {
     Diag(Tok.getLocation(),
          diag::warn_cxx98_compat_generalized_initializer_lists);
-    ExprResult InitList = ParseBraceInitializer();
-    if (InitList.isInvalid())
-      return InitList;
-    ConstructorArgs.push_back(InitList.take());
+    Initializer = ParseBraceInitializer();
   }
+  if (Initializer.isInvalid())
+    return Initializer;
 
   return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
                              move_arg(PlacementArgs), PlacementRParen,
-                             TypeIdParens, DeclaratorInfo, ConstructorLParen,
-                             move_arg(ConstructorArgs), ConstructorRParen);
+                             TypeIdParens, DeclaratorInfo, Initializer.take());
 }
 
 /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be

Modified: cfe/branches/tooling/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseInit.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseInit.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseInit.cpp Mon Feb 20 19:34:24 2012
@@ -21,18 +21,92 @@
 using namespace clang;
 
 
-/// MayBeDesignationStart - Return true if this token might be the start of a
-/// designator.  If we can tell it is impossible that it is a designator, return
-/// false.
-static bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) {
-  switch (K) {
-  default: return false;
+/// MayBeDesignationStart - Return true if the current token might be the start 
+/// of a designator.  If we can tell it is impossible that it is a designator, 
+/// return false.
+bool Parser::MayBeDesignationStart() {
+  switch (Tok.getKind()) {
+  default: 
+    return false;
+      
   case tok::period:      // designator: '.' identifier
-  case tok::l_square:    // designator: array-designator
+    return true;
+      
+  case tok::l_square: {  // designator: array-designator
+    if (!PP.getLangOptions().CPlusPlus0x)
       return true;
+    
+    // C++11 lambda expressions and C99 designators can be ambiguous all the
+    // way through the closing ']' and to the next character. Handle the easy
+    // cases here, and fall back to tentative parsing if those fail.
+    switch (PP.LookAhead(0).getKind()) {
+    case tok::equal:
+    case tok::r_square:
+      // Definitely starts a lambda expression.
+      return false;
+      
+    case tok::amp:
+    case tok::kw_this:
+    case tok::identifier:
+      // We have to do additional analysis, because these could be the
+      // start of a constant expression or a lambda capture list.
+      break;
+        
+    default:
+      // Anything not mentioned above cannot occur following a '[' in a 
+      // lambda expression.
+      return true;        
+    }
+    
+    // Handle the complicated case below.
+    break;    
+  }
   case tok::identifier:  // designation: identifier ':'
     return PP.LookAhead(0).is(tok::colon);
   }
+  
+  // Parse up to (at most) the token after the closing ']' to determine 
+  // whether this is a C99 designator or a lambda.
+  TentativeParsingAction Tentative(*this);
+  ConsumeBracket();
+  while (true) {
+    switch (Tok.getKind()) {
+    case tok::equal:
+    case tok::amp:
+    case tok::identifier:
+    case tok::kw_this:
+      // These tokens can occur in a capture list or a constant-expression.
+      // Keep looking.
+      ConsumeToken();
+      continue;
+      
+    case tok::comma:
+      // Since a comma cannot occur in a constant-expression, this must
+      // be a lambda.
+      Tentative.Revert();
+      return false;
+      
+    case tok::r_square: {
+      // Once we hit the closing square bracket, we look at the next
+      // token. If it's an '=', this is a designator. Otherwise, it's a
+      // lambda expression. This decision favors lambdas over the older
+      // GNU designator syntax, which allows one to omit the '=', but is
+      // consistent with GCC.
+      ConsumeBracket();
+      tok::TokenKind Kind = Tok.getKind();
+      Tentative.Revert();
+      return Kind == tok::equal;
+    }
+      
+    default:
+      // Anything else cannot occur in a lambda capture list, so it
+      // must be a designator.
+      Tentative.Revert();
+      return true;
+    }
+  }
+  
+  return true;
 }
 
 static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
@@ -356,7 +430,7 @@
     // If we know that this cannot be a designation, just parse the nested
     // initializer directly.
     ExprResult SubElt;
-    if (MayBeDesignationStart(Tok.getKind(), PP))
+    if (MayBeDesignationStart())
       SubElt = ParseInitializerWithPotentialDesignator();
     else
       SubElt = ParseInitializer();
@@ -439,7 +513,7 @@
     // If we know that this cannot be a designation, just parse the nested
     // initializer directly.
     ExprResult SubElt;
-    if (MayBeDesignationStart(Tok.getKind(), PP))
+    if (MayBeDesignationStart())
       SubElt = ParseInitializerWithPotentialDesignator();
     else
       SubElt = ParseInitializer();

Modified: cfe/branches/tooling/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseObjc.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseObjc.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseObjc.cpp Mon Feb 20 19:34:24 2012
@@ -2635,9 +2635,11 @@
   StmtResult FnBody(ParseCompoundStatementBody());
     
   // If the function body could not be parsed, make a bogus compoundstmt.
-  if (FnBody.isInvalid())
+  if (FnBody.isInvalid()) {
+    Sema::CompoundScopeRAII CompoundScope(Actions);
     FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
                                        MultiStmtArg(Actions), false);
+  }
     
   // Leave the function body scope.
   BodyScope.Exit();

Modified: cfe/branches/tooling/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParsePragma.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParsePragma.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParsePragma.cpp Mon Feb 20 19:34:24 2012
@@ -426,6 +426,44 @@
   }
 }
 
+// #pragma redefine_extname identifier identifier
+void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, 
+                                               PragmaIntroducerKind Introducer,
+                                                Token &RedefToken) {
+  SourceLocation RedefLoc = RedefToken.getLocation();
+
+  Token Tok;
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
+      "redefine_extname";
+    return;
+  }
+
+  IdentifierInfo *RedefName = Tok.getIdentifierInfo(), *AliasName = 0;
+  SourceLocation RedefNameLoc = Tok.getLocation(), AliasNameLoc;
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+        << "redefine_extname";
+    return;
+  }
+  AliasName = Tok.getIdentifierInfo();
+  AliasNameLoc = Tok.getLocation();
+  PP.Lex(Tok);
+
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
+      "redefine_extname";
+    return;
+  }
+
+  Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
+      RedefNameLoc, AliasNameLoc);
+}
+
+
 void
 PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 
                                       PragmaIntroducerKind Introducer,

Modified: cfe/branches/tooling/lib/Parse/ParsePragma.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParsePragma.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParsePragma.h (original)
+++ cfe/branches/tooling/lib/Parse/ParsePragma.h Mon Feb 20 19:34:24 2012
@@ -90,6 +90,16 @@
                             Token &FirstToken);
 };
 
+class PragmaRedefineExtnameHandler : public PragmaHandler {
+  Sema &Actions;
+public:
+  explicit PragmaRedefineExtnameHandler(Sema &A)
+    : PragmaHandler("redefine_extname"), Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                            Token &FirstToken);
+};
+
 class PragmaOpenCLExtensionHandler : public PragmaHandler {
   Sema &Actions;
   Parser &parser;

Modified: cfe/branches/tooling/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseStmt.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseStmt.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseStmt.cpp Mon Feb 20 19:34:24 2012
@@ -596,7 +596,8 @@
     // Nicely diagnose the common error "switch (X) { case 4: }", which is
     // not valid.
     SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
-    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement);
+    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
+      << FixItHint::CreateInsertion(AfterColonLoc, " ;");
     SubStmt = true;
   }
 
@@ -638,16 +639,22 @@
     ColonLoc = ExpectedLoc;
   }
 
-  // Diagnose the common error "switch (X) {... default: }", which is not valid.
-  if (Tok.is(tok::r_brace)) {
+  StmtResult SubStmt;
+
+  if (Tok.isNot(tok::r_brace)) {
+    SubStmt = ParseStatement();
+  } else {
+    // Diagnose the common error "switch (X) {... default: }", which is
+    // not valid.
     SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
-    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement);
-    return StmtError();
+    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
+      << FixItHint::CreateInsertion(AfterColonLoc, " ;");
+    SubStmt = true;
   }
 
-  StmtResult SubStmt(ParseStatement());
+  // Broken sub-stmt shouldn't prevent forming the case statement properly.
   if (SubStmt.isInvalid())
-    return StmtError();
+    SubStmt = Actions.ActOnNullStmt(ColonLoc);
 
   return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
                                   SubStmt.get(), getCurScope());
@@ -700,7 +707,6 @@
   return ParseCompoundStatementBody(isStmtExpr);
 }
 
-
 /// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
 /// ActOnCompoundStmt action.  This expects the '{' to be the current token, and
 /// consume the '}' at the end of the block.  It does not manipulate the scope
@@ -714,6 +720,8 @@
   if (T.consumeOpen())
     return StmtError();
 
+  Sema::CompoundScopeRAII CompoundScope(Actions);
+
   StmtVector Stmts(Actions);
 
   // "__label__ X, Y, Z;" is the GNU "Local Label" extension.  These are
@@ -1084,9 +1092,14 @@
   InnerScope.Exit();
   SwitchScope.Exit();
 
-  if (Body.isInvalid())
+  if (Body.isInvalid()) {
     // FIXME: Remove the case statement list from the Switch statement.
-    Body = Actions.ActOnNullStmt(Tok.getLocation());
+
+    // Put the synthesized null statement on the same line as the end of switch
+    // condition.
+    SourceLocation SynthesizedNullStmtLocation = Cond.get()->getLocEnd();
+    Body = Actions.ActOnNullStmt(SynthesizedNullStmtLocation);
+  }
 
   return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
 }
@@ -1956,9 +1969,11 @@
   StmtResult FnBody(ParseCompoundStatementBody());
 
   // If the function body could not be parsed, make a bogus compoundstmt.
-  if (FnBody.isInvalid())
+  if (FnBody.isInvalid()) {
+    Sema::CompoundScopeRAII CompoundScope(Actions);
     FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
                                        MultiStmtArg(Actions), false);
+  }
 
   BodyScope.Exit();
   return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
@@ -1993,9 +2008,11 @@
   StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc));
   // If we failed to parse the try-catch, we just give the function an empty
   // compound statement as the body.
-  if (FnBody.isInvalid())
+  if (FnBody.isInvalid()) {
+    Sema::CompoundScopeRAII CompoundScope(Actions);
     FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
                                        MultiStmtArg(Actions), false);
+  }
 
   BodyScope.Exit();
   return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());

Modified: cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseTemplate.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseTemplate.cpp Mon Feb 20 19:34:24 2012
@@ -241,6 +241,10 @@
     return 0;
   }
 
+  LateParsedAttrList LateParsedAttrs;
+  if (DeclaratorInfo.isFunctionDeclarator())
+    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
+
   // If we have a declaration or declarator list, handle it.
   if (isDeclarationAfterDeclarator()) {
     // Parse this declaration.
@@ -256,6 +260,8 @@
 
     // Eat the semi colon after the declaration.
     ExpectAndConsume(tok::semi, diag::err_expected_semi_declaration);
+    if (LateParsedAttrs.size() > 0)
+      ParseLexedAttributeList(LateParsedAttrs, ThisDecl, true, false);
     DeclaratorInfo.complete(ThisDecl);
     return ThisDecl;
   }
@@ -270,7 +276,8 @@
         << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
       DS.ClearStorageClassSpecs();
     }
-    return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo);
+    return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo,
+                                   &LateParsedAttrs);
   }
 
   if (DeclaratorInfo.isFunctionDeclarator())

Modified: cfe/branches/tooling/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/Parser.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/Parser.cpp (original)
+++ cfe/branches/tooling/lib/Parse/Parser.cpp Mon Feb 20 19:34:24 2012
@@ -64,6 +64,9 @@
   WeakHandler.reset(new PragmaWeakHandler(actions));
   PP.AddPragmaHandler(WeakHandler.get());
 
+  RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler(actions));
+  PP.AddPragmaHandler(RedefineExtnameHandler.get());
+
   FPContractHandler.reset(new PragmaFPContractHandler(actions, *this));
   PP.AddPragmaHandler("STDC", FPContractHandler.get());
 
@@ -382,6 +385,8 @@
   UnusedHandler.reset();
   PP.RemovePragmaHandler(WeakHandler.get());
   WeakHandler.reset();
+  PP.RemovePragmaHandler(RedefineExtnameHandler.get());
+  RedefineExtnameHandler.reset();
 
   if (getLang().OpenCL) {
     PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
@@ -821,7 +826,8 @@
 ///         decl-specifier-seq[opt] declarator function-try-block
 ///
 Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
-                                      const ParsedTemplateInfo &TemplateInfo) {
+                                      const ParsedTemplateInfo &TemplateInfo,
+                                      LateParsedAttrList *LateParsedAttrs) {
   // Poison the SEH identifiers so they are flagged as illegal in function bodies
   PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
   const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
@@ -844,7 +850,6 @@
   if (FTI.isKNRPrototype())
     ParseKNRParamDeclarations(D);
 
-
   // We should have either an opening brace or, in a C++ constructor,
   // we may have a colon.
   if (Tok.isNot(tok::l_brace) && 
@@ -861,6 +866,19 @@
       return 0;
   }
 
+  // Check to make sure that any normal attributes are allowed to be on
+  // a definition.  Late parsed attributes are checked at the end.
+  if (Tok.isNot(tok::equal)) {
+    AttributeList *DtorAttrs = D.getAttributes();
+    while (DtorAttrs) {
+      if (!IsThreadSafetyAttribute(DtorAttrs->getName()->getName())) {
+        Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition)
+          << DtorAttrs->getName()->getName();
+      }
+      DtorAttrs = DtorAttrs->getNext();
+    }
+  }
+
   // In delayed template parsing mode, for function template we consume the
   // tokens and store them for late parsing at the end of the translation unit.
   if (getLang().DelayedTemplateParsing &&
@@ -974,6 +992,10 @@
   } else
     Actions.ActOnDefaultCtorInitializers(Res);
 
+  // Late attributes are parsed in the same scope as the function body.
+  if (LateParsedAttrs)
+    ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
+
   return ParseFunctionStatementBody(Res, BodyScope);
 }
 

Modified: cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp Mon Feb 20 19:34:24 2012
@@ -107,8 +107,8 @@
     SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
     llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
     llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
-    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
-    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
+    SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
     SmallVector<Stmt *, 32> Stmts;
     SmallVector<int, 8> ObjCBcLabelNo;
     // Remember all the @protocol(<expr>) expressions.
@@ -161,7 +161,7 @@
     void InitializeCommon(ASTContext &context);
 
   public:
-
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
     // Top Level Driver code.
     virtual bool HandleTopLevelDecl(DeclGroupRef D) {
       for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
@@ -169,6 +169,10 @@
           if (!Class->isThisDeclarationADefinition()) {
             RewriteForwardClassDecl(D);
             break;
+          } else {
+            // Keep track of all interface declarations seen.
+            ObjCInterfacesSeen.push_back(Class->getCanonicalDecl());
+            break;
           }
         }
 
@@ -1192,7 +1196,7 @@
     SuperClass = SuperClass->getSuperClass();
   }
   std::string ResultStr;
-  if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
+  if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
     // we haven't seen a forward decl - generate a typedef.
     ResultStr = "#ifndef _REWRITER_typedef_";
     ResultStr += ClassDecl->getNameAsString();
@@ -1203,29 +1207,26 @@
     ResultStr += "typedef struct objc_object ";
     ResultStr += ClassDecl->getNameAsString();
     ResultStr += ";\n#endif\n";
-    // Mark this typedef as having been generated.
-    ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl());
-  }
-  RewriteObjCInternalStruct(ClassDecl, ResultStr);
-
-  for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
+    RewriteObjCInternalStruct(ClassDecl, ResultStr);
+    // Mark this typedef as having been written into its c++ equivalent.
+    ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl());
+  
+    for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
          E = ClassDecl->prop_end(); I != E; ++I)
-    RewriteProperty(*I);
-  for (ObjCInterfaceDecl::instmeth_iterator
+      RewriteProperty(*I);
+    for (ObjCInterfaceDecl::instmeth_iterator
          I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-  for (ObjCInterfaceDecl::classmeth_iterator
+         I != E; ++I)
+      RewriteMethodDeclaration(*I);
+    for (ObjCInterfaceDecl::classmeth_iterator
          I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
+         I != E; ++I)
+      RewriteMethodDeclaration(*I);
 
-  // Lastly, comment out the @end.
-  ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
-              "/* @end */");
-  // Mark this struct as having been generated.
-  if (!ObjCSynthesizedStructs.insert(ClassDecl))
-    llvm_unreachable("struct already synthesize- RewriteInterfaceDecl");
+    // Lastly, comment out the @end.
+    ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
+                "/* @end */");
+  }
 }
 
 Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
@@ -3167,7 +3168,7 @@
   Result += CDecl->getNameAsString();
   Result += "_IMPL {\n";
   
-  if (RCDecl) {
+  if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
     Result += "\tstruct "; Result += RCDecl->getNameAsString();
     Result += "_IMPL "; Result += RCDecl->getNameAsString();
     Result += "_IVARS;\n";
@@ -3191,6 +3192,9 @@
   Result += "};\n";
   endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
   ReplaceText(LocStart, endBuf-startBuf, Result);
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl))
+    llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
 }
 
 //===----------------------------------------------------------------------===//
@@ -3202,6 +3206,16 @@
 /// and emits meta-data.
 
 void RewriteModernObjC::RewriteImplementations() {
+  
+  for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
+    ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
+    // Write struct declaration for the class matching its ivar declarations.
+    // Note that for modern abi, this is postponed until the end of TU
+    // because class extensions and the implementation might declare their own
+    // private ivars.
+    RewriteInterfaceDecl(CDecl);
+  }
+  
   int ClsDefCount = ClassImplementation.size();
   int CatDefCount = CategoryImplementation.size();
 
@@ -3210,18 +3224,19 @@
     ObjCImplementationDecl *OIMP = ClassImplementation[i];
     ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
     if (CDecl->isImplicitInterfaceDecl())
-    assert(false &&
-           "Legacy implicit interface rewriting not supported in moder abi");
-    // Write struct declaration for the class matching its ivar declarations.
-    // Note that for modern abi, this is postponed until implementation decl.
-    // because class extensions and the implementation might declare their own
-    // private ivars.
-    RewriteInterfaceDecl(CDecl);
+      assert(false &&
+             "Legacy implicit interface rewriting not supported in moder abi");
     RewriteImplementationDecl(OIMP);
   }
 
-  for (int i = 0; i < CatDefCount; i++)
-    RewriteImplementationDecl(CategoryImplementation[i]);
+  for (int i = 0; i < CatDefCount; i++) {
+    ObjCCategoryImplDecl *CIMP = CategoryImplementation[i];
+    ObjCInterfaceDecl *CDecl = CIMP->getClassInterface();
+    if (CDecl->isImplicitInterfaceDecl())
+      assert(false &&
+             "Legacy implicit interface rewriting not supported in moder abi");
+    RewriteImplementationDecl(CIMP);
+  }
 }
 
 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 
@@ -5208,7 +5223,7 @@
 ///   const uint8_t * const ivarLayout;
 ///   const char *const name;
 ///   const struct _method_list_t * const baseMethods;
-///   const struct _objc_protocol_list *const baseProtocols;
+///   const struct _protocol_list_t *const baseProtocols;
 ///   const struct _ivar_list_t *const ivars;
 ///   const uint8_t * const weakIvarLayout;
 ///   const struct _prop_list_t * const properties;
@@ -5219,7 +5234,7 @@
 ///   struct _class_t * const superclass;
 ///   void *cache;
 ///   IMP *vtable;
-///   struct class_ro_t *ro;
+///   struct _class_ro_t *ro;
 /// }
 
 /// struct _category_t {
@@ -5258,7 +5273,7 @@
   Result += "\nstruct _objc_method {\n";
   Result += "\tstruct objc_selector * _cmd;\n";
   Result += "\tconst char *method_type;\n";
-  Result += "\tchar *_imp;\n";
+  Result += "\tvoid  *_imp;\n";
   Result += "};\n";
   
   Result += "\nstruct _protocol_t {\n";
@@ -5302,7 +5317,7 @@
   Result += "\tstruct _class_t *const superclass;\n";
   Result += "\tvoid *cache;\n";
   Result += "\tvoid *vtable;\n";
-  Result += "\tstruct class_ro_t *ro;\n";
+  Result += "\tstruct _class_ro_t *ro;\n";
   Result += "};\n";
   
   Result += "\nstruct _category_t {\n";
@@ -5314,6 +5329,9 @@
   Result += "\tconst struct _prop_list_t *const properties;\n";
   Result += "};\n";
   
+  Result += "extern void *_objc_empty_cache;\n";
+  Result += "extern void *_objc_empty_vtable;\n";
+  
   meta_data_declared = true;
 }
 
@@ -5379,15 +5397,17 @@
   }
 }
 
-static void Write_method_list_t_initializer(ASTContext *Context, std::string &Result,
+static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                            ASTContext *Context, std::string &Result,
                                             ArrayRef<ObjCMethodDecl *> Methods,
                                             StringRef VarName,
-                                            StringRef ProtocolName) {
+                                            StringRef TopLevelDeclName,
+                                            bool MethodImpl) {
   if (Methods.size() > 0) {
     Result += "\nstatic ";
     Write_method_list_t_TypeDecl(Result, Methods.size());
     Result += " "; Result += VarName;
-    Result += ProtocolName; 
+    Result += TopLevelDeclName; 
     Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
     Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n";
     Result += "\t"; Result += utostr(Methods.size()); Result += ",\n";
@@ -5403,17 +5423,22 @@
       Context->getObjCEncodingForMethodDecl(MD, MethodTypeString);
       Result += "\""; Result += MethodTypeString; Result += "\"";
       Result += ", ";
-      // FIXME is _imp always null here?
+      if (!MethodImpl)
+        Result += "0";
+      else {
+        Result += "(void *)";
+        Result += RewriteObj.MethodInternalNames[MD];
+      }
       if (i  == e-1)
-        Result += "0}}\n";
+        Result += "}}\n";
       else
-        Result += "0},\n";
+        Result += "},\n";
     }
     Result += "};\n";
   }
 }
 
-static void Write__prop_list_t_initializer(RewriteModernObjC &RewriteObj,
+static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
                                            ASTContext *Context, std::string &Result,
                                            ArrayRef<ObjCPropertyDecl *> Properties,
                                            const Decl *Container,
@@ -5447,6 +5472,204 @@
   }
 }
 
+// Metadata flags
+enum MetaDataDlags {
+  CLS = 0x0,
+  CLS_META = 0x1,
+  CLS_ROOT = 0x2,
+  OBJC2_CLS_HIDDEN = 0x10,
+  CLS_EXCEPTION = 0x20,
+  
+  /// (Obsolete) ARC-specific: this class has a .release_ivars method
+  CLS_HAS_IVAR_RELEASER = 0x40,
+  /// class was compiled with -fobjc-arr
+  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
+};
+
+static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 
+                                          unsigned int flags, 
+                                          const std::string &InstanceStart, 
+                                          const std::string &InstanceSize,
+                                          ArrayRef<ObjCMethodDecl *>baseMethods,
+                                          ArrayRef<ObjCProtocolDecl *>baseProtocols,
+                                          ArrayRef<ObjCIvarDecl *>ivars,
+                                          ArrayRef<ObjCPropertyDecl *>Properties,
+                                          StringRef VarName,
+                                          StringRef ClassName) {
+  Result += "\nstatic struct _class_ro_t ";
+  Result += VarName; Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+  Result += "\t"; 
+  Result += llvm::utostr(flags); Result += ", "; 
+  Result += InstanceStart; Result += ", ";
+  Result += InstanceSize; Result += ", \n";
+  Result += "\t";
+  // uint32_t const reserved; // only when building for 64bit targets
+  Result += "(unsigned int)0, \n\t";
+  // const uint8_t * const ivarLayout;
+  Result += "0, \n\t";
+  Result += "\""; Result += ClassName; Result += "\",\n\t";
+  bool metaclass = ((flags & CLS_META) != 0);
+  if (baseMethods.size() > 0) {
+    Result += "(const struct _method_list_t *)&";
+    if (metaclass)
+      Result += "_OBJC_$_CLASS_METHODS_";
+    else
+      Result += "_OBJC_$_INSTANCE_METHODS_";
+    Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  if (!metaclass && baseProtocols.size() > 0) {
+    Result += "(const struct _objc_protocol_list *)&";
+    Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  if (!metaclass && ivars.size() > 0) {
+    Result += "(const struct _ivar_list_t *)&";
+    Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  // weakIvarLayout
+  Result += "0, \n\t";
+  if (!metaclass && Properties.size() > 0) {
+    Result += "(const struct _prop_list_t *)&";
+    Result += "_OBJC_$_PROP_LIST_"; Result += ClassName;
+    Result += ",\n";
+  }
+  else
+    Result += "0, \n";
+
+  Result += "};\n";
+}
+
+static void Write_class_t(ASTContext *Context, std::string &Result,
+                          StringRef VarName,
+                          const ObjCInterfaceDecl *CDecl, bool metadata) {
+  
+  if (metadata && !CDecl->getSuperClass()) {
+    // Need to handle a case of use of forward declaration.
+    Result += "\nextern struct _class_t OBJC_CLASS_$_";
+    Result += CDecl->getNameAsString();
+    Result += ";\n";
+  }
+  // Also, for possibility of 'super' metadata class not having been defined yet.
+  if (CDecl->getSuperClass()) {
+    Result += "\nextern struct _class_t "; Result += VarName;
+    Result += CDecl->getSuperClass()->getNameAsString();
+    Result += ";\n";
+  }
+  
+  Result += "\nstruct _class_t "; Result += VarName; Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
+  Result += "\t";
+  if (metadata) {
+    if (CDecl->getSuperClass()) {
+      Result += "&"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+      Result += "&"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+    }
+    else {
+      Result += "&"; Result += VarName; 
+      Result += CDecl->getNameAsString();
+      Result += ",\n\t";
+      Result += "&OBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+      Result += ",\n\t";
+    }
+  }
+  else {
+    Result += "&OBJC_METACLASS_$_"; 
+    Result += CDecl->getNameAsString();
+    Result += ",\n\t";
+    if (CDecl->getSuperClass()) {
+      Result += "&"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+    }
+    else 
+      Result += "0,\n\t";
+  }
+  Result += "(void *)&_objc_empty_cache,\n\t";
+  Result += "(void *)&_objc_empty_vtable,\n\t";
+  if (metadata)
+    Result += "&_OBJC_METACLASS_RO_$_";
+  else
+    Result += "&_OBJC_CLASS_RO_$_";
+  Result += CDecl->getNameAsString();
+  Result += ",\n};\n";
+}
+
+static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
+                             std::string &Result,
+                             StringRef CatName,
+                             StringRef ClassName,
+                             ArrayRef<ObjCMethodDecl *> InstanceMethods,
+                             ArrayRef<ObjCMethodDecl *> ClassMethods,
+                             ArrayRef<ObjCProtocolDecl *> RefedProtocols,
+                             ArrayRef<ObjCPropertyDecl *> ClassProperties) {
+  // must declare an extern class object in case this class is not implemented 
+  // in this TU.
+  Result += "\nextern struct _class_t ";
+  Result += "OBJC_CLASS_$_"; Result += ClassName;
+  Result += ";\n";
+  
+  Result += "\nstatic struct _category_t ";
+  Result += "_OBJC_$_CATEGORY_";
+  Result += ClassName; Result += "_$_"; Result += CatName;
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
+  Result += "{\n";
+  Result += "\t\""; Result += ClassName; Result += "\",\n";
+  Result += "\t&"; Result += "OBJC_CLASS_$_"; Result += ClassName;
+  Result += ",\n";
+  if (InstanceMethods.size() > 0) {
+    Result += "\t(const struct _method_list_t *)&";  
+    Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ClassMethods.size() > 0) {
+    Result += "\t(const struct _method_list_t *)&";  
+    Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (RefedProtocols.size() > 0) {
+    Result += "\t(const struct _protocol_list_t *)&";  
+    Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ClassProperties.size() > 0) {
+    Result += "\t(const struct _prop_list_t *)&";  Result += "_OBJC_$_PROP_LIST_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  Result += "};\n";
+}
+
 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
                                            ASTContext *Context, std::string &Result,
                                            ArrayRef<ObjCMethodDecl *> Methods,
@@ -5624,21 +5847,21 @@
                                   "_OBJC_PROTOCOL_REFS_",
                                   PDecl->getNameAsString());
   
-  Write_method_list_t_initializer(Context, Result, InstanceMethods, 
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 
                                   "_OBJC_PROTOCOL_INSTANCE_METHODS_",
-                                  PDecl->getNameAsString());
+                                  PDecl->getNameAsString(), false);
   
-  Write_method_list_t_initializer(Context, Result, ClassMethods, 
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 
                                   "_OBJC_PROTOCOL_CLASS_METHODS_",
-                                  PDecl->getNameAsString());
+                                  PDecl->getNameAsString(), false);
 
-  Write_method_list_t_initializer(Context, Result, OptInstanceMethods, 
+  Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 
                                   "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
-                                  PDecl->getNameAsString());
+                                  PDecl->getNameAsString(), false);
   
-  Write_method_list_t_initializer(Context, Result, OptClassMethods, 
+  Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 
                                   "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
-                                  PDecl->getNameAsString());
+                                  PDecl->getNameAsString(), false);
   
   // Protocol's property metadata.
   std::vector<ObjCPropertyDecl *> ProtocolProperties;
@@ -5646,7 +5869,7 @@
        E = PDecl->prop_end(); I != E; ++I)
     ProtocolProperties.push_back(*I);
   
-  Write__prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
+  Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
                                  /* Container */0,
                                  "_OBJC_PROTOCOL_PROPERTIES_",
                                  PDecl->getNameAsString());
@@ -5757,6 +5980,18 @@
   Result += "\t }\n};\n";
 }
 
+/// hasObjCExceptionAttribute - Return true if this class or any super
+/// class has the __objc_exception__ attribute.
+/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
+static bool hasObjCExceptionAttribute(ASTContext &Context,
+                                      const ObjCInterfaceDecl *OID) {
+  if (OID->hasAttr<ObjCExceptionAttr>())
+    return true;
+  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+    return hasObjCExceptionAttribute(Context, Super);
+  return false;
+}
+
 void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
                                            std::string &Result) {
   ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
@@ -5778,8 +6013,152 @@
   }
   
   Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
-                                 "_OBJC_INSTANCE_VARIABLES_",
+                                 "_OBJC_$_INSTANCE_VARIABLES_",
                                  CDecl->getNameAsString());
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32>
+    InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+       PropEnd = IDecl->propimpl_end();
+       Prop != PropEnd; ++Prop) {
+    if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!(*Prop)->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      if (!Getter->isDefined())
+        InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      if (!Setter->isDefined())
+        InstanceMethods.push_back(Setter);
+  }
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
+                                  "_OBJC_$_INSTANCE_METHODS_",
+                                  IDecl->getNameAsString(), true);
+  
+  SmallVector<ObjCMethodDecl *, 32>
+    ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
+                                  "_OBJC_$_CLASS_METHODS_",
+                                  IDecl->getNameAsString(), true);
+  
+  // Protocols referenced in class declaration?
+  // Protocol's super protocol list
+  std::vector<ObjCProtocolDecl *> RefedProtocols;
+  const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+       E = Protocols.end();
+       I != E; ++I) {
+    RefedProtocols.push_back(*I);
+    // Must write out all protocol definitions in current qualifier list,
+    // and in their nested qualifiers before writing out current definition.
+    RewriteObjCProtocolMetaData(*I, Result);
+  }
+  
+  Write_protocol_list_initializer(Context, Result, 
+                                  RefedProtocols,
+                                  "_OBJC_CLASS_PROTOCOLS_$_",
+                                  IDecl->getNameAsString());
+  
+  // Protocol's property metadata.
+  std::vector<ObjCPropertyDecl *> ClassProperties;
+  for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
+       E = CDecl->prop_end(); I != E; ++I)
+    ClassProperties.push_back(*I);
+  
+  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
+                                 /* Container */0,
+                                 "_OBJC_$_PROP_LIST_",
+                                 CDecl->getNameAsString());
+
+  
+  // Data for initializing _class_ro_t  metaclass meta-data
+  uint32_t flags = CLS_META;
+  std::string InstanceSize;
+  std::string InstanceStart;
+  
+  
+  bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  
+  if (!CDecl->getSuperClass())
+    // class is root
+    flags |= CLS_ROOT;
+  InstanceSize = "sizeof(struct _class_t)";
+  InstanceStart = InstanceSize;
+  Write__class_ro_t_initializer(Context, Result, flags, 
+                                InstanceStart, InstanceSize,
+                                ClassMethods,
+                                0,
+                                0,
+                                0,
+                                "_OBJC_METACLASS_RO_$_",
+                                CDecl->getNameAsString());
+
+  
+  // Data for initializing _class_ro_t meta-data
+  flags = CLS;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  
+  if (hasObjCExceptionAttribute(*Context, CDecl))
+    flags |= CLS_EXCEPTION;
+
+  if (!CDecl->getSuperClass())
+    // class is root
+    flags |= CLS_ROOT;
+  
+  InstanceSize.clear();
+  InstanceStart.clear();
+  if (!ObjCSynthesizedStructs.count(CDecl)) {
+    InstanceSize = "0";
+    InstanceStart = "0";
+  }
+  else {
+    InstanceSize = "sizeof(struct ";
+    InstanceSize += CDecl->getNameAsString();
+    InstanceSize += "_IMPL)";
+    
+    ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+    if (IVD) {
+      InstanceStart += "__OFFSETOFIVAR__(struct ";
+      InstanceStart += CDecl->getNameAsString();
+      InstanceStart += "_IMPL, ";
+      InstanceStart += IVD->getNameAsString();
+      InstanceStart += ")";
+    }
+    else 
+      InstanceStart = InstanceSize;
+  }
+  Write__class_ro_t_initializer(Context, Result, flags, 
+                                InstanceStart, InstanceSize,
+                                InstanceMethods,
+                                RefedProtocols,
+                                IVars,
+                                ClassProperties,
+                                "_OBJC_CLASS_RO_$_",
+                                CDecl->getNameAsString());
+  
+  Write_class_t(Context, Result,
+                "OBJC_METACLASS_$_",
+                CDecl, /*metaclass*/true);
+  
+  Write_class_t(Context, Result,
+                "OBJC_CLASS_$_",
+                CDecl, /*metaclass*/false);
+                
 }
 
 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
@@ -5794,88 +6173,35 @@
   for (int i = 0; i < CatDefCount; i++)
     RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
   
-  // Write objc_symtab metadata
-  /*
-   struct _objc_symtab
-   {
-   long sel_ref_cnt;
-   SEL *refs;
-   short cls_def_cnt;
-   short cat_def_cnt;
-   void *defs[cls_def_cnt + cat_def_cnt];
-   };
-   */
-  
-  Result += "\nstruct _objc_symtab {\n";
-  Result += "\tlong sel_ref_cnt;\n";
-  Result += "\tSEL *refs;\n";
-  Result += "\tshort cls_def_cnt;\n";
-  Result += "\tshort cat_def_cnt;\n";
-  Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
-  Result += "};\n\n";
-  
-  Result += "static struct _objc_symtab "
-  "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
-  Result += "\t0, 0, " + utostr(ClsDefCount)
-  + ", " + utostr(CatDefCount) + "\n";
-  for (int i = 0; i < ClsDefCount; i++) {
-    Result += "\t,&_OBJC_CLASS_";
-    Result += ClassImplementation[i]->getNameAsString();
-    Result += "\n";
-  }
-  
-  for (int i = 0; i < CatDefCount; i++) {
-    Result += "\t,&_OBJC_CATEGORY_";
-    Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
-    Result += "_";
-    Result += CategoryImplementation[i]->getNameAsString();
-    Result += "\n";
+  if (ClsDefCount > 0) {
+    Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
+    Result += llvm::utostr(ClsDefCount); Result += "]";
+    Result += 
+      " __attribute__((used, section (\"__DATA, __objc_classlist,"
+      "regular,no_dead_strip\")))= {\n";
+    for (int i = 0; i < ClsDefCount; i++) {
+      Result += "\t&OBJC_CLASS_$_";
+      Result += ClassImplementation[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
   }
   
-  Result += "};\n\n";
-  
-  // Write objc_module metadata
-  
-  /*
-   struct _objc_module {
-   long version;
-   long size;
-   const char *name;
-   struct _objc_symtab *symtab;
-   }
-   */
-  
-  Result += "\nstruct _objc_module {\n";
-  Result += "\tlong version;\n";
-  Result += "\tlong size;\n";
-  Result += "\tconst char *name;\n";
-  Result += "\tstruct _objc_symtab *symtab;\n";
-  Result += "};\n\n";
-  Result += "static struct _objc_module "
-  "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
-  Result += "\t" + utostr(OBJC_ABI_VERSION) +
-  ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
-  Result += "};\n\n";
-  
-  if (LangOpts.MicrosoftExt) {
-    if (ProtocolExprDecls.size()) {
-      Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
-      Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
-      for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
-           E = ProtocolExprDecls.end(); I != E; ++I) {
-        Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
-        Result += (*I)->getNameAsString();
-        Result += " = &_OBJC_PROTOCOL_";
-        Result += (*I)->getNameAsString();
-        Result += ";\n";
-      }
-      Result += "#pragma data_seg(pop)\n\n";
-    }
-    Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
-    Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
-    Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
-    Result += "&_OBJC_MODULES;\n";
-    Result += "#pragma data_seg(pop)\n\n";
+  if (CatDefCount > 0) {
+    Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
+    Result += llvm::utostr(CatDefCount); Result += "]";
+    Result += 
+    " __attribute__((used, section (\"__DATA, __objc_catlist,"
+    "regular,no_dead_strip\")))= {\n";
+    for (int i = 0; i < CatDefCount; i++) {
+      Result += "\t&_OBJC_$_CATEGORY_";
+      Result += 
+        CategoryImplementation[i]->getClassInterface()->getNameAsString(); 
+      Result += "_$_";
+      Result += CategoryImplementation[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
   }
 }
 
@@ -5883,17 +6209,18 @@
 /// implementation.
 void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
                                               std::string &Result) {
+  WriteModernMetadataDeclarations(Result);
   ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
   // Find category declaration for this implementation.
-  ObjCCategoryDecl *CDecl;
+  ObjCCategoryDecl *CDecl=0;
   for (CDecl = ClassDecl->getCategoryList(); CDecl;
        CDecl = CDecl->getNextClassCategory())
     if (CDecl->getIdentifier() == IDecl->getIdentifier())
       break;
   
   std::string FullCategoryName = ClassDecl->getNameAsString();
-  FullCategoryName += '_';
-  FullCategoryName += IDecl->getNameAsString();
+  FullCategoryName += "_$_";
+  FullCategoryName += CDecl->getNameAsString();
   
   // Build _objc_method_list for class's instance methods if needed
   SmallVector<ObjCMethodDecl *, 32>
@@ -5918,79 +6245,55 @@
     if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
       InstanceMethods.push_back(Setter);
   }
-  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
-                             true, "CATEGORY_", FullCategoryName.c_str(),
-                             Result);
-  
-  // Build _objc_method_list for class's class methods if needed
-  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
-                             false, "CATEGORY_", FullCategoryName.c_str(),
-                             Result);
   
-  // Protocols referenced in class declaration?
-  // Null CDecl is case of a category implementation with no category interface
-  if (CDecl)
-    RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
-                                    FullCategoryName, Result);
-  /* struct _objc_category {
-   char *category_name;
-   char *class_name;
-   struct _objc_method_list *instance_methods;
-   struct _objc_method_list *class_methods;
-   struct _objc_protocol_list *protocols;
-   // Objective-C 1.0 extensions
-   uint32_t size;     // sizeof (struct _objc_category)
-   struct _objc_property_list *instance_properties;  // category's own
-   // @property decl.
-   };
-   */
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
+                                  "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
+                                  FullCategoryName, true);
   
-  static bool objc_category = false;
-  if (!objc_category) {
-    Result += "\nstruct _objc_category {\n";
-    Result += "\tchar *category_name;\n";
-    Result += "\tchar *class_name;\n";
-    Result += "\tstruct _objc_method_list *instance_methods;\n";
-    Result += "\tstruct _objc_method_list *class_methods;\n";
-    Result += "\tstruct _objc_protocol_list *protocols;\n";
-    Result += "\tunsigned int size;\n";
-    Result += "\tstruct _objc_property_list *instance_properties;\n";
-    Result += "};\n";
-    objc_category = true;
-  }
-  Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
-  Result += FullCategoryName;
-  Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
-  Result += IDecl->getNameAsString();
-  Result += "\"\n\t, \"";
-  Result += ClassDecl->getNameAsString();
-  Result += "\"\n";
-  
-  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
-    Result += "\t, (struct _objc_method_list *)"
-    "&_OBJC_CATEGORY_INSTANCE_METHODS_";
-    Result += FullCategoryName;
-    Result += "\n";
-  }
-  else
-    Result += "\t, 0\n";
-  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
-    Result += "\t, (struct _objc_method_list *)"
-    "&_OBJC_CATEGORY_CLASS_METHODS_";
-    Result += FullCategoryName;
-    Result += "\n";
-  }
-  else
-    Result += "\t, 0\n";
+  SmallVector<ObjCMethodDecl *, 32>
+    ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
   
-  if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
-    Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
-    Result += FullCategoryName;
-    Result += "\n";
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
+                                  "_OBJC_$_CATEGORY_CLASS_METHODS_",
+                                  FullCategoryName, true);
+  
+  // Protocols referenced in class declaration?
+  // Protocol's super protocol list
+  std::vector<ObjCProtocolDecl *> RefedProtocols;
+  const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+       E = Protocols.end();
+       I != E; ++I) {
+    RefedProtocols.push_back(*I);
+    // Must write out all protocol definitions in current qualifier list,
+    // and in their nested qualifiers before writing out current definition.
+    RewriteObjCProtocolMetaData(*I, Result);
   }
-  else
-    Result += "\t, 0\n";
-  Result += "\t, sizeof(struct _objc_category), 0\n};\n";
+  
+  Write_protocol_list_initializer(Context, Result, 
+                                  RefedProtocols,
+                                  "_OBJC_CATEGORY_PROTOCOLS_$_",
+                                  FullCategoryName);
+  
+  // Protocol's property metadata.
+  std::vector<ObjCPropertyDecl *> ClassProperties;
+  for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
+       E = CDecl->prop_end(); I != E; ++I)
+    ClassProperties.push_back(*I);
+  
+  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
+                                /* Container */0,
+                                "_OBJC_$_PROP_LIST_",
+                                FullCategoryName);
+  
+  Write_category_t(*this, Context, Result,
+                   CDecl->getNameAsString(),
+                   ClassDecl->getNameAsString(),
+                   InstanceMethods,
+                   ClassMethods,
+                   RefedProtocols,
+                   ClassProperties);
+  
 }
 
 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or

Modified: cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp Mon Feb 20 19:34:24 2012
@@ -218,7 +218,7 @@
   unsigned diag_AlwaysFallThrough_HasNoReturn;
   unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
   unsigned diag_NeverFallThroughOrReturn;
-  bool funMode;
+  enum { Function, Block, Lambda } funMode;
   SourceLocation FuncLoc;
 
   static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
@@ -250,7 +250,7 @@
     else
       D.diag_NeverFallThroughOrReturn = 0;
     
-    D.funMode = true;
+    D.funMode = Function;
     return D;
   }
 
@@ -266,13 +266,28 @@
       diag::err_falloff_nonvoid_block;
     D.diag_NeverFallThroughOrReturn =
       diag::warn_suggest_noreturn_block;
-    D.funMode = false;
+    D.funMode = Block;
+    return D;
+  }
+
+  static CheckFallThroughDiagnostics MakeForLambda() {
+    CheckFallThroughDiagnostics D;
+    D.diag_MaybeFallThrough_HasNoReturn =
+      diag::err_noreturn_lambda_has_return_expr;
+    D.diag_MaybeFallThrough_ReturnsNonVoid =
+      diag::warn_maybe_falloff_nonvoid_lambda;
+    D.diag_AlwaysFallThrough_HasNoReturn =
+      diag::err_noreturn_lambda_has_return_expr;
+    D.diag_AlwaysFallThrough_ReturnsNonVoid =
+      diag::warn_falloff_nonvoid_lambda;
+    D.diag_NeverFallThroughOrReturn = 0;
+    D.funMode = Lambda;
     return D;
   }
 
   bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
                         bool HasNoReturn) const {
-    if (funMode) {
+    if (funMode == Function) {
       return (ReturnsVoid ||
               D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
                                    FuncLoc) == DiagnosticsEngine::Ignored)
@@ -284,9 +299,9 @@
               == DiagnosticsEngine::Ignored);
     }
 
-    // For blocks.
-    return  ReturnsVoid && !HasNoReturn
-            && (!ReturnsVoid ||
+    // For blocks / lambdas.
+    return ReturnsVoid && !HasNoReturn
+            && ((funMode == Lambda) ||
                 D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
                   == DiagnosticsEngine::Ignored);
   }
@@ -888,7 +903,11 @@
   if (P.enableCheckFallThrough) {
     const CheckFallThroughDiagnostics &CD =
       (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
-                         : CheckFallThroughDiagnostics::MakeForFunction(D));
+       : (isa<CXXMethodDecl>(D) &&
+          cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
+          cast<CXXMethodDecl>(D)->getParent()->isLambda())
+            ? CheckFallThroughDiagnostics::MakeForLambda()
+            : CheckFallThroughDiagnostics::MakeForFunction(D));
     CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
   }
 

Modified: cfe/branches/tooling/lib/Sema/Scope.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/Scope.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/Scope.cpp (original)
+++ cfe/branches/tooling/lib/Sema/Scope.cpp Mon Feb 20 19:34:24 2012
@@ -19,23 +19,28 @@
 void Scope::Init(Scope *parent, unsigned flags) {
   AnyParent = parent;
   Flags = flags;
-    
+
+  if (parent && !(flags & FnScope)) {
+    BreakParent    = parent->BreakParent;
+    ContinueParent = parent->ContinueParent;
+  } else {
+    // Control scopes do not contain the contents of nested function scopes for
+    // control flow purposes.
+    BreakParent = ContinueParent = 0;
+  }
+
   if (parent) {
     Depth = parent->Depth + 1;
     PrototypeDepth = parent->PrototypeDepth;
     PrototypeIndex = 0;
     FnParent       = parent->FnParent;
-    BreakParent    = parent->BreakParent;
-    ContinueParent = parent->ContinueParent;
-    ControlParent  = parent->ControlParent;
     BlockParent    = parent->BlockParent;
     TemplateParamParent = parent->TemplateParamParent;
   } else {
     Depth = 0;
     PrototypeDepth = 0;
     PrototypeIndex = 0;
-    FnParent = BreakParent = ContinueParent = BlockParent = 0;
-    ControlParent = 0;
+    FnParent = BlockParent = 0;
     TemplateParamParent = 0;
   }
 
@@ -43,7 +48,6 @@
   if (flags & FnScope)            FnParent = this;
   if (flags & BreakScope)         BreakParent = this;
   if (flags & ContinueScope)      ContinueParent = this;
-  if (flags & ControlScope)       ControlParent = this;
   if (flags & BlockScope)         BlockParent = this;
   if (flags & TemplateParamScope) TemplateParamParent = this;
 

Modified: cfe/branches/tooling/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/Sema.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/Sema.cpp (original)
+++ cfe/branches/tooling/lib/Sema/Sema.cpp Mon Feb 20 19:34:24 2012
@@ -861,6 +861,17 @@
   }
 }
 
+void Sema::PushCompoundScope() {
+  getCurFunction()->CompoundScopes.push_back(CompoundScopeInfo());
+}
+
+void Sema::PopCompoundScope() {
+  FunctionScopeInfo *CurFunction = getCurFunction();
+  assert(!CurFunction->CompoundScopes.empty() && "mismatched push/pop");
+
+  CurFunction->CompoundScopes.pop_back();
+}
+
 /// \brief Determine whether any errors occurred within this function/method/
 /// block.
 bool Sema::hasAnyUnrecoverableErrorsInThisFunction() const {

Modified: cfe/branches/tooling/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaAccess.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaAccess.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaAccess.cpp Mon Feb 20 19:34:24 2012
@@ -1481,6 +1481,13 @@
     break;
   }
 
+  case InitializedEntity::EK_LambdaCapture: {
+    const VarDecl *Var = Entity.getCapturedVar();
+    PD = PDiag(diag::err_access_lambda_capture);
+    PD << Var->getName() << Entity.getType() << getSpecialMember(Constructor);
+    break;
+  }
+
   }
 
   return CheckConstructorAccess(UseLoc, Constructor, Access, PD);

Modified: cfe/branches/tooling/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCast.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCast.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCast.cpp Mon Feb 20 19:34:24 2012
@@ -1576,7 +1576,8 @@
     }
 
     // A valid member pointer cast.
-    Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
+    assert(!IsLValueCast);
+    Kind = CK_ReinterpretMemberPointer;
     return TC_Success;
   }
 

Modified: cfe/branches/tooling/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaChecking.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaChecking.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaChecking.cpp Mon Feb 20 19:34:24 2012
@@ -2181,7 +2181,8 @@
 
     // We may be able to offer a FixItHint if it is a supported type.
     PrintfSpecifier fixedFS = FS;
-    bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions());
+    bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions(),
+                                   S.Context, IsObjCLiteral);
 
     if (success) {
       // Get the fix string from the fixed format specifier
@@ -2340,7 +2341,8 @@
   const analyze_scanf::ScanfArgTypeResult &ATR = FS.getArgType(S.Context);
   if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
     ScanfSpecifier fixedFS = FS;
-    bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions());
+    bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions(),
+                                   S.Context);
 
     if (success) {
       // Get the fix string from the fixed format specifier.
@@ -4827,3 +4829,130 @@
     }
   }
 }
+
+//===--- CHECK: Empty statement body (-Wempty-body) ---------------------===//
+
+namespace {
+bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr,
+                                 SourceLocation StmtLoc,
+                                 const NullStmt *Body) {
+  // Do not warn if the body is a macro that expands to nothing, e.g:
+  //
+  // #define CALL(x)
+  // if (condition)
+  //   CALL(0);
+  //
+  if (Body->hasLeadingEmptyMacro())
+    return false;
+
+  // Get line numbers of statement and body.
+  bool StmtLineInvalid;
+  unsigned StmtLine = SourceMgr.getSpellingLineNumber(StmtLoc,
+                                                      &StmtLineInvalid);
+  if (StmtLineInvalid)
+    return false;
+
+  bool BodyLineInvalid;
+  unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->getSemiLoc(),
+                                                      &BodyLineInvalid);
+  if (BodyLineInvalid)
+    return false;
+
+  // Warn if null statement and body are on the same line.
+  if (StmtLine != BodyLine)
+    return false;
+
+  return true;
+}
+} // Unnamed namespace
+
+void Sema::DiagnoseEmptyStmtBody(SourceLocation StmtLoc,
+                                 const Stmt *Body,
+                                 unsigned DiagID) {
+  // Since this is a syntactic check, don't emit diagnostic for template
+  // instantiations, this just adds noise.
+  if (CurrentInstantiationScope)
+    return;
+
+  // The body should be a null statement.
+  const NullStmt *NBody = dyn_cast<NullStmt>(Body);
+  if (!NBody)
+    return;
+
+  // Do the usual checks.
+  if (!ShouldDiagnoseEmptyStmtBody(SourceMgr, StmtLoc, NBody))
+    return;
+
+  Diag(NBody->getSemiLoc(), DiagID);
+  Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line);
+}
+
+void Sema::DiagnoseEmptyLoopBody(const Stmt *S,
+                                 const Stmt *PossibleBody) {
+  assert(!CurrentInstantiationScope); // Ensured by caller
+
+  SourceLocation StmtLoc;
+  const Stmt *Body;
+  unsigned DiagID;
+  if (const ForStmt *FS = dyn_cast<ForStmt>(S)) {
+    StmtLoc = FS->getRParenLoc();
+    Body = FS->getBody();
+    DiagID = diag::warn_empty_for_body;
+  } else if (const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
+    StmtLoc = WS->getCond()->getSourceRange().getEnd();
+    Body = WS->getBody();
+    DiagID = diag::warn_empty_while_body;
+  } else
+    return; // Neither `for' nor `while'.
+
+  // The body should be a null statement.
+  const NullStmt *NBody = dyn_cast<NullStmt>(Body);
+  if (!NBody)
+    return;
+
+  // Skip expensive checks if diagnostic is disabled.
+  if (Diags.getDiagnosticLevel(DiagID, NBody->getSemiLoc()) ==
+          DiagnosticsEngine::Ignored)
+    return;
+
+  // Do the usual checks.
+  if (!ShouldDiagnoseEmptyStmtBody(SourceMgr, StmtLoc, NBody))
+    return;
+
+  // `for(...);' and `while(...);' are popular idioms, so in order to keep
+  // noise level low, emit diagnostics only if for/while is followed by a
+  // CompoundStmt, e.g.:
+  //    for (int i = 0; i < n; i++);
+  //    {
+  //      a(i);
+  //    }
+  // or if for/while is followed by a statement with more indentation
+  // than for/while itself:
+  //    for (int i = 0; i < n; i++);
+  //      a(i);
+  bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
+  if (!ProbableTypo) {
+    bool BodyColInvalid;
+    unsigned BodyCol = SourceMgr.getPresumedColumnNumber(
+                             PossibleBody->getLocStart(),
+                             &BodyColInvalid);
+    if (BodyColInvalid)
+      return;
+
+    bool StmtColInvalid;
+    unsigned StmtCol = SourceMgr.getPresumedColumnNumber(
+                             S->getLocStart(),
+                             &StmtColInvalid);
+    if (StmtColInvalid)
+      return;
+
+    if (BodyCol > StmtCol)
+      ProbableTypo = true;
+  }
+
+  if (ProbableTypo) {
+    Diag(NBody->getSemiLoc(), DiagID);
+    Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line);
+  }
+}
+

Modified: cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp Mon Feb 20 19:34:24 2012
@@ -274,9 +274,9 @@
     /// of the shadow maps), or replace an existing result (for, e.g., a 
     /// redeclaration).
     ///
-    /// \param CurContext the result to add (if it is unique).
+    /// \param R the result to add (if it is unique).
     ///
-    /// \param R the context in which this result will be named.
+    /// \param CurContext the context in which this result will be named.
     void MaybeAddResult(Result R, DeclContext *CurContext = 0);
     
     /// \brief Add a new result to this result set, where we already know
@@ -325,6 +325,7 @@
     bool IsMember(NamedDecl *ND) const;
     bool IsObjCIvar(NamedDecl *ND) const;
     bool IsObjCMessageReceiver(NamedDecl *ND) const;
+    bool IsObjCMessageReceiverOrLambdaCapture(NamedDecl *ND) const;
     bool IsObjCCollection(NamedDecl *ND) const;
     bool IsImpossibleToSatisfy(NamedDecl *ND) const;
     //@}    
@@ -1152,6 +1153,17 @@
   return isObjCReceiverType(SemaRef.Context, T);
 }
 
+bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(NamedDecl *ND) const {
+  if (IsObjCMessageReceiver(ND))
+    return true;
+  
+  VarDecl *Var = dyn_cast<VarDecl>(ND);
+  if (!Var)
+    return false;
+  
+  return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
+}
+
 bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
   if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
       (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
@@ -1423,6 +1435,23 @@
   return Allocator.CopyString(Result);
 }
 
+/// \brief Add a completion for "this", if we're in a member function.
+static void addThisCompletion(Sema &S, ResultBuilder &Results) {
+  QualType ThisTy = S.getCurrentThisType();
+  if (ThisTy.isNull())
+    return;
+  
+  CodeCompletionAllocator &Allocator = Results.getAllocator();
+  CodeCompletionBuilder Builder(Allocator);
+  PrintingPolicy Policy = getCompletionPrintingPolicy(S);
+  Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, 
+                                                     S.Context, 
+                                                     Policy,
+                                                     Allocator));
+  Builder.AddTypedTextChunk("this");
+  Results.AddResult(CodeCompletionResult(Builder.TakeString()));            
+}
+
 /// \brief Add language constructs that show up for "ordinary" names.
 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
@@ -1758,15 +1787,7 @@
   case Sema::PCC_Expression: {
     if (SemaRef.getLangOptions().CPlusPlus) {
       // 'this', if we're in a non-static member function.
-      QualType ThisTy = SemaRef.getCurrentThisType();
-      if (!ThisTy.isNull()) {
-        Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, 
-                                                           SemaRef.Context, 
-                                                           Policy,
-                                                           Allocator));
-        Builder.AddTypedTextChunk("this");
-        Results.AddResult(Result(Builder.TakeString()));      
-      }
+      addThisCompletion(SemaRef, Results);
       
       // true
       Builder.AddResultTypeChunk("bool");
@@ -3665,7 +3686,6 @@
     kind = CodeCompletionContext::CCC_OtherWithMacros;
   }
   
-  
   HandleCodeCompleteResults(this, CodeCompleter, 
                             kind,
                             Results.data(),Results.size());
@@ -3849,12 +3869,14 @@
   // "else" block
   CodeCompletionBuilder Builder(Results.getAllocator());
   Builder.AddTypedTextChunk("else");
-  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
-  Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
-  Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
-  Builder.AddPlaceholderChunk("statements");
-  Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
-  Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+  if (Results.includeCodePatterns()) {
+    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
+    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Builder.AddPlaceholderChunk("statements");
+    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+  }
   Results.AddResult(Builder.TakeString());
 
   // "else if" block
@@ -3868,12 +3890,14 @@
   else
     Builder.AddPlaceholderChunk("expression");
   Builder.AddChunk(CodeCompletionString::CK_RightParen);
-  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
-  Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
-  Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
-  Builder.AddPlaceholderChunk("statements");
-  Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
-  Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+  if (Results.includeCodePatterns()) {
+    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
+    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Builder.AddPlaceholderChunk("statements");
+    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+  }
   Results.AddResult(Builder.TakeString());
 
   Results.ExitScope();
@@ -4181,6 +4205,60 @@
                             Results.data(), Results.size());
 }
 
+/// \brief Determine whether this scope denotes a namespace.
+static bool isNamespaceScope(Scope *S) {
+  DeclContext *DC = static_cast<DeclContext *>(S->getEntity());
+  if (!DC)
+    return false;
+
+  return DC->isFileContext();
+}
+
+void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
+                                        bool AfterAmpersand) {
+  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompletionContext::CCC_Other);
+  Results.EnterNewScope();
+
+  // Note what has already been captured.
+  llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
+  bool IncludedThis = false;
+  for (SmallVectorImpl<LambdaCapture>::iterator C = Intro.Captures.begin(),
+                                             CEnd = Intro.Captures.end();
+       C != CEnd; ++C) {
+    if (C->Kind == LCK_This) {
+      IncludedThis = true;
+      continue;
+    }
+    
+    Known.insert(C->Id);
+  }
+  
+  // Look for other capturable variables.
+  for (; S && !isNamespaceScope(S); S = S->getParent()) {
+    for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+         D != DEnd; ++D) {
+      VarDecl *Var = dyn_cast<VarDecl>(*D);
+      if (!Var ||
+          !Var->hasLocalStorage() ||
+          Var->hasAttr<BlocksAttr>())
+        continue;
+      
+      if (Known.insert(Var->getIdentifier()))
+        Results.AddResult(CodeCompletionResult(Var), CurContext, 0, false);
+    }
+  }
+
+  // Add 'this', if it would be valid.
+  if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
+    addThisCompletion(*this, Results);
+  
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
+}
+
 // Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
 // true or false.
 #define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
@@ -4980,7 +5058,9 @@
   typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompletionContext::CCC_ObjCMessageReceiver,
-                        &ResultBuilder::IsObjCMessageReceiver);
+                        getLangOptions().CPlusPlus0x
+                          ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
+                          : &ResultBuilder::IsObjCMessageReceiver);
   
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
   Results.EnterNewScope();
@@ -4997,6 +5077,9 @@
         AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
       }
   
+  if (getLangOptions().CPlusPlus0x)
+    addThisCompletion(*this, Results);
+  
   Results.ExitScope();
   
   if (CodeCompleter->includeMacros())

Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Mon Feb 20 19:34:24 2012
@@ -3920,20 +3920,24 @@
       } else if (SC == SC_None)
         SC = SC_Static;
     }
-    if (SC == SC_Static) {
+    if (SC == SC_Static && CurContext->isRecord()) {
       if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
         if (RD->isLocalClass())
           Diag(D.getIdentifierLoc(),
                diag::err_static_data_member_not_allowed_in_local_class)
             << Name << RD->getDeclName();
 
-        // C++ [class.union]p1: If a union contains a static data member,
-        // the program is ill-formed.
-        //
-        // We also disallow static data members in anonymous structs.
-        if (CurContext->isRecord() && (RD->isUnion() || !RD->getDeclName()))
+        // C++98 [class.union]p1: If a union contains a static data member,
+        // the program is ill-formed. C++11 drops this restriction.
+        if (RD->isUnion())
+          Diag(D.getIdentifierLoc(),
+               getLangOptions().CPlusPlus0x
+                 ? diag::warn_cxx98_compat_static_data_member_in_union
+                 : diag::ext_static_data_member_in_union) << Name;
+        // We conservatively disallow static data members in anonymous structs.
+        else if (!RD->getDeclName())
           Diag(D.getIdentifierLoc(),
-               diag::err_static_data_member_not_allowed_in_union_or_anon_struct)
+               diag::err_static_data_member_not_allowed_in_anon_struct)
             << Name << RD->isUnion();
       }
     }
@@ -4055,6 +4059,13 @@
 
     NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
                                                 Context, Label));
+  } else if (!ExtnameUndeclaredIdentifiers.empty()) {
+    llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
+      ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
+    if (I != ExtnameUndeclaredIdentifiers.end()) {
+      NewVD->addAttr(I->second);
+      ExtnameUndeclaredIdentifiers.erase(I);
+    }
   }
 
   // Diagnose shadowed variables before filtering for scope.
@@ -4435,11 +4446,26 @@
 namespace {
 
 // Callback to only accept typo corrections that have a non-zero edit distance.
+// Also only accept corrections that have the same parent decl.
 class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
  public:
+  DifferentNameValidatorCCC(CXXRecordDecl *Parent)
+      : ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {}
+
   virtual bool ValidateCandidate(const TypoCorrection &candidate) {
-    return candidate.getEditDistance() > 0;
+    if (candidate.getEditDistance() == 0)
+      return false;
+
+    if (CXXMethodDecl *MD = candidate.getCorrectionDeclAs<CXXMethodDecl>()) {
+      CXXRecordDecl *Parent = MD->getParent();
+      return Parent && Parent->getCanonicalDecl() == ExpectedParent;
+    }
+
+    return !ExpectedParent;
   }
+
+ private:
+  CXXRecordDecl *ExpectedParent;
 };
 
 }
@@ -4473,7 +4499,8 @@
   SemaRef.LookupQualifiedName(Prev, NewDC);
   assert(!Prev.isAmbiguous() &&
          "Cannot have an ambiguity in previous-declaration lookup");
-  DifferentNameValidatorCCC Validator;
+  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
+  DifferentNameValidatorCCC Validator(MD ? MD->getParent() : 0);
   if (!Prev.empty()) {
     for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
          Func != FuncEnd; ++Func) {
@@ -5137,6 +5164,13 @@
     StringLiteral *SE = cast<StringLiteral>(E);
     NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
                                                 SE->getString()));
+  } else if (!ExtnameUndeclaredIdentifiers.empty()) {
+    llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
+      ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
+    if (I != ExtnameUndeclaredIdentifiers.end()) {
+      NewFD->addAttr(I->second);
+      ExtnameUndeclaredIdentifiers.erase(I);
+    }
   }
 
   // Copy the parameter declarations from the declarator D to the function
@@ -5794,9 +5828,23 @@
 
   QualType T = FD->getType();
   assert(T->isFunctionType() && "function decl is not of function type");
-  const FunctionType* FT = T->getAs<FunctionType>();
+  const FunctionType* FT = T->castAs<FunctionType>();
 
-  if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
+  // All the standards say that main() should should return 'int'.
+  if (Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
+    // In C and C++, main magically returns 0 if you fall off the end;
+    // set the flag which tells us that.
+    // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.
+    FD->setHasImplicitReturnZero(true);
+
+  // In C with GNU extensions we allow main() to have non-integer return
+  // type, but we should warn about the extension, and we disable the
+  // implicit-return-zero rule.
+  } else if (getLangOptions().GNUMode && !getLangOptions().CPlusPlus) {
+    Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
+
+  // Otherwise, this is just a flat-out error.
+  } else {
     Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
     FD->setInvalidDecl(true);
   }
@@ -7259,16 +7307,11 @@
 
   if (FD) {
     FD->setBody(Body);
-    if (FD->isMain()) {
-      // C and C++ allow for main to automagically return 0.
-      // Implements C++ [basic.start.main]p5 and C99 5.1.2.2.3.
-      FD->setHasImplicitReturnZero(true);
-      WP.disableCheckFallThrough();
-    } else if (FD->hasAttr<NakedAttr>()) {
-      // If the function is marked 'naked', don't complain about missing return
-      // statements.
+
+    // If the function implicitly returns zero (like 'main') or is naked,
+    // don't complain about missing return statements.
+    if (FD->hasImplicitReturnZero() || FD->hasAttr<NakedAttr>())
       WP.disableCheckFallThrough();
-    }
 
     // MSVC permits the use of pure specifier (=0) on function definition,
     // defined at class scope, warn about this non standard construct.
@@ -7811,7 +7854,7 @@
                                           UPPC_FixedUnderlyingType))
         EnumUnderlying = Context.IntTy.getTypePtr();
 
-    } else if (getLangOptions().MicrosoftExt)
+    } else if (getLangOptions().MicrosoftMode)
       // Microsoft enums are always of int type.
       EnumUnderlying = Context.IntTy.getTypePtr();
   }
@@ -8272,7 +8315,7 @@
         Diag(Def->getLocation(), diag::note_previous_definition);
       } else {
         unsigned DiagID = diag::ext_forward_ref_enum;
-        if (getLangOptions().MicrosoftExt)
+        if (getLangOptions().MicrosoftMode)
           DiagID = diag::ext_ms_forward_ref_enum;
         else if (getLangOptions().CPlusPlus)
           DiagID = diag::err_forward_ref_enum;
@@ -9673,7 +9716,7 @@
           // we perform a non-narrowing conversion as part of converted constant
           // expression checking.
           if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
-            if (getLangOptions().MicrosoftExt) {
+            if (getLangOptions().MicrosoftMode) {
               Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
               Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
             } else
@@ -10123,6 +10166,23 @@
   return Import;
 }
 
+void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
+                                      IdentifierInfo* AliasName,
+                                      SourceLocation PragmaLoc,
+                                      SourceLocation NameLoc,
+                                      SourceLocation AliasNameLoc) {
+  Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
+                                    LookupOrdinaryName);
+  AsmLabelAttr *Attr =
+     ::new (Context) AsmLabelAttr(AliasNameLoc, Context, AliasName->getName());
+
+  if (PrevDecl) 
+    PrevDecl->addAttr(Attr);
+  else 
+    (void)ExtnameUndeclaredIdentifiers.insert(
+      std::pair<IdentifierInfo*,AsmLabelAttr*>(Name, Attr));
+}
+
 void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
                              SourceLocation PragmaLoc,
                              SourceLocation NameLoc) {

Modified: cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp Mon Feb 20 19:34:24 2012
@@ -283,6 +283,9 @@
       << Attr.getName();
     return false;
   }
+  // Don't check for lockable if the class hasn't been defined yet. 
+  if (RT->isIncompleteType())
+    return true;
   // Flag error if the type is not lockable.
   if (!RT->getDecl()->getAttr<LockableAttr>()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable)

Modified: cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp Mon Feb 20 19:34:24 2012
@@ -585,11 +585,25 @@
   unsigned NumParams = FD->getNumParams();
   unsigned p;
 
+  bool IsLambda = FD->getOverloadedOperator() == OO_Call &&
+                  isa<CXXMethodDecl>(FD) &&
+                  cast<CXXMethodDecl>(FD)->getParent()->isLambda();
+              
   // Find first parameter with a default argument
   for (p = 0; p < NumParams; ++p) {
     ParmVarDecl *Param = FD->getParamDecl(p);
-    if (Param->hasDefaultArg())
+    if (Param->hasDefaultArg()) {
+      // C++11 [expr.prim.lambda]p5:
+      //   [...] Default arguments (8.3.6) shall not be specified in the 
+      //   parameter-declaration-clause of a lambda-declarator.
+      //
+      // FIXME: Core issue 974 strikes this sentence, we only provide an
+      // extension warning.
+      if (IsLambda)
+        Diag(Param->getLocation(), diag::ext_lambda_default_arguments)
+          << Param->getDefaultArgRange();
       break;
+    }
   }
 
   // C++ [dcl.fct.default]p4:
@@ -861,12 +875,6 @@
         break;
 
       ReturnStmts.push_back((*BodyIt)->getLocStart());
-      // FIXME
-      // - every constructor call and implicit conversion used in initializing
-      //   the return value shall be one of those allowed in a constant
-      //   expression.
-      // Deal with this as part of a general check that the function can produce
-      // a constant expression (for [dcl.constexpr]p5).
       continue;
 
     default:
@@ -930,20 +938,6 @@
           return false;
       }
     }
-
-    // FIXME
-    // - every constructor involved in initializing non-static data members
-    //   and base class sub-objects shall be a constexpr constructor;
-    // - every assignment-expression that is an initializer-clause appearing
-    //   directly or indirectly within a brace-or-equal-initializer for
-    //   a non-static data member that is not named by a mem-initializer-id
-    //   shall be a constant expression; and
-    // - every implicit conversion used in converting a constructor argument
-    //   to the corresponding parameter type and converting
-    //   a full-expression to the corresponding member type shall be one of
-    //   those allowed in a constant expression.
-    // Deal with these as part of a general check that the function can produce
-    // a constant expression (for [dcl.constexpr]p5).
   } else {
     if (ReturnStmts.empty()) {
       Diag(Dcl->getLocation(), diag::err_constexpr_body_no_return);
@@ -3288,7 +3282,7 @@
     CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
     if (FieldClassDecl->isInvalidDecl())
       continue;
-    if (FieldClassDecl->hasTrivialDestructor())
+    if (FieldClassDecl->hasIrrelevantDestructor())
       continue;
 
     CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
@@ -3299,6 +3293,7 @@
                             << FieldType);
 
     MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
+    DiagnoseUseOfDecl(Dtor, Location);
   }
 
   llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
@@ -3317,8 +3312,7 @@
     // If our base class is invalid, we probably can't get its dtor anyway.
     if (BaseClassDecl->isInvalidDecl())
       continue;
-    // Ignore trivial destructors.
-    if (BaseClassDecl->hasTrivialDestructor())
+    if (BaseClassDecl->hasIrrelevantDestructor())
       continue;
 
     CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
@@ -3331,6 +3325,7 @@
                             << Base->getSourceRange());
     
     MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
+    DiagnoseUseOfDecl(Dtor, Location);
   }
   
   // Virtual bases.
@@ -3348,8 +3343,7 @@
     // If our base class is invalid, we probably can't get its dtor anyway.
     if (BaseClassDecl->isInvalidDecl())
       continue;
-    // Ignore trivial destructors.
-    if (BaseClassDecl->hasTrivialDestructor())
+    if (BaseClassDecl->hasIrrelevantDestructor())
       continue;
 
     CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
@@ -3359,6 +3353,7 @@
                             << VBase->getType());
 
     MarkFunctionReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor));
+    DiagnoseUseOfDecl(Dtor, Location);
   }
 }
 
@@ -4056,7 +4051,7 @@
     return;
   }
 
-  if (ShouldDeleteCopyAssignmentOperator(MD)) {
+  if (ShouldDeleteSpecialMember(MD, CXXCopyAssignment)) {
     if (First) {
       MD->setDeletedAsWritten();
     } else {
@@ -4234,7 +4229,7 @@
     return;
   }
 
-  if (ShouldDeleteMoveAssignmentOperator(MD)) {
+  if (ShouldDeleteSpecialMember(MD, CXXMoveAssignment)) {
     if (First) {
       MD->setDeletedAsWritten();
     } else {
@@ -4276,7 +4271,7 @@
     DD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
   }
 
-  if (ShouldDeleteDestructor(DD)) {
+  if (ShouldDeleteSpecialMember(DD, CXXDestructor)) {
     if (First) {
       DD->setDeletedAsWritten();
     } else {
@@ -4287,665 +4282,380 @@
   }
 }
 
-/// This function implements the following C++0x paragraphs:
-///  - [class.ctor]/5
-///  - [class.copy]/11
-bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM) {
-  assert(!MD->isInvalidDecl());
-  CXXRecordDecl *RD = MD->getParent();
-  assert(!RD->isDependentType() && "do deletion after instantiation");
-  if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
-    return false;
+namespace {
+struct SpecialMemberDeletionInfo {
+  Sema &S;
+  CXXMethodDecl *MD;
+  Sema::CXXSpecialMember CSM;
 
-  bool IsUnion = RD->isUnion();
-  bool IsConstructor = false;
-  bool IsAssignment = false;
-  bool IsMove = false;
-  
-  bool ConstArg = false;
-
-  switch (CSM) {
-  case CXXDefaultConstructor:
-    IsConstructor = true;
-
-    // C++11 [expr.lambda.prim]p19:
-    //   The closure type associated with a lambda-expression has a
-    //   deleted (8.4.3) default constructor.
-    if (RD->isLambda())
-      return true;
+  // Properties of the special member, computed for convenience.
+  bool IsConstructor, IsAssignment, IsMove, ConstArg, VolatileArg;
+  SourceLocation Loc;
+
+  bool AllFieldsAreConst;
+
+  SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
+                            Sema::CXXSpecialMember CSM)
+    : S(S), MD(MD), CSM(CSM),
+      IsConstructor(false), IsAssignment(false), IsMove(false),
+      ConstArg(false), VolatileArg(false), Loc(MD->getLocation()),
+      AllFieldsAreConst(true) {
+    switch (CSM) {
+      case Sema::CXXDefaultConstructor:
+      case Sema::CXXCopyConstructor:
+        IsConstructor = true;
+        break;
+      case Sema::CXXMoveConstructor:
+        IsConstructor = true;
+        IsMove = true;
+        break;
+      case Sema::CXXCopyAssignment:
+        IsAssignment = true;
+        break;
+      case Sema::CXXMoveAssignment:
+        IsAssignment = true;
+        IsMove = true;
+        break;
+      case Sema::CXXDestructor:
+        break;
+      case Sema::CXXInvalid:
+        llvm_unreachable("invalid special member kind");
+    }
 
-    break;
-  case CXXCopyConstructor:
-    IsConstructor = true;
-    ConstArg = MD->getParamDecl(0)->getType().isConstQualified();
-    break;
-  case CXXMoveConstructor:
-    IsConstructor = true;
-    IsMove = true;
-    break;
-  default:
-    llvm_unreachable("function only currently implemented for default ctors");
+    if (MD->getNumParams()) {
+      ConstArg = MD->getParamDecl(0)->getType().isConstQualified();
+      VolatileArg = MD->getParamDecl(0)->getType().isVolatileQualified();
+    }
   }
 
-  SourceLocation Loc = MD->getLocation();
+  bool inUnion() const { return MD->getParent()->isUnion(); }
 
-  // Do access control from the special member function
-  ContextRAII MethodContext(*this, MD);
+  /// Look up the corresponding special member in the given class.
+  Sema::SpecialMemberOverloadResult *lookupIn(CXXRecordDecl *Class) {
+    unsigned TQ = MD->getTypeQualifiers();
+    return S.LookupSpecialMember(Class, CSM, ConstArg, VolatileArg,
+                                 MD->getRefQualifier() == RQ_RValue,
+                                 TQ & Qualifiers::Const,
+                                 TQ & Qualifiers::Volatile);
+  }
 
-  bool AllConst = true;
+  bool shouldDeleteForBase(CXXRecordDecl *BaseDecl, bool IsVirtualBase);
+  bool shouldDeleteForField(FieldDecl *FD);
+  bool shouldDeleteForAllConstMembers();
+};
+}
 
-  // We do this because we should never actually use an anonymous
-  // union's constructor.
-  if (IsUnion && RD->isAnonymousStructOrUnion())
-    return false;
+/// Check whether we should delete a special member function due to the class
+/// having a particular direct or virtual base class.
+bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXRecordDecl *BaseDecl,
+                                                    bool IsVirtualBase) {
+  // C++11 [class.copy]p23:
+  // -- for the move assignment operator, any direct or indirect virtual
+  //    base class.
+  if (CSM == Sema::CXXMoveAssignment && IsVirtualBase)
+    return true;
 
-  // FIXME: We should put some diagnostic logic right into this function.
+  // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5:
+  // -- any direct or virtual base class [...] has a type with a destructor
+  //    that is deleted or inaccessible
+  if (!IsAssignment) {
+    CXXDestructorDecl *BaseDtor = S.LookupDestructor(BaseDecl);
+    if (BaseDtor->isDeleted())
+      return true;
+    if (S.CheckDestructorAccess(Loc, BaseDtor, S.PDiag())
+          != Sema::AR_accessible)
+      return true;
+  }
 
-  for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end();
-       BI != BE; ++BI) {
-    // We'll handle this one later
-    if (BI->isVirtual())
-      continue;
+  // C++11 [class.ctor]p5:
+  // -- any direct or virtual base class [...] has class type M [...] and
+  //    either M has no default constructor or overload resolution as applied
+  //    to M's default constructor results in an ambiguity or in a function
+  //    that is deleted or inaccessible
+  // C++11 [class.copy]p11, C++11 [class.copy]p23:
+  // -- a direct or virtual base class B that cannot be copied/moved because
+  //    overload resolution, as applied to B's corresponding special member,
+  //    results in an ambiguity or a function that is deleted or inaccessible
+  //    from the defaulted special member
+  if (CSM != Sema::CXXDestructor) {
+    Sema::SpecialMemberOverloadResult *SMOR = lookupIn(BaseDecl);
+    if (!SMOR->hasSuccess())
+      return true;
 
-    CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
-    assert(BaseDecl && "base isn't a CXXRecordDecl");
+    CXXMethodDecl *BaseMember = SMOR->getMethod();
+    if (IsConstructor) {
+      CXXConstructorDecl *BaseCtor = cast<CXXConstructorDecl>(BaseMember);
+      if (S.CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(),
+                                   S.PDiag()) != Sema::AR_accessible)
+        return true;
 
-    // Unless we have an assignment operator, the base's destructor must
-    // be accessible and not deleted.
-    if (!IsAssignment) {
-      CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl);
-      if (BaseDtor->isDeleted())
+      // -- for the move constructor, a [...] direct or virtual base class with
+      //    a type that does not have a move constructor and is not trivially
+      //    copyable.
+      if (IsMove && !BaseCtor->isMoveConstructor() &&
+          !BaseDecl->isTriviallyCopyable())
         return true;
-      if (CheckDestructorAccess(Loc, BaseDtor, PDiag()) !=
-          AR_accessible)
+    } else {
+      assert(IsAssignment && "unexpected kind of special member");
+      if (S.CheckDirectMemberAccess(Loc, BaseMember, S.PDiag())
+            != Sema::AR_accessible)
         return true;
-    }
 
-    // Finding the corresponding member in the base should lead to a
-    // unique, accessible, non-deleted function. If we are doing
-    // a destructor, we have already checked this case.
-    if (CSM != CXXDestructor) {
-      SpecialMemberOverloadResult *SMOR =
-        LookupSpecialMember(BaseDecl, CSM, ConstArg, false, false, false,
-                            false);
-      if (!SMOR->hasSuccess())
+      // -- for the move assignment operator, a direct base class with a type
+      //    that does not have a move assignment operator and is not trivially
+      //    copyable.
+      if (IsMove && !BaseMember->isMoveAssignmentOperator() &&
+          !BaseDecl->isTriviallyCopyable())
         return true;
-      CXXMethodDecl *BaseMember = SMOR->getMethod();
-      if (IsConstructor) {
-        CXXConstructorDecl *BaseCtor = cast<CXXConstructorDecl>(BaseMember);
-        if (CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(),
-                                   PDiag()) != AR_accessible)
-          return true;
-
-        // For a move operation, the corresponding operation must actually
-        // be a move operation (and not a copy selected by overload
-        // resolution) unless we are working on a trivially copyable class.
-        if (IsMove && !BaseCtor->isMoveConstructor() &&
-            !BaseDecl->isTriviallyCopyable())
-          return true;
-      }
     }
   }
 
-  for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
-                                          BE = RD->vbases_end();
-       BI != BE; ++BI) {
-    CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
-    assert(BaseDecl && "base isn't a CXXRecordDecl");
-
-    // Unless we have an assignment operator, the base's destructor must
-    // be accessible and not deleted.
-    if (!IsAssignment) {
-      CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl);
-      if (BaseDtor->isDeleted())
-        return true;
-      if (CheckDestructorAccess(Loc, BaseDtor, PDiag()) !=
-          AR_accessible)
-        return true;
-    }
-
-    // Finding the corresponding member in the base should lead to a
-    // unique, accessible, non-deleted function.
-    if (CSM != CXXDestructor) {
-      SpecialMemberOverloadResult *SMOR =
-        LookupSpecialMember(BaseDecl, CSM, ConstArg, false, false, false,
-                            false);
-      if (!SMOR->hasSuccess())
-        return true;
-      CXXMethodDecl *BaseMember = SMOR->getMethod();
-      if (IsConstructor) {
-        CXXConstructorDecl *BaseCtor = cast<CXXConstructorDecl>(BaseMember);
-        if (CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(),
-                                   PDiag()) != AR_accessible)
-          return true;
-
-        // For a move operation, the corresponding operation must actually
-        // be a move operation (and not a copy selected by overload
-        // resolution) unless we are working on a trivially copyable class.
-        if (IsMove && !BaseCtor->isMoveConstructor() &&
-            !BaseDecl->isTriviallyCopyable())
-          return true;
-      }
-    }
+  // C++11 [class.dtor]p5:
+  // -- for a virtual destructor, lookup of the non-array deallocation function
+  //    results in an ambiguity or in a function that is deleted or inaccessible
+  if (CSM == Sema::CXXDestructor && MD->isVirtual()) {
+    FunctionDecl *OperatorDelete = 0;
+    DeclarationName Name =
+      S.Context.DeclarationNames.getCXXOperatorName(OO_Delete);
+    if (S.FindDeallocationFunction(Loc, MD->getParent(), Name,
+                                   OperatorDelete, false))
+      return true;
   }
 
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end();
-       FI != FE; ++FI) {
-    if (FI->isInvalidDecl() || FI->isUnnamedBitfield())
-      continue;
-    
-    QualType FieldType = Context.getBaseElementType(FI->getType());
-    CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
+  return false;
+}
+
+/// Check whether we should delete a special member function due to the class
+/// having a particular non-static data member.
+bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
+  QualType FieldType = S.Context.getBaseElementType(FD->getType());
+  CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
 
+  if (CSM == Sema::CXXDefaultConstructor) {
     // For a default constructor, all references must be initialized in-class
     // and, if a union, it must have a non-const member.
-    if (CSM == CXXDefaultConstructor) {
-      if (FieldType->isReferenceType() && !FI->hasInClassInitializer())
-        return true;
+    if (FieldType->isReferenceType() && !FD->hasInClassInitializer())
+      return true;
 
-      if (IsUnion && !FieldType.isConstQualified())
-        AllConst = false;
+    if (inUnion() && !FieldType.isConstQualified())
+      AllFieldsAreConst = false;
+  } else if (CSM == Sema::CXXCopyConstructor) {
     // For a copy constructor, data members must not be of rvalue reference
     // type.
-    } else if (CSM == CXXCopyConstructor) {
-      if (FieldType->isRValueReferenceType())
-        return true;
-    }
+    if (FieldType->isRValueReferenceType())
+      return true;
+  } else if (IsAssignment) {
+    // For an assignment operator, data members must not be of reference type.
+    if (FieldType->isReferenceType())
+      return true;
+  }
 
-    if (FieldRecord) {
-      // For a default constructor, a const member must have a user-provided
-      // default constructor or else be explicitly initialized.
-      if (CSM == CXXDefaultConstructor && FieldType.isConstQualified() &&
-          !FI->hasInClassInitializer() &&
-          !FieldRecord->hasUserProvidedDefaultConstructor())
-        return true;
- 
-      // Some additional restrictions exist on the variant members.
-      if (!IsUnion && FieldRecord->isUnion() &&
-          FieldRecord->isAnonymousStructOrUnion()) {
-        // We're okay to reuse AllConst here since we only care about the
-        // value otherwise if we're in a union.
-        AllConst = true;
-
-        for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
-                                           UE = FieldRecord->field_end();
-             UI != UE; ++UI) {
-          QualType UnionFieldType = Context.getBaseElementType(UI->getType());
-          CXXRecordDecl *UnionFieldRecord =
-            UnionFieldType->getAsCXXRecordDecl();
+  if (FieldRecord) {
+    // For a default constructor, a const member must have a user-provided
+    // default constructor or else be explicitly initialized.
+    if (CSM == Sema::CXXDefaultConstructor && FieldType.isConstQualified() &&
+        !FD->hasInClassInitializer() &&
+        !FieldRecord->hasUserProvidedDefaultConstructor())
+      return true;
 
-          if (!UnionFieldType.isConstQualified())
-            AllConst = false;
+    // Some additional restrictions exist on the variant members.
+    if (!inUnion() && FieldRecord->isUnion() &&
+        FieldRecord->isAnonymousStructOrUnion()) {
+      bool AllVariantFieldsAreConst = true;
+
+      for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
+                                         UE = FieldRecord->field_end();
+           UI != UE; ++UI) {
+        QualType UnionFieldType = S.Context.getBaseElementType(UI->getType());
+        CXXRecordDecl *UnionFieldRecord =
+          UnionFieldType->getAsCXXRecordDecl();
+
+        if (!UnionFieldType.isConstQualified())
+          AllVariantFieldsAreConst = false;
+
+        if (UnionFieldRecord) {
+          // FIXME: Checking for accessibility and validity of this
+          //        destructor is technically going beyond the
+          //        standard, but this is believed to be a defect.
+          if (!IsAssignment) {
+            CXXDestructorDecl *FieldDtor = S.LookupDestructor(UnionFieldRecord);
+            if (FieldDtor->isDeleted())
+              return true;
+            if (S.CheckDestructorAccess(Loc, FieldDtor, S.PDiag()) !=
+                Sema::AR_accessible)
+              return true;
+            if (!FieldDtor->isTrivial())
+              return true;
+          }
 
-          if (UnionFieldRecord) {
+          // FIXME: in-class initializers should be handled here
+          if (CSM != Sema::CXXDestructor) {
+            Sema::SpecialMemberOverloadResult *SMOR =
+                lookupIn(UnionFieldRecord);
             // FIXME: Checking for accessibility and validity of this
-            //        destructor is technically going beyond the
+            //        corresponding member is technically going beyond the
             //        standard, but this is believed to be a defect.
-            if (!IsAssignment) {
-              CXXDestructorDecl *FieldDtor = LookupDestructor(UnionFieldRecord);
-              if (FieldDtor->isDeleted())
-                return true;
-              if (CheckDestructorAccess(Loc, FieldDtor, PDiag()) !=
-                  AR_accessible)
-                return true;
-              if (!FieldDtor->isTrivial())
-                return true;
-            }
-
-            if (CSM != CXXDestructor) {
-              SpecialMemberOverloadResult *SMOR =
-                LookupSpecialMember(UnionFieldRecord, CSM, ConstArg, false,
-                                    false, false, false);
-              // FIXME: Checking for accessibility and validity of this
-              //        corresponding member is technically going beyond the
-              //        standard, but this is believed to be a defect.
-              if (!SMOR->hasSuccess())
-                return true;
+            if (!SMOR->hasSuccess())
+              return true;
 
-              CXXMethodDecl *FieldMember = SMOR->getMethod();
-              // A member of a union must have a trivial corresponding
-              // constructor.
-              if (!FieldMember->isTrivial())
-                return true;
+            CXXMethodDecl *FieldMember = SMOR->getMethod();
+            // A member of a union must have a trivial corresponding
+            // special member.
+            if (!FieldMember->isTrivial())
+              return true;
 
-              if (IsConstructor) {
-                CXXConstructorDecl *FieldCtor = cast<CXXConstructorDecl>(FieldMember);
-                if (CheckConstructorAccess(Loc, FieldCtor, FieldCtor->getAccess(),
-                                           PDiag()) != AR_accessible)
+            if (IsConstructor) {
+              CXXConstructorDecl *FieldCtor =
+                  cast<CXXConstructorDecl>(FieldMember);
+              if (S.CheckConstructorAccess(Loc, FieldCtor,
+                                           FieldCtor->getAccess(),
+                                           S.PDiag()) != Sema::AR_accessible)
+              return true;
+            } else {
+              assert(IsAssignment && "unexpected kind of special member");
+              if (S.CheckDirectMemberAccess(Loc, FieldMember, S.PDiag())
+                  != Sema::AR_accessible)
                 return true;
-              }
             }
           }
         }
-
-        // At least one member in each anonymous union must be non-const
-        if (CSM == CXXDefaultConstructor && AllConst)
-          return true;
-
-        // Don't try to initialize the anonymous union
-        // This is technically non-conformant, but sanity demands it.
-        continue;
       }
 
-      // Unless we're doing assignment, the field's destructor must be
-      // accessible and not deleted.
-      if (!IsAssignment) {
-        CXXDestructorDecl *FieldDtor = LookupDestructor(FieldRecord);
-        if (FieldDtor->isDeleted())
-          return true;
-        if (CheckDestructorAccess(Loc, FieldDtor, PDiag()) !=
-            AR_accessible)
-          return true;
-      }
-
-      // Check that the corresponding member of the field is accessible,
-      // unique, and non-deleted. We don't do this if it has an explicit
-      // initialization when default-constructing.
-      if (CSM != CXXDestructor &&
-          (CSM != CXXDefaultConstructor || !FI->hasInClassInitializer())) {
-        SpecialMemberOverloadResult *SMOR =
-          LookupSpecialMember(FieldRecord, CSM, ConstArg, false, false, false,
-                              false);
-        if (!SMOR->hasSuccess())
-          return true;
-
-        CXXMethodDecl *FieldMember = SMOR->getMethod();
-        if (IsConstructor) {
-          CXXConstructorDecl *FieldCtor = cast<CXXConstructorDecl>(FieldMember);
-          if (CheckConstructorAccess(Loc, FieldCtor, FieldCtor->getAccess(),
-                                     PDiag()) != AR_accessible)
-          return true;
-
-          // For a move operation, the corresponding operation must actually
-          // be a move operation (and not a copy selected by overload
-          // resolution) unless we are working on a trivially copyable class.
-          if (IsMove && !FieldCtor->isMoveConstructor() &&
-              !FieldRecord->isTriviallyCopyable())
-            return true;
-        }
+      // At least one member in each anonymous union must be non-const
+      if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst)
+        return true;
 
-        // We need the corresponding member of a union to be trivial so that
-        // we can safely copy them all simultaneously.
-        // FIXME: Note that performing the check here (where we rely on the lack
-        // of an in-class initializer) is technically ill-formed. However, this
-        // seems most obviously to be a bug in the standard.
-        if (IsUnion && !FieldMember->isTrivial())
-          return true;
-      }
-    } else if (CSM == CXXDefaultConstructor && !IsUnion &&
-               FieldType.isConstQualified() && !FI->hasInClassInitializer()) {
-      // We can't initialize a const member of non-class type to any value.
-      return true;
+      // Don't try to initialize the anonymous union
+      // This is technically non-conformant, but sanity demands it.
+      return false;
     }
-  }
-
-  // We can't have all const members in a union when default-constructing,
-  // or else they're all nonsensical garbage values that can't be changed.
-  if (CSM == CXXDefaultConstructor && IsUnion && AllConst)
-    return true;
-
-  return false;
-}
-
-bool Sema::ShouldDeleteCopyAssignmentOperator(CXXMethodDecl *MD) {
-  CXXRecordDecl *RD = MD->getParent();
-  assert(!RD->isDependentType() && "do deletion after instantiation");
-  if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
-    return false;
-
-  // C++11 [expr.lambda.prim]p19:
-  //   The closure type associated with a lambda-expression has a
-  //   [...] deleted copy assignment operator.
-  if (RD->isLambda())
-    return true;
-
-  SourceLocation Loc = MD->getLocation();
-
-  // Do access control from the constructor
-  ContextRAII MethodContext(*this, MD);
-
-  bool Union = RD->isUnion();
-
-  unsigned ArgQuals =
-    MD->getParamDecl(0)->getType()->getPointeeType().isConstQualified() ?
-      Qualifiers::Const : 0;
-
-  // We do this because we should never actually use an anonymous
-  // union's constructor.
-  if (Union && RD->isAnonymousStructOrUnion())
-    return false;
-
-  // FIXME: We should put some diagnostic logic right into this function.
-
-  // C++0x [class.copy]/20
-  //    A defaulted [copy] assignment operator for class X is defined as deleted
-  //    if X has:
-
-  for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end();
-       BI != BE; ++BI) {
-    // We'll handle this one later
-    if (BI->isVirtual())
-      continue;
-
-    QualType BaseType = BI->getType();
-    CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl();
-    assert(BaseDecl && "base isn't a CXXRecordDecl");
-
-    // -- a [direct base class] B that cannot be [copied] because overload
-    //    resolution, as applied to B's [copy] assignment operator, results in
-    //    an ambiguity or a function that is deleted or inaccessible from the
-    //    assignment operator
-    CXXMethodDecl *CopyOper = LookupCopyingAssignment(BaseDecl, ArgQuals, false,
-                                                      0);
-    if (!CopyOper || CopyOper->isDeleted())
-      return true;
-    if (CheckDirectMemberAccess(Loc, CopyOper, PDiag()) != AR_accessible)
-      return true;
-  }
 
-  for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
-                                          BE = RD->vbases_end();
-       BI != BE; ++BI) {
-    QualType BaseType = BI->getType();
-    CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl();
-    assert(BaseDecl && "base isn't a CXXRecordDecl");
-
-    // -- a [virtual base class] B that cannot be [copied] because overload
-    //    resolution, as applied to B's [copy] assignment operator, results in
-    //    an ambiguity or a function that is deleted or inaccessible from the
-    //    assignment operator
-    CXXMethodDecl *CopyOper = LookupCopyingAssignment(BaseDecl, ArgQuals, false,
-                                                      0);
-    if (!CopyOper || CopyOper->isDeleted())
-      return true;
-    if (CheckDirectMemberAccess(Loc, CopyOper, PDiag()) != AR_accessible)
-      return true;
-  }
+    // Unless we're doing assignment, the field's destructor must be
+    // accessible and not deleted.
+    if (!IsAssignment) {
+      CXXDestructorDecl *FieldDtor = S.LookupDestructor(FieldRecord);
+      if (FieldDtor->isDeleted())
+        return true;
+      if (S.CheckDestructorAccess(Loc, FieldDtor, S.PDiag()) !=
+          Sema::AR_accessible)
+        return true;
+    }
 
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end();
-       FI != FE; ++FI) {
-    if (FI->isUnnamedBitfield())
-      continue;
-    
-    QualType FieldType = Context.getBaseElementType(FI->getType());
-    
-    // -- a non-static data member of reference type
-    if (FieldType->isReferenceType())
-      return true;
+    // Check that the corresponding member of the field is accessible,
+    // unique, and non-deleted. We don't do this if it has an explicit
+    // initialization when default-constructing.
+    if (CSM != Sema::CXXDestructor &&
+        !(CSM == Sema::CXXDefaultConstructor && FD->hasInClassInitializer())) {
+      Sema::SpecialMemberOverloadResult *SMOR = lookupIn(FieldRecord);
+      if (!SMOR->hasSuccess())
+        return true;
 
-    // -- a non-static data member of const non-class type (or array thereof)
-    if (FieldType.isConstQualified() && !FieldType->isRecordType())
-      return true;
- 
-    CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
+      CXXMethodDecl *FieldMember = SMOR->getMethod();
+      if (IsConstructor) {
+        CXXConstructorDecl *FieldCtor = cast<CXXConstructorDecl>(FieldMember);
+        if (S.CheckConstructorAccess(Loc, FieldCtor, FieldCtor->getAccess(),
+                                     S.PDiag()) != Sema::AR_accessible)
+        return true;
 
-    if (FieldRecord) {
-      // This is an anonymous union
-      if (FieldRecord->isUnion() && FieldRecord->isAnonymousStructOrUnion()) {
-        // Anonymous unions inside unions do not variant members create
-        if (!Union) {
-          for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
-                                             UE = FieldRecord->field_end();
-               UI != UE; ++UI) {
-            QualType UnionFieldType = Context.getBaseElementType(UI->getType());
-            CXXRecordDecl *UnionFieldRecord =
-              UnionFieldType->getAsCXXRecordDecl();
-
-            // -- a variant member with a non-trivial [copy] assignment operator
-            //    and X is a union-like class
-            if (UnionFieldRecord &&
-                !UnionFieldRecord->hasTrivialCopyAssignment())
-              return true;
-          }
-        }
+        // For a move operation, the corresponding operation must actually
+        // be a move operation (and not a copy selected by overload
+        // resolution) unless we are working on a trivially copyable class.
+        if (IsMove && !FieldCtor->isMoveConstructor() &&
+            !FieldRecord->isTriviallyCopyable())
+          return true;
+      } else {
+        assert(IsAssignment && "unexpected kind of special member");
+        if (S.CheckDirectMemberAccess(Loc, FieldMember, S.PDiag())
+              != Sema::AR_accessible)
+          return true;
 
-        // Don't try to initalize an anonymous union
-        continue;
-      // -- a variant member with a non-trivial [copy] assignment operator
-      //    and X is a union-like class
-      } else if (Union && !FieldRecord->hasTrivialCopyAssignment()) {
+        // -- for the move assignment operator, a non-static data member with a
+        //    type that does not have a move assignment operator and is not
+        //    trivially copyable.
+        if (IsMove && !FieldMember->isMoveAssignmentOperator() &&
+            !FieldRecord->isTriviallyCopyable())
           return true;
       }
 
-      CXXMethodDecl *CopyOper = LookupCopyingAssignment(FieldRecord, ArgQuals,
-                                                        false, 0);
-      if (!CopyOper || CopyOper->isDeleted())
-        return true;
-      if (CheckDirectMemberAccess(Loc, CopyOper, PDiag()) != AR_accessible)
+      // We need the corresponding member of a union to be trivial so that
+      // we can safely copy them all simultaneously.
+      // FIXME: Note that performing the check here (where we rely on the lack
+      // of an in-class initializer) is technically ill-formed. However, this
+      // seems most obviously to be a bug in the standard.
+      if (inUnion() && !FieldMember->isTrivial())
         return true;
     }
+  } else if (CSM == Sema::CXXDefaultConstructor && !inUnion() &&
+             FieldType.isConstQualified() && !FD->hasInClassInitializer()) {
+    // We can't initialize a const member of non-class type to any value.
+    return true;
+  } else if (IsAssignment && FieldType.isConstQualified()) {
+    // C++11 [class.copy]p23:
+    // -- a non-static data member of const non-class type (or array thereof)
+    return true;
   }
 
   return false;
 }
 
-bool Sema::ShouldDeleteMoveAssignmentOperator(CXXMethodDecl *MD) {
+/// C++11 [class.ctor] p5:
+///   A defaulted default constructor for a class X is defined as deleted if
+/// X is a union and all of its variant members are of const-qualified type.
+bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
+  return CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst;
+}
+
+/// Determine whether a defaulted special member function should be defined as
+/// deleted, as specified in C++11 [class.ctor]p5, C++11 [class.copy]p11,
+/// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
+bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM) {
+  assert(!MD->isInvalidDecl());
   CXXRecordDecl *RD = MD->getParent();
   assert(!RD->isDependentType() && "do deletion after instantiation");
   if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
     return false;
 
-  SourceLocation Loc = MD->getLocation();
-
-  // Do access control from the constructor
-  ContextRAII MethodContext(*this, MD);
-
-  bool Union = RD->isUnion();
-
-  // We do this because we should never actually use an anonymous
-  // union's constructor.
-  if (Union && RD->isAnonymousStructOrUnion())
-    return false;
-
-  // C++0x [class.copy]/20
-  //    A defaulted [move] assignment operator for class X is defined as deleted
-  //    if X has:
-
-  //    -- for the move constructor, [...] any direct or indirect virtual base
-  //       class.
-  if (RD->getNumVBases() != 0)
+  // C++11 [expr.lambda.prim]p19:
+  //   The closure type associated with a lambda-expression has a
+  //   deleted (8.4.3) default constructor and a deleted copy
+  //   assignment operator.
+  if (RD->isLambda() &&
+      (CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment))
     return true;
 
-  for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end();
-       BI != BE; ++BI) {
-
-    QualType BaseType = BI->getType();
-    CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl();
-    assert(BaseDecl && "base isn't a CXXRecordDecl");
-
-    // -- a [direct base class] B that cannot be [moved] because overload
-    //    resolution, as applied to B's [move] assignment operator, results in
-    //    an ambiguity or a function that is deleted or inaccessible from the
-    //    assignment operator
-    CXXMethodDecl *MoveOper = LookupMovingAssignment(BaseDecl, false, 0);
-    if (!MoveOper || MoveOper->isDeleted())
-      return true;
-    if (CheckDirectMemberAccess(Loc, MoveOper, PDiag()) != AR_accessible)
-      return true;
-
-    // -- for the move assignment operator, a [direct base class] with a type
-    //    that does not have a move assignment operator and is not trivially
-    //    copyable.
-    if (!MoveOper->isMoveAssignmentOperator() &&
-        !BaseDecl->isTriviallyCopyable())
-      return true;
-  }
-
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end();
-       FI != FE; ++FI) {
-    if (FI->isUnnamedBitfield())
-      continue;
-        
-    QualType FieldType = Context.getBaseElementType(FI->getType());
-    
-    // -- a non-static data member of reference type
-    if (FieldType->isReferenceType())
-      return true;
-
-    // -- a non-static data member of const non-class type (or array thereof)
-    if (FieldType.isConstQualified() && !FieldType->isRecordType())
-      return true;
-
-    CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
-
-    if (FieldRecord) {
-      // This is an anonymous union
-      if (FieldRecord->isUnion() && FieldRecord->isAnonymousStructOrUnion()) {
-        // Anonymous unions inside unions do not variant members create
-        if (!Union) {
-          for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
-                                             UE = FieldRecord->field_end();
-               UI != UE; ++UI) {
-            QualType UnionFieldType = Context.getBaseElementType(UI->getType());
-            CXXRecordDecl *UnionFieldRecord =
-              UnionFieldType->getAsCXXRecordDecl();
-
-            // -- a variant member with a non-trivial [move] assignment operator
-            //    and X is a union-like class
-            if (UnionFieldRecord &&
-                !UnionFieldRecord->hasTrivialMoveAssignment())
-              return true;
-          }
-        }
-
-        // Don't try to initalize an anonymous union
-        continue;
-      // -- a variant member with a non-trivial [move] assignment operator
-      //    and X is a union-like class
-      } else if (Union && !FieldRecord->hasTrivialMoveAssignment()) {
-          return true;
-      }
-
-      CXXMethodDecl *MoveOper = LookupMovingAssignment(FieldRecord, false, 0);
-      if (!MoveOper || MoveOper->isDeleted())
-        return true;
-      if (CheckDirectMemberAccess(Loc, MoveOper, PDiag()) != AR_accessible)
-        return true;
-
-      // -- for the move assignment operator, a [non-static data member] with a
-      //    type that does not have a move assignment operator and is not
-      //    trivially copyable.
-      if (!MoveOper->isMoveAssignmentOperator() &&
-          !FieldRecord->isTriviallyCopyable())
-        return true;
-    }
-  }
-
-  return false;
-}
-
-bool Sema::ShouldDeleteDestructor(CXXDestructorDecl *DD) {
-  CXXRecordDecl *RD = DD->getParent();
-  assert(!RD->isDependentType() && "do deletion after instantiation");
-  if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
+  // For an anonymous struct or union, the copy and assignment special members
+  // will never be used, so skip the check. For an anonymous union declared at
+  // namespace scope, the constructor and destructor are used.
+  if (CSM != CXXDefaultConstructor && CSM != CXXDestructor &&
+      RD->isAnonymousStructOrUnion())
     return false;
 
-  SourceLocation Loc = DD->getLocation();
-
-  // Do access control from the destructor
-  ContextRAII CtorContext(*this, DD);
+  // Do access control from the special member function
+  ContextRAII MethodContext(*this, MD);
 
-  bool Union = RD->isUnion();
+  SpecialMemberDeletionInfo SMI(*this, MD, CSM);
 
-  // We do this because we should never actually use an anonymous
-  // union's destructor.
-  if (Union && RD->isAnonymousStructOrUnion())
-    return false;
+  // FIXME: We should put some diagnostic logic right into this function.
 
-  // C++0x [class.dtor]p5
-  //    A defaulted destructor for a class X is defined as deleted if:
   for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end();
-       BI != BE; ++BI) {
-    // We'll handle this one later
-    if (BI->isVirtual())
-      continue;
-
-    CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
-    CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl);
-    assert(BaseDtor && "base has no destructor");
-
-    // -- any direct or virtual base class has a deleted destructor or
-    //    a destructor that is inaccessible from the defaulted destructor
-    if (BaseDtor->isDeleted())
-      return true;
-    if (CheckDestructorAccess(Loc, BaseDtor, PDiag()) !=
-        AR_accessible)
+                                          BE = RD->bases_end(); BI != BE; ++BI)
+    if (!BI->isVirtual() &&
+        SMI.shouldDeleteForBase(BI->getType()->getAsCXXRecordDecl(), false))
       return true;
-  }
 
   for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
-                                          BE = RD->vbases_end();
-       BI != BE; ++BI) {
-    CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
-    CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl);
-    assert(BaseDtor && "base has no destructor");
-
-    // -- any direct or virtual base class has a deleted destructor or
-    //    a destructor that is inaccessible from the defaulted destructor
-    if (BaseDtor->isDeleted())
-      return true;
-    if (CheckDestructorAccess(Loc, BaseDtor, PDiag()) !=
-        AR_accessible)
+                                          BE = RD->vbases_end(); BI != BE; ++BI)
+    if (SMI.shouldDeleteForBase(BI->getType()->getAsCXXRecordDecl(), true))
       return true;
-  }
 
   for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end();
-       FI != FE; ++FI) {
-    QualType FieldType = Context.getBaseElementType(FI->getType());
-    CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
-    if (FieldRecord) {
-      if (FieldRecord->isUnion() && FieldRecord->isAnonymousStructOrUnion()) {
-         for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
-                                            UE = FieldRecord->field_end();
-              UI != UE; ++UI) {
-           QualType UnionFieldType = Context.getBaseElementType(FI->getType());
-           CXXRecordDecl *UnionFieldRecord =
-             UnionFieldType->getAsCXXRecordDecl();
-
-           // -- X is a union-like class that has a variant member with a non-
-           //    trivial destructor.
-           if (UnionFieldRecord && !UnionFieldRecord->hasTrivialDestructor())
-             return true;
-         }
-      // Technically we are supposed to do this next check unconditionally.
-      // But that makes absolutely no sense.
-      } else {
-        CXXDestructorDecl *FieldDtor = LookupDestructor(FieldRecord);
-
-        // -- any of the non-static data members has class type M (or array
-        //    thereof) and M has a deleted destructor or a destructor that is
-        //    inaccessible from the defaulted destructor
-        if (FieldDtor->isDeleted())
-          return true;
-        if (CheckDestructorAccess(Loc, FieldDtor, PDiag()) !=
-          AR_accessible)
-        return true;
-        
-        // -- X is a union-like class that has a variant member with a non-
-        //    trivial destructor.
-        if (Union && !FieldDtor->isTrivial())
-          return true;
-      }
-    }
-  }
-
-  if (DD->isVirtual()) {
-    FunctionDecl *OperatorDelete = 0;
-    DeclarationName Name =
-      Context.DeclarationNames.getCXXOperatorName(OO_Delete);
-    if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete,
-          false))
+                                     FE = RD->field_end(); FI != FE; ++FI)
+    if (!FI->isInvalidDecl() && !FI->isUnnamedBitfield() &&
+        SMI.shouldDeleteForField(*FI))
       return true;
-  }
 
+  if (SMI.shouldDeleteForAllConstMembers())
+    return true;
 
   return false;
 }
@@ -7469,7 +7179,7 @@
   // This could be uniqued if it ever proves significant.
   Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty));
 
-  if (ShouldDeleteDestructor(Destructor))
+  if (ShouldDeleteSpecialMember(Destructor, CXXDestructor))
     Destructor->setDeletedAsWritten();
   
   AddOverriddenMethods(ClassDecl, Destructor);
@@ -7918,7 +7628,7 @@
   if ((ClassDecl->hasUserDeclaredMoveConstructor() &&
           !getLangOptions().MicrosoftMode) ||
       ClassDecl->hasUserDeclaredMoveAssignment() ||
-      ShouldDeleteCopyAssignmentOperator(CopyAssignment))
+      ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment))
     CopyAssignment->setDeletedAsWritten();
   
   AddOverriddenMethods(ClassDecl, CopyAssignment);
@@ -8218,10 +7928,14 @@
     CopyAssignOperator->setInvalidDecl();
     return;
   }
-  
-  StmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
-                                            /*isStmtExpr=*/false);
-  assert(!Body.isInvalid() && "Compound statement creation cannot fail");
+
+  StmtResult Body;
+  {
+    CompoundScopeRAII CompoundScope(*this);
+    Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
+                             /*isStmtExpr=*/false);
+    assert(!Body.isInvalid() && "Compound statement creation cannot fail");
+  }
   CopyAssignOperator->setBody(Body.takeAs<Stmt>());
 
   if (ASTMutationListener *L = getASTMutationListener()) {
@@ -8334,7 +8048,7 @@
   //   [...]
   //   - the move assignment operator would not be implicitly defined as
   //     deleted.
-  if (ShouldDeleteMoveAssignmentOperator(MoveAssignment)) {
+  if (ShouldDeleteSpecialMember(MoveAssignment, CXXMoveAssignment)) {
     // Cache this result so that we don't try to generate this over and over
     // on every lookup, leaking memory and wasting time.
     ClassDecl->setFailedImplicitMoveAssignment();
@@ -8650,10 +8364,14 @@
     MoveAssignOperator->setInvalidDecl();
     return;
   }
-  
-  StmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
-                                            /*isStmtExpr=*/false);
-  assert(!Body.isInvalid() && "Compound statement creation cannot fail");
+
+  StmtResult Body;
+  {
+    CompoundScopeRAII CompoundScope(*this);
+    Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
+                             /*isStmtExpr=*/false);
+    assert(!Body.isInvalid() && "Compound statement creation cannot fail");
+  }
   MoveAssignOperator->setBody(Body.takeAs<Stmt>());
 
   if (ASTMutationListener *L = getASTMutationListener()) {
@@ -8852,9 +8570,10 @@
       << CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
     CopyConstructor->setInvalidDecl();
   }  else {
+    Sema::CompoundScopeRAII CompoundScope(*this);
     CopyConstructor->setBody(ActOnCompoundStmt(CopyConstructor->getLocation(),
                                                CopyConstructor->getLocation(),
-                                               MultiStmtArg(*this, 0, 0), 
+                                               MultiStmtArg(*this, 0, 0),
                                                /*isStmtExpr=*/false)
                                                               .takeAs<Stmt>());
     CopyConstructor->setImplicitlyDefined(true);
@@ -9006,9 +8725,10 @@
       << CXXMoveConstructor << Context.getTagDeclType(ClassDecl);
     MoveConstructor->setInvalidDecl();
   }  else {
+    Sema::CompoundScopeRAII CompoundScope(*this);
     MoveConstructor->setBody(ActOnCompoundStmt(MoveConstructor->getLocation(),
                                                MoveConstructor->getLocation(),
-                                               MultiStmtArg(*this, 0, 0), 
+                                               MultiStmtArg(*this, 0, 0),
                                                /*isStmtExpr=*/false)
                                                               .takeAs<Stmt>());
     MoveConstructor->setImplicitlyDefined(true);
@@ -9021,6 +8741,98 @@
   }
 }
 
+bool Sema::isImplicitlyDeleted(FunctionDecl *FD) {
+  return FD->isDeleted() && 
+         (FD->isDefaulted() || FD->isImplicit()) &&
+         isa<CXXMethodDecl>(FD);
+}
+
+/// \brief Mark the call operator of the given lambda closure type as "used".
+static void markLambdaCallOperatorUsed(Sema &S, CXXRecordDecl *Lambda) {
+  CXXMethodDecl *CallOperator 
+  = cast<CXXMethodDecl>(
+      *Lambda->lookup(
+        S.Context.DeclarationNames.getCXXOperatorName(OO_Call)).first);
+  CallOperator->setReferenced();
+  CallOperator->setUsed();
+}
+
+void Sema::DefineImplicitLambdaToFunctionPointerConversion(
+       SourceLocation CurrentLocation,
+       CXXConversionDecl *Conv) 
+{
+  CXXRecordDecl *Lambda = Conv->getParent();
+  
+  // Make sure that the lambda call operator is marked used.
+  markLambdaCallOperatorUsed(*this, Lambda);
+  
+  Conv->setUsed();
+  
+  ImplicitlyDefinedFunctionScope Scope(*this, Conv);
+  DiagnosticErrorTrap Trap(Diags);
+  
+  // Return the address of the __invoke function.
+  DeclarationName InvokeName = &Context.Idents.get("__invoke");
+  CXXMethodDecl *Invoke 
+    = cast<CXXMethodDecl>(*Lambda->lookup(InvokeName).first);
+  Expr *FunctionRef = BuildDeclRefExpr(Invoke, Invoke->getType(),
+                                       VK_LValue, Conv->getLocation()).take();
+  assert(FunctionRef && "Can't refer to __invoke function?");
+  Stmt *Return = ActOnReturnStmt(Conv->getLocation(), FunctionRef).take();
+  Conv->setBody(new (Context) CompoundStmt(Context, &Return, 1, 
+                                           Conv->getLocation(),
+                                           Conv->getLocation()));
+    
+  // Fill in the __invoke function with a dummy implementation. IR generation
+  // will fill in the actual details.
+  Invoke->setUsed();
+  Invoke->setReferenced();
+  Invoke->setBody(new (Context) CompoundStmt(Context, 0, 0, Conv->getLocation(),
+                                             Conv->getLocation()));
+  
+  if (ASTMutationListener *L = getASTMutationListener()) {
+    L->CompletedImplicitDefinition(Conv);
+    L->CompletedImplicitDefinition(Invoke);
+  }
+}
+
+void Sema::DefineImplicitLambdaToBlockPointerConversion(
+       SourceLocation CurrentLocation,
+       CXXConversionDecl *Conv) 
+{
+  // Make sure that the lambda call operator is marked used.
+  markLambdaCallOperatorUsed(*this, Conv->getParent());
+  Conv->setUsed();
+  
+  ImplicitlyDefinedFunctionScope Scope(*this, Conv);
+  DiagnosticErrorTrap Trap(Diags);
+  
+  // Copy-initialize the lambda object as needed to capture
+  Expr *This = ActOnCXXThis(CurrentLocation).take();
+  Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take();
+  ExprResult Init = PerformCopyInitialization(
+                      InitializedEntity::InitializeBlock(CurrentLocation, 
+                                                         DerefThis->getType(), 
+                                                         /*NRVO=*/false),
+                      CurrentLocation, DerefThis);
+  if (!Init.isInvalid())
+    Init = ActOnFinishFullExpr(Init.take());
+  
+  if (!Init.isInvalid())
+    Conv->setLambdaToBlockPointerCopyInit(Init.take());
+  else {
+    Diag(CurrentLocation, diag::note_lambda_to_block_conv);
+  }
+  
+  // Introduce a bogus body, which IR generation will override anyway.
+  Conv->setBody(new (Context) CompoundStmt(Context, 0, 0, Conv->getLocation(),
+                                           Conv->getLocation()));
+  
+  if (ASTMutationListener *L = getASTMutationListener()) {
+    L->CompletedImplicitDefinition(Conv);
+  }
+}
+
 ExprResult
 Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                             CXXConstructorDecl *Constructor,
@@ -9107,7 +8919,7 @@
 
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Record->getDecl());
   if (ClassDecl->isInvalidDecl()) return;
-  if (ClassDecl->hasTrivialDestructor()) return;
+  if (ClassDecl->hasIrrelevantDestructor()) return;
   if (ClassDecl->isDependentContext()) return;
 
   CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);
@@ -9116,6 +8928,7 @@
                         PDiag(diag::err_access_dtor_var)
                         << VD->getDeclName()
                         << VD->getType());
+  DiagnoseUseOfDecl(Destructor, VD->getLocation());
 
   if (!VD->hasGlobalStorage()) return;
 
@@ -9159,8 +8972,12 @@
   bool Invalid = GatherArgumentsForCall(Loc, Constructor,
                                         Proto, 0, Args, NumArgs, AllArgs, 
                                         CallType);
-  for (unsigned i =0, size = AllArgs.size(); i < size; i++)
-    ConvertedArgs.push_back(AllArgs[i]);
+  ConvertedArgs.append(AllArgs.begin(), AllArgs.end());
+
+  DiagnoseSentinelCalls(Constructor, Loc, AllArgs.data(), AllArgs.size());
+
+  // FIXME: Missing call to CheckFunctionCall or equivalent
+
   return Invalid;
 }
 

Modified: cfe/branches/tooling/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExpr.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExpr.cpp Mon Feb 20 19:34:24 2012
@@ -2094,42 +2094,6 @@
   return S.getCurBlock() != 0;
 }
 
-/// \brief Determine whether the given lambda would capture the given
-/// variable by copy.
-static bool willCaptureByCopy(LambdaScopeInfo *LSI, VarDecl *Var) {
-  if (LSI->isCaptured(Var))
-    return LSI->getCapture(Var).isCopyCapture();
-
-  return LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval;
-}
-
-static bool shouldAddConstQualToVarRef(ValueDecl *D, Sema &S) {
-  VarDecl *var = dyn_cast<VarDecl>(D);
-  if (!var)
-    return false;
-  if (var->getDeclContext() == S.CurContext)
-    return false;
-  if (!var->hasLocalStorage())
-    return false;
-
-  LambdaScopeInfo *LSI = S.getCurLambda();
-  if (!LSI)
-    return false;
-
-  // We don't actually allow capturing a __block variable in a lambda, but
-  // this way gives better diagnostics.
-  if (var->hasAttr<BlocksAttr>())
-    return false;
-
-  // FIXME: Does the addition of const really only apply in
-  // potentially-evaluated contexts?  The text in the lambda spec
-  // about decltype hints that it might apply in unevaluated contexts
-  // as well... and there's precent in our blocks implementation.
-  return !LSI->Mutable &&
-         S.ExprEvalContexts.back().Context != Sema::Unevaluated &&
-         willCaptureByCopy(LSI, var);
-}
-
 static ExprResult BuildBlockDeclRefExpr(Sema &S, ValueDecl *VD,
                                         const DeclarationNameInfo &NameInfo) {
   VarDecl *var = cast<VarDecl>(VD);
@@ -2269,7 +2233,7 @@
       // fallthrough
 
     case Decl::ImplicitParam:
-    case Decl::ParmVar:
+    case Decl::ParmVar: {
       // These are always l-values.
       valueKind = VK_LValue;
       type = type.getNonReferenceType();
@@ -2277,11 +2241,18 @@
       if (shouldBuildBlockDeclRef(VD, *this))
         return BuildBlockDeclRefExpr(*this, VD, NameInfo);
 
-      if (shouldAddConstQualToVarRef(VD, *this))
-        type.addConst();
-
+      // FIXME: Does the addition of const really only apply in
+      // potentially-evaluated contexts? Since the variable isn't actually
+      // captured in an unevaluated context, it seems that the answer is no.
+      if (ExprEvalContexts.back().Context != Sema::Unevaluated) {
+        QualType CapturedType = getCapturedDeclRefType(cast<VarDecl>(VD), Loc);
+        if (!CapturedType.isNull())
+          type = CapturedType;
+      }
+      
       break;
-
+    }
+        
     case Decl::Function: {
       const FunctionType *fty = type->castAs<FunctionType>();
 
@@ -3128,6 +3099,7 @@
       //   the semantic constraints are checked, at the point where the
       //   default argument expression appears.
       ContextRAII SavedContext(*this, FD);
+      LocalInstantiationScope Local(*this);
       Result = SubstExpr(UninstExpr, ArgList);
     }
     if (Result.isInvalid())
@@ -4227,8 +4199,7 @@
       return ExprError();
     }
     else
-      for (unsigned i = 0, e = numExprs; i != e; ++i)
-        initExprs.push_back(exprs[i]);
+      initExprs.append(exprs, exprs + numExprs);
   }
   else {
     // For OpenCL, when the number of initializers is a single value,
@@ -4245,8 +4216,7 @@
         return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
     }
     
-    for (unsigned i = 0, e = numExprs; i != e; ++i)
-      initExprs.push_back(exprs[i]);
+    initExprs.append(exprs, exprs + numExprs);
   }
   // FIXME: This means that pretty-printing the final AST will produce curly
   // braces instead of the original commas.
@@ -8125,11 +8095,17 @@
   case UO_Real:
   case UO_Imag:
     resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real);
-    // _Real and _Imag map ordinary l-values into ordinary l-values.
+    // _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary
+    // complex l-values to ordinary l-values and all other values to r-values.
     if (Input.isInvalid()) return ExprError();
-    if (Input.get()->getValueKind() != VK_RValue &&
-        Input.get()->getObjectKind() == OK_Ordinary)
-      VK = Input.get()->getValueKind();
+    if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) {
+      if (Input.get()->getValueKind() != VK_RValue &&
+          Input.get()->getObjectKind() == OK_Ordinary)
+        VK = Input.get()->getValueKind();
+    } else if (!getLangOptions().CPlusPlus) {
+      // In C, a volatile scalar is read by __imag. In C++, it is not.
+      Input = DefaultLvalueConversion(Input.take());
+    }
     break;
   case UO_Extension:
     resultType = Input.get()->getType();
@@ -9406,7 +9382,11 @@
 
   Func->setReferenced();
 
-  if (Func->isUsed(false))
+  // Don't mark this function as used multiple times, unless it's a constexpr
+  // function which we need to instantiate.
+  if (Func->isUsed(false) &&
+      !(Func->isConstexpr() && !Func->getBody() &&
+        Func->isImplicitlyInstantiable()))
     return;
 
   if (!IsPotentiallyEvaluatedContext(*this))
@@ -9445,6 +9425,13 @@
         else
           DefineImplicitMoveAssignment(Loc, MethodDecl);
       }
+    } else if (isa<CXXConversionDecl>(MethodDecl) &&
+               MethodDecl->getParent()->isLambda()) {
+      CXXConversionDecl *Conversion = cast<CXXConversionDecl>(MethodDecl);
+      if (Conversion->isLambdaToBlockPointerConversion())
+        DefineImplicitLambdaToBlockPointerConversion(Loc, Conversion);
+      else
+        DefineImplicitLambdaToFunctionPointerConversion(Loc, Conversion);
     } else if (MethodDecl->isVirtual())
       MarkVTableUsed(Loc, MethodDecl->getParent());
   }
@@ -9457,34 +9444,40 @@
   // class templates.
   if (Func->isImplicitlyInstantiable()) {
     bool AlreadyInstantiated = false;
+    SourceLocation PointOfInstantiation = Loc;
     if (FunctionTemplateSpecializationInfo *SpecInfo
                               = Func->getTemplateSpecializationInfo()) {
       if (SpecInfo->getPointOfInstantiation().isInvalid())
         SpecInfo->setPointOfInstantiation(Loc);
       else if (SpecInfo->getTemplateSpecializationKind()
-                 == TSK_ImplicitInstantiation)
+                 == TSK_ImplicitInstantiation) {
         AlreadyInstantiated = true;
+        PointOfInstantiation = SpecInfo->getPointOfInstantiation();
+      }
     } else if (MemberSpecializationInfo *MSInfo
                                 = Func->getMemberSpecializationInfo()) {
       if (MSInfo->getPointOfInstantiation().isInvalid())
         MSInfo->setPointOfInstantiation(Loc);
       else if (MSInfo->getTemplateSpecializationKind()
-                 == TSK_ImplicitInstantiation)
+                 == TSK_ImplicitInstantiation) {
         AlreadyInstantiated = true;
+        PointOfInstantiation = MSInfo->getPointOfInstantiation();
+      }
     }
 
-    if (!AlreadyInstantiated) {
+    if (!AlreadyInstantiated || Func->isConstexpr()) {
       if (isa<CXXRecordDecl>(Func->getDeclContext()) &&
           cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass())
-        PendingLocalImplicitInstantiations.push_back(std::make_pair(Func,
-                                                                    Loc));
-      else if (Func->getTemplateInstantiationPattern()->isConstexpr())
+        PendingLocalImplicitInstantiations.push_back(
+            std::make_pair(Func, PointOfInstantiation));
+      else if (Func->isConstexpr())
         // Do not defer instantiations of constexpr functions, to avoid the
         // expression evaluator needing to call back into Sema if it sees a
         // call to such a function.
-        InstantiateFunctionDefinition(Loc, Func);
+        InstantiateFunctionDefinition(PointOfInstantiation, Func);
       else {
-        PendingInstantiations.push_back(std::make_pair(Func, Loc));
+        PendingInstantiations.push_back(std::make_pair(Func,
+                                                       PointOfInstantiation));
         // Notify the consumer that a function was implicitly instantiated.
         Consumer.HandleCXXImplicitFunctionInstantiation(Func);
       }
@@ -9554,51 +9547,12 @@
   // capture.
 }
 
-static bool shouldAddConstForScope(CapturingScopeInfo *CSI, VarDecl *VD) {
-  if (VD->hasAttr<BlocksAttr>())
-    return false;
-  if (isa<BlockScopeInfo>(CSI))
-    return true;
-  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI))
-    return !LSI->Mutable;
-  return false;
-}
-
-QualType Sema::getLambdaCaptureFieldType(QualType T, bool ByRef) {
-  if (ByRef) {
-    // C++11 [expr.prim.lambda]p15:
-    //   An entity is captured by reference if it is implicitly or
-    //   explicitly captured but not captured by copy. It is
-    //   unspecified whether additional unnamed non-static data
-    //   members are declared in the closure type for entities
-    //   captured by reference.
-    return Context.getLValueReferenceType(T.getNonReferenceType());
-  }
-
-  // C++11 [expr.prim.lambda]p14:
-  //   For each entity captured by copy, an unnamed non-static
-  //   data member is declared in the closure type. The
-  //   declaration order of these members is unspecified. The type
-  //   of such a data member is the type of the corresponding
-  //   captured entity if the entity is not a reference to an
-  //   object, or the referenced type otherwise. [Note: If the
-  //   captured entity is a reference to a function, the
-  //   corresponding data member is also a reference to a
-  //   function. - end note ]
-  if (const ReferenceType *RefType = T->getAs<ReferenceType>()) {
-    if (!RefType->getPointeeType()->isFunctionType())
-      return RefType->getPointeeType();
-  }
-
-  return T;
-}
-
 /// \brief Capture the given variable in the given lambda expression.
 static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
-                                  VarDecl *Var, QualType Type, 
-                                  SourceLocation Loc, bool ByRef) {
+                                  VarDecl *Var, QualType FieldType, 
+                                  QualType DeclRefType,
+                                  SourceLocation Loc) {
   CXXRecordDecl *Lambda = LSI->Lambda;
-  QualType FieldType = S.getLambdaCaptureFieldType(Type, ByRef);
 
   // Build the non-static data member.
   FieldDecl *Field
@@ -9617,8 +9571,6 @@
   //   direct-initialized in increasing subscript order.) These
   //   initializations are performed in the (unspecified) order in
   //   which the non-static data members are declared.
-  //
-  // FIXME: Introduce an initialization entity for lambda captures.
       
   // Introduce a new evaluation context for the initialization, so
   // that temporaries introduced as part of the capture are retained
@@ -9628,8 +9580,7 @@
   // C++ [expr.prim.labda]p12:
   //   An entity captured by a lambda-expression is odr-used (3.2) in
   //   the scope containing the lambda-expression.
-  Expr *Ref = new (S.Context) DeclRefExpr(Var, Type.getNonReferenceType(),
-                                          VK_LValue, Loc);
+  Expr *Ref = new (S.Context) DeclRefExpr(Var, DeclRefType, VK_LValue, Loc);
   Var->setUsed(true);
 
   // When the field has array type, create index variables for each
@@ -9637,14 +9588,11 @@
   // the source array, and other clients (e.g., CodeGen) will perform
   // the necessary iteration with these index variables.
   SmallVector<VarDecl *, 4> IndexVariables;
-  bool InitializingArray = false;
   QualType BaseType = FieldType;
   QualType SizeType = S.Context.getSizeType();
   LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
   while (const ConstantArrayType *Array
                         = S.Context.getAsConstantArrayType(BaseType)) {
-    InitializingArray = true;
-    
     // Create the iteration variable for this array index.
     IdentifierInfo *IterationVarName = 0;
     {
@@ -9689,7 +9637,8 @@
   // of array-subscript entities. 
   SmallVector<InitializedEntity, 4> Entities;
   Entities.reserve(1 + IndexVariables.size());
-  Entities.push_back(InitializedEntity::InitializeMember(Field));
+  Entities.push_back(
+    InitializedEntity::InitializeLambdaCapture(Var, Field, Loc));
   for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
     Entities.push_back(InitializedEntity::InitializeElement(S.Context,
                                                             0,
@@ -9716,20 +9665,27 @@
   return Result;
 }
 
-bool Sema::canCaptureVariable(VarDecl *Var, SourceLocation Loc, bool Explicit,
-                              bool Diagnose, QualType &Type, 
-                              unsigned &FunctionScopesIndex, bool &Nested) {
-  Type = Var->getType();
-  FunctionScopesIndex = FunctionScopes.size() - 1;
-  Nested = false;
+bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, 
+                              TryCaptureKind Kind, SourceLocation EllipsisLoc,
+                              bool BuildAndDiagnose, 
+                              QualType &CaptureType,
+                              QualType &DeclRefType) {
+  bool Nested = false;
   
   DeclContext *DC = CurContext;
-  if (Var->getDeclContext() == DC) return false;
-  if (!Var->hasLocalStorage()) return false;
+  if (Var->getDeclContext() == DC) return true;
+  if (!Var->hasLocalStorage()) return true;
 
   bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();
 
-  // Figure out whether we can capture the variable.
+  // Walk up the stack to determine whether we can capture the variable,
+  // performing the "simple" checks that don't depend on type. We stop when
+  // we've either hit the declared scope of the variable or find an existing
+  // capture of that variable.
+  CaptureType = Var->getType();
+  DeclRefType = CaptureType.getNonReferenceType();
+  bool Explicit = (Kind != TryCapture_Implicit);
+  unsigned FunctionScopesIndex = FunctionScopes.size() - 1;
   do {
     // Only block literals and lambda expressions can capture; other
     // scopes don't work.
@@ -9741,9 +9697,9 @@
              cast<CXXRecordDecl>(DC->getParent())->isLambda())
       ParentDC = DC->getParent()->getParent();
     else {
-      if (Diagnose)
+      if (BuildAndDiagnose)
         diagnoseUncapturableValueReference(*this, Loc, Var, DC);
-      return false;
+      return true;
     }
 
     CapturingScopeInfo *CSI =
@@ -9751,32 +9707,40 @@
 
     // Check whether we've already captured it.
     if (CSI->CaptureMap.count(Var)) {
-      // If we found a capture, any subcaptures are nested
+      // If we found a capture, any subcaptures are nested.
       Nested = true;
-
-      if (shouldAddConstForScope(CSI, Var))
-        Type.addConst();
+      
+      // Retrieve the capture type for this variable.
+      CaptureType = CSI->getCapture(Var).getCaptureType();
+      
+      // Compute the type of an expression that refers to this variable.
+      DeclRefType = CaptureType.getNonReferenceType();
+      
+      const CapturingScopeInfo::Capture &Cap = CSI->getCapture(Var);
+      if (Cap.isCopyCapture() &&
+          !(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable))
+        DeclRefType.addConst();
       break;
     }
 
     bool IsBlock = isa<BlockScopeInfo>(CSI);
-    bool IsLambda = isa<LambdaScopeInfo>(CSI);
+    bool IsLambda = !IsBlock;
 
     // Lambdas are not allowed to capture unnamed variables
     // (e.g. anonymous unions).
     // FIXME: The C++11 rule don't actually state this explicitly, but I'm
     // assuming that's the intent.
     if (IsLambda && !Var->getDeclName()) {
-      if (Diagnose) {
+      if (BuildAndDiagnose) {
         Diag(Loc, diag::err_lambda_capture_anonymous_var);
         Diag(Var->getLocation(), diag::note_declared_at);
       }
-      return false;
+      return true;
     }
 
     // Prohibit variably-modified types; they're difficult to deal with.
-    if (Type->isVariablyModifiedType()) {
-      if (Diagnose) {
+    if (Var->getType()->isVariablyModifiedType()) {
+      if (BuildAndDiagnose) {
         if (IsBlock)
           Diag(Loc, diag::err_ref_vm_type);
         else
@@ -9784,41 +9748,31 @@
         Diag(Var->getLocation(), diag::note_previous_decl) 
           << Var->getDeclName();
       }
-      return false;
-    }
-
-    // Blocks are not allowed to capture arrays.
-    if (IsBlock && Type->isArrayType()) {
-      if (Diagnose) {
-        Diag(Loc, diag::err_ref_array_type);
-        Diag(Var->getLocation(), diag::note_previous_decl) 
-          << Var->getDeclName();
-      }
-      return false;
+      return true;
     }
 
     // Lambdas are not allowed to capture __block variables; they don't
     // support the expected semantics.
     if (IsLambda && HasBlocksAttr) {
-      if (Diagnose) {
+      if (BuildAndDiagnose) {
         Diag(Loc, diag::err_lambda_capture_block) 
           << Var->getDeclName();
         Diag(Var->getLocation(), diag::note_previous_decl) 
           << Var->getDeclName();
       }
-      return false;
+      return true;
     }
 
     if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
       // No capture-default
-      if (Diagnose) {
+      if (BuildAndDiagnose) {
         Diag(Loc, diag::err_lambda_impcap) << Var->getDeclName();
         Diag(Var->getLocation(), diag::note_previous_decl) 
           << Var->getDeclName();
         Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(),
              diag::note_lambda_decl);
       }
-      return false;
+      return true;
     }
 
     FunctionScopesIndex--;
@@ -9826,97 +9780,175 @@
     Explicit = false;
   } while (!Var->getDeclContext()->Equals(DC));
 
-  ++FunctionScopesIndex;
-  return !Type->isVariablyModifiedType();
-}
+  // Walk back down the scope stack, computing the type of the capture at
+  // each step, checking type-specific requirements, and adding captures if
+  // requested.
+  for (unsigned I = ++FunctionScopesIndex, N = FunctionScopes.size(); I != N; 
+       ++I) {
+    CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[I]);
+    
+    // Compute the type of the capture and of a reference to the capture within
+    // this scope.
+    if (isa<BlockScopeInfo>(CSI)) {
+      Expr *CopyExpr = 0;
+      bool ByRef = false;
+      
+      // Blocks are not allowed to capture arrays.
+      if (CaptureType->isArrayType()) {
+        if (BuildAndDiagnose) {
+          Diag(Loc, diag::err_ref_array_type);
+          Diag(Var->getLocation(), diag::note_previous_decl) 
+          << Var->getDeclName();
+        }
+        return true;
+      }
+
+      if (HasBlocksAttr || CaptureType->isReferenceType()) {
+        // Block capture by reference does not change the capture or
+        // declaration reference types.
+        ByRef = true;
+      } else {
+        // Block capture by copy introduces 'const'.
+        CaptureType = CaptureType.getNonReferenceType().withConst();
+        DeclRefType = CaptureType;
+                
+        if (getLangOptions().CPlusPlus && BuildAndDiagnose) {
+          if (const RecordType *Record = DeclRefType->getAs<RecordType>()) {
+            // The capture logic needs the destructor, so make sure we mark it.
+            // Usually this is unnecessary because most local variables have
+            // their destructors marked at declaration time, but parameters are
+            // an exception because it's technically only the call site that
+            // actually requires the destructor.
+            if (isa<ParmVarDecl>(Var))
+              FinalizeVarWithDestructor(Var, Record);
+            
+            // According to the blocks spec, the capture of a variable from
+            // the stack requires a const copy constructor.  This is not true
+            // of the copy/move done to move a __block variable to the heap.
+            Expr *DeclRef = new (Context) DeclRefExpr(Var, 
+                                                      DeclRefType.withConst(), 
+                                                      VK_LValue, Loc);
+            ExprResult Result
+              = PerformCopyInitialization(
+                  InitializedEntity::InitializeBlock(Var->getLocation(),
+                                                     CaptureType, false),
+                  Loc, Owned(DeclRef));
+            
+            // Build a full-expression copy expression if initialization
+            // succeeded and used a non-trivial constructor.  Recover from
+            // errors by pretending that the copy isn't necessary.
+            if (!Result.isInvalid() &&
+                !cast<CXXConstructExpr>(Result.get())->getConstructor()
+                   ->isTrivial()) {
+              Result = MaybeCreateExprWithCleanups(Result);
+              CopyExpr = Result.take();
+            }
+          }
+        }
+      }
 
-// Check if the variable needs to be captured; if so, try to perform
-// the capture.
-void Sema::TryCaptureVar(VarDecl *var, SourceLocation loc,
-                         TryCaptureKind Kind) {
-  QualType type;
-  unsigned functionScopesIndex;
-  bool Nested;
-  // Determine whether we can capture this variable, and where to
-  // start capturing.
-  if (!canCaptureVariable(var, loc, /*Explicit=*/Kind != TryCapture_Implicit,
-                          /*Diagnose=*/true, type, functionScopesIndex, Nested))
-    return;
-
-  bool hasBlocksAttr = var->hasAttr<BlocksAttr>();
-
-  for (unsigned i = functionScopesIndex,
-                e = FunctionScopes.size(); i != e; ++i) {
-    CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[i]);
-    bool isLambda = isa<LambdaScopeInfo>(CSI);
-
-    bool byRef;
-    bool isInnermostCapture = (i == e - 1);
-    if (isInnermostCapture && Kind == TryCapture_ExplicitByVal) {
-      byRef = false;
-    } else if (isInnermostCapture && Kind == TryCapture_ExplicitByRef) {
-      byRef = true;
-    } else if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval) {
-      // capture-default '='
-      byRef = false;
-    } else if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref) {
-      // capture-default '&'
-      byRef = true;
+      // Actually capture the variable.
+      if (BuildAndDiagnose)
+        CSI->addCapture(Var, HasBlocksAttr, ByRef, Nested, Loc, 
+                        SourceLocation(), CaptureType, CopyExpr);
+      Nested = true;
+      continue;
+    } 
+    
+    LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI);
+    
+    // Determine whether we are capturing by reference or by value.
+    bool ByRef = false;
+    if (I == N - 1 && Kind != TryCapture_Implicit) {
+      ByRef = (Kind == TryCapture_ExplicitByRef);
     } else {
-      // A block captures __block variables in a special __block fashion, 
-      // variables of reference type by reference (in the sense of
-      // [expr.prim.lambda]), and other non-__block variables by copy.
-      assert(CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block);
-      byRef = hasBlocksAttr || type->isReferenceType();
+      ByRef = (LSI->ImpCaptureStyle == LambdaScopeInfo::ImpCap_LambdaByref);
     }
-
-    // Build a copy expression if we are capturing by copy into a
-    // block and the copy might be non-trivial.
-    Expr *copyExpr = 0;
-    const RecordType *rtype;
-    if (isLambda) {
-      ExprResult Result = captureInLambda(*this, cast<LambdaScopeInfo>(CSI), 
-                                          var, type, loc, byRef);
-      if (!Result.isInvalid())
-        copyExpr = Result.take();
-    } else if (!byRef && getLangOptions().CPlusPlus &&
-        (rtype = type.getNonReferenceType()->getAs<RecordType>())) {
-      // The capture logic needs the destructor, so make sure we mark it.
-      // Usually this is unnecessary because most local variables have
-      // their destructors marked at declaration time, but parameters are
-      // an exception because it's technically only the call site that
-      // actually requires the destructor.
-      if (isa<ParmVarDecl>(var))
-        FinalizeVarWithDestructor(var, rtype);
-
-      // According to the blocks spec, the capture of a variable from
-      // the stack requires a const copy constructor.  This is not true
-      // of the copy/move done to move a __block variable to the heap.
-      type.addConst();
-
-      Expr *declRef = new (Context) DeclRefExpr(var, type, VK_LValue, loc);
-      ExprResult result =
-        PerformCopyInitialization(
-                        InitializedEntity::InitializeBlock(var->getLocation(),
-                                                           type, false),
-                                    loc, Owned(declRef));
-
-      // Build a full-expression copy expression if initialization
-      // succeeded and used a non-trivial constructor.  Recover from
-      // errors by pretending that the copy isn't necessary.
-      if (!result.isInvalid() &&
-          !cast<CXXConstructExpr>(result.get())->getConstructor()->isTrivial()) {
-        result = MaybeCreateExprWithCleanups(result);
-        copyExpr = result.take();
+    
+    // Compute the type of the field that will capture this variable.
+    if (ByRef) {
+      // C++11 [expr.prim.lambda]p15:
+      //   An entity is captured by reference if it is implicitly or
+      //   explicitly captured but not captured by copy. It is
+      //   unspecified whether additional unnamed non-static data
+      //   members are declared in the closure type for entities
+      //   captured by reference.
+      //
+      // FIXME: It is not clear whether we want to build an lvalue reference
+      // to the DeclRefType or to CaptureType.getNonReferenceType(). GCC appears
+      // to do the former, while EDG does the latter. Core issue 1249 will 
+      // clarify, but for now we follow GCC because it's a more permissive and
+      // easily defensible position.
+      CaptureType = Context.getLValueReferenceType(DeclRefType);
+    } else {
+      // C++11 [expr.prim.lambda]p14:
+      //   For each entity captured by copy, an unnamed non-static
+      //   data member is declared in the closure type. The
+      //   declaration order of these members is unspecified. The type
+      //   of such a data member is the type of the corresponding
+      //   captured entity if the entity is not a reference to an
+      //   object, or the referenced type otherwise. [Note: If the
+      //   captured entity is a reference to a function, the
+      //   corresponding data member is also a reference to a
+      //   function. - end note ]
+      if (const ReferenceType *RefType = CaptureType->getAs<ReferenceType>()){
+        if (!RefType->getPointeeType()->isFunctionType())
+          CaptureType = RefType->getPointeeType();
       }
     }
 
-    CSI->AddCapture(var, hasBlocksAttr, byRef, Nested, loc, copyExpr);
-
+    // Capture this variable in the lambda.
+    Expr *CopyExpr = 0;
+    if (BuildAndDiagnose) {
+      ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType,
+                                          DeclRefType, Loc);
+      if (!Result.isInvalid())
+        CopyExpr = Result.take();
+    }
+    
+    // Compute the type of a reference to this captured variable.
+    if (ByRef)
+      DeclRefType = CaptureType.getNonReferenceType();
+    else {
+      // C++ [expr.prim.lambda]p5:
+      //   The closure type for a lambda-expression has a public inline 
+      //   function call operator [...]. This function call operator is 
+      //   declared const (9.3.1) if and only if the lambda-expression’s 
+      //   parameter-declaration-clause is not followed by mutable.
+      DeclRefType = CaptureType.getNonReferenceType();
+      if (!LSI->Mutable && !CaptureType->isReferenceType())
+        DeclRefType.addConst();      
+    }
+    
+    // Add the capture.
+    if (BuildAndDiagnose)
+      CSI->addCapture(Var, /*IsBlock=*/false, ByRef, Nested, Loc,
+                      EllipsisLoc, CaptureType, CopyExpr);
     Nested = true;
-    if (shouldAddConstForScope(CSI, var))
-      type.addConst();
   }
+
+  return false;
+}
+
+bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
+                              TryCaptureKind Kind, SourceLocation EllipsisLoc) {  
+  QualType CaptureType;
+  QualType DeclRefType;
+  return tryCaptureVariable(Var, Loc, Kind, EllipsisLoc,
+                            /*BuildAndDiagnose=*/true, CaptureType,
+                            DeclRefType);
+}
+
+QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) {
+  QualType CaptureType;
+  QualType DeclRefType;
+  
+  // Determine whether we can capture this variable.
+  if (tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(),
+                         /*BuildAndDiagnose=*/false, CaptureType, DeclRefType))
+    return QualType();
+
+  return DeclRefType;
 }
 
 static void MarkVarDeclODRUsed(Sema &SemaRef, VarDecl *Var,
@@ -9930,7 +9962,7 @@
     if (old.isInvalid()) old = Loc;
   }
 
-  SemaRef.TryCaptureVar(Var, Loc);
+  SemaRef.tryCaptureVariable(Var, Loc);
 
   Var->setUsed(true);
 }
@@ -9979,22 +10011,26 @@
     return;
 
   // Implicit instantiation of static data members of class templates.
-  if (Var->isStaticDataMember() &&
-      Var->getInstantiatedFromStaticDataMember()) {
+  if (Var->isStaticDataMember() && Var->getInstantiatedFromStaticDataMember()) {
     MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
     assert(MSInfo && "Missing member specialization information?");
-    if (MSInfo->getPointOfInstantiation().isInvalid() &&
-        MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
-      MSInfo->setPointOfInstantiation(Loc);
-      // This is a modification of an existing AST node. Notify listeners.
-      if (ASTMutationListener *L = SemaRef.getASTMutationListener())
-        L->StaticDataMemberInstantiated(Var);
+    bool AlreadyInstantiated = !MSInfo->getPointOfInstantiation().isInvalid();
+    if (MSInfo->getTemplateSpecializationKind() == TSK_ImplicitInstantiation &&
+        (!AlreadyInstantiated || Var->isUsableInConstantExpressions())) {
+      if (!AlreadyInstantiated) {
+        // This is a modification of an existing AST node. Notify listeners.
+        if (ASTMutationListener *L = SemaRef.getASTMutationListener())
+          L->StaticDataMemberInstantiated(Var);
+        MSInfo->setPointOfInstantiation(Loc);
+      }
+      SourceLocation PointOfInstantiation = MSInfo->getPointOfInstantiation();
       if (Var->isUsableInConstantExpressions())
         // Do not defer instantiations of variables which could be used in a
         // constant expression.
-        SemaRef.InstantiateStaticDataMemberDefinition(Loc, Var);
+        SemaRef.InstantiateStaticDataMemberDefinition(PointOfInstantiation,Var);
       else
-        SemaRef.PendingInstantiations.push_back(std::make_pair(Var, Loc));
+        SemaRef.PendingInstantiations.push_back(
+            std::make_pair(Var, PointOfInstantiation));
     }
   }
 
@@ -10029,7 +10065,7 @@
   }
 
   SemaRef.MarkAnyDeclReferenced(Loc, D);
-}
+} 
 
 /// \brief Perform reference-marking and odr-use handling for a
 /// BlockDeclRefExpr.
@@ -10129,15 +10165,13 @@
     }
     
     void VisitCXXNewExpr(CXXNewExpr *E) {
-      if (E->getConstructor())
-        S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor());
       if (E->getOperatorNew())
         S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew());
       if (E->getOperatorDelete())
         S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
       Inherited::VisitCXXNewExpr(E);
     }
-    
+
     void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
       if (E->getOperatorDelete())
         S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());

Modified: cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp Mon Feb 20 19:34:24 2012
@@ -30,6 +30,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
 #include "TypeLocBuilder.h"
+#include "llvm/ADT/APInt.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace clang;
@@ -636,8 +637,8 @@
   if (isPointer)
     return Owned(E);
 
-  // If the class has a non-trivial destructor, we must be able to call it.
-  if (RD->hasTrivialDestructor())
+  // If the class has a destructor, we must be able to call it.
+  if (RD->hasIrrelevantDestructor())
     return Owned(E);
 
   CXXDestructorDecl *Destructor
@@ -648,6 +649,7 @@
   MarkFunctionReferenced(E->getExprLoc(), Destructor);
   CheckDestructorAccess(E->getExprLoc(), Destructor,
                         PDiag(diag::err_access_dtor_exception) << Ty);
+  DiagnoseUseOfDecl(Destructor, E->getExprLoc());
   return Owned(E);
 }
 
@@ -708,9 +710,9 @@
        NumClosures; --idx, --NumClosures) {
     CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
     Expr *ThisExpr = 0;
+    QualType ThisTy = getCurrentThisType();
     if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
       // For lambda expressions, build a field and an initializing expression.
-      QualType ThisTy = getCurrentThisType();
       CXXRecordDecl *Lambda = LSI->Lambda;
       FieldDecl *Field
         = FieldDecl::Create(Context, Lambda, Loc, Loc, 0, ThisTy,
@@ -722,7 +724,7 @@
       ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true);
     }
     bool isNested = NumClosures > 1;
-    CSI->AddThisCapture(isNested, Loc, ThisExpr);
+    CSI->addThisCapture(isNested, Loc, ThisTy, ThisExpr);
   }
 }
 
@@ -914,9 +916,7 @@
 Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
                   SourceLocation PlacementRParen, SourceRange TypeIdParens,
-                  Declarator &D, SourceLocation ConstructorLParen,
-                  MultiExprArg ConstructorArgs,
-                  SourceLocation ConstructorRParen) {
+                  Declarator &D, Expr *Initializer) {
   bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
 
   Expr *ArraySize = 0;
@@ -961,6 +961,10 @@
   if (D.isInvalidType())
     return ExprError();
 
+  SourceRange DirectInitRange;
+  if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
+    DirectInitRange = List->getSourceRange();
+
   return BuildCXXNew(StartLoc, UseGlobal,
                      PlacementLParen,
                      move(PlacementArgs),
@@ -969,12 +973,30 @@
                      AllocType,
                      TInfo,
                      ArraySize,
-                     ConstructorLParen,
-                     move(ConstructorArgs),
-                     ConstructorRParen,
+                     DirectInitRange,
+                     Initializer,
                      TypeContainsAuto);
 }
 
+static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
+                                       Expr *Init) {
+  if (!Init)
+    return true;
+  if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init))
+    return PLE->getNumExprs() == 0;
+  if (isa<ImplicitValueInitExpr>(Init))
+    return true;
+  else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
+    return !CCE->isListInitialization() &&
+           CCE->getConstructor()->isDefaultConstructor();
+  else if (Style == CXXNewExpr::ListInit) {
+    assert(isa<InitListExpr>(Init) &&
+           "Shouldn't create list CXXConstructExprs for arrays.");
+    return true;
+  }
+  return false;
+}
+
 ExprResult
 Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen,
@@ -984,29 +1006,56 @@
                   QualType AllocType,
                   TypeSourceInfo *AllocTypeInfo,
                   Expr *ArraySize,
-                  SourceLocation ConstructorLParen,
-                  MultiExprArg ConstructorArgs,
-                  SourceLocation ConstructorRParen,
+                  SourceRange DirectInitRange,
+                  Expr *Initializer,
                   bool TypeMayContainAuto) {
   SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
 
+  CXXNewExpr::InitializationStyle initStyle;
+  if (DirectInitRange.isValid()) {
+    assert(Initializer && "Have parens but no initializer.");
+    initStyle = CXXNewExpr::CallInit;
+  } else if (Initializer && isa<InitListExpr>(Initializer))
+    initStyle = CXXNewExpr::ListInit;
+  else {
+    assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
+            isa<CXXConstructExpr>(Initializer)) &&
+           "Initializer expression that cannot have been implicitly created.");
+    initStyle = CXXNewExpr::NoInit;
+  }
+
+  Expr **Inits = &Initializer;
+  unsigned NumInits = Initializer ? 1 : 0;
+  if (initStyle == CXXNewExpr::CallInit) {
+    if (ParenListExpr *List = dyn_cast<ParenListExpr>(Initializer)) {
+      Inits = List->getExprs();
+      NumInits = List->getNumExprs();
+    } else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Initializer)){
+      if (!isa<CXXTemporaryObjectExpr>(CCE)) {
+        // Can happen in template instantiation. Since this is just an implicit
+        // construction, we just take it apart and rebuild it.
+        Inits = CCE->getArgs();
+        NumInits = CCE->getNumArgs();
+      }
+    }
+  }
+
   // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && AllocType->getContainedAutoType()) {
-    if (ConstructorArgs.size() == 0)
+    if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
                        << AllocType << TypeRange);
-    if (ConstructorArgs.size() != 1) {
-      Expr *FirstBad = ConstructorArgs.get()[1];
+    if (initStyle == CXXNewExpr::ListInit)
+      return ExprError(Diag(Inits[0]->getSourceRange().getBegin(),
+                            diag::err_auto_new_requires_parens)
+                       << AllocType << TypeRange);
+    if (NumInits > 1) {
+      Expr *FirstBad = Inits[1];
       return ExprError(Diag(FirstBad->getSourceRange().getBegin(),
                             diag::err_auto_new_ctor_multiple_expressions)
                        << AllocType << TypeRange);
     }
-    Expr *Deduce = ConstructorArgs.get()[0];
-    if (ConstructorLParen.isInvalid()) {
-      return ExprError(Diag(Deduce->getSourceRange().getBegin(),
-                            diag::err_auto_new_requires_parens)
-                       << AllocType << TypeRange);
-    }
+    Expr *Deduce = Inits[0];
     TypeSourceInfo *DeducedType = 0;
     if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) ==
             DAR_Failed)
@@ -1035,15 +1084,10 @@
   if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
     return ExprError();
 
-  bool ListInitialization = ConstructorLParen.isInvalid() &&
-                            ConstructorArgs.size() > 0;
-  assert((!ListInitialization || (ConstructorArgs.size() == 1 &&
-                                  isa<InitListExpr>(ConstructorArgs.get()[0])))
-         && "List initialization means a braced-init-list for arguments.");
-  if (ListInitialization && isStdInitializerList(AllocType, 0)) {
+  if (initStyle == CXXNewExpr::ListInit && isStdInitializerList(AllocType, 0)) {
     Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
          diag::warn_dangling_std_initializer_list)
-      << /*at end of FE*/0 << ConstructorArgs.get()[0]->getSourceRange();
+      << /*at end of FE*/0 << Inits[0]->getSourceRange();
   }
 
   // In ARC, infer 'retaining' for the allocated 
@@ -1184,6 +1228,11 @@
     NumPlaceArgs = AllPlaceArgs.size();
     if (NumPlaceArgs > 0)
       PlaceArgs = &AllPlaceArgs[0];
+
+    DiagnoseSentinelCalls(OperatorNew, PlacementLParen,
+                          PlaceArgs, NumPlaceArgs);
+
+    // FIXME: Missing call to CheckFunctionCall or equivalent
   }
 
   // Warn if the type is over-aligned and is being allocated by global operator
@@ -1201,25 +1250,30 @@
     }
   }
 
-  bool Init = ConstructorLParen.isValid() || ConstructorArgs.size() > 0;
-  // --- Choosing a constructor ---
-  CXXConstructorDecl *Constructor = 0;
-  bool HadMultipleCandidates = false;
-  Expr **ConsArgs = (Expr**)ConstructorArgs.get();
-  unsigned NumConsArgs = ConstructorArgs.size();
-  ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
-
-  // Array 'new' can't have any initializers.
-  if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
-    SourceRange InitRange(ConsArgs[0]->getLocStart(),
-                          ConsArgs[NumConsArgs - 1]->getLocEnd());
-
-    Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
-    return ExprError();
+  QualType InitType = AllocType;
+  // Array 'new' can't have any initializers except empty parentheses.
+  // Initializer lists are also allowed, in C++11. Rely on the parser for the
+  // dialect distinction.
+  if (ResultType->isArrayType() || ArraySize) {
+    if (!isLegalArrayNewInitializer(initStyle, Initializer)) {
+      SourceRange InitRange(Inits[0]->getLocStart(),
+                            Inits[NumInits - 1]->getLocEnd());
+      Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
+      return ExprError();
+    }
+    if (InitListExpr *ILE = dyn_cast_or_null<InitListExpr>(Initializer)) {
+      // We do the initialization typechecking against the array type
+      // corresponding to the number of initializers + 1 (to also check
+      // default-initialization).
+      unsigned NumElements = ILE->getNumInits() + 1;
+      InitType = Context.getConstantArrayType(AllocType,
+          llvm::APInt(Context.getTypeSize(Context.getSizeType()), NumElements),
+                                              ArrayType::Normal, 0);
+    }
   }
 
   if (!AllocType->isDependentType() &&
-      !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
+      !Expr::hasAnyTypeDependentArguments(Inits, NumInits)) {
     // C++11 [expr.new]p15:
     //   A new-expression that creates an object of type T initializes that
     //   object as follows:
@@ -1227,49 +1281,31 @@
     //     - If the new-initializer is omitted, the object is default-
     //       initialized (8.5); if no initialization is performed,
     //       the object has indeterminate value
-      = !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
+      = initStyle == CXXNewExpr::NoInit
+          ? InitializationKind::CreateDefault(TypeRange.getBegin())
     //     - Otherwise, the new-initializer is interpreted according to the
     //       initialization rules of 8.5 for direct-initialization.
-             : ListInitialization ? InitializationKind::CreateDirectList(
-                                                          TypeRange.getBegin())
-                                  : InitializationKind::CreateDirect(
-                                                          TypeRange.getBegin(),
-                                                          ConstructorLParen,
-                                                          ConstructorRParen);
+          : initStyle == CXXNewExpr::ListInit
+              ? InitializationKind::CreateDirectList(TypeRange.getBegin())
+              : InitializationKind::CreateDirect(TypeRange.getBegin(),
+                                                 DirectInitRange.getBegin(),
+                                                 DirectInitRange.getEnd());
 
     InitializedEntity Entity
-      = InitializedEntity::InitializeNew(StartLoc, AllocType);
-    InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
+      = InitializedEntity::InitializeNew(StartLoc, InitType);
+    InitializationSequence InitSeq(*this, Entity, Kind, Inits, NumInits);
     ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
-                                                move(ConstructorArgs));
+                                          MultiExprArg(Inits, NumInits));
     if (FullInit.isInvalid())
       return ExprError();
 
-    // FullInit is our initializer; walk through it to determine if it's a
-    // constructor call, which CXXNewExpr handles directly.
-    if (Expr *FullInitExpr = (Expr *)FullInit.get()) {
-      if (CXXBindTemporaryExpr *Binder
-            = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr))
-        FullInitExpr = Binder->getSubExpr();
-      if (CXXConstructExpr *Construct
-                    = dyn_cast<CXXConstructExpr>(FullInitExpr)) {
-        Constructor = Construct->getConstructor();
-        HadMultipleCandidates = Construct->hadMultipleCandidates();
-        for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(),
-                                         AEnd = Construct->arg_end();
-             A != AEnd; ++A)
-          ConvertedConstructorArgs.push_back(*A);
-      } else {
-        // Take the converted initializer.
-        ConvertedConstructorArgs.push_back(FullInit.release());
-      }
-    } else {
-      // No initialization required.
-    }
+    // FullInit is our initializer; strip off CXXBindTemporaryExprs, because
+    // we don't want the initialized object to be destructed.
+    if (CXXBindTemporaryExpr *Binder =
+            dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
+      FullInit = Owned(Binder->getSubExpr());
 
-    // Take the converted arguments and use them for the new expression.
-    NumConsArgs = ConvertedConstructorArgs.size();
-    ConsArgs = (Expr **)ConvertedConstructorArgs.take();
+    Initializer = FullInit.take();
   }
 
   // Mark the new and delete operators as referenced.
@@ -1281,35 +1317,30 @@
   // C++0x [expr.new]p17:
   //   If the new expression creates an array of objects of class type,
   //   access and ambiguity control are done for the destructor.
-  if (ArraySize && Constructor) {
-    if (CXXDestructorDecl *dtor = LookupDestructor(Constructor->getParent())) {
+  if (ArraySize && AllocType->isRecordType() && !AllocType->isDependentType()) {
+    if (CXXDestructorDecl *dtor = LookupDestructor(
+            cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl()))) {
       MarkFunctionReferenced(StartLoc, dtor);
       CheckDestructorAccess(StartLoc, dtor, 
                             PDiag(diag::err_access_dtor)
                               << Context.getBaseElementType(AllocType));
+      DiagnoseUseOfDecl(dtor, StartLoc);
     }
   }
 
   PlacementArgs.release();
-  ConstructorArgs.release();
 
   return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
-                                        PlaceArgs, NumPlaceArgs, TypeIdParens,
-                                        ArraySize, Constructor, Init,
-                                        ConsArgs, NumConsArgs,
-                                        HadMultipleCandidates,
                                         OperatorDelete,
                                         UsualArrayDeleteWantsSize,
+                                        PlaceArgs, NumPlaceArgs, TypeIdParens,
+                                        ArraySize, initStyle, Initializer,
                                         ResultType, AllocTypeInfo,
-                                        StartLoc,
-                                        Init ? ConstructorRParen :
-                                               TypeRange.getEnd(),
-                                        ConstructorLParen, ConstructorRParen));
+                                        StartLoc, DirectInitRange));
 }
 
-/// CheckAllocatedType - Checks that a type is suitable as the allocated type
+/// \brief Checks that a type is suitable as the allocated type
 /// in a new-expression.
-/// dimension off and stores the size expression in ArraySize.
 bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
                               SourceRange R) {
   // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
@@ -2040,7 +2071,7 @@
           UsualArrayDeleteWantsSize = (OperatorDelete->getNumParams() == 2);
       }
 
-      if (!PointeeRD->hasTrivialDestructor())
+      if (!PointeeRD->hasIrrelevantDestructor())
         if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
           MarkFunctionReferenced(StartLoc,
                                     const_cast<CXXDestructorDecl*>(Dtor));
@@ -4285,23 +4316,28 @@
   }
 
   // That should be enough to guarantee that this type is complete.
-  // If it has a trivial destructor, we can avoid the extra copy.
   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-  if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
+  if (RD->isInvalidDecl() || RD->isDependentContext())
     return Owned(E);
-
   CXXDestructorDecl *Destructor = LookupDestructor(RD);
 
-  CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
   if (Destructor) {
     MarkFunctionReferenced(E->getExprLoc(), Destructor);
     CheckDestructorAccess(E->getExprLoc(), Destructor,
                           PDiag(diag::err_access_dtor_temp)
                             << E->getType());
+    DiagnoseUseOfDecl(Destructor, E->getExprLoc());
+  }
 
+  // If destructor is trivial, we can avoid the extra copy.
+  if (Destructor->isTrivial())
+    return Owned(E);
+
+  if (Destructor)
     // We need a cleanup, but we don't need to remember the temporary.
     ExprNeedsCleanups = true;
-  }
+
+  CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
   return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E));
 }
 

Modified: cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp Mon Feb 20 19:34:24 2012
@@ -247,7 +247,7 @@
   if (!method)
     return 0;
 
-  TryCaptureVar(method->getSelfDecl(), Loc);
+  tryCaptureVariable(method->getSelfDecl(), Loc);
 
   return method;
 }
@@ -1889,6 +1889,68 @@
   return S.LookupName(R, S.TUScope, false);
 }
 
+static void addFixitForObjCARCConversion(Sema &S,
+                                         DiagnosticBuilder &DiagB,
+                                         Sema::CheckedConversionKind CCK,
+                                         SourceLocation afterLParen,
+                                         QualType castType,
+                                         Expr *castExpr,
+                                         const char *bridgeKeyword,
+                                         const char *CFBridgeName) {
+  // We handle C-style and implicit casts here.
+  switch (CCK) {
+  case Sema::CCK_ImplicitConversion:
+  case Sema::CCK_CStyleCast:
+    break;
+  case Sema::CCK_FunctionalCast:
+  case Sema::CCK_OtherCast:
+    return;
+  }
+
+  if (CFBridgeName) {
+    Expr *castedE = castExpr;
+    if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))
+      castedE = CCE->getSubExpr();
+    castedE = castedE->IgnoreImpCasts();
+    SourceRange range = castedE->getSourceRange();
+    if (isa<ParenExpr>(castedE)) {
+      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
+                         CFBridgeName));
+    } else {
+      std::string namePlusParen = CFBridgeName;
+      namePlusParen += "(";
+      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
+                                                    namePlusParen));
+      DiagB.AddFixItHint(FixItHint::CreateInsertion(
+                                       S.PP.getLocForEndOfToken(range.getEnd()),
+                                       ")"));
+    }
+    return;
+  }
+
+  if (CCK == Sema::CCK_CStyleCast) {
+    DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
+  } else {
+    std::string castCode = "(";
+    castCode += bridgeKeyword;
+    castCode += castType.getAsString();
+    castCode += ")";
+    Expr *castedE = castExpr->IgnoreImpCasts();
+    SourceRange range = castedE->getSourceRange();
+    if (isa<ParenExpr>(castedE)) {
+      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
+                         castCode));
+    } else {
+      castCode += "(";
+      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
+                                                    castCode));
+      DiagB.AddFixItHint(FixItHint::CreateInsertion(
+                                       S.PP.getLocForEndOfToken(range.getEnd()),
+                                       ")"));
+    }
+  }
+}
+
 static void
 diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
                           QualType castType, ARCConversionTypeClass castACTC,
@@ -1934,14 +1996,18 @@
       << castRange
       << castExpr->getSourceRange();
     bool br = KnownName(S, "CFBridgingRelease");
-    S.Diag(noteLoc, diag::note_arc_bridge)
-      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
-            FixItHint::CreateInsertion(afterLParen, "__bridge "));
-    S.Diag(noteLoc, diag::note_arc_bridge_transfer)
-      << castExprType << br 
-      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
-          FixItHint::CreateInsertion(afterLParen, 
-                                br ? "CFBridgingRelease " : "__bridge_transfer "));
+    {
+      DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
+      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
+                                   castType, castExpr, "__bridge ", 0);
+    }
+    {
+      DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge_transfer)
+        << castExprType << br;
+      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
+                                   castType, castExpr, "__bridge_transfer ",
+                                   br ? "CFBridgingRelease" : 0);
+    }
 
     return;
   }
@@ -1958,14 +2024,18 @@
       << castRange
       << castExpr->getSourceRange();
 
-    S.Diag(noteLoc, diag::note_arc_bridge)
-      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
-            FixItHint::CreateInsertion(afterLParen, "__bridge "));
-    S.Diag(noteLoc, diag::note_arc_bridge_retained)
-      << castType << br
-      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
-          FixItHint::CreateInsertion(afterLParen, 
-                              br ? "CFBridgingRetain " : "__bridge_retained"));
+    {
+      DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
+      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
+                                   castType, castExpr, "__bridge ", 0);
+    }
+    {
+      DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge_retained)
+        << castType << br;
+      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
+                                   castType, castExpr, "__bridge_retained ",
+                                   br ? "CFBridgingRetain" : 0);
+    }
 
     return;
   }

Modified: cfe/branches/tooling/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaInit.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaInit.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaInit.cpp Mon Feb 20 19:34:24 2012
@@ -2321,6 +2321,9 @@
   case EK_Member:
     return VariableOrMember->getDeclName();
 
+  case EK_LambdaCapture:
+    return Capture.Var->getDeclName();
+      
   case EK_Result:
   case EK_Exception:
   case EK_New:
@@ -2356,6 +2359,7 @@
   case EK_VectorElement:
   case EK_ComplexElement:
   case EK_BlockElement:
+  case EK_LambdaCapture:
     return 0;
   }
 
@@ -2379,6 +2383,7 @@
   case EK_VectorElement:
   case EK_ComplexElement:
   case EK_BlockElement:
+  case EK_LambdaCapture:
     break;
   }
 
@@ -2412,6 +2417,7 @@
   case SK_StringInit:
   case SK_ObjCObjectConversion:
   case SK_ArrayInit:
+  case SK_ParenthesizedArrayInit:
   case SK_PassByIndirectCopyRestore:
   case SK_PassByIndirectRestore:
   case SK_ProduceObjCObject:
@@ -2613,6 +2619,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddParenthesizedArrayInitStep(QualType T) {
+  Step S;
+  S.Kind = SK_ParenthesizedArrayInit;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::AddPassByIndirectCopyRestoreStep(QualType type,
                                                               bool shouldCopy) {
   Step s;
@@ -2699,9 +2712,14 @@
                                             QualType DestType,
                                             InitializationSequence &Sequence) {
   // C++11 [dcl.init.list]p3:
-  //   List-initialization of an object of type T is defined as follows:
-  //   - If the initializer list has no elements and T is a class type with
-  //     a default constructor, the object is value-initialized.
+  //   List-initialization of an object or reference of type T is defined as
+  //   follows:
+  //   - If T is an aggregate, aggregate initialization is performed.
+  if (DestType->isAggregateType())
+    return false;
+
+  //   - Otherwise, if the initializer list has no elements and T is a class
+  //     type with a default constructor, the object is value-initialized.
   if (List->getNumInits() == 0) {
     if (CXXConstructorDecl *DefaultConstructor =
             S.LookupDefaultConstructor(DestRecordDecl)) {
@@ -3060,16 +3078,25 @@
     TryReferenceListInitialization(S, Entity, Kind, InitList, Sequence);
     return;
   }
-  if (DestType->isRecordType() && !DestType->isAggregateType()) {
-    if (S.getLangOptions().CPlusPlus0x) {
-      Expr *Arg = InitList;
-      // A direct-initializer is not list-syntax, i.e. there's no special
-      // treatment of "A a({1, 2});".
-      TryConstructorInitialization(S, Entity, Kind, &Arg, 1, DestType,
-                    Sequence, Kind.getKind() != InitializationKind::IK_Direct);
-    } else
-      Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
-    return;
+  if (DestType->isRecordType()) {
+    if (S.RequireCompleteType(InitList->getLocStart(), DestType, S.PDiag())) {
+      Sequence.SetFailed(InitializationSequence::FK_Incomplete);
+      return;
+    }
+
+    if (!DestType->isAggregateType()) {
+      if (S.getLangOptions().CPlusPlus0x) {
+        Expr *Arg = InitList;
+        // A direct-initializer is not list-syntax, i.e. there's no special
+        // treatment of "A a({1, 2});".
+        TryConstructorInitialization(S, Entity, Kind, &Arg, 1, DestType, 
+                                     Sequence,
+                               Kind.getKind() != InitializationKind::IK_Direct);
+      } else
+        Sequence.SetFailed(
+            InitializationSequence::FK_InitListBadDestinationType);
+      return;
+    }
   }
 
   InitListChecker CheckInitList(S, Entity, InitList,
@@ -3549,31 +3576,42 @@
                                    const InitializedEntity &Entity,
                                    const InitializationKind &Kind,
                                    InitializationSequence &Sequence) {
-  // C++ [dcl.init]p5:
+  // C++98 [dcl.init]p5, C++11 [dcl.init]p7:
   //
   //   To value-initialize an object of type T means:
   QualType T = Entity.getType();
 
   //     -- if T is an array type, then each element is value-initialized;
-  while (const ArrayType *AT = S.Context.getAsArrayType(T))
-    T = AT->getElementType();
+  T = S.Context.getBaseElementType(T);
 
   if (const RecordType *RT = T->getAs<RecordType>()) {
     if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      // C++98:
       // -- if T is a class type (clause 9) with a user-declared
       //    constructor (12.1), then the default constructor for T is
       //    called (and the initialization is ill-formed if T has no
       //    accessible default constructor);
-      //
-      // FIXME: we really want to refer to a single subobject of the array,
-      // but Entity doesn't have a way to capture that (yet).
-      if (ClassDecl->hasUserDeclaredConstructor())
-        return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
+      if (!S.getLangOptions().CPlusPlus0x) {
+        if (ClassDecl->hasUserDeclaredConstructor())
+          // FIXME: we really want to refer to a single subobject of the array,
+          // but Entity doesn't have a way to capture that (yet).
+          return TryConstructorInitialization(S, Entity, Kind, 0, 0,
+                                              T, Sequence);
+      } else {
+        // C++11:
+        // -- if T is a class type (clause 9) with either no default constructor
+        //    (12.1 [class.ctor]) or a default constructor that is user-provided
+        //    or deleted, then the object is default-initialized;
+        CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl);
+        if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted())
+          return TryConstructorInitialization(S, Entity, Kind, 0, 0,
+                                              T, Sequence);
+      }
 
-      // -- if T is a (possibly cv-qualified) non-union class type
-      //    without a user-provided constructor, then the object is
-      //    zero-initialized and, if T's implicitly-declared default
-      //    constructor is non-trivial, that constructor is called.
+      // -- if T is a (possibly cv-qualified) non-union class type without a
+      //    user-provided or deleted default constructor, then the object is
+      //    zero-initialized and, if T has a non-trivial default constructor,
+      //    default-initialized;
       if ((ClassDecl->getTagKind() == TTK_Class ||
            ClassDecl->getTagKind() == TTK_Struct)) {
         Sequence.AddZeroInitializationStep(Entity.getType());
@@ -4037,6 +4075,15 @@
       else {
         AddArrayInitStep(DestType);
       }
+    }
+    // Note: as a GNU C++ extension, we allow initialization of a
+    // class member from a parenthesized initializer list.
+    else if (S.getLangOptions().CPlusPlus &&
+             Entity.getKind() == InitializedEntity::EK_Member &&
+             Initializer && isa<InitListExpr>(Initializer)) {
+      TryListInitialization(S, Entity, Kind, cast<InitListExpr>(Initializer),
+                            *this);
+      AddParenthesizedArrayInitStep(DestType);
     } else if (DestAT->getElementType()->isAnyCharacterType())
       SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
     else
@@ -4194,6 +4241,7 @@
   case InitializedEntity::EK_VectorElement:
   case InitializedEntity::EK_ComplexElement:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaCapture:
     return Sema::AA_Initializing;
   }
 
@@ -4215,6 +4263,7 @@
   case InitializedEntity::EK_ComplexElement:
   case InitializedEntity::EK_Exception:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaCapture:
     return false;
 
   case InitializedEntity::EK_Parameter:
@@ -4237,6 +4286,7 @@
     case InitializedEntity::EK_VectorElement:
     case InitializedEntity::EK_ComplexElement:
     case InitializedEntity::EK_BlockElement:
+    case InitializedEntity::EK_LambdaCapture:
       return false;
 
     case InitializedEntity::EK_Variable:
@@ -4307,6 +4357,9 @@
   case InitializedEntity::EK_Variable:
     return Entity.getDecl()->getLocation();
 
+  case InitializedEntity::EK_LambdaCapture:
+    return Entity.getCaptureLoc();
+      
   case InitializedEntity::EK_ArrayElement:
   case InitializedEntity::EK_Member:
   case InitializedEntity::EK_Parameter:
@@ -4760,6 +4813,7 @@
   case SK_StringInit:
   case SK_ObjCObjectConversion:
   case SK_ArrayInit:
+  case SK_ParenthesizedArrayInit:
   case SK_PassByIndirectCopyRestore:
   case SK_PassByIndirectRestore:
   case SK_ProduceObjCObject:
@@ -5055,8 +5109,9 @@
       // When an initializer list is passed for a parameter of type "reference
       // to object", we don't get an EK_Temporary entity, but instead an
       // EK_Parameter entity with reference type.
-      // FIXME: This is a hack. Why is this necessary here, but not in other
-      // places where implicit temporaries are created?
+      // FIXME: This is a hack. What we really should do is create a user
+      // conversion step for this case, but this makes it considerably more
+      // complicated. For now, this will do.
       InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
                                         Entity.getType().getNonReferenceType());
       bool UseTemporary = Entity.getType()->isReferenceType();
@@ -5085,11 +5140,22 @@
       break;
     }
 
-    case SK_ConstructorInitialization:
-      CurInit = PerformConstructorInitialization(S, Entity, Kind, move(Args),
-                                                 *Step,
+    case SK_ConstructorInitialization: {
+      // When an initializer list is passed for a parameter of type "reference
+      // to object", we don't get an EK_Temporary entity, but instead an
+      // EK_Parameter entity with reference type.
+      // FIXME: This is a hack. What we really should do is create a user
+      // conversion step for this case, but this makes it considerably more
+      // complicated. For now, this will do.
+      InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
+                                        Entity.getType().getNonReferenceType());
+      bool UseTemporary = Entity.getType()->isReferenceType();
+      CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity
+                                                                 : Entity,
+                                                 Kind, move(Args), *Step,
                                                ConstructorInitRequiresZeroInit);
       break;
+    }
 
     case SK_ZeroInitialization: {
       step_iterator NextStep = Step;
@@ -5186,6 +5252,13 @@
       }
       break;
 
+    case SK_ParenthesizedArrayInit:
+      // Okay: we checked everything before creating this step. Note that
+      // this is a GNU extension.
+      S.Diag(Kind.getLocation(), diag::ext_array_init_parens)
+        << CurInit.get()->getSourceRange();
+      break;
+
     case SK_PassByIndirectCopyRestore:
     case SK_PassByIndirectRestore:
       checkIndirectCopyRestoreSource(S, CurInit.get());
@@ -5230,6 +5303,7 @@
                        Converted.data(), NumInits, ILE->getRBraceLoc());
       Semantic->setSyntacticForm(ILE);
       Semantic->setType(Dest);
+      Semantic->setInitializesStdInitializerList();
       CurInit = S.Owned(Semantic);
       break;
     }
@@ -5246,6 +5320,26 @@
   return move(CurInit);
 }
 
+/// \brief Provide some notes that detail why a function was implicitly
+/// deleted.
+static void diagnoseImplicitlyDeletedFunction(Sema &S, CXXMethodDecl *Method) {
+  // FIXME: This is a work in progress. It should dig deeper to figure out
+  // why the function was deleted (e.g., because one of its members doesn't
+  // have a copy constructor, for the copy-constructor case).
+  if (!Method->isImplicit()) {
+    S.Diag(Method->getLocation(), diag::note_callee_decl)
+      << Method->getDeclName();
+  }
+  
+  if (Method->getParent()->isLambda()) {
+    S.Diag(Method->getParent()->getLocation(), diag::note_lambda_decl);
+    return;
+  }
+  
+  S.Diag(Method->getParent()->getLocation(), diag::note_defined_here)
+    << Method->getParent();
+}
+
 //===----------------------------------------------------------------------===//
 // Diagnose initialization failures
 //===----------------------------------------------------------------------===//
@@ -5509,17 +5603,33 @@
         break;
 
       case OR_Deleted: {
-        S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
-          << true << DestType << ArgsRange;
         OverloadCandidateSet::iterator Best;
         OverloadingResult Ovl
           = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
-        if (Ovl == OR_Deleted) {
-          S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
-            << 1 << Best->Function->isDeleted();
-        } else {
+        if (Ovl != OR_Deleted) {
+          S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
+            << true << DestType << ArgsRange;
           llvm_unreachable("Inconsistent overload resolution?");
+          break;
+        }
+       
+        // If this is a defaulted or implicitly-declared function, then
+        // it was implicitly deleted. Make it clear that the deletion was
+        // implicit.
+        if (S.isImplicitlyDeleted(Best->Function)) {
+          S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
+            << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function)) 
+            << DestType << ArgsRange;
+        
+          diagnoseImplicitlyDeletedFunction(S, 
+            cast<CXXMethodDecl>(Best->Function));            
+          break;
         }
+        
+        S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
+          << true << DestType << ArgsRange;
+        S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
+          << 1 << Best->Function->isDeleted();
         break;
       }
 
@@ -5826,6 +5936,10 @@
       OS << "array initialization";
       break;
 
+    case SK_ParenthesizedArrayInit:
+      OS << "parenthesized array initialization";
+      break;
+
     case SK_PassByIndirectCopyRestore:
       OS << "pass by indirect copy and restore";
       break;

Modified: cfe/branches/tooling/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaLambda.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaLambda.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaLambda.cpp Mon Feb 20 19:34:24 2012
@@ -36,7 +36,8 @@
 CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
                                            SourceRange IntroducerRange,
                                            TypeSourceInfo *MethodType,
-                                           SourceLocation EndLoc) {
+                                           SourceLocation EndLoc,
+                 llvm::ArrayRef<ParmVarDecl *> Params) {
   // C++11 [expr.prim.lambda]p5:
   //   The closure type for a lambda-expression has a public inline function 
   //   call operator (13.5.4) whose parameters and return type are described by
@@ -66,6 +67,19 @@
   // context, so that the Scope stack matches the lexical nesting.
   Method->setLexicalDeclContext(Class->getDeclContext());  
   
+  // Add parameters.
+  if (!Params.empty()) {
+    Method->setParams(Params);
+    CheckParmsForFunctionDef(const_cast<ParmVarDecl **>(Params.begin()),
+                             const_cast<ParmVarDecl **>(Params.end()),
+                             /*CheckParameterNames=*/false);
+    
+    for (CXXMethodDecl::param_iterator P = Method->param_begin(), 
+                                    PEnd = Method->param_end();
+         P != PEnd; ++P)
+      (*P)->setOwningFunction(Method);
+  }
+  
   return Method;
 }
 
@@ -87,6 +101,17 @@
 
   if (ExplicitResultType) {
     LSI->ReturnType = CallOperator->getResultType();
+    
+    if (!LSI->ReturnType->isDependentType() &&
+        !LSI->ReturnType->isVoidType()) {
+      if (RequireCompleteType(CallOperator->getLocStart(), LSI->ReturnType,
+                              diag::err_lambda_incomplete_result)) {
+        // Do nothing.
+      } else if (LSI->ReturnType->isObjCObjectOrInterfaceType()) {
+        Diag(CallOperator->getLocStart(), diag::err_lambda_objc_object_result)
+          << LSI->ReturnType;
+      }
+    }
   } else {
     LSI->HasImplicitReturnType = true;
   }
@@ -98,18 +123,11 @@
   LSI->finishedExplicitCaptures();
 }
 
-void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope,
-                               llvm::ArrayRef<ParmVarDecl *> Params) {
-  CallOperator->setParams(Params);
-  CheckParmsForFunctionDef(const_cast<ParmVarDecl **>(Params.begin()), 
-                           const_cast<ParmVarDecl **>(Params.end()),
-                           /*CheckParameterNames=*/false);
-  
+void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) {  
   // Introduce our parameters into the function scope
   for (unsigned p = 0, NumParams = CallOperator->getNumParams(); 
        p < NumParams; ++p) {
     ParmVarDecl *Param = CallOperator->getParamDecl(p);
-    Param->setOwningFunction(CallOperator);
     
     // If this has an identifier, add it to the scope stack.
     if (CurScope && Param->getIdentifier()) {
@@ -130,6 +148,7 @@
   bool ExplicitParams = true;
   bool ExplicitResultType = true;
   SourceLocation EndLoc;
+  llvm::ArrayRef<ParmVarDecl *> Params;
   if (ParamInfo.getNumTypeObjects() == 0) {
     // C++11 [expr.prim.lambda]p4:
     //   If a lambda-expression does not include a lambda-declarator, it is as 
@@ -155,23 +174,25 @@
     if (!FTI.hasMutableQualifier())
       FTI.TypeQuals |= DeclSpec::TQ_const;
     
-    // C++11 [expr.prim.lambda]p5:
-    //   [...] Default arguments (8.3.6) shall not be specified in the 
-    //   parameter-declaration-clause of a lambda-declarator.
-    CheckExtraCXXDefaultArguments(ParamInfo);
-    
     MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
-    // FIXME: Can these asserts actually fail?
     assert(MethodTyInfo && "no type from lambda-declarator");
     EndLoc = ParamInfo.getSourceRange().getEnd();
     
     ExplicitResultType
       = MethodTyInfo->getType()->getAs<FunctionType>()->getResultType() 
                                                         != Context.DependentTy;
+    
+    TypeLoc TL = MethodTyInfo->getTypeLoc();
+    FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+    Params = llvm::ArrayRef<ParmVarDecl *>(Proto.getParmArray(), 
+                                           Proto.getNumArgs());
   }
   
   CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, 
-                                                MethodTyInfo, EndLoc);
+                                                MethodTyInfo, EndLoc, Params);
+  
+  if (ExplicitParams)
+    CheckCXXDefaultArguments(Method);
   
   // Attributes on the lambda apply to the method.  
   ProcessDeclAttributes(CurScope, Method, ParamInfo);
@@ -266,7 +287,8 @@
     //   for unqualified name lookup (3.4.1); each such lookup shall find a 
     //   variable with automatic storage duration declared in the reaching 
     //   scope of the local lambda expression.
-    // FIXME: Check reaching scope. 
+    // 
+    // Note that the 'reaching scope' check happens in tryCaptureVariable().
     VarDecl *Var = R.getAsSingle<VarDecl>();
     if (!Var) {
       Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id;
@@ -291,21 +313,32 @@
       continue;
     }
 
+    // C++11 [expr.prim.lambda]p23:
+    //   A capture followed by an ellipsis is a pack expansion (14.5.3).
+    SourceLocation EllipsisLoc;
+    if (C->EllipsisLoc.isValid()) {
+      if (Var->isParameterPack()) {
+        EllipsisLoc = C->EllipsisLoc;
+      } else {
+        Diag(C->EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
+          << SourceRange(C->Loc);
+        
+        // Just ignore the ellipsis.
+      }
+    } else if (Var->isParameterPack()) {
+      Diag(C->Loc, diag::err_lambda_unexpanded_pack);
+      continue;
+    }
+    
     TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
                                                  TryCapture_ExplicitByVal;
-    TryCaptureVar(Var, C->Loc, Kind);
+    tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
   }
   finishLambdaExplicitCaptures(LSI);
 
-  // Set the parameters on the decl, if specified.
-  if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
-    FunctionProtoTypeLoc Proto
-      = cast<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc());
-    addLambdaParameters(Method, CurScope, Proto.getParams());
-  }
+  // Add lambda parameters into scope.
+  addLambdaParameters(Method, CurScope);
 
-  // FIXME: Check return type is complete, !isObjCObjectType
-  
   // Enter a new evaluation context to insulate the lambda from any
   // cleanups from the enclosing full-expression.
   PushExpressionEvaluationContext(PotentiallyEvaluated);  
@@ -333,6 +366,122 @@
   PopFunctionScopeInfo();
 }
 
+/// \brief Add a lambda's conversion to function pointer, as described in
+/// C++11 [expr.prim.lambda]p6.
+static void addFunctionPointerConversion(Sema &S, 
+                                         SourceRange IntroducerRange,
+                                         CXXRecordDecl *Class,
+                                         CXXMethodDecl *CallOperator) {
+  // Add the conversion to function pointer.
+  const FunctionProtoType *Proto
+    = CallOperator->getType()->getAs<FunctionProtoType>(); 
+  QualType FunctionPtrTy;
+  QualType FunctionTy;
+  {
+    FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();
+    ExtInfo.TypeQuals = 0;
+    FunctionTy = S.Context.getFunctionType(Proto->getResultType(),
+                                           Proto->arg_type_begin(),
+                                           Proto->getNumArgs(),
+                                           ExtInfo);
+    FunctionPtrTy = S.Context.getPointerType(FunctionTy);
+  }
+  
+  FunctionProtoType::ExtProtoInfo ExtInfo;
+  ExtInfo.TypeQuals = Qualifiers::Const;
+  QualType ConvTy = S.Context.getFunctionType(FunctionPtrTy, 0, 0, ExtInfo);
+  
+  SourceLocation Loc = IntroducerRange.getBegin();
+  DeclarationName Name
+    = S.Context.DeclarationNames.getCXXConversionFunctionName(
+        S.Context.getCanonicalType(FunctionPtrTy));
+  DeclarationNameLoc NameLoc;
+  NameLoc.NamedType.TInfo = S.Context.getTrivialTypeSourceInfo(FunctionPtrTy,
+                                                               Loc);
+  CXXConversionDecl *Conversion 
+    = CXXConversionDecl::Create(S.Context, Class, Loc, 
+                                DeclarationNameInfo(Name, Loc, NameLoc),
+                                ConvTy, 
+                                S.Context.getTrivialTypeSourceInfo(ConvTy, 
+                                                                   Loc),
+                                /*isInline=*/false, /*isExplicit=*/false,
+                                /*isConstexpr=*/false, 
+                                CallOperator->getBody()->getLocEnd());
+  Conversion->setAccess(AS_public);
+  Conversion->setImplicit(true);
+  Class->addDecl(Conversion);
+  
+  // Add a non-static member function "__invoke" that will be the result of
+  // the conversion.
+  Name = &S.Context.Idents.get("__invoke");
+  CXXMethodDecl *Invoke
+    = CXXMethodDecl::Create(S.Context, Class, Loc, 
+                            DeclarationNameInfo(Name, Loc), FunctionTy, 
+                            CallOperator->getTypeSourceInfo(),
+                            /*IsStatic=*/true, SC_Static, /*IsInline=*/true,
+                            /*IsConstexpr=*/false, 
+                            CallOperator->getBody()->getLocEnd());
+  SmallVector<ParmVarDecl *, 4> InvokeParams;
+  for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) {
+    ParmVarDecl *From = CallOperator->getParamDecl(I);
+    InvokeParams.push_back(ParmVarDecl::Create(S.Context, Invoke,
+                                               From->getLocStart(),
+                                               From->getLocation(),
+                                               From->getIdentifier(),
+                                               From->getType(),
+                                               From->getTypeSourceInfo(),
+                                               From->getStorageClass(),
+                                               From->getStorageClassAsWritten(),
+                                               /*DefaultArg=*/0));
+  }
+  Invoke->setParams(InvokeParams);
+  Invoke->setAccess(AS_private);
+  Invoke->setImplicit(true);
+  Class->addDecl(Invoke);
+}
+
+/// \brief Add a lambda's conversion to block pointer.
+static void addBlockPointerConversion(Sema &S, 
+                                      SourceRange IntroducerRange,
+                                      CXXRecordDecl *Class,
+                                      CXXMethodDecl *CallOperator) {
+  const FunctionProtoType *Proto
+    = CallOperator->getType()->getAs<FunctionProtoType>(); 
+  QualType BlockPtrTy;
+  {
+    FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();
+    ExtInfo.TypeQuals = 0;
+    QualType FunctionTy
+      = S.Context.getFunctionType(Proto->getResultType(),
+                                  Proto->arg_type_begin(),
+                                  Proto->getNumArgs(),
+                                  ExtInfo);
+    BlockPtrTy = S.Context.getBlockPointerType(FunctionTy);
+  }
+  
+  FunctionProtoType::ExtProtoInfo ExtInfo;
+  ExtInfo.TypeQuals = Qualifiers::Const;
+  QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, 0, 0, ExtInfo);
+  
+  SourceLocation Loc = IntroducerRange.getBegin();
+  DeclarationName Name
+    = S.Context.DeclarationNames.getCXXConversionFunctionName(
+        S.Context.getCanonicalType(BlockPtrTy));
+  DeclarationNameLoc NameLoc;
+  NameLoc.NamedType.TInfo = S.Context.getTrivialTypeSourceInfo(BlockPtrTy, Loc);
+  CXXConversionDecl *Conversion 
+    = CXXConversionDecl::Create(S.Context, Class, Loc, 
+                                DeclarationNameInfo(Name, Loc, NameLoc),
+                                ConvTy, 
+                                S.Context.getTrivialTypeSourceInfo(ConvTy, Loc),
+                                /*isInline=*/false, /*isExplicit=*/false,
+                                /*isConstexpr=*/false, 
+                                CallOperator->getBody()->getLocEnd());
+  Conversion->setAccess(AS_public);
+  Conversion->setImplicit(true);
+  Class->addDecl(Conversion);
+}
+
 ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, 
                                  Scope *CurScope, bool IsInstantiation) {
   // Leave the expression-evaluation context.
@@ -380,10 +529,9 @@
       }
 
       VarDecl *Var = From.getVariable();
-      // FIXME: Handle pack expansions.
       LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef;
       Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, 
-                                             Kind, Var));
+                                             Kind, Var, From.getEllipsisLoc()));
       CaptureInits.push_back(From.getCopyExpr());
     }
 
@@ -462,45 +610,18 @@
     //   has a public non-virtual non-explicit const conversion function
     //   to pointer to function having the same parameter and return
     //   types as the closure type's function call operator.
-    if (Captures.empty() && CaptureDefault == LCD_None) {
-      const FunctionProtoType *Proto
-        = CallOperator->getType()->getAs<FunctionProtoType>(); 
-      QualType FunctionPtrTy;
-      {
-        FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();
-        ExtInfo.TypeQuals = 0;
-        QualType FunctionTy
-          = Context.getFunctionType(Proto->getResultType(),
-                                    Proto->arg_type_begin(),
-                                    Proto->getNumArgs(),
-                                    ExtInfo);
-        FunctionPtrTy = Context.getPointerType(FunctionTy);
-      }
-
-      FunctionProtoType::ExtProtoInfo ExtInfo;
-      ExtInfo.TypeQuals = Qualifiers::Const;
-      QualType ConvTy = Context.getFunctionType(FunctionPtrTy, 0, 0, ExtInfo);
-
-      SourceLocation Loc = IntroducerRange.getBegin();
-      DeclarationName Name
-        = Context.DeclarationNames.getCXXConversionFunctionName(
-            Context.getCanonicalType(FunctionPtrTy));
-      DeclarationNameLoc NameLoc;
-      NameLoc.NamedType.TInfo = Context.getTrivialTypeSourceInfo(FunctionPtrTy,
-                                                                 Loc);
-      CXXConversionDecl *Conversion 
-        = CXXConversionDecl::Create(Context, Class, Loc, 
-                                    DeclarationNameInfo(Name, Loc, NameLoc),
-                                    ConvTy, 
-                                    Context.getTrivialTypeSourceInfo(ConvTy, 
-                                                                     Loc),
-                                    /*isInline=*/false, /*isExplicit=*/false,
-                                    /*isConstexpr=*/false, Body->getLocEnd());
-      Conversion->setAccess(AS_public);
-      Conversion->setImplicit(true);
-      Class->addDecl(Conversion);
-    }
-
+    if (Captures.empty() && CaptureDefault == LCD_None)
+      addFunctionPointerConversion(*this, IntroducerRange, Class,
+                                   CallOperator);
+
+    // Objective-C++:
+    //   The closure type for a lambda-expression has a public non-virtual
+    //   non-explicit const conversion function to a block pointer having the
+    //   same parameter and return types as the closure type's function call
+    //   operator.
+    if (getLangOptions().Blocks)
+      addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
+    
     // Finalize the lambda class.
     SmallVector<Decl*, 4> Fields(Class->field_begin(), Class->field_end());
     ActOnFields(0, Class->getLocation(), Class, Fields, 

Modified: cfe/branches/tooling/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaLookup.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaLookup.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaLookup.cpp Mon Feb 20 19:34:24 2012
@@ -37,6 +37,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/edit_distance.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <limits>
 #include <list>
@@ -2275,7 +2276,7 @@
     CXXDestructorDecl *DD = RD->getDestructor();
     assert(DD && "record without a destructor");
     Result->setMethod(DD);
-    Result->setSuccess(DD->isDeleted());
+    Result->setSuccess(!DD->isDeleted());
     Result->setConstParamMatch(false);
     return Result;
   }
@@ -3109,9 +3110,12 @@
     return (*BestResults.begin()->second)[Name];
   }
 
-  unsigned getBestEditDistance() {
-    return (BestResults.empty()) ?
-        (std::numeric_limits<unsigned>::max)() : BestResults.begin()->first;
+  unsigned getBestEditDistance(bool Normalized) {
+    if (BestResults.empty())
+      return (std::numeric_limits<unsigned>::max)();
+
+    unsigned BestED = BestResults.begin()->first;
+    return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
   }
 };
 
@@ -3167,7 +3171,7 @@
 
 void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
   StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
-  TypoResultsMap *& Map = BestResults[Correction.getEditDistance()];
+  TypoResultsMap *& Map = BestResults[Correction.getEditDistance(false)];
   if (!Map)
     Map = new TypoResultsMap;
 
@@ -3188,6 +3192,47 @@
   }
 }
 
+// Fill the supplied vector with the IdentifierInfo pointers for each piece of
+// the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",
+// fill the vector with the IdentifierInfo pointers for "foo" and "bar").
+static void getNestedNameSpecifierIdentifiers(
+    NestedNameSpecifier *NNS,
+    SmallVectorImpl<const IdentifierInfo*> &Identifiers) {
+  if (NestedNameSpecifier *Prefix = NNS->getPrefix())
+    getNestedNameSpecifierIdentifiers(Prefix, Identifiers);
+  else
+    Identifiers.clear();
+
+  const IdentifierInfo *II = NULL;
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    II = NNS->getAsIdentifier();
+    break;
+
+  case NestedNameSpecifier::Namespace:
+    if (NNS->getAsNamespace()->isAnonymousNamespace())
+      return;
+    II = NNS->getAsNamespace()->getIdentifier();
+    break;
+
+  case NestedNameSpecifier::NamespaceAlias:
+    II = NNS->getAsNamespaceAlias()->getIdentifier();
+    break;
+
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+  case NestedNameSpecifier::TypeSpec:
+    II = QualType(NNS->getAsType(), 0).getBaseTypeIdentifier();
+    break;
+
+  case NestedNameSpecifier::Global:
+    return;
+  }
+
+  if (II)
+    Identifiers.push_back(II);
+}
+
 namespace {
 
 class SpecifierInfo {
@@ -3206,6 +3251,8 @@
 class NamespaceSpecifierSet {
   ASTContext &Context;
   DeclContextList CurContextChain;
+  SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
+  SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
   bool isSorted;
 
   SpecifierInfoList Specifiers;
@@ -3219,9 +3266,23 @@
   void SortNamespaces();
 
  public:
-  explicit NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext)
+  NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
+                        CXXScopeSpec *CurScopeSpec)
       : Context(Context), CurContextChain(BuildContextChain(CurContext)),
-        isSorted(true) {}
+        isSorted(true) {
+    if (CurScopeSpec && CurScopeSpec->getScopeRep())
+      getNestedNameSpecifierIdentifiers(CurScopeSpec->getScopeRep(),
+                                        CurNameSpecifierIdentifiers);
+    // Build the list of identifiers that would be used for an absolute
+    // (from the global context) NestedNameSpecifier refering to the current
+    // context.
+    for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
+                                        CEnd = CurContextChain.rend();
+         C != CEnd; ++C) {
+      if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
+        CurContextIdentifiers.push_back(ND->getIdentifier());
+    }
+  }
 
   /// \brief Add the namespace to the set, computing the corresponding
   /// NestedNameSpecifier and its distance in the process.
@@ -3259,7 +3320,7 @@
 
   Specifiers.clear();
   for (SmallVector<unsigned, 4>::iterator DI = sortedDistances.begin(),
-                                             DIEnd = sortedDistances.end();
+                                       DIEnd = sortedDistances.end();
        DI != DIEnd; ++DI) {
     SpecifierInfoList &SpecList = DistanceMap[*DI];
     Specifiers.append(SpecList.begin(), SpecList.end());
@@ -3273,8 +3334,9 @@
   NestedNameSpecifier *NNS = NULL;
   unsigned NumSpecifiers = 0;
   DeclContextList NamespaceDeclChain(BuildContextChain(Ctx));
+  DeclContextList FullNamespaceDeclChain(NamespaceDeclChain);
 
-  // Eliminate common elements from the two DeclContext chains
+  // Eliminate common elements from the two DeclContext chains.
   for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
                                       CEnd = CurContextChain.rend();
        C != CEnd && !NamespaceDeclChain.empty() &&
@@ -3282,6 +3344,21 @@
     NamespaceDeclChain.pop_back();
   }
 
+  // Add an explicit leading '::' specifier if needed.
+  if (NamespaceDecl *ND =
+        NamespaceDeclChain.empty() ? NULL :
+          dyn_cast_or_null<NamespaceDecl>(NamespaceDeclChain.back())) {
+    IdentifierInfo *Name = ND->getIdentifier();
+    if (std::find(CurContextIdentifiers.begin(), CurContextIdentifiers.end(),
+                  Name) != CurContextIdentifiers.end() ||
+        std::find(CurNameSpecifierIdentifiers.begin(),
+                  CurNameSpecifierIdentifiers.end(),
+                  Name) != CurNameSpecifierIdentifiers.end()) {
+      NamespaceDeclChain = FullNamespaceDeclChain;
+      NNS = NestedNameSpecifier::GlobalSpecifier(Context);
+    }
+  }
+
   // Build the NestedNameSpecifier from what is left of the NamespaceDeclChain
   for (DeclContextList::reverse_iterator C = NamespaceDeclChain.rbegin(),
                                       CEnd = NamespaceDeclChain.rend();
@@ -3293,6 +3370,18 @@
     }
   }
 
+  // If the built NestedNameSpecifier would be replacing an existing
+  // NestedNameSpecifier, use the number of component identifiers that
+  // would need to be changed as the edit distance instead of the number
+  // of components in the built NestedNameSpecifier.
+  if (NNS && !CurNameSpecifierIdentifiers.empty()) {
+    SmallVector<const IdentifierInfo*, 4> NewNameSpecifierIdentifiers;
+    getNestedNameSpecifierIdentifiers(NNS, NewNameSpecifierIdentifiers);
+    NumSpecifiers = llvm::ComputeEditDistance(
+      llvm::ArrayRef<const IdentifierInfo*>(CurNameSpecifierIdentifiers),
+      llvm::ArrayRef<const IdentifierInfo*>(NewNameSpecifierIdentifiers));
+  }
+
   isSorted = false;
   Distances.insert(NumSpecifiers);
   DistanceMap[NumSpecifiers].push_back(SpecifierInfo(Ctx, NNS, NumSpecifiers));
@@ -3478,6 +3567,12 @@
   }
 }
 
+static bool isCandidateViable(CorrectionCandidateCallback &CCC,
+                              TypoCorrection &Candidate) {
+  Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
+  return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
+}
+
 /// \brief Try to "correct" a typo in the source code by finding
 /// visible declarations whose names are similar to the name that was
 /// present in the source code.
@@ -3541,17 +3636,18 @@
   if (!ActiveTemplateInstantiations.empty())
     return TypoCorrection();
 
-  NamespaceSpecifierSet Namespaces(Context, CurContext);
+  NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
 
   TypoCorrectionConsumer Consumer(*this, Typo);
 
-  // If a callback object returns true for an empty typo correction candidate,
-  // assume it does not do any actual validation of the candidates.
+  // If a callback object considers an empty typo correction candidate to be
+  // viable, assume it does not do any actual validation of the candidates.
   TypoCorrection EmptyCorrection;
-  bool ValidatingCallback = !CCC.ValidateCandidate(EmptyCorrection);
+  bool ValidatingCallback = !isCandidateViable(CCC, EmptyCorrection);
 
   // Perform name lookup to find visible, similarly-named entities.
   bool IsUnqualifiedLookup = false;
+  DeclContext *QualifiedDC = MemberContext;
   if (MemberContext) {
     LookupVisibleDecls(MemberContext, LookupKind, Consumer);
 
@@ -3563,8 +3659,8 @@
         LookupVisibleDecls(*I, LookupKind, Consumer);
     }
   } else if (SS && SS->isSet()) {
-    DeclContext *DC = computeDeclContext(*SS, EnteringContext);
-    if (!DC)
+    QualifiedDC = computeDeclContext(*SS, EnteringContext);
+    if (!QualifiedDC)
       return TypoCorrection();
 
     // Provide a stop gap for files that are just seriously broken.  Trying
@@ -3574,7 +3670,7 @@
       return TypoCorrection();
     ++TyposCorrected;
 
-    LookupVisibleDecls(DC, LookupKind, Consumer);
+    LookupVisibleDecls(QualifiedDC, LookupKind, Consumer);
   } else {
     IsUnqualifiedLookup = true;
     UnqualifiedTyposCorrectedMap::iterator Cached
@@ -3584,7 +3680,7 @@
       // keyword case, we'll end up adding the keyword below.
       if (Cached->second) {
         if (!Cached->second.isKeyword() &&
-            CCC.ValidateCandidate(Cached->second))
+            isCandidateViable(CCC, Cached->second))
           Consumer.addCorrection(Cached->second);
       } else {
         // Only honor no-correction cache hits when a callback that will validate
@@ -3600,7 +3696,9 @@
       if (TyposCorrected + UnqualifiedTyposCorrected.size() >= 20)
         return TypoCorrection();
     }
+  }
 
+  if (IsUnqualifiedLookup || (QualifiedDC && QualifiedDC->isNamespace())) {
     // For unqualified lookup, look through all of the names that we have
     // seen in this translation unit.
     // FIXME: Re-add the ability to skip very unlikely potential corrections.
@@ -3637,7 +3735,7 @@
 
   // Make sure that the user typed at least 3 characters for each correction
   // made. Otherwise, we don't even both looking at the results.
-  unsigned ED = Consumer.getBestEditDistance();
+  unsigned ED = Consumer.getBestEditDistance(true);
   if (ED > 0 && Typo->getName().size() / ED < 3) {
     // If this was an unqualified lookup, note that no correction was found.
     if (IsUnqualifiedLookup)
@@ -3666,7 +3764,7 @@
 
   // Weed out any names that could not be found by name lookup or, if a
   // CorrectionCandidateCallback object was provided, failed validation.
-  llvm::SmallPtrSet<IdentifierInfo*, 16> QualifiedResults;
+  llvm::SmallVector<TypoCorrection, 16> QualifiedResults;
   LookupResult TmpRes(*this, TypoName, LookupKind);
   TmpRes.suppressDiagnostics();
   while (!Consumer.empty()) {
@@ -3681,7 +3779,7 @@
       if (I->second.isResolved()) {
         TypoCorrectionConsumer::result_iterator Prev = I;
         ++I;
-        if (!CCC.ValidateCandidate(Prev->second))
+        if (!isCandidateViable(CCC, Prev->second))
           DI->second->erase(Prev);
         continue;
       }
@@ -3695,7 +3793,7 @@
       case LookupResult::NotFound:
       case LookupResult::NotFoundInCurrentInstantiation:
       case LookupResult::FoundUnresolvedValue:
-        QualifiedResults.insert(Name);
+        QualifiedResults.push_back(I->second);
         // We didn't find this name in our scope, or didn't like what we found;
         // ignore it.
         {
@@ -3718,7 +3816,7 @@
              TRD != TRDEnd; ++TRD)
           I->second.addCorrectionDecl(*TRD);
         ++I;
-        if (!CCC.ValidateCandidate(Prev->second))
+        if (!isCandidateViable(CCC, Prev->second))
           DI->second->erase(Prev);
         break;
       }
@@ -3727,7 +3825,7 @@
         TypoCorrectionConsumer::result_iterator Prev = I;
         I->second.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>());
         ++I;
-        if (!CCC.ValidateCandidate(Prev->second))
+        if (!isCandidateViable(CCC, Prev->second))
           DI->second->erase(Prev);
         break;
       }
@@ -3744,7 +3842,7 @@
     // Only perform the qualified lookups for C++
     if (getLangOptions().CPlusPlus) {
       TmpRes.suppressDiagnostics();
-      for (llvm::SmallPtrSet<IdentifierInfo*,
+      for (llvm::SmallVector<TypoCorrection,
                              16>::iterator QRI = QualifiedResults.begin(),
                                         QRIEnd = QualifiedResults.end();
            QRI != QRIEnd; ++QRI) {
@@ -3752,31 +3850,35 @@
                                           NIEnd = Namespaces.end();
              NI != NIEnd; ++NI) {
           DeclContext *Ctx = NI->DeclCtx;
-          unsigned QualifiedED = ED + NI->EditDistance;
 
           // FIXME: Stop searching once the namespaces are too far away to create
           // acceptable corrections for this identifier (since the namespaces
           // are sorted in ascending order by edit distance).
 
           TmpRes.clear();
-          TmpRes.setLookupName(*QRI);
+          TmpRes.setLookupName(QRI->getCorrectionAsIdentifierInfo());
           if (!LookupQualifiedName(TmpRes, Ctx)) continue;
 
           // Any corrections added below will be validated in subsequent
           // iterations of the main while() loop over the Consumer's contents.
           switch (TmpRes.getResultKind()) {
-          case LookupResult::Found:
-            Consumer.addName((*QRI)->getName(), TmpRes.getAsSingle<NamedDecl>(),
-                             QualifiedED, NI->NameSpecifier);
+          case LookupResult::Found: {
+            TypoCorrection TC(*QRI);
+            TC.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>());
+            TC.setCorrectionSpecifier(NI->NameSpecifier);
+            TC.setQualifierDistance(NI->EditDistance);
+            Consumer.addCorrection(TC);
             break;
+          }
           case LookupResult::FoundOverloaded: {
-            TypoCorrection corr(&Context.Idents.get((*QRI)->getName()), NULL,
-                                NI->NameSpecifier, QualifiedED);
+            TypoCorrection TC(*QRI);
+            TC.setCorrectionSpecifier(NI->NameSpecifier);
+            TC.setQualifierDistance(NI->EditDistance);
             for (LookupResult::iterator TRD = TmpRes.begin(),
                                      TRDEnd = TmpRes.end();
                  TRD != TRDEnd; ++TRD)
-              corr.addCorrectionDecl(*TRD);
-            Consumer.addCorrection(corr);
+              TC.addCorrectionDecl(*TRD);
+            Consumer.addCorrection(TC);
             break;
           }
           case LookupResult::NotFound:
@@ -3796,7 +3898,7 @@
   if (Consumer.empty()) return TypoCorrection();
 
   TypoResultsMap &BestResults = *Consumer.begin()->second;
-  ED = Consumer.begin()->first;
+  ED = TypoCorrection::NormalizeEditDistance(Consumer.begin()->first);
 
   if (ED > 0 && Typo->getName().size() / ED < 3) {
     // If this was an unqualified lookup and we believe the callback
@@ -3808,22 +3910,6 @@
     return TypoCorrection();
   }
 
-  // If we have multiple possible corrections, eliminate the ones where we
-  // added namespace qualifiers to try to resolve the ambiguity (and to favor
-  // corrections without additional namespace qualifiers)
-  if (getLangOptions().CPlusPlus && BestResults.size() > 1) {
-    TypoCorrectionConsumer::distance_iterator DI = Consumer.begin();
-    for (TypoCorrectionConsumer::result_iterator I = DI->second->begin(),
-                                              IEnd = DI->second->end();
-         I != IEnd; /* Increment in loop. */) {
-      if (I->second.getCorrectionSpecifier() != NULL) {
-        TypoCorrectionConsumer::result_iterator Cur = I;
-        ++I;
-        DI->second->erase(Cur);
-      } else ++I;
-    }
-  }
-
   // If only a single name remains, return that result.
   if (BestResults.size() == 1) {
     const llvm::StringMapEntry<TypoCorrection> &Correction = *(BestResults.begin());

Modified: cfe/branches/tooling/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaOverload.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaOverload.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaOverload.cpp Mon Feb 20 19:34:24 2012
@@ -9984,11 +9984,24 @@
       return ExprError();
 
     case OR_Deleted:
-      Diag(OpLoc, diag::err_ovl_deleted_oper)
-        << Best->Function->isDeleted()
-        << BinaryOperator::getOpcodeStr(Opc)
-        << getDeletedOrUnavailableSuffix(Best->Function)
-        << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      if (isImplicitlyDeleted(Best->Function)) {
+        CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
+        Diag(OpLoc, diag::err_ovl_deleted_special_oper)
+          << getSpecialMember(Method)
+          << BinaryOperator::getOpcodeStr(Opc)
+          << getDeletedOrUnavailableSuffix(Best->Function);
+        
+        if (Method->getParent()->isLambda()) {
+          Diag(Method->getParent()->getLocation(), diag::note_lambda_decl);
+          return ExprError();
+        }
+      } else {
+        Diag(OpLoc, diag::err_ovl_deleted_oper)
+          << Best->Function->isDeleted()
+          << BinaryOperator::getOpcodeStr(Opc)
+          << getDeletedOrUnavailableSuffix(Best->Function)
+          << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+      }
       CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
                                   BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
@@ -10385,6 +10398,8 @@
                               RParenLoc))
     return ExprError();
 
+  DiagnoseSentinelCalls(Method, LParenLoc, Args, NumArgs);
+
   if (CheckFunctionCall(Method, TheCall))
     return ExprError();
 
@@ -10688,6 +10703,8 @@
 
   if (IsError) return true;
 
+  DiagnoseSentinelCalls(Method, LParenLoc, Args, NumArgs);
+
   if (CheckFunctionCall(Method, TheCall))
     return true;
 

Modified: cfe/branches/tooling/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaStmt.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaStmt.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaStmt.cpp Mon Feb 20 19:34:24 2012
@@ -225,6 +225,18 @@
   DiagRuntimeBehavior(Loc, 0, PDiag(DiagID) << R1 << R2);
 }
 
+void Sema::ActOnStartOfCompoundStmt() {
+  PushCompoundScope();
+}
+
+void Sema::ActOnFinishOfCompoundStmt() {
+  PopCompoundScope();
+}
+
+sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
+  return getCurFunction()->CompoundScopes.back();
+}
+
 StmtResult
 Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                         MultiStmtArg elts, bool isStmtExpr) {
@@ -257,6 +269,15 @@
     DiagnoseUnusedExprResult(Elts[i]);
   }
 
+  // Check for suspicious empty body (null statement) in `for' and `while'
+  // statements.  Don't do anything for template instantiations, this just adds
+  // noise.
+  if (NumElts != 0 && !CurrentInstantiationScope &&
+      getCurCompoundScope().HasEmptyLoopBodies) {
+    for (unsigned i = 0; i != NumElts - 1; ++i)
+      DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
+  }
+
   return Owned(new (Context) CompoundStmt(Context, Elts, NumElts, L, R));
 }
 
@@ -355,21 +376,9 @@
 
   DiagnoseUnusedExprResult(thenStmt);
 
-  // Warn if the if block has a null body without an else value.
-  // this helps prevent bugs due to typos, such as
-  // if (condition);
-  //   do_stuff();
-  //
   if (!elseStmt) {
-    if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
-      // But do not warn if the body is a macro that expands to nothing, e.g:
-      //
-      // #define CALL(x)
-      // if (condition)
-      //   CALL(0);
-      //
-      if (!stmt->hasLeadingEmptyMacro())
-        Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
+    DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,
+                          diag::warn_empty_if_body);
   }
 
   DiagnoseUnusedExprResult(elseStmt);
@@ -957,6 +966,9 @@
     }
   }
 
+  DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt,
+                        diag::warn_empty_switch_body);
+
   // FIXME: If the case list was broken is some way, we don't have a good system
   // to patch it up.  Instead, just return the whole substmt as broken.
   if (CaseListIsErroneous)
@@ -983,6 +995,9 @@
 
   DiagnoseUnusedExprResult(Body);
 
+  if (isa<NullStmt>(Body))
+    getCurCompoundScope().setHasEmptyLoopBodies();
+
   return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
                                        Body, WhileLoc));
 }
@@ -1046,6 +1061,9 @@
   DiagnoseUnusedExprResult(Third);
   DiagnoseUnusedExprResult(Body);
 
+  if (isa<NullStmt>(Body))
+    getCurCompoundScope().setHasEmptyLoopBodies();
+
   return Owned(new (Context) ForStmt(Context, First,
                                      SecondResult.take(), ConditionVar,
                                      Third, Body, ForLoc, LParenLoc,
@@ -1587,7 +1605,12 @@
   if (!S || !B)
     return StmtError();
 
-  cast<CXXForRangeStmt>(S)->setBody(B);
+  CXXForRangeStmt *ForStmt = cast<CXXForRangeStmt>(S);
+  ForStmt->setBody(B);
+
+  DiagnoseEmptyStmtBody(ForStmt->getRParenLoc(), B,
+                        diag::warn_empty_range_based_for_body);
+
   return S;
 }
 
@@ -1824,9 +1847,9 @@
         !CurCap->ReturnType->isDependentType() &&
         !ReturnT->isDependentType() &&
         !Context.hasSameType(ReturnT, CurCap->ReturnType)) { 
-      // FIXME: Adapt diagnostic for lambdas.
       Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible) 
-          << ReturnT << CurCap->ReturnType;
+          << ReturnT << CurCap->ReturnType
+          << (getCurLambda() != 0);
       return StmtError();
     }
     CurCap->ReturnType = ReturnT;
@@ -1834,12 +1857,18 @@
   QualType FnRetType = CurCap->ReturnType;
   assert(!FnRetType.isNull());
 
-  if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap))
+  if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
     if (CurBlock->FunctionType->getAs<FunctionType>()->getNoReturnAttr()) {
       Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
       return StmtError();
     }
-  // FIXME: [[noreturn]] for lambdas!
+  } else {
+    LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CurCap);
+    if (LSI->CallOperator->getType()->getAs<FunctionType>()->getNoReturnAttr()){
+      Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr);
+      return StmtError();
+    }
+  }
 
   // Otherwise, verify that this result type matches the previous one.  We are
   // pickier with blocks than for normal functions because we don't have GCC

Modified: cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Feb 20 19:34:24 2012
@@ -326,7 +326,7 @@
     if (Owner->isFunctionOrMethod())
       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
   }
-  SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Var, LateAttrs, StartingScope);
 
   // Link instantiations of static data members back to the template from
   // which they were instantiated.
@@ -2629,7 +2629,8 @@
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
   ContextRAII previousContext(*this, Var->getDeclContext());
-
+  LocalInstantiationScope Local(*this);
+  
   VarDecl *OldVar = Var;
   Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(),
                                         getTemplateInstantiationArgs(Var)));
@@ -2644,7 +2645,8 @@
     DeclGroupRef DG(Var);
     Consumer.HandleTopLevelDecl(DG);
   }
-
+  Local.Exit();
+  
   if (Recursive) {
     // Define any newly required vtables.
     DefineUsedVTables();
@@ -3096,7 +3098,8 @@
   DeclContext *ParentDC = D->getDeclContext();
   if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
       isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
-      (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) {
+      (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) ||
+      (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {
     // D is a local of some kind. Look into the map of local
     // declarations to their instantiations.
     typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;

Modified: cfe/branches/tooling/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaType.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaType.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaType.cpp Mon Feb 20 19:34:24 2012
@@ -4382,42 +4382,9 @@
     if (isa<ParenExpr>(E)) {
       if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
         if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
-          QualType T = Var->getType();
-          unsigned FunctionScopesIndex;
-          bool Nested;
-          // Determine whether we can capture this variable.
-          if (S.canCaptureVariable(Var, DRE->getLocation(), 
-                                   /*Explicit=*/false, /*Diagnose=*/false, 
-                                   T, FunctionScopesIndex, Nested)) {
-            // Outer lambda scopes may have an effect on the type of a
-            // capture. Walk the captures outside-in to determine
-            // whether they can add 'const' to a capture by copy.
-            if (FunctionScopesIndex == S.FunctionScopes.size())
-              --FunctionScopesIndex;
-            for (unsigned I = FunctionScopesIndex, 
-                          E = S.FunctionScopes.size();
-                 I != E; ++I) {
-              LambdaScopeInfo *LSI
-                = dyn_cast<LambdaScopeInfo>(S.FunctionScopes[I]);
-              if (!LSI)
-                continue;
-
-              bool ByRef = false;
-              if (LSI->isCaptured(Var))
-                ByRef = LSI->getCapture(Var).isReferenceCapture();
-              else
-                ByRef = (LSI->ImpCaptureStyle
-                           == CapturingScopeInfo::ImpCap_LambdaByref);
-
-              T = S.getLambdaCaptureFieldType(T, ByRef);
-              if (!ByRef && !LSI->Mutable)
-                T.addConst();
-            }
-
-            if (!T->isReferenceType())
-              T = S.Context.getLValueReferenceType(T);
-            return T;
-          }
+          QualType T = S.getCapturedDeclRefType(Var, DRE->getLocation());
+          if (!T.isNull())
+            return S.Context.getLValueReferenceType(T);
         }
       }
     }

Modified: cfe/branches/tooling/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/TreeTransform.h?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/TreeTransform.h (original)
+++ cfe/branches/tooling/lib/Sema/TreeTransform.h Mon Feb 20 19:34:24 2012
@@ -878,7 +878,6 @@
       case LookupResult::FoundOverloaded:
       case LookupResult::FoundUnresolvedValue:
         llvm_unreachable("Tag lookup cannot find non-tags");
-        return QualType();
         
       case LookupResult::Ambiguous:
         // Let the LookupResult structure handle ambiguities.
@@ -1783,8 +1782,6 @@
     default:
       llvm_unreachable("Invalid C++ named cast");
     }
-
-    return ExprError();
   }
 
   /// \brief Build a new C++ static_cast expression.
@@ -1976,9 +1973,8 @@
                                QualType AllocatedType,
                                TypeSourceInfo *AllocatedTypeInfo,
                                Expr *ArraySize,
-                               SourceLocation ConstructorLParen,
-                               MultiExprArg ConstructorArgs,
-                               SourceLocation ConstructorRParen) {
+                               SourceRange DirectInitRange,
+                               Expr *Initializer) {
     return getSema().BuildCXXNew(StartLoc, UseGlobal,
                                  PlacementLParen,
                                  move(PlacementArgs),
@@ -1987,9 +1983,8 @@
                                  AllocatedType,
                                  AllocatedTypeInfo,
                                  ArraySize,
-                                 ConstructorLParen,
-                                 move(ConstructorArgs),
-                                 ConstructorRParen);
+                                 DirectInitRange,
+                                 Initializer);
   }
 
   /// \brief Build a new C++ "delete" expression.
@@ -2856,7 +2851,6 @@
   
   // These should be getting filtered out before they reach the AST.
   llvm_unreachable("overloaded function decl survived to here");
-  return TemplateName();
 }
 
 template<typename Derived>
@@ -3257,7 +3251,6 @@
   }
 
   llvm_unreachable("unhandled type loc!");
-  return QualType();
 }
 
 /// FIXME: By default, this routine adds type qualifiers only to types
@@ -5006,6 +4999,8 @@
 StmtResult
 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
                                               bool IsStmtExpr) {
+  Sema::CompoundScopeRAII CompoundScope(getSema());
+
   bool SubStmtInvalid = false;
   bool SubStmtChanged = false;
   ASTOwningVector<Stmt*> Statements(getSema());
@@ -6737,7 +6732,6 @@
   case OO_Array_New:
   case OO_Array_Delete:
     llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
-    return ExprError();
     
   case OO_Call: {
     // This is a call to an object's operator().
@@ -6774,12 +6768,10 @@
 
   case OO_Conditional:
     llvm_unreachable("conditional operator is not actually overloadable");
-    return ExprError();
 
   case OO_None:
   case NUM_OVERLOADED_OPERATORS:
     llvm_unreachable("not an overloaded operator?");
-    return ExprError();
   }
 
   ExprResult Callee = getDerived().TransformExpr(E->getCallee());
@@ -7104,29 +7096,17 @@
   if (getDerived().TransformExprs(E->getPlacementArgs(), 
                                   E->getNumPlacementArgs(), true,
                                   PlacementArgs, &ArgumentChanged))
-    return ExprError();  
+    return ExprError();
 
-  // Transform the constructor arguments (if any).
-  // As an annoying corner case, we may have introduced an implicit value-
-  // initialization expression when allocating a new array, which we implicitly
-  // drop. It will be re-created during type checking.
-  ASTOwningVector<Expr*> ConstructorArgs(SemaRef);
-  if (!(E->isArray() && E->getNumConstructorArgs() == 1 &&
-        isa<ImplicitValueInitExpr>(E->getConstructorArgs()[0])) &&
-      TransformExprs(E->getConstructorArgs(), E->getNumConstructorArgs(), true,
-                     ConstructorArgs, &ArgumentChanged))
-    return ExprError();  
-
-  // Transform constructor, new operator, and delete operator.
-  CXXConstructorDecl *Constructor = 0;
-  if (E->getConstructor()) {
-    Constructor = cast_or_null<CXXConstructorDecl>(
-                                   getDerived().TransformDecl(E->getLocStart(),
-                                                         E->getConstructor()));
-    if (!Constructor)
-      return ExprError();
-  }
+  // Transform the initializer (if any).
+  Expr *OldInit = E->getInitializer();
+  ExprResult NewInit;
+  if (OldInit)
+    NewInit = getDerived().TransformExpr(OldInit);
+  if (NewInit.isInvalid())
+    return ExprError();
 
+  // Transform new operator and delete operator.
   FunctionDecl *OperatorNew = 0;
   if (E->getOperatorNew()) {
     OperatorNew = cast_or_null<FunctionDecl>(
@@ -7148,21 +7128,18 @@
   if (!getDerived().AlwaysRebuild() &&
       AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
       ArraySize.get() == E->getArraySize() &&
-      Constructor == E->getConstructor() &&
+      NewInit.get() == OldInit &&
       OperatorNew == E->getOperatorNew() &&
       OperatorDelete == E->getOperatorDelete() &&
       !ArgumentChanged) {
     // Mark any declarations we need as referenced.
     // FIXME: instantiation-specific.
-    if (Constructor)
-      SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
     if (OperatorNew)
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew);
     if (OperatorDelete)
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
     
-    if (E->isArray() && Constructor && 
-        !E->getAllocatedType()->isDependentType()) {
+    if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
       QualType ElementType
         = SemaRef.Context.getBaseElementType(E->getAllocatedType());
       if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
@@ -7172,7 +7149,7 @@
         }
       }
     }
-    
+
     return SemaRef.Owned(E);
   }
 
@@ -7202,7 +7179,7 @@
       }
     }
   }
-  
+
   return getDerived().RebuildCXXNewExpr(E->getLocStart(),
                                         E->isGlobalNew(),
                                         /*FIXME:*/E->getLocStart(),
@@ -7212,9 +7189,8 @@
                                         AllocType,
                                         AllocTypeInfo,
                                         ArraySize.get(),
-                                        E->getConstructorLParen(),
-                                        move_arg(ConstructorArgs),
-                                        E->getConstructorRParen());
+                                        E->getDirectInitRange(),
+                                        NewInit.take());
 }
 
 template<typename Derived>
@@ -7665,11 +7641,22 @@
   if (!MethodTy)
     return ExprError();
 
+  // Transform lambda parameters.
+  bool Invalid = false;
+  llvm::SmallVector<QualType, 4> ParamTypes;
+  llvm::SmallVector<ParmVarDecl *, 4> Params;
+  if (getDerived().TransformFunctionTypeParams(E->getLocStart(),
+        E->getCallOperator()->param_begin(),
+        E->getCallOperator()->param_size(),
+        0, ParamTypes, &Params))
+    Invalid = true;  
+
   // Build the call operator.
   CXXMethodDecl *CallOperator
     = getSema().startLambdaDefinition(Class, E->getIntroducerRange(),
                                       MethodTy, 
-                                      E->getCallOperator()->getLocEnd());
+                                      E->getCallOperator()->getLocEnd(),
+                                      Params);
   getDerived().transformAttrs(E->getCallOperator(), CallOperator);
   
   // FIXME: Instantiation-specific.
@@ -7688,7 +7675,6 @@
                                  E->isMutable());
   
   // Transform captures.
-  bool Invalid = false;
   bool FinishedExplicitCaptures = false;
   for (LambdaExpr::capture_iterator C = E->capture_begin(), 
                                  CEnd = E->capture_end();
@@ -7706,6 +7692,49 @@
       continue;
     }
     
+    // Determine the capture kind for Sema.
+    Sema::TryCaptureKind Kind
+      = C->isImplicit()? Sema::TryCapture_Implicit
+                       : C->getCaptureKind() == LCK_ByCopy
+                           ? Sema::TryCapture_ExplicitByVal
+                           : Sema::TryCapture_ExplicitByRef;
+    SourceLocation EllipsisLoc;
+    if (C->isPackExpansion()) {
+      UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
+      bool ShouldExpand = false;
+      bool RetainExpansion = false;
+      llvm::Optional<unsigned> NumExpansions;
+      if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), 
+                                               C->getLocation(), 
+                                               Unexpanded,
+                                               ShouldExpand, RetainExpansion,
+                                               NumExpansions))
+        return ExprError();
+      
+      if (ShouldExpand) {
+        // The transform has determined that we should perform an expansion;
+        // transform and capture each of the arguments.
+        // expansion of the pattern. Do so.
+        VarDecl *Pack = C->getCapturedVar();
+        for (unsigned I = 0; I != *NumExpansions; ++I) {
+          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
+          VarDecl *CapturedVar
+            = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), 
+                                                               Pack));
+          if (!CapturedVar) {
+            Invalid = true;
+            continue;
+          }
+          
+          // Capture the transformed variable.
+          getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);          
+        }          
+        continue;
+      }
+      
+      EllipsisLoc = C->getEllipsisLoc();
+    }
+    
     // Transform the captured variable.
     VarDecl *CapturedVar
       = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), 
@@ -7714,28 +7743,13 @@
       Invalid = true;
       continue;
     }
-    
+  
     // Capture the transformed variable.
-    getSema().TryCaptureVar(CapturedVar, C->getLocation(),
-                            C->isImplicit()? Sema::TryCapture_Implicit
-                                           : C->getCaptureKind() == LCK_ByCopy
-                                             ? Sema::TryCapture_ExplicitByVal
-                                             : Sema::TryCapture_ExplicitByRef);
+    getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
   }
   if (!FinishedExplicitCaptures)
     getSema().finishLambdaExplicitCaptures(LSI);
 
-  // Transform lambda parameters.
-  llvm::SmallVector<QualType, 4> ParamTypes;
-  llvm::SmallVector<ParmVarDecl *, 4> Params;
-  if (!getDerived().TransformFunctionTypeParams(E->getLocStart(),
-         E->getCallOperator()->param_begin(),
-         E->getCallOperator()->param_size(),
-         0, ParamTypes, &Params))
-    getSema().addLambdaParameters(CallOperator, /*CurScope=*/0, Params);
-  else
-    Invalid = true;
-  
 
   // Enter a new evaluation context to insulate the lambda from any
   // cleanups from the enclosing full-expression.

Modified: cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp Mon Feb 20 19:34:24 2012
@@ -1050,6 +1050,7 @@
 void ASTDeclReader::ReadCXXDefinitionData(
                                    struct CXXRecordDecl::DefinitionData &Data,
                                    const RecordData &Record, unsigned &Idx) {
+  // Note: the caller has deserialized the IsLambda bit already.
   Data.UserDeclaredConstructor = Record[Idx++];
   Data.UserDeclaredCopyConstructor = Record[Idx++];
   Data.UserDeclaredMoveConstructor = Record[Idx++];
@@ -1097,6 +1098,25 @@
   Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx);
   assert(Data.Definition && "Data.Definition should be already set!");
   Data.FirstFriend = ReadDeclAs<FriendDecl>(Record, Idx);
+  
+  if (Data.IsLambda) {
+    typedef LambdaExpr::Capture Capture;
+    CXXRecordDecl::LambdaDefinitionData &Lambda
+      = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
+    Lambda.NumCaptures = Record[Idx++];
+    Lambda.NumExplicitCaptures = Record[Idx++];
+    Lambda.Captures 
+      = (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures);
+    Capture *ToCapture = Lambda.Captures;
+    for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
+      SourceLocation Loc = ReadSourceLocation(Record, Idx);
+      bool IsImplicit = Record[Idx++];
+      LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record[Idx++]);
+      VarDecl *Var = ReadDeclAs<VarDecl>(Record, Idx);
+      SourceLocation EllipsisLoc = ReadSourceLocation(Record, Idx);
+      *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc);
+    }
+  }
 }
 
 void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
@@ -1104,7 +1124,13 @@
 
   ASTContext &C = Reader.getContext();
   if (Record[Idx++]) {
-    D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
+    // Determine whether this is a lambda closure type, so that we can
+    // allocate the appropriate DefinitionData structure.
+    bool IsLambda = Record[Idx++];
+    if (IsLambda)
+      D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D);
+    else
+      D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
     
     // Propagate the DefinitionData pointer to the canonical declaration, so
     // that all other deserialized declarations will see it.
@@ -1180,6 +1206,8 @@
 void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
   VisitCXXMethodDecl(D);
   D->IsExplicitSpecified = Record[Idx++];
+  if (D->isLambdaToBlockPointerConversion())
+    D->setLambdaToBlockPointerCopyInit(Reader.ReadExpr(F));
 }
 
 void ASTDeclReader::VisitImportDecl(ImportDecl *D) {

Modified: cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp Mon Feb 20 19:34:24 2012
@@ -1050,7 +1050,31 @@
 
 void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
   VisitExpr(E);
-  assert(false && "Cannot deserialize lambda expressions yet");
+  unsigned NumCaptures = Record[Idx++];
+  assert(NumCaptures == E->NumCaptures);(void)NumCaptures;
+  unsigned NumArrayIndexVars = Record[Idx++];
+  E->IntroducerRange = ReadSourceRange(Record, Idx);
+  E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record[Idx++]);
+  E->ExplicitParams = Record[Idx++];
+  E->ExplicitResultType = Record[Idx++];
+  E->ClosingBrace = ReadSourceLocation(Record, Idx);
+  
+  // Read capture initializers.
+  for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
+                                      CEnd = E->capture_init_end();
+       C != CEnd; ++C)
+    *C = Reader.ReadSubExpr();
+  
+  // Read array capture index variables.
+  if (NumArrayIndexVars > 0) {
+    unsigned *ArrayIndexStarts = E->getArrayIndexStarts();
+    for (unsigned I = 0; I != NumCaptures + 1; ++I)
+      ArrayIndexStarts[I] = Record[Idx++];
+    
+    VarDecl **ArrayIndexVars = E->getArrayIndexVars();
+    for (unsigned I = 0; I != NumArrayIndexVars; ++I)
+      ArrayIndexVars[I] = ReadDeclAs<VarDecl>(Record, Idx);
+  }
 }
 
 void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
@@ -1143,27 +1167,24 @@
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
   E->GlobalNew = Record[Idx++];
-  E->Initializer = Record[Idx++];
-  E->UsualArrayDeleteWantsSize = Record[Idx++];
   bool isArray = Record[Idx++];
-  E->setHadMultipleCandidates(Record[Idx++]);
+  E->UsualArrayDeleteWantsSize = Record[Idx++];
   unsigned NumPlacementArgs = Record[Idx++];
-  unsigned NumCtorArgs = Record[Idx++];
+  E->StoredInitializationStyle = Record[Idx++];
   E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
   E->setOperatorDelete(ReadDeclAs<FunctionDecl>(Record, Idx));
-  E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
   E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx);
   SourceRange TypeIdParens;
   TypeIdParens.setBegin(ReadSourceLocation(Record, Idx));
   TypeIdParens.setEnd(ReadSourceLocation(Record, Idx));
   E->TypeIdParens = TypeIdParens;
   E->StartLoc = ReadSourceLocation(Record, Idx);
-  E->EndLoc = ReadSourceLocation(Record, Idx);
-  E->ConstructorLParen = ReadSourceLocation(Record, Idx);
-  E->ConstructorRParen = ReadSourceLocation(Record, Idx);
+  SourceRange DirectInitRange;
+  DirectInitRange.setBegin(ReadSourceLocation(Record, Idx));
+  DirectInitRange.setEnd(ReadSourceLocation(Record, Idx));
 
   E->AllocateArgsArray(Reader.getContext(), isArray, NumPlacementArgs,
-                       NumCtorArgs);
+                       E->StoredInitializationStyle != 0);
 
   // Install all the subexpressions.
   for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();
@@ -2083,6 +2104,14 @@
     case EXPR_ATOMIC:
       S = new (Context) AtomicExpr(Empty);
       break;
+        
+    case EXPR_LAMBDA: {
+      unsigned NumCaptures = Record[ASTStmtReader::NumExprFields];
+      unsigned NumArrayIndexVars = Record[ASTStmtReader::NumExprFields + 1];
+      S = LambdaExpr::CreateDeserialized(Context, NumCaptures, 
+                                         NumArrayIndexVars);
+      break;
+    }
     }
     
     // We hit a STMT_STOP, so we're done with this expression.

Modified: cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriter.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriter.cpp Mon Feb 20 19:34:24 2012
@@ -4274,6 +4274,7 @@
 void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) {
   assert(D->DefinitionData);
   struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+  Record.push_back(Data.IsLambda);
   Record.push_back(Data.UserDeclaredConstructor);
   Record.push_back(Data.UserDeclaredCopyConstructor);
   Record.push_back(Data.UserDeclaredMoveConstructor);
@@ -4325,6 +4326,24 @@
   AddUnresolvedSet(Data.VisibleConversions, Record);
   // Data.Definition is the owning decl, no need to write it. 
   AddDeclRef(Data.FirstFriend, Record);
+  
+  // Add lambda-specific data.
+  if (Data.IsLambda) {
+    CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData();
+    Record.push_back(Lambda.NumCaptures);
+    Record.push_back(Lambda.NumExplicitCaptures);
+    for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
+      LambdaExpr::Capture &Capture = Lambda.Captures[I];
+      AddSourceLocation(Capture.getLocation(), Record);
+      Record.push_back(Capture.isImplicit());
+      Record.push_back(Capture.getCaptureKind()); // FIXME: stable!
+      VarDecl *Var = Capture.capturesVariable()? Capture.getCapturedVar() : 0;
+      AddDeclRef(Var, Record);
+      AddSourceLocation(Capture.isPackExpansion()? Capture.getEllipsisLoc()
+                                                 : SourceLocation(), 
+                        Record);
+    }
+  }
 }
 
 void ASTWriter::ReaderInitialized(ASTReader *Reader) {

Modified: cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp Mon Feb 20 19:34:24 2012
@@ -961,6 +961,8 @@
 void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
   VisitCXXMethodDecl(D);
   Record.push_back(D->IsExplicitSpecified);
+  if (D->isLambdaToBlockPointerConversion())
+    Writer.AddStmt(D->getLambdaToBlockPointerCopyInit());
   Code = serialization::DECL_CXX_CONVERSION;
 }
 

Modified: cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp Mon Feb 20 19:34:24 2012
@@ -1024,7 +1024,34 @@
 
 void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
   VisitExpr(E);
-  assert(false && "Cannot serialize lambda expressions yet");
+  Record.push_back(E->NumCaptures);
+  unsigned NumArrayIndexVars = 0;
+  if (E->HasArrayIndexVars)
+    NumArrayIndexVars = E->getArrayIndexStarts()[E->NumCaptures];
+  Record.push_back(NumArrayIndexVars);
+  Writer.AddSourceRange(E->IntroducerRange, Record);
+  Record.push_back(E->CaptureDefault); // FIXME: stable encoding
+  Record.push_back(E->ExplicitParams);
+  Record.push_back(E->ExplicitResultType);
+  Writer.AddSourceLocation(E->ClosingBrace, Record);
+  
+  // Add capture initializers.
+  for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
+                                      CEnd = E->capture_init_end();
+       C != CEnd; ++C) {
+    Writer.AddStmt(*C);
+  }
+  
+  // Add array index variables, if any.
+  if (NumArrayIndexVars) {
+    Record.append(E->getArrayIndexStarts(), 
+                  E->getArrayIndexStarts() + E->NumCaptures + 1);
+    VarDecl **ArrayIndexVars = E->getArrayIndexVars();
+    for (unsigned I = 0; I != NumArrayIndexVars; ++I)
+      Writer.AddDeclRef(ArrayIndexVars[I], Record);
+  }
+  
+  Code = serialization::EXPR_LAMBDA;
 }
 
 void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
@@ -1131,25 +1158,20 @@
 void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
   VisitExpr(E);
   Record.push_back(E->isGlobalNew());
-  Record.push_back(E->hasInitializer());
-  Record.push_back(E->doesUsualArrayDeleteWantSize());
   Record.push_back(E->isArray());
-  Record.push_back(E->hadMultipleCandidates());
+  Record.push_back(E->doesUsualArrayDeleteWantSize());
   Record.push_back(E->getNumPlacementArgs());
-  Record.push_back(E->getNumConstructorArgs());
+  Record.push_back(E->StoredInitializationStyle);
   Writer.AddDeclRef(E->getOperatorNew(), Record);
   Writer.AddDeclRef(E->getOperatorDelete(), Record);
-  Writer.AddDeclRef(E->getConstructor(), Record);
   Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
   Writer.AddSourceRange(E->getTypeIdParens(), Record);
   Writer.AddSourceLocation(E->getStartLoc(), Record);
-  Writer.AddSourceLocation(E->getEndLoc(), Record);
-  Writer.AddSourceLocation(E->getConstructorLParen(), Record);
-  Writer.AddSourceLocation(E->getConstructorRParen(), Record);
+  Writer.AddSourceRange(E->getDirectInitRange(), Record);
   for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
        I != e; ++I)
     Writer.AddStmt(*I);
-  
+
   Code = serialization::EXPR_CXX_NEW;
 }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Mon Feb 20 19:34:24 2012
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "InterCheckerAPI.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
@@ -64,7 +65,8 @@
     checkRegionChanges(ProgramStateRef state,
                        const StoreManager::InvalidatedSymbols *,
                        ArrayRef<const MemRegion *> ExplicitRegions,
-                       ArrayRef<const MemRegion *> Regions) const;
+                       ArrayRef<const MemRegion *> Regions,
+                       const CallOrObjCMessage *Call) const;
 
   typedef void (CStringChecker::*FnCheck)(CheckerContext &,
                                           const CallExpr *) const;
@@ -825,7 +827,8 @@
 
     // Invalidate this region.
     unsigned Count = C.getCurrentBlockCount();
-    return state->invalidateRegions(R, E, Count);
+    const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
+    return state->invalidateRegions(R, E, Count, LCtx);
   }
 
   // If we have a non-region value by chance, just remove the binding.
@@ -955,7 +958,7 @@
         // conjure a return value for later.
         unsigned Count = C.getCurrentBlockCount();
         SVal result =
-          C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
+          C.getSValBuilder().getConjuredSymbolVal(NULL, CE, LCtx, Count);
         state = state->BindExpr(CE, LCtx, result);
       }
 
@@ -1075,7 +1078,7 @@
       if (state) {
         // The return value is the comparison result, which we don't know.
         unsigned Count = C.getCurrentBlockCount();
-        SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
+        SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, LCtx, Count);
         state = state->BindExpr(CE, LCtx, CmpV);
         C.addTransition(state);
       }
@@ -1182,7 +1185,7 @@
       // All we know is the return value is the min of the string length
       // and the limit. This is better than nothing.
       unsigned Count = C.getCurrentBlockCount();
-      result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
+      result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, LCtx, Count);
       NonLoc *resultNL = cast<NonLoc>(&result);
 
       if (strLengthNL) {
@@ -1210,7 +1213,7 @@
     // value, so it can be used in constraints, at least.
     if (result.isUnknown()) {
       unsigned Count = C.getCurrentBlockCount();
-      result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
+      result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, LCtx, Count);
     }
   }
 
@@ -1555,7 +1558,7 @@
   // overflow, we still need a result. Conjure a return value.
   if (returnEnd && Result.isUnknown()) {
     unsigned Count = C.getCurrentBlockCount();
-    Result = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
+    Result = svalBuilder.getConjuredSymbolVal(NULL, CE, LCtx, Count);
   }
 
   // Set the return value.
@@ -1701,7 +1704,7 @@
   if (!canComputeResult) {
     // Conjure a symbolic value. It's the best we can do.
     unsigned Count = C.getCurrentBlockCount();
-    SVal resultVal = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
+    SVal resultVal = svalBuilder.getConjuredSymbolVal(NULL, CE, LCtx, Count);
     state = state->BindExpr(CE, LCtx, resultVal);
   }
 
@@ -1714,31 +1717,47 @@
 //===----------------------------------------------------------------------===//
 
 bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
-  StringRef Name = C.getCalleeName(CE);
-  if (Name.empty())
-    return false;
-  if (Name.startswith("__builtin_"))
-    Name = Name.substr(10);
+  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
 
-  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
-    .Cases("memcpy", "__memcpy_chk", &CStringChecker::evalMemcpy)
-    .Cases("mempcpy", "__mempcpy_chk", &CStringChecker::evalMempcpy)
-    .Cases("memcmp", "bcmp", &CStringChecker::evalMemcmp)
-    .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove)
-    .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy)
-    .Cases("strncpy", "__strncpy_chk", &CStringChecker::evalStrncpy)
-    .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy)
-    .Cases("strcat", "__strcat_chk", &CStringChecker::evalStrcat)
-    .Cases("strncat", "__strncat_chk", &CStringChecker::evalStrncat)
-    .Case("strlen", &CStringChecker::evalstrLength)
-    .Case("strnlen", &CStringChecker::evalstrnLength)
-    .Case("strcmp", &CStringChecker::evalStrcmp)
-    .Case("strncmp", &CStringChecker::evalStrncmp)
-    .Case("strcasecmp", &CStringChecker::evalStrcasecmp)
-    .Case("strncasecmp", &CStringChecker::evalStrncasecmp)
-    .Case("bcopy", &CStringChecker::evalBcopy)
-    .Default(NULL);
+  if (!FDecl)
+    return false;
 
+  FnCheck evalFunction = 0;
+  if (C.isCLibraryFunction(FDecl, "memcpy"))
+    evalFunction =  &CStringChecker::evalMemcpy;
+  else if (C.isCLibraryFunction(FDecl, "mempcpy"))
+    evalFunction =  &CStringChecker::evalMempcpy;
+  else if (C.isCLibraryFunction(FDecl, "memcmp"))
+    evalFunction =  &CStringChecker::evalMemcmp;
+  else if (C.isCLibraryFunction(FDecl, "memmove"))
+    evalFunction =  &CStringChecker::evalMemmove;
+  else if (C.isCLibraryFunction(FDecl, "strcpy"))
+    evalFunction =  &CStringChecker::evalStrcpy;
+  else if (C.isCLibraryFunction(FDecl, "strncpy"))
+    evalFunction =  &CStringChecker::evalStrncpy;
+  else if (C.isCLibraryFunction(FDecl, "stpcpy"))
+    evalFunction =  &CStringChecker::evalStpcpy;
+  else if (C.isCLibraryFunction(FDecl, "strcat"))
+    evalFunction =  &CStringChecker::evalStrcat;
+  else if (C.isCLibraryFunction(FDecl, "strncat"))
+    evalFunction =  &CStringChecker::evalStrncat;
+  else if (C.isCLibraryFunction(FDecl, "strlen"))
+    evalFunction =  &CStringChecker::evalstrLength;
+  else if (C.isCLibraryFunction(FDecl, "strnlen"))
+    evalFunction =  &CStringChecker::evalstrnLength;
+  else if (C.isCLibraryFunction(FDecl, "strcmp"))
+    evalFunction =  &CStringChecker::evalStrcmp;
+  else if (C.isCLibraryFunction(FDecl, "strncmp"))
+    evalFunction =  &CStringChecker::evalStrncmp;
+  else if (C.isCLibraryFunction(FDecl, "strcasecmp"))
+    evalFunction =  &CStringChecker::evalStrcasecmp;
+  else if (C.isCLibraryFunction(FDecl, "strncasecmp"))
+    evalFunction =  &CStringChecker::evalStrncasecmp;
+  else if (C.isCLibraryFunction(FDecl, "bcopy"))
+    evalFunction =  &CStringChecker::evalBcopy;
+  else if (C.isCLibraryFunction(FDecl, "bcmp"))
+    evalFunction =  &CStringChecker::evalMemcmp;
+  
   // If the callee isn't a string function, let another checker handle it.
   if (!evalFunction)
     return false;
@@ -1807,7 +1826,8 @@
 CStringChecker::checkRegionChanges(ProgramStateRef state,
                                    const StoreManager::InvalidatedSymbols *,
                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                   ArrayRef<const MemRegion *> Regions) const {
+                                   ArrayRef<const MemRegion *> Regions,
+                                   const CallOrObjCMessage *Call) const {
   CStringLength::EntryMap Entries = state->get<CStringLength>();
   if (Entries.isEmpty())
     return state;
@@ -1906,3 +1926,7 @@
 REGISTER_CHECKER(CStringOutOfBounds)
 REGISTER_CHECKER(CStringBufferOverlap)
 REGISTER_CHECKER(CStringNotNullTerm)
+
+void ento::registerCStringCheckerBasic(CheckerManager &Mgr) {
+  registerCStringNullArg(Mgr);
+}

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Mon Feb 20 19:34:24 2012
@@ -32,6 +32,7 @@
   mutable OwningPtr<BugType> BT_call_undef;
   mutable OwningPtr<BugType> BT_call_arg;
   mutable OwningPtr<BugType> BT_msg_undef;
+  mutable OwningPtr<BugType> BT_objc_prop_undef;
   mutable OwningPtr<BugType> BT_msg_arg;
   mutable OwningPtr<BugType> BT_msg_ret;
 public:
@@ -228,11 +229,21 @@
     SVal recVal = state->getSVal(receiver, LCtx);
     if (recVal.isUndef()) {
       if (ExplodedNode *N = C.generateSink()) {
-        if (!BT_msg_undef)
-          BT_msg_undef.reset(new BuiltinBug("Receiver in message expression is "
-                                            "an uninitialized value"));
+        BugType *BT = 0;
+        if (msg.isPureMessageExpr()) {
+          if (!BT_msg_undef)
+            BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
+                                              "is an uninitialized value"));
+          BT = BT_msg_undef.get();
+        }
+        else {
+          if (!BT_objc_prop_undef)
+            BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
+                                              "uninitialized object pointer"));
+          BT = BT_objc_prop_undef.get();
+        }
         BugReport *R =
-          new BugReport(*BT_msg_undef, BT_msg_undef->getName(), N);
+          new BugReport(*BT, BT->getName(), N);
         R->addRange(receiver->getSourceRange());
         R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
                                                                    receiver));
@@ -306,13 +317,13 @@
   if (CanRetTy->isStructureOrClassType()) {
     // Structure returns are safe since the compiler zeroes them out.
     SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
-    C.addTransition(state->BindExpr(msg.getOriginExpr(), LCtx, V));
+    C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V));
     return;
   }
 
   // Other cases: check if sizeof(return type) > sizeof(void*)
   if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
-                                  .isConsumedExpr(msg.getOriginExpr())) {
+                                  .isConsumedExpr(msg.getMessageExpr())) {
     // Compute: sizeof(void *) and sizeof(return type)
     const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
     const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
@@ -343,7 +354,7 @@
     // of this case unless we have *a lot* more knowledge.
     //
     SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
-    C.addTransition(state->BindExpr(msg.getOriginExpr(), LCtx, V));
+    C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V));
     return;
   }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp Mon Feb 20 19:34:24 2012
@@ -184,13 +184,27 @@
   /// check::LiveSymbols
   void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}
 
-  /// check::RegionChanges
+
   bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
+  
+  /// check::RegionChanges
+  /// Allows tracking regions which get invalidated.
+  /// \param state The current program state.
+  /// \param invalidated A set of all symbols potentially touched by the change.
+  /// \param ExplicitRegions The regions explicitly requested for invalidation.
+  ///   For example, in the case of a function call, these would be arguments.
+  /// \param Regions The transitive closure of accessible regions,
+  ///   i.e. all regions that may have been touched by this change.
+  /// \param The call expression wrapper if the regions are invalidated by a
+  ///   call, 0 otherwise.
+  /// Note, in order to be notified, the checker should also implement 
+  /// wantsRegionChangeUpdate callback.
   ProgramStateRef 
     checkRegionChanges(ProgramStateRef State,
                        const StoreManager::InvalidatedSymbols *,
                        ArrayRef<const MemRegion *> ExplicitRegions,
-                       ArrayRef<const MemRegion *> Regions) const {
+                       ArrayRef<const MemRegion *> Regions,
+                       const CallOrObjCMessage *Call) const {
     return State;
   }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Mon Feb 20 19:34:24 2012
@@ -13,10 +13,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "InterCheckerAPI.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
@@ -66,24 +68,40 @@
   }
 };
 
+struct ReallocPair {
+  SymbolRef ReallocatedSym;
+  bool IsFreeOnFailure;
+  ReallocPair(SymbolRef S, bool F) : ReallocatedSym(S), IsFreeOnFailure(F) {}
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(IsFreeOnFailure);
+    ID.AddPointer(ReallocatedSym);
+  }
+  bool operator==(const ReallocPair &X) const {
+    return ReallocatedSym == X.ReallocatedSym &&
+           IsFreeOnFailure == X.IsFreeOnFailure;
+  }
+};
+
 class MallocChecker : public Checker<check::DeadSymbols,
                                      check::EndPath,
                                      check::PreStmt<ReturnStmt>,
+                                     check::PreStmt<CallExpr>,
                                      check::PostStmt<CallExpr>,
                                      check::Location,
                                      check::Bind,
                                      eval::Assume,
                                      check::RegionChanges>
 {
-  mutable OwningPtr<BuiltinBug> BT_DoubleFree;
-  mutable OwningPtr<BuiltinBug> BT_Leak;
-  mutable OwningPtr<BuiltinBug> BT_UseFree;
-  mutable OwningPtr<BuiltinBug> BT_UseRelinquished;
-  mutable OwningPtr<BuiltinBug> BT_BadFree;
-  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc;
+  mutable OwningPtr<BugType> BT_DoubleFree;
+  mutable OwningPtr<BugType> BT_Leak;
+  mutable OwningPtr<BugType> BT_UseFree;
+  mutable OwningPtr<BugType> BT_BadFree;
+  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
+                         *II_valloc, *II_reallocf;
 
 public:
-  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
+  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0),
+                    II_valloc(0), II_reallocf(0) {}
 
   /// In pessimistic mode, the checker assumes that it does not know which
   /// functions might free the memory.
@@ -94,8 +112,7 @@
 
   ChecksFilter Filter;
 
-  void initIdentifierInfo(CheckerContext &C) const;
-
+  void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
   void checkEndPath(CheckerContext &C) const;
@@ -110,12 +127,19 @@
   checkRegionChanges(ProgramStateRef state,
                      const StoreManager::InvalidatedSymbols *invalidated,
                      ArrayRef<const MemRegion *> ExplicitRegions,
-                     ArrayRef<const MemRegion *> Regions) const;
+                     ArrayRef<const MemRegion *> Regions,
+                     const CallOrObjCMessage *Call) const;
   bool wantsRegionChangeUpdate(ProgramStateRef state) const {
     return true;
   }
 
 private:
+  void initIdentifierInfo(ASTContext &C) const;
+
+  /// Check if this is one of the functions which can allocate/reallocate memory 
+  /// pointed to by one of its arguments.
+  bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
+
   static void MallocMem(CheckerContext &C, const CallExpr *CE);
   static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
                                    const OwnershipAttr* Att);
@@ -137,13 +161,18 @@
                                  ProgramStateRef state, unsigned Num,
                                  bool Hold) const;
 
-  void ReallocMem(CheckerContext &C, const CallExpr *CE) const;
+  void ReallocMem(CheckerContext &C, const CallExpr *CE,
+                  bool FreesMemOnFailure) const;
   static void CallocMem(CheckerContext &C, const CallExpr *CE);
   
   bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const;
   bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
                          const Stmt *S = 0) const;
 
+  /// Check if the function is not known to us. So, for example, we could
+  /// conservatively assume it can free/reallocate it's pointer arguments.
+  bool hasUnknownBehavior(const FunctionDecl *FD, ProgramStateRef State) const;
+
   static bool SummarizeValue(raw_ostream &os, SVal V);
   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
   void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
@@ -155,11 +184,18 @@
   /// region.
   class MallocBugVisitor : public BugReporterVisitor {
   protected:
+    enum NotificationMode {
+      Normal,
+      Complete,
+      ReallocationFailed
+    };
+
     // The allocated region symbol tracked by the main analysis.
     SymbolRef Sym;
+    NotificationMode Mode;
 
   public:
-    MallocBugVisitor(SymbolRef S) : Sym(S) {}
+    MallocBugVisitor(SymbolRef S) : Sym(S), Mode(Normal) {}
     virtual ~MallocBugVisitor() {}
 
     void Profile(llvm::FoldingSetNodeID &ID) const {
@@ -168,14 +204,28 @@
       ID.AddPointer(Sym);
     }
 
-    inline bool isAllocated(const RefState *S, const RefState *SPrev) {
+    inline bool isAllocated(const RefState *S, const RefState *SPrev,
+                            const Stmt *Stmt) {
       // Did not track -> allocated. Other state (released) -> allocated.
-      return ((S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
+      return (Stmt && isa<CallExpr>(Stmt) &&
+              (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
     }
 
-    inline bool isReleased(const RefState *S, const RefState *SPrev) {
+    inline bool isReleased(const RefState *S, const RefState *SPrev,
+                           const Stmt *Stmt) {
       // Did not track -> released. Other state (allocated) -> released.
-      return ((S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
+      return (Stmt && isa<CallExpr>(Stmt) &&
+              (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
+    }
+
+    inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
+                                     const Stmt *Stmt) {
+      // If the expression is not a call, and the state change is
+      // released -> allocated, it must be the realloc return value
+      // check. If we have to handle more cases here, it might be cleaner just
+      // to track this extra bit in the state itself.
+      return ((!Stmt || !isa<CallExpr>(Stmt)) &&
+              (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated()));
     }
 
     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
@@ -187,7 +237,7 @@
 } // end anonymous namespace
 
 typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
-typedef llvm::ImmutableMap<SymbolRef, SymbolRef> SymRefToSymRefTy;
+typedef llvm::ImmutableMap<SymbolRef, ReallocPair > ReallocMap;
 class RegionState {};
 class ReallocPairs {};
 namespace clang {
@@ -200,7 +250,7 @@
 
   template <>
   struct ProgramStateTrait<ReallocPairs>
-    : public ProgramStatePartialTrait<SymRefToSymRefTy> {
+    : public ProgramStatePartialTrait<ReallocMap> {
     static void *GDMIndex() { static int x; return &x; }
   };
 }
@@ -220,39 +270,67 @@
 };
 } // end anonymous namespace
 
-void MallocChecker::initIdentifierInfo(CheckerContext &C) const {
-  ASTContext &Ctx = C.getASTContext();
+void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
   if (!II_malloc)
     II_malloc = &Ctx.Idents.get("malloc");
   if (!II_free)
     II_free = &Ctx.Idents.get("free");
   if (!II_realloc)
     II_realloc = &Ctx.Idents.get("realloc");
+  if (!II_reallocf)
+    II_reallocf = &Ctx.Idents.get("reallocf");
   if (!II_calloc)
     II_calloc = &Ctx.Idents.get("calloc");
+  if (!II_valloc)
+    II_valloc = &Ctx.Idents.get("valloc");
+}
+
+bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
+  if (!FD)
+    return false;
+  IdentifierInfo *FunI = FD->getIdentifier();
+  if (!FunI)
+    return false;
+
+  initIdentifierInfo(C);
+
+  // TODO: Add more here : ex: reallocf!
+  if (FunI == II_malloc || FunI == II_free || FunI == II_realloc ||
+      FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc)
+    return true;
+
+  if (Filter.CMallocOptimistic && FD->hasAttrs() &&
+      FD->specific_attr_begin<OwnershipAttr>() !=
+          FD->specific_attr_end<OwnershipAttr>())
+    return true;
+
+
+  return false;
 }
 
 void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
   const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return;
-  initIdentifierInfo(C);
 
-  if (FD->getIdentifier() == II_malloc) {
+  initIdentifierInfo(C.getASTContext());
+  IdentifierInfo *FunI = FD->getIdentifier();
+  if (!FunI)
+    return;
+
+  if (FunI == II_malloc || FunI == II_valloc) {
     MallocMem(C, CE);
     return;
-  }
-  if (FD->getIdentifier() == II_realloc) {
-    ReallocMem(C, CE);
+  } else if (FunI == II_realloc) {
+    ReallocMem(C, CE, false);
     return;
-  }
-
-  if (FD->getIdentifier() == II_calloc) {
+  } else if (FunI == II_reallocf) {
+    ReallocMem(C, CE, true);
+    return;
+  } else if (FunI == II_calloc) {
     CallocMem(C, CE);
     return;
-  }
-
-  if (FD->getIdentifier() == II_free) {
+  }else if (FunI == II_free) {
     FreeMem(C, CE);
     return;
   }
@@ -278,42 +356,6 @@
       }
     }
   }
-
-  // Check use after free, when a freed pointer is passed to a call.
-  ProgramStateRef State = C.getState();
-  for (CallExpr::const_arg_iterator I = CE->arg_begin(),
-                                    E = CE->arg_end(); I != E; ++I) {
-    const Expr *A = *I;
-    if (A->getType().getTypePtr()->isAnyPointerType()) {
-      SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol();
-      if (!Sym)
-        continue;
-      if (checkUseAfterFree(Sym, C, A))
-        return;
-    }
-  }
-
-  // The pointer might escape through a function call.
-  // TODO: This should be rewritten to take into account inlining.
-  if (Filter.CMallocPessimistic) {
-    SourceLocation FLoc = FD->getLocation();
-    // We assume that the pointers cannot escape through calls to system
-    // functions.
-    if (C.getSourceManager().isInSystemHeader(FLoc))
-      return;
-
-    ProgramStateRef State = C.getState();
-    for (CallExpr::const_arg_iterator I = CE->arg_begin(),
-                                      E = CE->arg_end(); I != E; ++I) {
-      const Expr *A = *I;
-      if (A->getType().getTypePtr()->isAnyPointerType()) {
-        SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol();
-        if (!Sym)
-          continue;
-        checkEscape(Sym, A, C);
-      }
-    }
-  }
 }
 
 void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
@@ -348,6 +390,10 @@
   // Get the return value.
   SVal retVal = state->getSVal(CE, C.getLocationContext());
 
+  // We expect the malloc functions to return a pointer.
+  if (!isa<Loc>(retVal))
+    return 0;
+
   // Fill the region with the initialization value.
   state = state->bindDefault(retVal, Init);
 
@@ -473,10 +519,10 @@
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_DoubleFree)
         BT_DoubleFree.reset(
-          new BuiltinBug("Double free",
-                         "Try to free a memory block that has been released"));
+          new BugType("Double free", "Memory Error"));
       BugReport *R = new BugReport(*BT_DoubleFree, 
-                                   BT_DoubleFree->getDescription(), N);
+                        "Attempt to free released memory", N);
+      R->addRange(ArgExpr->getSourceRange());
       R->addVisitor(new MallocBugVisitor(Sym));
       C.EmitReport(R);
     }
@@ -580,7 +626,7 @@
                                   SourceRange range) const {
   if (ExplodedNode *N = C.generateSink()) {
     if (!BT_BadFree)
-      BT_BadFree.reset(new BuiltinBug("Bad free"));
+      BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
     
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
@@ -614,7 +660,8 @@
   }
 }
 
-void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
+void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE,
+                               bool FreesOnFail) const {
   ProgramStateRef state = C.getState();
   const Expr *arg0Expr = CE->getArg(0);
   const LocationContext *LCtx = C.getLocationContext();
@@ -679,7 +726,8 @@
       // The semantics of the return value are:
       // If size was equal to 0, either NULL or a pointer suitable to be passed
       // to free() is returned.
-      stateFree = stateFree->set<ReallocPairs>(ToPtr, FromPtr);
+      stateFree = stateFree->set<ReallocPairs>(ToPtr,
+                                            ReallocPair(FromPtr, FreesOnFail));
       C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
       C.addTransition(stateFree);
       return;
@@ -692,7 +740,8 @@
                                                 UnknownVal(), stateFree);
     if (!stateRealloc)
       return;
-    stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, FromPtr);
+    stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
+                                            ReallocPair(FromPtr, FreesOnFail));
     C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
     C.addTransition(stateRealloc);
     return;
@@ -716,8 +765,7 @@
                                CheckerContext &C) const {
   assert(N);
   if (!BT_Leak) {
-    BT_Leak.reset(new BuiltinBug("Memory leak",
-        "Allocated memory never released. Potential memory leak."));
+    BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
     // Leaks should not be reported if they are post-dominated by a sink:
     // (1) Sinks are higher importance bugs.
     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
@@ -726,7 +774,8 @@
     BT_Leak->setSuppressOnSink(true);
   }
 
-  BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
+  BugReport *R = new BugReport(*BT_Leak,
+                  "Memory is never released; potential memory leak", N);
   R->addVisitor(new MallocBugVisitor(Sym));
   C.EmitReport(R);
 }
@@ -756,9 +805,10 @@
   }
   
   // Cleanup the Realloc Pairs Map.
-  SymRefToSymRefTy RP = state->get<ReallocPairs>();
-  for (SymRefToSymRefTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
-    if (SymReaper.isDead(I->first) || SymReaper.isDead(I->second)) {
+  ReallocMap RP = state->get<ReallocPairs>();
+  for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
+    if (SymReaper.isDead(I->first) ||
+        SymReaper.isDead(I->second.ReallocatedSym)) {
       state = state->remove<ReallocPairs>(I->first);
     }
   }
@@ -802,6 +852,25 @@
   return false;
 }
 
+void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
+  if (isMemFunction(C.getCalleeDecl(CE), C.getASTContext()))
+    return;
+
+  // Check use after free, when a freed pointer is passed to a call.
+  ProgramStateRef State = C.getState();
+  for (CallExpr::const_arg_iterator I = CE->arg_begin(),
+                                    E = CE->arg_end(); I != E; ++I) {
+    const Expr *A = *I;
+    if (A->getType().getTypePtr()->isAnyPointerType()) {
+      SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol();
+      if (!Sym)
+        continue;
+      if (checkUseAfterFree(Sym, C, A))
+        return;
+    }
+  }
+}
+
 void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
   const Expr *E = S->getRetValue();
   if (!E)
@@ -813,11 +882,11 @@
     return;
 
   // Check if we are returning freed memory.
-  if (checkUseAfterFree(Sym, C, S))
+  if (checkUseAfterFree(Sym, C, E))
     return;
 
   // Check if the symbol is escaping.
-  checkEscape(Sym, S, C);
+  checkEscape(Sym, E, C);
 }
 
 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
@@ -827,10 +896,10 @@
   if (RS && RS->isReleased()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_UseFree)
-        BT_UseFree.reset(new BuiltinBug("Use of dynamically allocated memory "
-            "after it is freed."));
+        BT_UseFree.reset(new BugType("Use-after-free", "Memory Error"));
 
-      BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),N);
+      BugReport *R = new BugReport(*BT_UseFree,
+                                   "Use of memory after it is freed",N);
       if (S)
         R->addRange(S->getSourceRange());
       R->addVisitor(new MallocBugVisitor(Sym));
@@ -876,6 +945,12 @@
       // the binding).
       escapes = (state == (state->bindLoc(*regionLoc, val)));
     }
+    if (!escapes) {
+      // Case 4: We do not currently model what happens when a symbol is
+      // assigned to a struct field, so be conservative here and let the symbol
+      // go. TODO: This could definitely be improved upon.
+      escapes = !isa<VarRegion>(regionLoc->getRegion());
+    }
   }
 
   // If our store can represent the binding and we aren't storing to something
@@ -905,19 +980,17 @@
 
   // Realloc returns 0 when reallocation fails, which means that we should
   // restore the state of the pointer being reallocated.
-  SymRefToSymRefTy RP = state->get<ReallocPairs>();
-  for (SymRefToSymRefTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
+  ReallocMap RP = state->get<ReallocPairs>();
+  for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
     // If the symbol is assumed to NULL or another constant, this will
     // return an APSInt*.
     if (state->getSymVal(I.getKey())) {
-      const RefState *RS = state->get<RegionState>(I.getData());
+      SymbolRef ReallocSym = I.getData().ReallocatedSym;
+      const RefState *RS = state->get<RegionState>(ReallocSym);
       if (RS) {
-        if (RS->isReleased())
-          state = state->set<RegionState>(I.getData(),
+        if (RS->isReleased() && ! I.getData().IsFreeOnFailure)
+          state = state->set<RegionState>(ReallocSym,
                              RefState::getAllocateUnchecked(RS->getStmt()));
-        else if (RS->isAllocated())
-          state = state->set<RegionState>(I.getData(),
-                             RefState::getReleased(RS->getStmt()));
       }
       state = state->remove<ReallocPairs>(I.getKey());
     }
@@ -926,22 +999,55 @@
   return state;
 }
 
+// Check if the function is not known to us. So, for example, we could
+// conservatively assume it can free/reallocate it's pointer arguments.
+// (We assume that the pointers cannot escape through calls to system
+// functions not handled by this checker.)
+bool MallocChecker::hasUnknownBehavior(const FunctionDecl *FD,
+                                       ProgramStateRef State) const {
+  ASTContext &ASTC = State->getStateManager().getContext();
+
+  // If it's one of the allocation functions we can reason about, we model it's
+  // behavior explicitly.
+  if (isMemFunction(FD, ASTC)) {
+    return false;
+  }
+
+  // If it's a system call, we know it does not free the memory.
+  SourceManager &SM = ASTC.getSourceManager();
+  if (SM.isInSystemHeader(FD->getLocation())) {
+    return false;
+  }
+
+  // Otherwise, assume that the function can free memory.
+  return true;
+}
+
 // If the symbol we are tracking is invalidated, but not explicitly (ex: the &p
 // escapes, when we are tracking p), do not track the symbol as we cannot reason
 // about it anymore.
 ProgramStateRef
-MallocChecker::checkRegionChanges(ProgramStateRef state,
+MallocChecker::checkRegionChanges(ProgramStateRef State,
                             const StoreManager::InvalidatedSymbols *invalidated,
                                     ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions) const {
+                                    ArrayRef<const MemRegion *> Regions,
+                                    const CallOrObjCMessage *Call) const {
   if (!invalidated)
-    return state;
-
+    return State;
   llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
-  for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
-       E = ExplicitRegions.end(); I != E; ++I) {
-    if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
-      WhitelistedSymbols.insert(SR->getSymbol());
+
+  const FunctionDecl *FD = (Call ?
+                            dyn_cast_or_null<FunctionDecl>(Call->getDecl()) :0);
+
+  // If it's a call which might free or reallocate memory, we assume that all
+  // regions (explicit and implicit) escaped. Otherwise, whitelist explicit
+  // pointers; we still can track them.
+  if (!(FD && hasUnknownBehavior(FD, State))) {
+    for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
+        E = ExplicitRegions.end(); I != E; ++I) {
+      if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>())
+        WhitelistedSymbols.insert(R->getSymbol());
+    }
   }
 
   for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
@@ -949,10 +1055,11 @@
     SymbolRef sym = *I;
     if (WhitelistedSymbols.count(sym))
       continue;
-    // Don't track the symbol.
-    state = state->remove<RegionState>(sym);
+    // The symbol escaped.
+    if (const RefState *RS = State->get<RegionState>(sym))
+      State = State->set<RegionState>(sym, RefState::getEscaped(RS->getStmt()));
   }
-  return state;
+  return State;
 }
 
 PathDiagnosticPiece *
@@ -965,28 +1072,58 @@
   if (!RS && !RSPrev)
     return 0;
 
-  // We expect the interesting locations be StmtPoints corresponding to call
-  // expressions. We do not support indirect function calls as of now.
-  const CallExpr *CE = 0;
-  if (isa<StmtPoint>(N->getLocation()))
-    CE = dyn_cast<CallExpr>(cast<StmtPoint>(N->getLocation()).getStmt());
-  if (!CE)
-    return 0;
-  const FunctionDecl *funDecl = CE->getDirectCallee();
-  if (!funDecl)
+  const Stmt *S = 0;
+  const char *Msg = 0;
+
+  // Retrieve the associated statement.
+  ProgramPoint ProgLoc = N->getLocation();
+  if (isa<StmtPoint>(ProgLoc))
+    S = cast<StmtPoint>(ProgLoc).getStmt();
+  // If an assumption was made on a branch, it should be caught
+  // here by looking at the state transition.
+  if (isa<BlockEdge>(ProgLoc)) {
+    const CFGBlock *srcBlk = cast<BlockEdge>(ProgLoc).getSrc();
+    S = srcBlk->getTerminator();
+  }
+  if (!S)
     return 0;
 
   // Find out if this is an interesting point and what is the kind.
-  const char *Msg = 0;
-  if (isAllocated(RS, RSPrev))
-    Msg = "Memory is allocated here";
-  else if (isReleased(RS, RSPrev))
-    Msg = "Memory is released here";
+  if (Mode == Normal) {
+    if (isAllocated(RS, RSPrev, S))
+      Msg = "Memory is allocated";
+    else if (isReleased(RS, RSPrev, S))
+      Msg = "Memory is released";
+    else if (isReallocFailedCheck(RS, RSPrev, S)) {
+      Mode = ReallocationFailed;
+      Msg = "Reallocation failed";
+    }
+
+  // We are in a special mode if a reallocation failed later in the path.
+  } else if (Mode == ReallocationFailed) {
+    // Generate a special diagnostic for the first realloc we find.
+    if (!isAllocated(RS, RSPrev, S) && !isReleased(RS, RSPrev, S))
+      return 0;
+
+    // Check that the name of the function is realloc.
+    const CallExpr *CE = dyn_cast<CallExpr>(S);
+    if (!CE)
+      return 0;
+    const FunctionDecl *funDecl = CE->getDirectCallee();
+    if (!funDecl)
+      return 0;
+    StringRef FunName = funDecl->getName();
+    if (!(FunName.equals("realloc") || FunName.equals("reallocf")))
+      return 0;
+    Msg = "Attempt to reallocate memory";
+    Mode = Normal;
+  }
+
   if (!Msg)
     return 0;
 
   // Generate the extra diagnostic.
-  PathDiagnosticLocation Pos(CE, BRC.getSourceManager(),
+  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                              N->getLocationContext());
   return new PathDiagnosticEventPiece(Pos, Msg);
 }
@@ -994,6 +1131,7 @@
 
 #define REGISTER_CHECKER(name) \
 void ento::register##name(CheckerManager &mgr) {\
+  registerCStringCheckerBasic(mgr); \
   mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
 }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Mon Feb 20 19:34:24 2012
@@ -196,7 +196,7 @@
     // value out when we return from this method.
     state = state->set<CalledInit>(true);
     
-    SVal V = state->getSVal(msg.getOriginExpr(), C.getLocationContext());
+    SVal V = state->getSVal(msg.getMessageExpr(), C.getLocationContext());
     addSelfFlag(state, V, SelfFlag_InitRes, C);
     return;
   }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Mon Feb 20 19:34:24 2012
@@ -655,10 +655,11 @@
     ObjCMethodSummaries[S] = Summ;
   }
 
-  void addClassMethSummary(const char* Cls, const char* nullaryName,
-                           const RetainSummary *Summ) {
+  void addClassMethSummary(const char* Cls, const char* name,
+                           const RetainSummary *Summ, bool isNullary = true) {
     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
-    Selector S = GetNullarySelector(nullaryName, Ctx);
+    Selector S = isNullary ? GetNullarySelector(name, Ctx) 
+                           : GetUnarySelector(name, Ctx);
     ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
   }
 
@@ -1508,6 +1509,7 @@
   // Don't track allocated autorelease pools yet, as it is okay to prematurely
   // exit a method.
   addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
+  addClassMethSummary("NSAutoreleasePool", "allocWithZone", NoTrackYet, false);
 
   // Create summaries QCRenderer/QCView -createSnapShotImageOfType:
   addInstMethSummary("QCRenderer", AllocSumm,
@@ -2439,7 +2441,8 @@
   checkRegionChanges(ProgramStateRef state,
                      const StoreManager::InvalidatedSymbols *invalidated,
                      ArrayRef<const MemRegion *> ExplicitRegions,
-                     ArrayRef<const MemRegion *> Regions) const;
+                     ArrayRef<const MemRegion *> Regions,
+                     const CallOrObjCMessage *Call) const;
                                         
   bool wantsRegionChangeUpdate(ProgramStateRef state) const {
     return true;
@@ -3036,7 +3039,7 @@
     // If the receiver is unknown, conjure a return value.
     SValBuilder &SVB = C.getSValBuilder();
     unsigned Count = C.getCurrentBlockCount();
-    SVal RetVal = SVB.getConjuredSymbolVal(0, CE, ResultTy, Count);
+    SVal RetVal = SVB.getConjuredSymbolVal(0, CE, LCtx, ResultTy, Count);
   }
   state = state->BindExpr(CE, LCtx, RetVal, false);
 
@@ -3051,7 +3054,7 @@
 
     // Invalidate the argument region.
     unsigned Count = C.getCurrentBlockCount();
-    state = state->invalidateRegions(ArgRegion, CE, Count);
+    state = state->invalidateRegions(ArgRegion, CE, Count, LCtx);
 
     // Restore the refcount status of the argument.
     if (Binding)
@@ -3303,7 +3306,8 @@
 RetainCountChecker::checkRegionChanges(ProgramStateRef state,
                             const StoreManager::InvalidatedSymbols *invalidated,
                                     ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions) const {
+                                    ArrayRef<const MemRegion *> Regions,
+                                    const CallOrObjCMessage *Call) const {
   if (!invalidated)
     return state;
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp Mon Feb 20 19:34:24 2012
@@ -221,8 +221,9 @@
   ProgramStateRef state = C.getState();
   unsigned Count = C.getCurrentBlockCount();
   SValBuilder &svalBuilder = C.getSValBuilder();
+  const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
   DefinedSVal RetVal =
-    cast<DefinedSVal>(svalBuilder.getConjuredSymbolVal(0, CE, Count));
+    cast<DefinedSVal>(svalBuilder.getConjuredSymbolVal(0, CE, LCtx, Count));
   state = state->BindExpr(CE, C.getLocationContext(), RetVal);
   
   ConstraintManager &CM = C.getConstraintManager();

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Mon Feb 20 19:34:24 2012
@@ -85,26 +85,8 @@
 BugReporterVisitor::getDefaultEndPath(BugReporterContext &BRC,
                                       const ExplodedNode *EndPathNode,
                                       BugReport &BR) {
-  const ProgramPoint &PP = EndPathNode->getLocation();
-  PathDiagnosticLocation L;
-
-  if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&PP)) {
-    const CFGBlock *block = BE->getBlock();
-    if (block->getBlockID() == 0) {
-      L = PathDiagnosticLocation::createDeclEnd(PP.getLocationContext(),
-                                                BRC.getSourceManager());
-    }
-  }
-
-  if (!L.isValid()) {
-    const Stmt *S = BR.getStmt();
-
-    if (!S)
-      return NULL;
-
-    L = PathDiagnosticLocation(S, BRC.getSourceManager(),
-                                  PP.getLocationContext());
-  }
+  PathDiagnosticLocation L =
+    PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
 
   BugReport::ranges_iterator Beg, End;
   llvm::tie(Beg, End) = BR.getRanges();

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerContext.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerContext.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerContext.cpp Mon Feb 20 19:34:24 2012
@@ -60,10 +60,14 @@
     return false;
 
   StringRef FName = II->getName();
-  if (FName.startswith("__inline"))
-    return (FName.find(Name) != StringRef::npos);
+  if (FName.equals(Name))
+    return true;
+
+  if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos))
+    return true;
 
-  if (FD->isExternC() && FName.equals(Name))
+  if (FName.startswith("__") && FName.endswith("_chk") &&
+      FName.find(Name) != StringRef::npos)
     return true;
 
   return false;

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp Mon Feb 20 19:34:24 2012
@@ -190,8 +190,10 @@
                     NodeBuilder &Bldr, ExplodedNode *Pred) {
       ProgramPoint::Kind K =  IsPreVisit ? ProgramPoint::PreStmtKind :
                                            ProgramPoint::PostStmtKind;
-      const ProgramPoint &L = ProgramPoint::getProgramPoint(Msg.getOriginExpr(),
-                                K, Pred->getLocationContext(), checkFn.Checker);
+      const ProgramPoint &L =
+        ProgramPoint::getProgramPoint(Msg.getMessageExpr(),
+                                      K, Pred->getLocationContext(),
+                                      checkFn.Checker);
       CheckerContext C(Bldr, Eng, Pred, L);
 
       checkFn(Msg, C);
@@ -413,14 +415,15 @@
 CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
                             const StoreManager::InvalidatedSymbols *invalidated,
                                     ArrayRef<const MemRegion *> ExplicitRegions,
-                                          ArrayRef<const MemRegion *> Regions) {
+                                          ArrayRef<const MemRegion *> Regions,
+                                          const CallOrObjCMessage *Call) {
   for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
       return NULL;
     state = RegionChangesCheckers[i].CheckFn(state, invalidated, 
-                                             ExplicitRegions, Regions);
+                                             ExplicitRegions, Regions, Call);
   }
   return state;
 }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Feb 20 19:34:24 2012
@@ -239,8 +239,8 @@
                                                  ProgramStateRef InitState, 
                                                  ExplodedNodeSet &Dst) {
   ExecuteWorkList(L, Steps, InitState);
-  for (SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(), 
-                                           E = G->EndNodes.end(); I != E; ++I) {
+  for (ExplodedGraph::eop_iterator I = G->eop_begin(), 
+                                   E = G->eop_end(); I != E; ++I) {
     Dst.Add(*I);
   }
 }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp Mon Feb 20 19:34:24 2012
@@ -45,22 +45,12 @@
 // Cleanup.
 //===----------------------------------------------------------------------===//
 
-typedef std::vector<ExplodedNode*> NodeList;
-static inline NodeList*& getNodeList(void *&p) { return (NodeList*&) p; }
-
 static const unsigned CounterTop = 1000;
 
 ExplodedGraph::ExplodedGraph()
-  : NumNodes(0), recentlyAllocatedNodes(0),
-    freeNodes(0), reclaimNodes(false),
-    reclaimCounter(CounterTop) {}
-
-ExplodedGraph::~ExplodedGraph() {
-  if (reclaimNodes) {
-    delete getNodeList(recentlyAllocatedNodes);
-    delete getNodeList(freeNodes);
-  }
-}
+  : NumNodes(0), reclaimNodes(false), reclaimCounter(CounterTop) {}
+
+ExplodedGraph::~ExplodedGraph() {}
 
 //===----------------------------------------------------------------------===//
 // Node reclamation.
@@ -131,16 +121,14 @@
   ExplodedNode *succ = *(node->succ_begin());
   pred->replaceSuccessor(succ);
   succ->replacePredecessor(pred);
-  if (!freeNodes)
-    freeNodes = new NodeList();
-  getNodeList(freeNodes)->push_back(node);
+  FreeNodes.push_back(node);
   Nodes.RemoveNode(node);
   --NumNodes;
   node->~ExplodedNode();  
 }
 
 void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
-  if (!recentlyAllocatedNodes)
+  if (ChangedNodes.empty())
     return;
 
   // Only periodically relcaim nodes so that we can build up a set of
@@ -150,16 +138,14 @@
   if (--reclaimCounter != 0)
     return;
   reclaimCounter = CounterTop;
-  
-  NodeList &nl = *getNodeList(recentlyAllocatedNodes);
-  
-  for (NodeList::iterator i = nl.begin(), e = nl.end() ; i != e; ++i) {
-    ExplodedNode *node = *i;    
+
+  for (NodeVector::iterator it = ChangedNodes.begin(), et = ChangedNodes.end();
+       it != et; ++it) {
+    ExplodedNode *node = *it;
     if (shouldCollect(node))
       collectNode(node);
   }
-  
-  nl.clear();
+  ChangedNodes.clear();
 }
 
 //===----------------------------------------------------------------------===//
@@ -259,10 +245,9 @@
   NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
 
   if (!V) {
-    if (freeNodes && !getNodeList(freeNodes)->empty()) {
-      NodeList *nl = getNodeList(freeNodes);
-      V = nl->back();
-      nl->pop_back();
+    if (!FreeNodes.empty()) {
+      V = FreeNodes.back();
+      FreeNodes.pop_back();
     }
     else {
       // Allocate a new node.
@@ -271,15 +256,11 @@
 
     new (V) NodeTy(L, State, IsSink);
 
-    if (reclaimNodes) {
-      if (!recentlyAllocatedNodes)
-        recentlyAllocatedNodes = new NodeList();
-      getNodeList(recentlyAllocatedNodes)->push_back(V);
-    }
+    if (reclaimNodes)
+      ChangedNodes.push_back(V);
 
     // Insert the node into the node set and return it.
     Nodes.InsertNode(V, InsertPos);
-
     ++NumNodes;
 
     if (IsNew) *IsNew = true;

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Feb 20 19:34:24 2012
@@ -176,9 +176,10 @@
 ExprEngine::processRegionChanges(ProgramStateRef state,
                             const StoreManager::InvalidatedSymbols *invalidated,
                                  ArrayRef<const MemRegion *> Explicits,
-                                 ArrayRef<const MemRegion *> Regions) {
+                                 ArrayRef<const MemRegion *> Regions,
+                                 const CallOrObjCMessage *Call) {
   return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
-                                                         Explicits, Regions);
+                                                      Explicits, Regions, Call);
 }
 
 void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
@@ -589,9 +590,14 @@
     case Stmt::CXXBoolLiteralExprClass:
     case Stmt::FloatingLiteralClass:
     case Stmt::SizeOfPackExprClass:
-    case Stmt::CXXNullPtrLiteralExprClass:
-      // No-op. Simply propagate the current state unchanged.
+    case Stmt::CXXNullPtrLiteralExprClass: {
+      Bldr.takeNodes(Pred);
+      ExplodedNodeSet preVisit;
+      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
+      getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
+      Bldr.addNodes(Dst);
       break;
+    }
 
     case Stmt::ArraySubscriptExprClass:
       Bldr.takeNodes(Pred);
@@ -802,11 +808,33 @@
       Bldr.addNodes(Dst);
       break;
 
-    case Stmt::ObjCMessageExprClass:
+    case Stmt::ObjCMessageExprClass: {
       Bldr.takeNodes(Pred);
-      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
+      // Is this a property access?
+      const ParentMap &PM = Pred->getLocationContext()->getParentMap();
+      const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(S);
+      bool evaluated = false;
+      
+      if (const PseudoObjectExpr *PO =
+          dyn_cast_or_null<PseudoObjectExpr>(PM.getParent(S))) {
+        const Expr *syntactic = PO->getSyntacticForm();
+        if (const ObjCPropertyRefExpr *PR =
+              dyn_cast<ObjCPropertyRefExpr>(syntactic)) {
+          bool isSetter = ME->getNumArgs() > 0;
+          VisitObjCMessage(ObjCMessage(ME, PR, isSetter), Pred, Dst);
+          evaluated = true;
+        }
+        else if (isa<BinaryOperator>(syntactic)) {
+          VisitObjCMessage(ObjCMessage(ME, 0, true), Pred, Dst);
+        }
+      }
+      
+      if (!evaluated)
+        VisitObjCMessage(ME, Pred, Dst);
+
       Bldr.addNodes(Dst);
       break;
+    }
 
     case Stmt::ObjCAtThrowStmtClass: {
       // FIXME: This is not complete.  We basically treat @throw as
@@ -1433,9 +1461,7 @@
   const Expr *StoreE = AssignE ? AssignE : LocationE;
 
   if (isa<loc::ObjCPropRef>(location)) {
-    loc::ObjCPropRef prop = cast<loc::ObjCPropRef>(location);
-    return VisitObjCMessage(ObjCPropertySetter(prop.getPropRefExpr(),
-                                               StoreE, Val), Pred, Dst);
+    assert(false);
   }
 
   // Evaluate the location (checks for bad dereferences).
@@ -1460,9 +1486,7 @@
   assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
 
   if (isa<loc::ObjCPropRef>(location)) {
-    loc::ObjCPropRef prop = cast<loc::ObjCPropRef>(location);
-    return VisitObjCMessage(ObjCPropertyGetter(prop.getPropRefExpr(), Ex),
-                            Pred, Dst);
+    assert(false);
   }
 
   // Are we loading from a region?  This actually results in two loads; one

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineC.cpp Mon Feb 20 19:34:24 2012
@@ -46,7 +46,7 @@
       // FIXME: Handle structs.
       if (RightV.isUnknown()) {
         unsigned Count = currentBuilderContext->getCurrentBlockCount();
-        RightV = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), Count);
+        RightV = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LCtx, Count);
       }
       // Simulate the effects of a "store":  bind the value of the RHS
       // to the L-Value represented by the LHS.
@@ -131,8 +131,8 @@
         // The symbolic value is actually for the type of the left-hand side
         // expression, not the computation type, as this is the value the
         // LValue on the LHS will bind to.
-        LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LTy,
-                                                  Count);
+        LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LCtx,
+						  LTy, Count);
         
         // However, we need to convert the symbol to the computation type.
         Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
@@ -289,6 +289,7 @@
       case CK_NullToMemberPointer:
       case CK_BaseToDerivedMemberPointer:
       case CK_DerivedToBaseMemberPointer:
+      case CK_ReinterpretMemberPointer:
       case CK_UserDefinedConversion:
       case CK_ConstructorConversion:
       case CK_VectorSplat:
@@ -297,12 +298,10 @@
         QualType resultType = CastE->getType();
         if (CastE->isLValue())
           resultType = getContext().getPointerType(resultType);
-        
+        const LocationContext *LCtx = Pred->getLocationContext();
         SVal result =
-        svalBuilder.getConjuredSymbolVal(NULL, CastE, resultType,
+	  svalBuilder.getConjuredSymbolVal(NULL, CastE, LCtx, resultType,
                                currentBuilderContext->getCurrentBlockCount());
-        
-        const LocationContext *LCtx = Pred->getLocationContext();
         ProgramStateRef state = Pred->getState()->BindExpr(CastE, LCtx,
                                                                result);
         Bldr.generateNode(CastE, Pred, state);
@@ -375,7 +374,7 @@
       // Recover some path-sensitivity if a scalar value evaluated to
       // UnknownVal.
       if (InitVal.isUnknown()) {
-        InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx,
+        InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, LC,
                                  currentBuilderContext->getCurrentBlockCount());
       }
       B.takeNodes(N);
@@ -569,48 +568,34 @@
       break;
     case UO_Real: {
       const Expr *Ex = U->getSubExpr()->IgnoreParens();
-      ExplodedNodeSet Tmp;
-      Visit(Ex, Pred, Tmp);
-      
-      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
         
-        // FIXME: We don't have complex SValues yet.
-        if (Ex->getType()->isAnyComplexType()) {
-          // Just report "Unknown."
-          continue;
-        }
+      // FIXME: We don't have complex SValues yet.
+      if (Ex->getType()->isAnyComplexType()) {
+        // Just report "Unknown."
+        break;
+      }
         
-        // For all other types, UO_Real is an identity operation.
-        assert (U->getType() == Ex->getType());
-        ProgramStateRef state = (*I)->getState();
-        const LocationContext *LCtx = (*I)->getLocationContext();
-        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
+      // For all other types, UO_Real is an identity operation.
+      assert (U->getType() == Ex->getType());
+      ProgramStateRef state = Pred->getState();
+      const LocationContext *LCtx = Pred->getLocationContext();
+      Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
                                                  state->getSVal(Ex, LCtx)));
-      }
-      
       break;
     }
       
-    case UO_Imag: {
-      
+    case UO_Imag: {      
       const Expr *Ex = U->getSubExpr()->IgnoreParens();
-      ExplodedNodeSet Tmp;
-      Visit(Ex, Pred, Tmp);
-      
-      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-        // FIXME: We don't have complex SValues yet.
-        if (Ex->getType()->isAnyComplexType()) {
-          // Just report "Unknown."
-          continue;
-        }
-        
-        // For all other types, UO_Imag returns 0.
-        ProgramStateRef state = (*I)->getState();
-        const LocationContext *LCtx = (*I)->getLocationContext();
-        SVal X = svalBuilder.makeZeroVal(Ex->getType());
-        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
-      }
-      
+      // FIXME: We don't have complex SValues yet.
+      if (Ex->getType()->isAnyComplexType()) {
+        // Just report "Unknown."
+        break;
+      }
+      // For all other types, UO_Imag returns 0.
+      ProgramStateRef state = Pred->getState();
+      const LocationContext *LCtx = Pred->getLocationContext();
+      SVal X = svalBuilder.makeZeroVal(Ex->getType());
+      Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, X));
       break;
     }
       
@@ -620,23 +605,18 @@
     case UO_Deref:
     case UO_AddrOf:
     case UO_Extension: {
-      
+      // FIXME: We can probably just have some magic in Environment::getSVal()
+      // that propagates values, instead of creating a new node here.
+      //
       // Unary "+" is a no-op, similar to a parentheses.  We still have places
       // where it may be a block-level expression, so we need to
       // generate an extra node that just propagates the value of the
-      // subexpression.
-      
+      // subexpression.      
       const Expr *Ex = U->getSubExpr()->IgnoreParens();
-      ExplodedNodeSet Tmp;
-      Visit(Ex, Pred, Tmp);
-      
-      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-        ProgramStateRef state = (*I)->getState();
-        const LocationContext *LCtx = (*I)->getLocationContext();
-        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
+      ProgramStateRef state = Pred->getState();
+      const LocationContext *LCtx = Pred->getLocationContext();
+      Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
                                                  state->getSVal(Ex, LCtx)));
-      }
-      
       break;
     }
       
@@ -645,60 +625,49 @@
     case UO_Not: {
       assert (!U->isLValue());
       const Expr *Ex = U->getSubExpr()->IgnoreParens();
-      ExplodedNodeSet Tmp;
-      Visit(Ex, Pred, Tmp);
-      
-      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-        ProgramStateRef state = (*I)->getState();
-        const LocationContext *LCtx = (*I)->getLocationContext();
+      ProgramStateRef state = Pred->getState();
+      const LocationContext *LCtx = Pred->getLocationContext();
         
-        // Get the value of the subexpression.
-        SVal V = state->getSVal(Ex, LCtx);
+      // Get the value of the subexpression.
+      SVal V = state->getSVal(Ex, LCtx);
         
-        if (V.isUnknownOrUndef()) {
-          Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
-          continue;
-        }
-        
-        switch (U->getOpcode()) {
-          default:
-            llvm_unreachable("Invalid Opcode.");
-            
-          case UO_Not:
-            // FIXME: Do we need to handle promotions?
-            state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
-            break;
-            
-          case UO_Minus:
-            // FIXME: Do we need to handle promotions?
-            state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
-            break;
-            
-          case UO_LNot:
-            
-            // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
-            //
-            //  Note: technically we do "E == 0", but this is the same in the
-            //    transfer functions as "0 == E".
-            SVal Result;
-            
-            if (isa<Loc>(V)) {
-              Loc X = svalBuilder.makeNull();
-              Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
-                                 U->getType());
-            }
-            else {
-              nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
-              Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
-                                 U->getType());
-            }
-            
-            state = state->BindExpr(U, LCtx, Result);
-            
-            break;
-        }
-        Bldr.generateNode(U, *I, state);
+      if (V.isUnknownOrUndef()) {
+        Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, V));
+        break;
+      }
+        
+      switch (U->getOpcode()) {
+        default:
+          llvm_unreachable("Invalid Opcode.");
+        case UO_Not:
+          // FIXME: Do we need to handle promotions?
+          state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
+          break;
+        case UO_Minus:
+          // FIXME: Do we need to handle promotions?
+          state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
+          break;
+        case UO_LNot:
+          // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
+          //
+          //  Note: technically we do "E == 0", but this is the same in the
+          //    transfer functions as "0 == E".
+          SVal Result;          
+          if (isa<Loc>(V)) {
+            Loc X = svalBuilder.makeNull();
+            Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
+                               U->getType());
+          }
+          else {
+            nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
+            Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
+                               U->getType());
+          }
+          
+          state = state->BindExpr(U, LCtx, Result);          
+          break;
       }
+      Bldr.generateNode(U, Pred, state);
       break;
     }
   }
@@ -710,90 +679,85 @@
                                                  ExplodedNodeSet &Dst) {
   // Handle ++ and -- (both pre- and post-increment).
   assert (U->isIncrementDecrementOp());
-  ExplodedNodeSet Tmp;
   const Expr *Ex = U->getSubExpr()->IgnoreParens();
-  Visit(Ex, Pred, Tmp);
   
-  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
-    const LocationContext *LCtx = (*I)->getLocationContext();
-    ProgramStateRef state = (*I)->getState();
-    SVal loc = state->getSVal(Ex, LCtx);
-    
-    // Perform a load.
-    ExplodedNodeSet Tmp2;
-    evalLoad(Tmp2, Ex, *I, state, loc);
-    
-    ExplodedNodeSet Dst2;
-    StmtNodeBuilder Bldr(Tmp2, Dst2, *currentBuilderContext);
-    for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end();I2!=E2;++I2) {
-      
-      state = (*I2)->getState();
-      assert(LCtx == (*I2)->getLocationContext());
-      SVal V2_untested = state->getSVal(Ex, LCtx);
-      
-      // Propagate unknown and undefined values.
-      if (V2_untested.isUnknownOrUndef()) {
-        Bldr.generateNode(U, *I2, state->BindExpr(U, LCtx, V2_untested));
-        continue;
-      }
-      DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
-      
-      // Handle all other values.
-      BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add
-      : BO_Sub;
-      
-      // If the UnaryOperator has non-location type, use its type to create the
-      // constant value. If the UnaryOperator has location type, create the
-      // constant with int type and pointer width.
-      SVal RHS;
-      
-      if (U->getType()->isAnyPointerType())
-        RHS = svalBuilder.makeArrayIndex(1);
-      else
-        RHS = svalBuilder.makeIntVal(1, U->getType());
-      
-      SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
+  const LocationContext *LCtx = Pred->getLocationContext();
+  ProgramStateRef state = Pred->getState();
+  SVal loc = state->getSVal(Ex, LCtx);
+  
+  // Perform a load.
+  ExplodedNodeSet Tmp;
+  evalLoad(Tmp, Ex, Pred, state, loc);
+  
+  ExplodedNodeSet Dst2;
+  StmtNodeBuilder Bldr(Tmp, Dst2, *currentBuilderContext);
+  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
+    
+    state = (*I)->getState();
+    assert(LCtx == (*I)->getLocationContext());
+    SVal V2_untested = state->getSVal(Ex, LCtx);
+    
+    // Propagate unknown and undefined values.
+    if (V2_untested.isUnknownOrUndef()) {
+      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
+      continue;
+    }
+    DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
+    
+    // Handle all other values.
+    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
+    
+    // If the UnaryOperator has non-location type, use its type to create the
+    // constant value. If the UnaryOperator has location type, create the
+    // constant with int type and pointer width.
+    SVal RHS;
+    
+    if (U->getType()->isAnyPointerType())
+      RHS = svalBuilder.makeArrayIndex(1);
+    else
+      RHS = svalBuilder.makeIntVal(1, U->getType());
+    
+    SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
+    
+    // Conjure a new symbol if necessary to recover precision.
+    if (Result.isUnknown()){
+      DefinedOrUnknownSVal SymVal =
+	svalBuilder.getConjuredSymbolVal(NULL, Ex, LCtx,
+                               currentBuilderContext->getCurrentBlockCount());
+      Result = SymVal;
       
-      // Conjure a new symbol if necessary to recover precision.
-      if (Result.isUnknown()){
-        DefinedOrUnknownSVal SymVal =
-        svalBuilder.getConjuredSymbolVal(NULL, Ex,
-                                 currentBuilderContext->getCurrentBlockCount());
-        Result = SymVal;
-        
-        // If the value is a location, ++/-- should always preserve
-        // non-nullness.  Check if the original value was non-null, and if so
-        // propagate that constraint.
-        if (Loc::isLocType(U->getType())) {
-          DefinedOrUnknownSVal Constraint =
-          svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
+      // If the value is a location, ++/-- should always preserve
+      // non-nullness.  Check if the original value was non-null, and if so
+      // propagate that constraint.
+      if (Loc::isLocType(U->getType())) {
+        DefinedOrUnknownSVal Constraint =
+        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
+        
+        if (!state->assume(Constraint, true)) {
+          // It isn't feasible for the original value to be null.
+          // Propagate this constraint.
+          Constraint = svalBuilder.evalEQ(state, SymVal,
+                                       svalBuilder.makeZeroVal(U->getType()));
           
-          if (!state->assume(Constraint, true)) {
-            // It isn't feasible for the original value to be null.
-            // Propagate this constraint.
-            Constraint = svalBuilder.evalEQ(state, SymVal,
-                                         svalBuilder.makeZeroVal(U->getType()));
-            
-            
-            state = state->assume(Constraint, false);
-            assert(state);
-          }
+          
+          state = state->assume(Constraint, false);
+          assert(state);
         }
       }
-      
-      // Since the lvalue-to-rvalue conversion is explicit in the AST,
-      // we bind an l-value if the operator is prefix and an lvalue (in C++).
-      if (U->isLValue())
-        state = state->BindExpr(U, LCtx, loc);
-      else
-        state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
-      
-      // Perform the store.
-      Bldr.takeNodes(*I2);
-      ExplodedNodeSet Dst4;
-      evalStore(Dst4, NULL, U, *I2, state, loc, Result);
-      Bldr.addNodes(Dst4);
     }
-    Dst.insert(Dst2);
+    
+    // Since the lvalue-to-rvalue conversion is explicit in the AST,
+    // we bind an l-value if the operator is prefix and an lvalue (in C++).
+    if (U->isLValue())
+      state = state->BindExpr(U, LCtx, loc);
+    else
+      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
+    
+    // Perform the store.
+    Bldr.takeNodes(*I);
+    ExplodedNodeSet Dst3;
+    evalStore(Dst3, NULL, U, *I, state, loc, Result);
+    Bldr.addNodes(Dst3);
   }
+  Dst.insert(Dst2);
 }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Mon Feb 20 19:34:24 2012
@@ -251,8 +251,9 @@
   StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
   
   unsigned blockCount = currentBuilderContext->getCurrentBlockCount();
+  const LocationContext *LCtx = Pred->getLocationContext();
   DefinedOrUnknownSVal symVal =
-    svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), blockCount);
+    svalBuilder.getConjuredSymbolVal(NULL, CNE, LCtx, CNE->getType(), blockCount);
   const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();  
   QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
   const ElementRegion *EleReg = 
@@ -268,6 +269,8 @@
     return;
   }
 
+  // FIXME: Update for AST changes.
+#if 0
   // Evaluate constructor arguments.
   const FunctionProtoType *FnType = NULL;
   const CXXConstructorDecl *CD = CNE->getConstructor();
@@ -327,6 +330,7 @@
                             loc::MemRegionVal(EleReg));
     Bldr.generateNode(CNE, *I, state);
   }
+#endif
 }
 
 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Mon Feb 20 19:34:24 2012
@@ -304,7 +304,7 @@
   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
   //  global variables.
   return State->invalidateRegions(RegionsToInvalidate,
-                                  Call.getOriginExpr(), Count,
+                                  Call.getOriginExpr(), Count, LC,
                                   &IS, &Call);
 
 }
@@ -375,10 +375,10 @@
       // Conjure a symbol value to use as the result.
       SValBuilder &SVB = Eng.getSValBuilder();
       unsigned Count = Eng.currentBuilderContext->getCurrentBlockCount();
-      SVal RetVal = SVB.getConjuredSymbolVal(0, CE, ResultTy, Count);
+      const LocationContext *LCtx = Pred->getLocationContext();
+      SVal RetVal = SVB.getConjuredSymbolVal(0, CE, LCtx, ResultTy, Count);
 
       // Generate a new state with the return value set.
-      const LocationContext *LCtx = Pred->getLocationContext();
       state = state->BindExpr(CE, LCtx, RetVal);
 
       // Invalidate the arguments.

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp Mon Feb 20 19:34:24 2012
@@ -113,7 +113,7 @@
         QualType T = R->getValueType();
         assert(Loc::isLocType(T));
         unsigned Count = currentBuilderContext->getCurrentBlockCount();
-        SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count);
+        SymbolRef Sym = SymMgr.getConjuredSymbol(elem, LCtx, T, Count);
         SVal V = svalBuilder.makeLoc(Sym);
         hasElems = hasElems->bindLoc(elementV, V);
         
@@ -255,7 +255,8 @@
     QualType ResultTy = msg.getResultType(getContext());
     unsigned Count = currentBuilderContext->getCurrentBlockCount();
     const Expr *CurrentE = cast<Expr>(currentStmt);
-    ReturnValue = SVB.getConjuredSymbolVal(NULL, CurrentE, ResultTy, Count);
+    const LocationContext *LCtx = Pred->getLocationContext();
+    ReturnValue = SVB.getConjuredSymbolVal(NULL, CurrentE, LCtx, ResultTy, Count);
   }
 
   // Bind the return value.
@@ -266,7 +267,7 @@
   state = invalidateArguments(state, CallOrObjCMessage(msg, state, LCtx), LCtx);
 
   // And create the new node.
-  Bldr.generateNode(msg.getOriginExpr(), Pred, state, GenSink);
+  Bldr.generateNode(msg.getMessageExpr(), Pred, state, GenSink);
   assert(Bldr.hasGeneratedNodes());
 }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/MemRegion.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/MemRegion.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/MemRegion.cpp Mon Feb 20 19:34:24 2012
@@ -690,18 +690,24 @@
 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
                                      const LocationContext *LC) {
   const MemRegion *sReg = 0;
-
-  if (LC) {
-    // FIXME: Once we implement scope handling, we want the parent region
-    // to be the scope.
-    const StackFrameContext *STC = LC->getCurrentStackFrame();
-    assert(STC);
-    sReg = getStackLocalsRegion(STC);
+  const BlockDecl *BD = BC->getDecl();
+  if (!BD->hasCaptures()) {
+    // This handles 'static' blocks.
+    sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
   }
   else {
-    // We allow 'LC' to be NULL for cases where want BlockDataRegions
-    // without context-sensitivity.
-    sReg = getUnknownRegion();
+    if (LC) {
+      // FIXME: Once we implement scope handling, we want the parent region
+      // to be the scope.
+      const StackFrameContext *STC = LC->getCurrentStackFrame();
+      assert(STC);
+      sReg = getStackLocalsRegion(STC);
+    }
+    else {
+      // We allow 'LC' to be NULL for cases where want BlockDataRegions
+      // without context-sensitivity.
+      sReg = getUnknownRegion();
+    }
   }
 
   return getSubRegion<BlockDataRegion>(BC, LC, sReg);

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp Mon Feb 20 19:34:24 2012
@@ -18,104 +18,11 @@
 using namespace clang;
 using namespace ento;
 
-QualType ObjCMessage::getType(ASTContext &ctx) const {
-  assert(isValid() && "This ObjCMessage is uninitialized!");
-  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-    return msgE->getType();
-  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-  if (isPropertySetter())
-    return ctx.VoidTy;
-  return propE->getType();
-}
-
-Selector ObjCMessage::getSelector() const {
-  assert(isValid() && "This ObjCMessage is uninitialized!");
-  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-    return msgE->getSelector();
-  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-  if (isPropertySetter())
-    return propE->getSetterSelector();
-  return propE->getGetterSelector();
-}
-
-ObjCMethodFamily ObjCMessage::getMethodFamily() const {
-  assert(isValid() && "This ObjCMessage is uninitialized!");
-  // Case 1.  Explicit message send.
-  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-    return msgE->getMethodFamily();
-
-  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-
-  // Case 2.  Reference to implicit property.
-  if (propE->isImplicitProperty()) {
-    if (isPropertySetter())
-      return propE->getImplicitPropertySetter()->getMethodFamily();
-    else
-      return propE->getImplicitPropertyGetter()->getMethodFamily();
-  }
-
-  // Case 3.  Reference to explicit property.
-  const ObjCPropertyDecl *prop = propE->getExplicitProperty();
-  if (isPropertySetter()) {
-    if (prop->getSetterMethodDecl())
-      return prop->getSetterMethodDecl()->getMethodFamily();
-    return prop->getSetterName().getMethodFamily();
-  } else {
-    if (prop->getGetterMethodDecl())
-      return prop->getGetterMethodDecl()->getMethodFamily();
-    return prop->getGetterName().getMethodFamily();
-  }
-}
-
-const ObjCMethodDecl *ObjCMessage::getMethodDecl() const {
-  assert(isValid() && "This ObjCMessage is uninitialized!");
-  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-    return msgE->getMethodDecl();
-  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-  if (propE->isImplicitProperty())
-    return isPropertySetter() ? propE->getImplicitPropertySetter()
-                              : propE->getImplicitPropertyGetter();
-  return 0;
-}
-
-const ObjCInterfaceDecl *ObjCMessage::getReceiverInterface() const {
-  assert(isValid() && "This ObjCMessage is uninitialized!");
-  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-    return msgE->getReceiverInterface();
-  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
-  if (propE->isClassReceiver())
-    return propE->getClassReceiver();
-  QualType recT;
-  if (const Expr *recE = getInstanceReceiver())
-    recT = recE->getType();
-  else {
-    assert(propE->isSuperReceiver());
-    recT = propE->getSuperReceiverType();
-  }
-  if (const ObjCObjectPointerType *Ptr = recT->getAs<ObjCObjectPointerType>())
-    return Ptr->getInterfaceDecl();
-  return 0;
-}
-
-const Expr *ObjCMessage::getArgExpr(unsigned i) const {
-  assert(isValid() && "This ObjCMessage is uninitialized!");
-  assert(i < getNumArgs() && "Invalid index for argument");
-  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
-    return msgE->getArg(i);
-  assert(isPropertySetter());
-  if (const BinaryOperator *bop = dyn_cast<BinaryOperator>(OriginE))
-    if (bop->isAssignmentOp())
-      return bop->getRHS();
-  return 0;
-}
-
 QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const {
   QualType resultTy;
   bool isLVal = false;
 
   if (isObjCMessage()) {
-    isLVal = isa<ObjCMessageExpr>(Msg.getOriginExpr()) &&
-             Msg.getOriginExpr()->isLValue();
     resultTy = Msg.getResultType(ctx);
   } else if (const CXXConstructExpr *Ctor =
               CallE.dyn_cast<const CXXConstructExpr *>()) {

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Mon Feb 20 19:34:24 2012
@@ -305,8 +305,9 @@
       return PathDiagnosticLocation(PS->getStmt(), SM, LC);
     else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
       const Stmt *Term = BE->getSrc()->getTerminator();
-      assert(Term);
-      return PathDiagnosticLocation(Term, SM, LC);
+      if (Term) {
+        return PathDiagnosticLocation(Term, SM, LC);
+      }
     }
     NI = NI->succ_empty() ? 0 : *(NI->succ_begin());
   }

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp Mon Feb 20 19:34:24 2012
@@ -155,19 +155,21 @@
 ProgramStateRef 
 ProgramState::invalidateRegions(ArrayRef<const MemRegion *> Regions,
                                 const Expr *E, unsigned Count,
+                                const LocationContext *LCtx,
                                 StoreManager::InvalidatedSymbols *IS,
                                 const CallOrObjCMessage *Call) const {
   if (!IS) {
     StoreManager::InvalidatedSymbols invalidated;
-    return invalidateRegionsImpl(Regions, E, Count,
+    return invalidateRegionsImpl(Regions, E, Count, LCtx,
                                  invalidated, Call);
   }
-  return invalidateRegionsImpl(Regions, E, Count, *IS, Call);
+  return invalidateRegionsImpl(Regions, E, Count, LCtx, *IS, Call);
 }
 
 ProgramStateRef 
 ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
                                     const Expr *E, unsigned Count,
+                                    const LocationContext *LCtx,
                                     StoreManager::InvalidatedSymbols &IS,
                                     const CallOrObjCMessage *Call) const {
   ProgramStateManager &Mgr = getStateManager();
@@ -176,14 +178,14 @@
   if (Eng && Eng->wantsRegionChangeUpdate(this)) {
     StoreManager::InvalidatedRegions Invalidated;
     const StoreRef &newStore
-      = Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, IS,
+      = Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, LCtx, IS,
                                         Call, &Invalidated);
     ProgramStateRef newState = makeWithStore(newStore);
-    return Eng->processRegionChanges(newState, &IS, Regions, Invalidated);
+    return Eng->processRegionChanges(newState, &IS, Regions, Invalidated, Call);
   }
 
   const StoreRef &newStore =
-    Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, IS,
+    Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, LCtx, IS,
                                     Call, NULL);
   return makeWithStore(newStore);
 }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp Mon Feb 20 19:34:24 2012
@@ -239,11 +239,13 @@
   RegionBindings invalidateGlobalRegion(MemRegion::Kind K,
                                         const Expr *Ex,
                                         unsigned Count,
+                                        const LocationContext *LCtx,
                                         RegionBindings B,
                                         InvalidatedRegions *Invalidated);
 
   StoreRef invalidateRegions(Store store, ArrayRef<const MemRegion *> Regions,
                              const Expr *E, unsigned Count,
+                             const LocationContext *LCtx,
                              InvalidatedSymbols &IS,
                              const CallOrObjCMessage *Call,
                              InvalidatedRegions *Invalidated);
@@ -594,6 +596,7 @@
 {
   const Expr *Ex;
   unsigned Count;
+  const LocationContext *LCtx;
   StoreManager::InvalidatedSymbols &IS;
   StoreManager::InvalidatedRegions *Regions;
 public:
@@ -601,11 +604,12 @@
                           ProgramStateManager &stateMgr,
                           RegionBindings b,
                           const Expr *ex, unsigned count,
+                          const LocationContext *lctx,
                           StoreManager::InvalidatedSymbols &is,
                           StoreManager::InvalidatedRegions *r,
                           bool includeGlobals)
     : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, includeGlobals),
-      Ex(ex), Count(count), IS(is), Regions(r) {}
+      Ex(ex), Count(count), LCtx(lctx), IS(is), Regions(r) {}
 
   void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
   void VisitBaseRegion(const MemRegion *baseR);
@@ -681,7 +685,7 @@
     // Invalidate the region by setting its default value to
     // conjured symbol. The type of the symbol is irrelavant.
     DefinedOrUnknownSVal V =
-      svalBuilder.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy, Count);
+      svalBuilder.getConjuredSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
     B = RM.addBinding(B, baseR, BindingKey::Default, V);
     return;
   }
@@ -697,7 +701,7 @@
     // Invalidate the region by setting its default value to
     // conjured symbol. The type of the symbol is irrelavant.
     DefinedOrUnknownSVal V =
-      svalBuilder.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy, Count);
+      svalBuilder.getConjuredSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
     B = RM.addBinding(B, baseR, BindingKey::Default, V);
     return;
   }
@@ -705,7 +709,8 @@
   if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
       // Set the default value of the array to conjured symbol.
     DefinedOrUnknownSVal V =
-    svalBuilder.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count);
+    svalBuilder.getConjuredSymbolVal(baseR, Ex, LCtx,
+                                     AT->getElementType(), Count);
     B = RM.addBinding(B, baseR, BindingKey::Default, V);
     return;
   }
@@ -720,7 +725,8 @@
   }
   
 
-  DefinedOrUnknownSVal V = svalBuilder.getConjuredSymbolVal(baseR, Ex, T,Count);
+  DefinedOrUnknownSVal V = svalBuilder.getConjuredSymbolVal(baseR, Ex, LCtx,
+                                                            T,Count);
   assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
   B = RM.addBinding(B, baseR, BindingKey::Direct, V);
 }
@@ -728,13 +734,14 @@
 RegionBindings RegionStoreManager::invalidateGlobalRegion(MemRegion::Kind K,
                                                           const Expr *Ex,
                                                           unsigned Count,
+                                                    const LocationContext *LCtx,
                                                           RegionBindings B,
                                             InvalidatedRegions *Invalidated) {
   // Bind the globals memory space to a new symbol that we will use to derive
   // the bindings for all globals.
   const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(K);
   SVal V =
-      svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex,
+      svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex, LCtx,
           /* symbol type, doesn't matter */ Ctx.IntTy,
           Count);
 
@@ -752,12 +759,13 @@
 StoreRef RegionStoreManager::invalidateRegions(Store store,
                                             ArrayRef<const MemRegion *> Regions,
                                                const Expr *Ex, unsigned Count,
+                                               const LocationContext *LCtx,
                                                InvalidatedSymbols &IS,
                                                const CallOrObjCMessage *Call,
                                               InvalidatedRegions *Invalidated) {
   invalidateRegionsWorker W(*this, StateMgr,
                             RegionStoreManager::GetRegionBindings(store),
-                            Ex, Count, IS, Invalidated, false);
+                            Ex, Count, LCtx, IS, Invalidated, false);
 
   // Scan the bindings and generate the clusters.
   W.GenerateClusters();
@@ -779,13 +787,13 @@
   // System calls invalidate only system globals.
   if (Call && Call->isInSystemHeader()) {
     B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
-                               Ex, Count, B, Invalidated);
+                               Ex, Count, LCtx, B, Invalidated);
   // Internal calls might invalidate both system and internal globals.
   } else {
     B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
-                               Ex, Count, B, Invalidated);
+                               Ex, Count, LCtx, B, Invalidated);
     B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
-                               Ex, Count, B, Invalidated);
+                               Ex, Count, LCtx, B, Invalidated);
   }
 
   return StoreRef(B.getRootWithoutRetain(), *this);

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp Mon Feb 20 19:34:24 2012
@@ -108,19 +108,21 @@
 
 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag,
                                                        const Expr *expr,
+						       const LocationContext *LCtx,
                                                        unsigned count) {
   QualType T = expr->getType();
-  return getConjuredSymbolVal(symbolTag, expr, T, count);
+  return getConjuredSymbolVal(symbolTag, expr, LCtx, T, count);
 }
 
 DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *symbolTag,
                                                        const Expr *expr,
+						       const LocationContext *LCtx,
                                                        QualType type,
                                                        unsigned count) {
   if (!SymbolManager::canSymbolicate(type))
     return UnknownVal();
 
-  SymbolRef sym = SymMgr.getConjuredSymbol(expr, type, count, symbolTag);
+  SymbolRef sym = SymMgr.getConjuredSymbol(expr, LCtx, type, count, symbolTag);
 
   if (Loc::isLocType(type))
     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/SymbolManager.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/SymbolManager.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/SymbolManager.cpp Mon Feb 20 19:34:24 2012
@@ -181,16 +181,17 @@
 }
 
 const SymbolConjured*
-SymbolManager::getConjuredSymbol(const Stmt *E, QualType T, unsigned Count,
+SymbolManager::getConjuredSymbol(const Stmt *E, const LocationContext *LCtx,
+                                 QualType T, unsigned Count,
                                  const void *SymbolTag) {
 
   llvm::FoldingSetNodeID profile;
-  SymbolConjured::Profile(profile, E, T, Count, SymbolTag);
+  SymbolConjured::Profile(profile, E, T, Count, LCtx, SymbolTag);
   void *InsertPos;
   SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
   if (!SD) {
     SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>();
-    new (SD) SymbolConjured(SymbolCounter, E, T, Count, SymbolTag);
+    new (SD) SymbolConjured(SymbolCounter, E, LCtx, T, Count, SymbolTag);
     DataSet.InsertNode(SD, InsertPos);
     ++SymbolCounter;
   }

Modified: cfe/branches/tooling/test/Analysis/malloc-annotations.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/malloc-annotations.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/malloc-annotations.c (original)
+++ cfe/branches/tooling/test/Analysis/malloc-annotations.c Mon Feb 20 19:34:24 2012
@@ -24,19 +24,19 @@
 
 void f1() {
   int *p = malloc(12);
-  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  return; // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void f2() {
   int *p = malloc(12);
   free(p);
-  free(p); // expected-warning{{Try to free a memory block that has been released}}
+  free(p); // expected-warning{{Attempt to free released memory}}
 }
 
 void f2_realloc_0() {
   int *p = malloc(12);
   realloc(p,0);
-  realloc(p,0); // expected-warning{{Try to free a memory block that has been released}}
+  realloc(p,0); // expected-warning{{Attempt to free released memory}}
 }
 
 void f2_realloc_1() {
@@ -52,25 +52,26 @@
 
 void n2af1() {
   int *p = my_malloc2(12);
-  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  return; // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void af1() {
   int *p = my_malloc(12);
-  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  return; // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void af1_b() {
-  int *p = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  int *p = my_malloc(12); // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void af1_c() {
   myglobalpointer = my_malloc(12); // no-warning
 }
 
+// TODO: We will be able to handle this after we add support for tracking allocations stored in struct fields.
 void af1_d() {
   struct stuff mystuff;
-  mystuff.somefield = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  mystuff.somefield = my_malloc(12); // false negative
 }
 
 // Test that we can pass out allocated memory via pointer-to-pointer.
@@ -91,25 +92,25 @@
 void af2() {
   int *p = my_malloc(12);
   my_free(p);
-  free(p); // expected-warning{{Try to free a memory block that has been released}}
+  free(p); // expected-warning{{Attempt to free released memory}}
 }
 
 void af2b() {
   int *p = my_malloc(12);
   free(p);
-  my_free(p); // expected-warning{{Try to free a memory block that has been released}}
+  my_free(p); // expected-warning{{Attempt to free released memory}}
 }
 
 void af2c() {
   int *p = my_malloc(12);
   free(p);
-  my_hold(p); // expected-warning{{Try to free a memory block that has been released}}
+  my_hold(p); // expected-warning{{Attempt to free released memory}}
 }
 
 void af2d() {
   int *p = my_malloc(12);
   free(p);
-  my_hold2(0, 0, p); // expected-warning{{Try to free a memory block that has been released}}
+  my_hold2(0, 0, p); // expected-warning{{Attempt to free released memory}}
 }
 
 // No leak if malloc returns null.
@@ -131,7 +132,7 @@
 int * af4() {
   int *p = my_malloc(12);
   my_free(p);
-  return p; // expected-warning{{Use of dynamically allocated}}
+  return p; // expected-warning{{Use of memory after it is freed}}
 }
 
 // This case is (possibly) ok, be conservative
@@ -197,13 +198,13 @@
 void f7() {
   char *x = (char*) malloc(4);
   free(x);
-  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+  x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
 }
 
 void f7_realloc() {
   char *x = (char*) malloc(4);
   realloc(x,0);
-  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+  x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
 }
 
 void PR6123() {

Modified: cfe/branches/tooling/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/malloc.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/malloc.c (original)
+++ cfe/branches/tooling/test/Analysis/malloc.c Mon Feb 20 19:34:24 2012
@@ -3,28 +3,31 @@
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
+void *valloc(size_t);
 void free(void *);
 void *realloc(void *ptr, size_t size);
+void *reallocf(void *ptr, size_t size);
 void *calloc(size_t nmemb, size_t size);
 
 void myfoo(int *p);
 void myfooint(int p);
+char *fooRetPtr();
 
 void f1() {
   int *p = malloc(12);
-  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  return; // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void f2() {
   int *p = malloc(12);
   free(p);
-  free(p); // expected-warning{{Try to free a memory block that has been released}}
+  free(p); // expected-warning{{Attempt to free released memory}}
 }
 
 void f2_realloc_0() {
   int *p = malloc(12);
   realloc(p,0);
-  realloc(p,0); // expected-warning{{Try to free a memory block that has been released}}
+  realloc(p,0); // expected-warning{{Attempt to free released memory}}
 }
 
 void f2_realloc_1() {
@@ -37,7 +40,7 @@
   char *p = (char*)malloc(size);
   if (p) {
     char *q = (char*)realloc(p, sizeIn);
-    char x = *q; // expected-warning {{Allocated memory never released.}}
+    char x = *q; // expected-warning {{Memory is never released; potential memory leak}}
   }
 }
 
@@ -76,7 +79,7 @@
   } else {
     free(r);
   }
-  free(p); // expected-warning {{Try to free a memory block that has been released}}
+  free(p); // expected-warning {{Attempt to free released memory}}
 }
 
 void reallocSizeZero3() {
@@ -95,7 +98,7 @@
 }
 
 void reallocPtrZero1() {
-  char *r = realloc(0, 12); // expected-warning {{Allocated memory never released.}}
+  char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential memory leak}}
 }
 
 void reallocPtrZero2() {
@@ -113,7 +116,7 @@
     char *buf = malloc(100);
     buf = (char*)realloc(buf, 0x1000000);
     if (!buf) {
-        return;// expected-warning {{Allocated memory never released.}}
+        return;// expected-warning {{Memory is never released; potential memory leak}}
     }
     free(buf);
 }
@@ -121,7 +124,7 @@
 void reallocRadar6337483_2() {
     char *buf = malloc(100);
     char *buf2 = (char*)realloc(buf, 0x1000000);
-    if (!buf2) { // expected-warning {{Allocated memory never released.}}
+    if (!buf2) { // expected-warning {{Memory is never released; potential memory leak}}
       ;
     } else {
       free(buf2);
@@ -144,12 +147,45 @@
     char *buf = malloc(100);
     char *buf2 = (char*)realloc(buf, 0x1000000);
     if (!buf2) {
-      return;  // expected-warning {{Allocated memory never released.}}
+      return;  // expected-warning {{Memory is never released; potential memory leak}}
     } else {
       free(buf2);
     }
 }
 
+int *reallocfTest1() {
+  int *q = malloc(12);
+  q = reallocf(q, 20);
+  return q; // no warning - returning the allocated value
+}
+
+void reallocfRadar6337483_4() {
+    char *buf = malloc(100);
+    char *buf2 = (char*)reallocf(buf, 0x1000000);
+    if (!buf2) {
+      return;  // no warning - reallocf frees even on failure
+    } else {
+      free(buf2);
+    }
+}
+
+void reallocfRadar6337483_3() {
+    char * buf = malloc(100);
+    char * tmp;
+    tmp = (char*)reallocf(buf, 0x1000000);
+    if (!tmp) {
+        free(buf); // expected-warning {{Attempt to free released memory}}
+        return;
+    }
+    buf = tmp;
+    free(buf);
+}
+
+void reallocfPtrZero1() {
+  char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential memory leak}}
+}
+
+
 // This case tests that storing malloc'ed memory to a static variable which is
 // then returned is not leaked.  In the absence of known contracts for functions
 // or inter-procedural analysis, this is a conservative answer.
@@ -204,13 +240,13 @@
 void f7() {
   char *x = (char*) malloc(4);
   free(x);
-  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+  x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
 }
 
 void f7_realloc() {
   char *x = (char*) malloc(4);
   realloc(x,0);
-  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+  x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
 }
 
 void PR6123() {
@@ -299,14 +335,14 @@
   int *p = malloc(12);
   myfoo(p);
   free(p);
-  free(p); // expected-warning{{Try to free a memory block that has been released}}
+  free(p); // expected-warning{{Attempt to free released memory}}
 }
 
 void mallocEscapeFreeUse() {
   int *p = malloc(12);
   myfoo(p);
   free(p);
-  myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+  myfoo(p); // expected-warning{{Use of memory after it is freed}}
 }
 
 int *myalloc();
@@ -332,18 +368,18 @@
   int *x = malloc(12);
   int *y = x;
   free(y);
-  myfoo(x); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+  myfoo(x); // expected-warning{{Use of memory after it is freed}}
 }
 
 void mallocEscapeMalloc() {
   int *p = malloc(12);
   myfoo(p);
-  p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+  p = malloc(12); // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void mallocMalloc() {
   int *p = malloc(12);
-  p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}}
+  p = malloc(12); // expected-warning{{Memory is never released; potential memory leak}}
 }
 
 void mallocFreeMalloc() {
@@ -356,13 +392,13 @@
 void mallocFreeUse_params() {
   int *p = malloc(12);
   free(p);
-  myfoo(p); //expected-warning{{Use of dynamically allocated memory after it is freed}}
+  myfoo(p); //expected-warning{{Use of memory after it is freed}}
 }
 
 void mallocFreeUse_params2() {
   int *p = malloc(12);
   free(p);
-  myfooint(*p); //expected-warning{{Use of dynamically allocated memory after it is freed}}
+  myfooint(*p); //expected-warning{{Use of memory after it is freed}}
 }
 
 void mallocFailedOrNot() {
@@ -380,14 +416,14 @@
 int *mallocReturnFreed() {
   int *p = malloc(12);
   free(p);
-  return p; // expected-warning {{Use of dynamically allocated}}
+  return p; // expected-warning {{Use of memory after it is freed}}
 }
 
 int useAfterFreeStruct() {
   struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
   px->g = 5;
   free(px);
-  return px->g; // expected-warning {{Use of dynamically allocated}}
+  return px->g; // expected-warning {{Use of memory after it is freed}}
 }
 
 void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
@@ -403,7 +439,24 @@
   if (p == 0)
     return; // no warning
   else
-    return; // expected-warning {{Allocated memory never released. Potential memory leak.}}
+    return; // expected-warning {{Memory is never released; potential memory leak}}
+}
+
+void mallocAssignment() {
+  char *p = malloc(12);
+  p = fooRetPtr(); // expected-warning {{leak}}
+}
+
+int vallocTest() {
+  char *mem = valloc(12);
+  return 0; // expected-warning {{Memory is never released; potential memory leak}}
+}
+
+void vallocEscapeFreeUse() {
+  int *p = valloc(12);
+  myfoo(p);
+  free(p);
+  myfoo(p); // expected-warning{{Use of memory after it is freed}}
 }
 
 int *Gl;
@@ -432,6 +485,57 @@
   free(GlS.x);
 }
 
+char *ArrayG[12];
+
+void globalArrayTest() {
+  char *p = (char*)malloc(12);
+  ArrayG[0] = p;
+}
+
+// Make sure that we properly handle a pointer stored into a local struct/array.
+typedef struct _StructWithPtr {
+  int *memP;
+} StructWithPtr;
+
+static StructWithPtr arrOfStructs[10];
+
+void testMalloc() {
+  int *x = malloc(12);
+  StructWithPtr St;
+  St.memP = x;
+  arrOfStructs[0] = St;
+}
+
+StructWithPtr testMalloc2() {
+  int *x = malloc(12);
+  StructWithPtr St;
+  St.memP = x;
+  return St;
+}
+
+int *testMalloc3() {
+  int *x = malloc(12);
+  int *y = x;
+  return y;
+}
+
+void testElemRegion1() {
+  char *x = (void*)malloc(2);
+  int *ix = (int*)x;
+  free(&(x[0]));
+}
+
+void testElemRegion2(int **pp) {
+  int *p = malloc(12);
+  *pp = p;
+  free(pp[0]);
+}
+
+void testElemRegion3(int **pp) {
+  int *p = malloc(12);
+  *pp = p;
+  free(*pp);
+}
 // Region escape testing.
 
 unsigned takePtrToPtr(int **p);
@@ -462,7 +566,7 @@
   struct X *px= malloc(sizeof(struct X));
   px->p = 0;
   px = s2;
-  return px; // expected-warning {{Allocated memory never released. Potential memory leak.}}
+  return px; // expected-warning {{Memory is never released; potential memory leak}}
 }
 
 struct X* RegInvalidationGiveUp1() {
@@ -476,7 +580,7 @@
   int *p = malloc(12);
   pp = &p;
   pp++;
-  return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}}
+  return 0;// expected-warning {{Memory is never released; potential memory leak}}
 }
 
 extern void exit(int) __attribute__ ((__noreturn__));
@@ -507,6 +611,26 @@
   strcpy(p, s); // expected-warning {{leak}}
 }
 
+// Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p.
+void symbolLostWithStrcpy(char *s) {
+  char *p = malloc(12);
+  p = strcpy(p, s);
+  free(p);
+}
+
+
+// The same test as the one above, but with what is actually generated on a mac.
+static __inline char *
+__inline_strcpy_chk (char *restrict __dest, const char *restrict __src)
+{
+  return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
+}
+
+void symbolLostWithStrcpy_InlineStrcpyVersion(char *s) {
+  char *p = malloc(12);
+  p = ((__builtin_object_size (p, 0) != (size_t) -1) ? __builtin___strcpy_chk (p, s, __builtin_object_size (p, 2 > 1)) : __inline_strcpy_chk (p, s));
+  free(p);
+}
 // Below are the known false positives.
 
 // TODO: There should be no warning here. This one might be difficult to get rid of.
@@ -522,7 +646,7 @@
   if (p != g)
     free(p);
   else
-    return; // expected-warning{{Allocated memory never released. Potential memory leak}}
+    return; // expected-warning{{Memory is never released; potential memory leak}}
   return;
 }
 
@@ -537,5 +661,22 @@
     p[0] = n;
     p++;
   }
-  return p;// expected-warning {{Allocated memory never released. Potential memory leak.}}
+  return p;// expected-warning {{Memory is never released; potential memory leak}}
+}
+
+// False negatives.
+
+// TODO: This requires tracking symbols stored inside the structs/arrays.
+void testMalloc5() {
+  StructWithPtr St;
+  StructWithPtr *pSt = &St;
+  pSt->memP = malloc(12);
+}
+
+// TODO: This should produce a warning, similar to the previous issue.
+void localArrayTest() {
+  char *p = (char*)malloc(12);
+  char *ArrayL[12];
+  ArrayL[0] = p;
 }
+

Modified: cfe/branches/tooling/test/Analysis/misc-ps-region-store.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/misc-ps-region-store.mm?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/misc-ps-region-store.mm (original)
+++ cfe/branches/tooling/test/Analysis/misc-ps-region-store.mm Mon Feb 20 19:34:24 2012
@@ -29,3 +29,20 @@
   return [p foo];
 }
 
+// Basic test of C++ references with Objective-C pointers.
+ at interface RDar10569024
+ at property(readonly) int x;
+ at end
+
+typedef RDar10569024* RDar10569024Ref;
+
+void rdar10569024_aux(RDar10569024Ref o);
+
+int rdar10569024(id p, id collection) {
+  for (id elem in collection) {
+    const RDar10569024Ref &o = (RDar10569024Ref) elem;
+    rdar10569024_aux(o); // no-warning
+    return o.x; // no-warning
+  }
+  return 0;
+}

Modified: cfe/branches/tooling/test/Analysis/misc-ps.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/misc-ps.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/misc-ps.m (original)
+++ cfe/branches/tooling/test/Analysis/misc-ps.m Mon Feb 20 19:34:24 2012
@@ -1248,7 +1248,7 @@
   struct s { char *bar[10]; } baz[2] = { 0 };
   unsigned i = 0;
   for (i = 0;
-  (* ({ while(0); ({ &baz[0]; }); })).bar[0] != 0;
+  (* ({ while(0); ({ &baz[0]; }); })).bar[0] != 0; // expected-warning {{while loop has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
        ++i) {}
 }
 

Modified: cfe/branches/tooling/test/Analysis/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/new.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/new.cpp (original)
+++ cfe/branches/tooling/test/Analysis/new.cpp Mon Feb 20 19:34:24 2012
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// XFAIL: *
 
 void f1() {
   int *n = new int;

Modified: cfe/branches/tooling/test/Analysis/plist-output.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/plist-output.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/plist-output.m (original)
+++ cfe/branches/tooling/test/Analysis/plist-output.m Mon Feb 20 19:34:24 2012
@@ -58,6 +58,27 @@
   return *p;
 }
 
+// The following previously crashed when generating extensive diagnostics.
+// <rdar://problem/10797980>
+ at interface RDar10797980_help
+ at property (readonly) int x;
+ at end
+
+ at interface RDar10797980 {
+  RDar10797980_help *y;
+}
+- (void) test;
+ at end
+
+ at implementation RDar10797980
+- (void) test {
+  if (y.x == 1) {
+    int *p = 0;
+    *p = 0xDEADBEEF; // expected-warning {{deference}}
+  }
+}
+ at end
+
 // CHECK: <?xml version="1.0" encoding="UTF-8"?>
 // CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 // CHECK: <plist version="1.0">
@@ -1189,6 +1210,185 @@
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
 // CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>77</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>77</integer>
+// CHECK:            <key>col</key><integer>6</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>77</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>77</integer>
+// CHECK:          <key>col</key><integer>6</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>77</integer>
+// CHECK:          <key>col</key><integer>6</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable 'p')</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>77</integer>
+// CHECK:    <key>col</key><integer>5</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
 // CHECK:  </array>
 // CHECK: </dict>
 // CHECK: </plist>
+

Modified: cfe/branches/tooling/test/Analysis/properties.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/properties.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/properties.m (original)
+++ cfe/branches/tooling/test/Analysis/properties.m Mon Feb 20 19:34:24 2012
@@ -143,3 +143,26 @@
   return super.name;
 }
 @end
+
+// <rdar://problem/9241180> Static analyzer doesn't detect uninitialized variable issues for property accesses
+ at interface RDar9241180
+ at property (readwrite,assign) id x;
+-(id)testAnalyzer1:(int) y;
+-(void)testAnalyzer2;
+ at end
+
+ at implementation RDar9241180
+ at synthesize x;
+-(id)testAnalyzer1:(int)y {
+    RDar9241180 *o;
+    if (y && o.x) // expected-warning {{Property access on an uninitialized object pointer}}
+      return o;
+    return o; // expected-warning {{Undefined or garbage value returned to caller}}
+}
+-(void)testAnalyzer2 {
+  id y;
+  self.x = y;  // expected-warning {{Argument for property setter is an uninitialized value}}
+}
+ at end
+
+

Modified: cfe/branches/tooling/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/retain-release.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/retain-release.m (original)
+++ cfe/branches/tooling/test/Analysis/retain-release.m Mon Feb 20 19:34:24 2012
@@ -672,7 +672,7 @@
 //===----------------------------------------------------------------------===//
 // <rdar://problem/6257780> clang checker fails to catch use-after-release
 //===----------------------------------------------------------------------===//
-                                 
+
 int rdar_6257780_Case1() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   NSArray *array = [NSArray array];
@@ -682,6 +682,15 @@
 }
 
 //===----------------------------------------------------------------------===//
+// <rdar://problem/10640253> Analyzer is confused about NSAutoreleasePool -allocWithZone:.
+//===----------------------------------------------------------------------===//
+
+void rdar_10640253_autorelease_allocWithZone() {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init];
+    (void) pool;
+}
+
+//===----------------------------------------------------------------------===//
 // <rdar://problem/6866843> Checker should understand new/setObject:/release constructs
 //===----------------------------------------------------------------------===//
 

Modified: cfe/branches/tooling/test/Analysis/stack-addr-ps.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/stack-addr-ps.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/stack-addr-ps.c (original)
+++ cfe/branches/tooling/test/Analysis/stack-addr-ps.c Mon Feb 20 19:34:24 2012
@@ -57,8 +57,15 @@
 
 typedef int (^ComparatorBlock)(int a, int b);
 ComparatorBlock test_return_block(void) {
+  // This block is a global since it has no captures.
   ComparatorBlock b = ^int(int a, int b){ return a > b; };
-  return b; // expected-warning{{Address of stack-allocated block declared on line 60 returned to caller}}
+  return b; // no-warning
+}
+
+ComparatorBlock test_return_block_with_capture(int x) {
+  // This block is stack allocated because it has captures.
+  ComparatorBlock b = ^int(int a, int b){ return a > b + x; };
+  return b; // expected-warning{{Address of stack-allocated block}}
 }
 
 ComparatorBlock test_return_block_neg_aux(void);
@@ -73,4 +80,13 @@
   return a; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}}
 };
 
+// Handle blocks that have no captures or are otherwise declared 'static'.
+// <rdar://problem/10348049>
+typedef int (^RDar10348049)(int value);
+RDar10348049 test_rdar10348049(void) {
+  static RDar10348049 b = ^int(int x) {
+    return x + 2;
+  };
+  return b; // no-warning
+}
 

Modified: cfe/branches/tooling/test/CXX/class/class.union/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/class/class.union/p1.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/class/class.union/p1.cpp (original)
+++ cfe/branches/tooling/test/CXX/class/class.union/p1.cpp Mon Feb 20 19:34:24 2012
@@ -91,8 +91,9 @@
 };
 
 union U4 {
-  static int i1; // expected-error {{static data member 'i1' not allowed in union}}
+  static int i1; // expected-warning {{static data member 'i1' in union is a C++11 extension}}
 };
+int U4::i1 = 10;
 
 union U5 {
   int& i1; // expected-error {{union member 'i1' has reference type 'int &'}}

Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp Mon Feb 20 19:34:24 2012
@@ -51,7 +51,7 @@
   0;
 }
 
-int ng; // expected-note 5{{here}}
+int ng; // expected-note 6{{here}}
 constexpr int BinaryOp1(int n) { return n + ng; } // expected-error {{never produces}} expected-note {{read}}
 constexpr int BinaryOp2(int n) { return ng + n; } // expected-error {{never produces}} expected-note {{read}}
 
@@ -64,13 +64,18 @@
 
 struct S { int a; int b; int c[2]; };
 constexpr S InitList(int a) { return { a, ng }; }; // expected-error {{never produces}} expected-note {{read}}
+constexpr S InitList1a(int a) { return S{ a, ng }; }; // expected-error {{never produces}} expected-note {{read}}
 constexpr S InitList2(int a) { return { a, a, { ng } }; }; // expected-error {{never produces}} expected-note {{read}}
+constexpr S InitList3(int a) { return a ? S{ a, a } : S{ a, ng }; }; // ok
 
-constexpr S InitList3(int a) { return a ? (S){ a, a } : (S){ a, ng }; }; // ok
+constexpr int LogicalAnd1(int n) { return n && (throw, 0); } // ok
+constexpr int LogicalAnd2(int n) { return 1 && (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
 
-// FIXME: Check both arms of a ?: if the conditional is a potential constant
-// expression with an unknown value, and diagnose if neither is constant.
-constexpr S InitList4(int a) { return a ? (S){ a, ng } : (S){ a, ng }; };
+constexpr int LogicalOr1(int n) { return n || (throw, 0); } // ok
+constexpr int LogicalOr2(int n) { return 0 || (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
+
+constexpr int Conditional1(bool b, int n) { return b ? n : ng; } // ok
+constexpr int Conditional2(bool b, int n) { return b ? n * ng : n + ng; } // expected-error {{never produces}} expected-note {{both arms of conditional operator are unable to produce a constant expression}}
 
 // __builtin_constant_p ? : is magical, and is always a potential constant.
 constexpr bool BcpCall(int n) {

Modified: cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp Mon Feb 20 19:34:24 2012
@@ -54,9 +54,9 @@
 };
 NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}}
 template<typename...BaseList>
-struct MaybeAggr5a : BaseList... {}; // expected-note {{explicitly marked deleted}}
+struct MaybeAggr5a : BaseList... {}; // expected-note {{defined here}}
 MaybeAggr5a<> ma5a0 = {}; // ok
-MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to deleted constructor of 'MaybeAggr5a<Aggr>'}}
+MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a<Aggr>'}}
 
 // and no virtual functions.
 struct NonAggr6 { // expected-note 3 {{candidate constructor}}

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=151016&r1=151015&r2=151016&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 Mon Feb 20 19:34:24 2012
@@ -49,25 +49,23 @@
 };
 
 // - an invocation of a constexpr function with arguments that, when substituted
-//   by function invocation substitution (7.1.5), do not produce a constant
+//   by function invocation substitution (7.1.5), do not produce a core constant
 //   expression;
 namespace NonConstExprReturn {
   static constexpr const int &id_ref(const int &n) {
-    return n; // expected-note {{reference to temporary cannot be returned from a constexpr function}}
+    return n;
   }
   struct NonConstExprFunction {
-    int n : id_ref( // expected-error {{constant expression}} expected-note {{in call to 'id_ref(16)'}}
-        16 // expected-note {{temporary created here}}
-        );
+    int n : id_ref(16); // ok
   };
   constexpr const int *address_of(const int &a) {
-    return &a; // expected-note {{pointer to 'n' cannot be returned from a constexpr function}}
+    return &a;
   }
   constexpr const int *return_param(int n) { // expected-note {{declared here}}
-    return address_of(n); // expected-note {{in call to 'address_of(n)'}}
+    return address_of(n);
   }
   struct S {
-    int n : *return_param(0); // expected-error {{constant expression}} expected-note {{in call to 'return_param(0)'}}
+    int n : *return_param(0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}}
   };
 }
 
@@ -78,16 +76,16 @@
 namespace NonConstExprCtor {
   struct T {
     constexpr T(const int &r) :
-      r(r) { // expected-note 2{{reference to temporary cannot be used to initialize a member in a constant expression}}
+      r(r) {
     }
     const int &r;
   };
   constexpr int n = 0;
   constexpr T t1(n); // ok
-  constexpr T t2(0); // expected-error {{must be initialized by a constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'T(0)'}}
+  constexpr T t2(0); // expected-error {{must be initialized by a constant expression}} expected-note {{temporary created here}} expected-note {{reference to temporary is not a constant expression}}
 
   struct S {
-    int n : T(4).r; // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'T(4)'}}
+    int n : T(4).r; // ok
   };
 }
 
@@ -176,12 +174,12 @@
   struct S {
     int m;
   };
-  constexpr S s = { 5 }; // expected-note {{declared here}}
+  constexpr S s = { 5 };
   constexpr const int *p = &s.m + 1;
   constexpr const int &f(const int *q) {
-    return q[0]; // expected-note {{dereferenced pointer past the end of subobject of 's' is not a constant expression}}
+    return q[0];
   }
-  constexpr int n = (f(p), 0); // expected-error {{constant expression}} expected-note {{in call to 'f(&s.m + 1)'}}
+  constexpr int n = (f(p), 0); // ok
   struct T {
     int n : f(p); // expected-error {{not an integral constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
   };

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.cpp Mon Feb 20 19:34:24 2012
@@ -6,3 +6,52 @@
 
   (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
 }
+
+void conversion_to_block(int captured) {
+  int (^b1)(int) = [=](int x) { return x + captured; };
+
+  const auto lambda = [=](int x) { return x + captured; };
+  int (^b2)(int) = lambda;
+}
+
+template<typename T>
+class ConstCopyConstructorBoom {
+public:
+  ConstCopyConstructorBoom(ConstCopyConstructorBoom&);
+
+  ConstCopyConstructorBoom(const ConstCopyConstructorBoom&) {
+    T *ptr = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}
+  }
+
+  void foo() const;
+};
+
+void conversion_to_block_init(ConstCopyConstructorBoom<int> boom,
+                              ConstCopyConstructorBoom<float> boom2) {
+  const auto& lambda1([=] { boom.foo(); }); // okay
+
+  const auto& lambda2([=] { boom2.foo(); }); // expected-note{{in instantiation of member function}}
+  void (^block)(void) = lambda2;
+}
+
+
+void nesting() {
+  int array[7]; // expected-note 2{{'array' declared here}}
+  [=] () mutable {
+    [&] {
+      ^ {
+        int i = array[2];
+        i += array[3];
+      }();
+    }();
+  }();
+
+  [&] {
+    [=] () mutable {
+      ^ {
+        int i = array[2]; // expected-error{{cannot refer to declaration with an array type inside block}}
+        i += array[3]; // expected-error{{cannot refer to declaration with an array type inside block}}
+      }();
+    }();
+  }();
+}

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp Mon Feb 20 19:34:24 2012
@@ -4,12 +4,22 @@
 
 class NonCopyable {
   NonCopyable(const NonCopyable&); // expected-note 2 {{implicitly declared private here}}
+public:
+  void foo() const;
+};
+
+class NonConstCopy {
+public:
+  NonConstCopy(NonConstCopy&); // expected-note{{would lose const}}
 };
 
-void capture_by_copy(NonCopyable nc, NonCopyable &ncr) {
-  // FIXME: error messages should talk about capture
-  (void)[nc] { }; // expected-error{{field of type 'NonCopyable' has private copy constructor}}
-  (void)[ncr] { }; // expected-error{{field of type 'NonCopyable' has private copy constructor}}
+void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) {
+  (void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}}
+  (void)[=] {
+    ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}} 
+  }();
+
+  [nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}}
 }
 
 struct NonTrivial {

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp Mon Feb 20 19:34:24 2012
@@ -2,7 +2,7 @@
 
 
 struct X {
-  X(const X&) = delete; // expected-note{{explicitly marked deleted}}
+  X(const X&) = delete; // expected-note 2{{explicitly marked deleted}}
   X(X&);
 };
 
@@ -10,7 +10,31 @@
   [x] { }(); // okay: non-const copy ctor
 
   [x] {
-    [x] { // expected-error{{call to deleted constructor of 'const X'}}
+    [x] { // expected-error{{call to deleted constructor of 'X'}}
     }();
   }();
+
+  [x] {
+    [&x] {
+      [x] { // expected-error{{call to deleted constructor of 'const X'}}
+      }();
+    }();
+  }();
+
+  int a; 
+  [=]{ 
+    [&] { 
+      int &x = a;  // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}}
+      int &x2 = a;  // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}}
+    }(); 
+  }(); 
+
+  [=]{ 
+    [&a] { 
+      [&] { 
+        int &x = a;  // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}}
+        int &x2 = a;  // expected-error{{binding of reference to type 'int' to a value of type 'const int' drops qualifiers}}
+      }();
+    }(); 
+  }(); 
 }

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp Mon Feb 20 19:34:24 2012
@@ -17,12 +17,12 @@
   const int &irc = i;
 
   [=,&irc,&ir] {
+    static_assert(is_same<decltype(((r))), float const&>::value, 
+                  "should be const float&");
     static_assert(is_same<decltype(x), float>::value, "should be float");
     static_assert(is_same<decltype((x)), const float&>::value, 
                   "should be const float&");
     static_assert(is_same<decltype(r), float&>::value, "should be float&");
-    static_assert(is_same<decltype(((r))), float const&>::value, 
-                  "should be const float&");
     static_assert(is_same<decltype(ir), int&>::value, "should be int&");
     static_assert(is_same<decltype((ir)), int&>::value, "should be int&");
     static_assert(is_same<decltype(irc), const int&>::value, 
@@ -34,8 +34,12 @@
   [=] {
     [=] () mutable {
       static_assert(is_same<decltype(x), float>::value, "should be float");
-      static_assert(is_same<decltype((x)), const float&>::value, 
-                    "should be const float&");
+      static_assert(is_same<decltype((x)), float&>::value, 
+                    "should be float&");
     }();
   }();
+
+  [&i] {
+    static_assert(is_same<decltype((i)), int&>::value, "should be int&");
+  }();
 }

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp Mon Feb 20 19:34:24 2012
@@ -7,16 +7,13 @@
 
 template<typename T> T &&move(T&);
 void test_special_member_functions(MoveOnly mo, int i) {
-  // FIXME: terrible note
-  auto lambda1 = [i]() { }; // expected-note{{function has been explicitly marked deleted here}} \
-  // expected-note{{the implicit copy assignment operator}} \
-  // expected-note{{the implicit move assignment operator}} \
+  auto lambda1 = [i]() { }; // expected-note 2 {{lambda expression begins here}}
 
   // Default constructor
-  decltype(lambda1) lambda2; // expected-error{{call to deleted constructor}}
+  decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '<lambda}}
 
   // Copy assignment operator
-  lambda1 = lambda1; // expected-error{{overload resolution selected deleted operator '='}}
+  lambda1 = lambda1; // expected-error{{overload resolution selected implicitly-deleted copy assignment operator}}
 
   // Move assignment operator
   lambda1 = move(lambda1);

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp Mon Feb 20 19:34:24 2012
@@ -37,7 +37,15 @@
   return [x](int y) { // expected-warning{{omitted result type}}
     if (y > 0)
       return X();
-    else // FIXME: shouldn't mention blocks
-      return x; // expected-error{{return type 'const X' must match previous return type 'X' when block literal has unspecified explicit return type}}
+    else 
+      return x; // expected-error{{return type 'const X' must match previous return type 'X' when lambda expression has unspecified explicit return type}}
   }(5);
 }
+
+struct Incomplete; // expected-note{{forward declaration of 'Incomplete'}}
+void test_result_type(int N) {
+  auto l1 = [] () -> Incomplete { }; // expected-error{{incomplete result type 'Incomplete' in lambda expression}}
+
+  typedef int vla[N];
+  auto l2 = [] () -> vla { }; // expected-error{{function cannot return array type 'vla' (aka 'int [N]')}}
+}

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp Mon Feb 20 19:34:24 2012
@@ -3,7 +3,9 @@
 // An attribute-specifier-seq in a lambda-declarator appertains to the
 // type of the corresponding function call operator.
 void test_attributes() {
-  auto nrl = []() [[noreturn]] {}; // expected-warning{{function declared 'noreturn' should not return}}
+  auto nrl = [](int x) -> int { if (x > 0) return x; }; // expected-warning{{control may reach end of non-void lambda}}
+
+  auto nrl2 = []() [[noreturn]] { return; }; // expected-error{{lambda declared 'noreturn' should not return}}
 }
 
 template<typename T>
@@ -38,9 +40,10 @@
 
 // Default arguments (8.3.6) shall not be specified in the
 // parameter-declaration-clause of a lambda- declarator.
+// Note: Removed by core issue 974.
 int test_default_args() {
-  return [](int i = 5,  // expected-error{{default arguments can only be specified for parameters in a function declaration}}
-            int j = 17) { return i+j;}(5, 6); // expected-error{{default arguments can only be specified for parameters in a function declaration}}
+  return [](int i = 5,  // expected-warning{{C++11 forbids default arguments for lambda expressions}}
+            int j = 17) { return i+j;}(5, 6);
 }
 
 // Any exception-specification specified on a lambda-expression

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp Mon Feb 20 19:34:24 2012
@@ -2,7 +2,7 @@
 
 // Check that analysis-based warnings work in lambda bodies.
 void analysis_based_warnings() {
-  (void)[]() -> int { }; // expected-warning{{control reaches end of non-void function}}
+  (void)[]() -> int { }; // expected-warning{{control reaches end of non-void lambda}}
 }
 
 // Check that we get the right types of captured variables (the

Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp Mon Feb 20 19:34:24 2012
@@ -2,7 +2,7 @@
 
 template<typename T>
 void test_attributes() {
-  auto nrl = []() [[noreturn]] {}; // expected-warning{{function declared 'noreturn' should not return}}
+  auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}}
 }
 
 template void test_attributes<int>(); // expected-note{{in instantiation of function}}
@@ -114,3 +114,36 @@
 
   template void double_capture(NonConstCopy&);
 }
+
+namespace NonLocalLambdaInstantation {
+  template<typename T>
+  struct X {
+    static int value;
+  };
+
+  template<typename T>
+  int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}}
+
+  template int X<int>::value;
+  template int X<float>::value;
+  template int X<int*>::value; // expected-note{{in instantiation of static data member }}
+
+  template<typename T>
+  void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \
+     // expected-note{{passing argument to parameter 'x' here}}
+
+  void call_defaults() {
+    defaults<int>();
+    defaults<float>();
+    defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}}
+  }
+
+  template<typename T>
+  struct X2 {
+    int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
+  };
+
+  X2<int> x2i;
+  X2<float> x2f;
+  X2<int*> x2ip; // expected-note{{in instantiation of template class 'NonLocalLambdaInstantation::X2<int *>' requested here}}
+}

Modified: cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp Mon Feb 20 19:34:24 2012
@@ -54,7 +54,7 @@
 
   static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
   HasMoveConstructor hmc;
-  hmc = HasMoveConstructor(); // expected-error {{selected deleted operator}}
+  hmc = HasMoveConstructor(); // expected-error {{selected implicitly-deleted copy assignment}}
 
   (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
   HasMoveAssignment hma;
@@ -87,8 +87,8 @@
   ~PrivateDestructor() noexcept;
 };
 
-struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note {{explicitly marked deleted}}
-struct ContainsPrivateDestructor { // expected-note {{explicitly marked deleted}}
+struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{defined here}}
+struct ContainsPrivateDestructor { // expected-note{{defined here}}
   PrivateDestructor pd;
 };
 
@@ -131,8 +131,8 @@
   ContainsPrivateMove cpm;
   static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
 
-  (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to deleted constructor}}
-  (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to deleted constructor}}
+  (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
+  (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
 
   static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
   static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");

Modified: cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp Mon Feb 20 19:34:24 2012
@@ -9,7 +9,7 @@
   DeletedNTVariant();
 };
 DeletedNTVariant DVa;
-DeletedNTVariant DVb(DVa); // expected-error{{call to deleted constructor}}
+DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct DeletedNTVariant2 { // expected-note{{here}}
   union {
@@ -18,7 +18,7 @@
   DeletedNTVariant2();
 };
 DeletedNTVariant2 DV2a;
-DeletedNTVariant2 DV2b(DV2a); // expected-error{{call to deleted constructor}}
+DeletedNTVariant2 DV2b(DV2a); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct NoAccess {
   NoAccess() = default;
@@ -32,7 +32,7 @@
   NoAccess NA;
 };
 HasNoAccess HNAa;
-HasNoAccess HNAb(HNAa); // expected-error{{call to deleted constructor}}
+HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct HasAccess {
   NoAccess NA;
@@ -55,13 +55,13 @@
   IsAmbiguous();
 };
 IsAmbiguous IAa;
-IsAmbiguous IAb(IAa); // expected-error{{call to deleted constructor}}
+IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct Deleted { // expected-note{{here}}
   IsAmbiguous IA;
 };
 Deleted Da;
-Deleted Db(Da); // expected-error{{call to deleted constructor}}
+Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct NoAccessDtor {
 private:
@@ -75,7 +75,7 @@
   ~HasNoAccessDtor();
 };
 HasNoAccessDtor HNADa;
-HasNoAccessDtor HNADb(HNADa); // expected-error{{call to deleted constructor}}
+HasNoAccessDtor HNADb(HNADa); // expected-error{{call to implicitly-deleted copy constructor}}
 
 struct HasAccessDtor {
   NoAccessDtor NAD;
@@ -87,4 +87,4 @@
   int && ri = 1;
 };
 RValue RVa;
-RValue RVb(RVa); // expected-error{{call to deleted constructor}}
+RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}}

Modified: cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp Mon Feb 20 19:34:24 2012
@@ -21,19 +21,22 @@
 
 // - X is a union-like class that has a variant member with a non-trivial
 // default constructor,
-union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{deleted here}}
-Deleted1a d1a; // expected-error {{deleted constructor}}
+union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{defined here}}
+Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
 union NotDeleted1a { DefaultedDefCtor1 nu; };
 NotDeleted1a nd1a;
 // FIXME: clang implements the pre-FDIS rule, under which DefaultedDefCtor2's
 // default constructor is non-trivial.
-union NotDeleted1b { DefaultedDefCtor2 nu; }; // unexpected-note {{deleted here}}
-NotDeleted1b nd1b; // unexpected-error {{deleted constructor}}
+union NotDeleted1b { DefaultedDefCtor2 nu; }; // unexpected-note {{defined here}}
+NotDeleted1b nd1b; // unexpected-error {{implicitly-deleted default constructor}}
 
 // - any non-static data member with no brace-or-equal-initializer is of
 // reference type,
-class Deleted2a { Deleted2a() = default; int &a; }; // expected-note {{deleted here}}
-Deleted2a d2a; // expected-error {{deleted constructor}}
+class Deleted2a {  // expected-note {{defined here}}
+  Deleted2a() = default;  // expected-note {{declared here}}
+  int &a; 
+}; 
+Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
 class NotDeleted2a { int &a = n; };
 NotDeleted2a nd2a;
 class NotDeleted2b { int &a = error; }; // expected-error {{undeclared identifier}}
@@ -45,11 +48,11 @@
 class Deleted3a { const int a; }; // expected-note {{here}} \
                                      expected-warning {{does not declare any constructor}} \
                                      expected-note {{will never be initialized}}
-Deleted3a d3a; // expected-error {{deleted constructor}}
+Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
 class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{here}}
-Deleted3b d3b; // expected-error {{deleted constructor}}
-class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{deleted}}
-Deleted3c d3c; // expected-error {{deleted constructor}}
+Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
+class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{defined here}}
+Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
 class NotDeleted3a { const int a = 0; };
 NotDeleted3a nd3a;
 class NotDeleted3b { const DefaultedDefCtor1 a[42] = {}; };
@@ -60,23 +63,23 @@
 NotDeleted3d nd3d;
 // FIXME: this class should not have a deleted default constructor.
 union NotDeleted3e { const DefaultedDefCtor1 a[42]; int b; }; // unexpected-note {{here}}
-NotDeleted3e nd3e; // unexpected-error {{deleted constructor}}
+NotDeleted3e nd3e; // unexpected-error {{implicitly-deleted default constructor}}
 // FIXME: clang implements the pre-FDIS rule, under which DefaultedDefCtor2 is
 // non-trivial.
 union NotDeleted3f { const DefaultedDefCtor2 a; int b; }; // unexpected-note {{here}}
-NotDeleted3f nd3f; // unexpected-error {{deleted constructor}}
+NotDeleted3f nd3f; // unexpected-error {{implicitly-deleted default constructor}}
 
 // - X is a union and all of its variant members are of const-qualified type (or
 // array thereof),
 union Deleted4a { const int a; const int b; const UserProvidedDefCtor c; }; // expected-note {{here}}
-Deleted4a d4a; // expected-error {{deleted constructor}}
+Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
 union Deleted4b { const int a; int b; };
 Deleted4b d4b;
 
 // - X is a non-union class and all members of any anonymous union member are of
 // const-qualified type (or array thereof),
 struct Deleted5a { union { const int a; }; union { int b; }; }; // expected-note {{here}}
-Deleted5a d5a; // expected-error {{deleted constructor}}
+Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted5b { union { const int a; int b; }; union { const int c; int d; }; };
 Deleted5b d5b;
 
@@ -86,17 +89,17 @@
 // constructor results in an ambiguity or in a function that is deleted or
 // inaccessible from the defaulted default constructor, or
 struct Deleted6a : Deleted2a {}; // expected-note {{here}}
-Deleted6a d6a; // expected-error {{deleted constructor}}
+Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted6b : virtual Deleted2a {}; // expected-note {{here}}
-Deleted6b d6b; // expected-error {{deleted constructor}}
+Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted6c { Deleted2a a; }; // expected-note {{here}}
-Deleted6c d6c; // expected-error {{deleted constructor}}
+Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted6d { DeletedDefCtor a; }; // expected-note {{here}}
-Deleted6d d6d; // expected-error {{deleted constructor}}
+Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted6a { DeletedDefCtor a = 0; };
 NotDeleted6a nd6a;
 struct Deleted6e { PrivateDefCtor a; }; // expected-note {{here}}
-Deleted6e d6e; // expected-error {{deleted constructor}}
+Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted6b { PrivateDefCtor a = 0; };
 NotDeleted6b nd6b;
 struct NotDeleted6c { Friend a; };
@@ -106,21 +109,21 @@
 // a destructor that is deleted or inaccessible from the defaulted default
 // constructor.
 struct Deleted7a : DeletedDtor {}; // expected-note {{here}}
-Deleted7a d7a; // expected-error {{deleted constructor}}
+Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7b : virtual DeletedDtor {}; // expected-note {{here}}
-Deleted7b d7b; // expected-error {{deleted constructor}}
+Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7c { DeletedDtor a; }; // expected-note {{here}}
-Deleted7c d7c; // expected-error {{deleted constructor}}
+Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{here}}
-Deleted7d d7d; // expected-error {{deleted constructor}}
+Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7e : PrivateDtor {}; // expected-note {{here}}
-Deleted7e d7e; // expected-error {{deleted constructor}}
+Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7f : virtual PrivateDtor {}; // expected-note {{here}}
-Deleted7f d7f; // expected-error {{deleted constructor}}
+Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7g { PrivateDtor a; }; // expected-note {{here}}
-Deleted7g d7g; // expected-error {{deleted constructor}}
+Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}}
 struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{here}}
-Deleted7h d7h; // expected-error {{deleted constructor}}
+Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted7i : Friend {};
 NotDeleted7i d7i;
 struct NotDeleted7j : virtual Friend {};

Modified: cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp Mon Feb 20 19:34:24 2012
@@ -16,10 +16,10 @@
     constexpr A(int n, double d, const char *y) : n(n), d(d), u(y) {}
   };
 
-  // CHECK: @_ZN11StructUnion1aE = global {{.*}} { i32 1, double 2.000000e+00, {{.*}} { i32 3, [4 x i8] undef } }
+  // CHECK: @_ZN11StructUnion1aE = constant {{.*}} { i32 1, double 2.000000e+00, {{.*}} { i32 3, [4 x i8] undef } }
   extern constexpr A a(1, 2.0, 3);
 
-  // CHECK: @_ZN11StructUnion1bE = global {{.*}} { i32 4, double 5.000000e+00, {{.*}} { i8* getelementptr inbounds ([6 x i8]* @{{.*}}, i32 0, i32 0) } }
+  // CHECK: @_ZN11StructUnion1bE = constant {{.*}} { i32 4, double 5.000000e+00, {{.*}} { i8* getelementptr inbounds ([6 x i8]* @{{.*}}, i32 0, i32 0) } }
   extern constexpr A b(4, 5, "hello");
 
   struct B {
@@ -62,21 +62,21 @@
   struct Test : Ts... { constexpr Test() : Ts()..., n(5) {} int n; };
 
   using Test1 = Test<N, C, Cs<1,2>, D, X<C,1>>;
-  // CHECK: @_ZN9BaseClass2t1E = global {{.*}} { i32 3, i8 1, i8 1, i8 1, double 4.000000e+00, i8 1, i32 5 }, align 8
+  // CHECK: @_ZN9BaseClass2t1E = constant {{.*}} { i32 3, i8 1, i8 1, i8 1, double 4.000000e+00, i8 1, i32 5 }, align 8
   extern constexpr Test1 t1 = Test1();
 
   struct DN : D, N {};
   struct DND : DN, X<D,0> {};
   struct DNN : DN, X<N,0> {};
-  // CHECK: @_ZN9BaseClass3dndE = global {{.*}} { double 4.000000e+00, i32 3, double 4.000000e+00 }
+  // CHECK: @_ZN9BaseClass3dndE = constant {{.*}} { double 4.000000e+00, i32 3, double 4.000000e+00 }
   extern constexpr DND dnd = DND();
   // Note, N subobject is laid out in DN subobject's tail padding.
-  // CHECK: @_ZN9BaseClass3dnnE = global {{.*}} { double 4.000000e+00, i32 3, i32 3 }
+  // CHECK: @_ZN9BaseClass3dnnE = constant {{.*}} { double 4.000000e+00, i32 3, i32 3 }
   extern constexpr DNN dnn = DNN();
 
   struct E {};
   struct Test2 : X<E,0>, X<E,1>, X<E,2>, X<E,3> {};
-  // CHECK: @_ZN9BaseClass2t2E = global {{.*}} undef
+  // CHECK: @_ZN9BaseClass2t2E = constant {{.*}} undef
   extern constexpr Test2 t2 = Test2();
 }
 
@@ -88,12 +88,20 @@
   extern constexpr char c[6][4] = { "foo", "a", { "bar" }, { 'x', 'y', 'z' }, { "b" }, '1', '2', '3' };
 
   struct C { constexpr C() : n(5) {} int n, m = 3 * n + 1; };
-  // CHECK: @_ZN5Array5ctorsE = global [3 x {{.*}}] [{{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }]
+  // CHECK: @_ZN5Array5ctorsE = constant [3 x {{.*}}] [{{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }, {{.*}} { i32 5, i32 16 }]
   extern const C ctors[3];
   constexpr C ctors[3];
 
   // CHECK: @_ZN5Array1dE = constant {{.*}} { [2 x i32] [i32 1, i32 2], [3 x i32] [i32 3, i32 4, i32 5] }
   struct D { int n[2]; int m[3]; } extern constexpr d = { 1, 2, 3, 4, 5 };
+
+  struct E {
+    char c[4];
+    char d[4];
+    constexpr E() : c("foo"), d("x") {}
+  };
+  // CHECK: @_ZN5Array1eE = constant {{.*}} { [4 x i8] c"foo\00", [4 x i8] c"x\00\00\00" }
+  extern constexpr E e = E();
 }
 
 namespace MemberPtr {
@@ -279,3 +287,17 @@
   // CHECK: sub nsw i64 ptrtoint (i8* blockaddress(@_ZN18CrossFuncLabelDiff4testEv, {{.*}}) to i64),
   // CHECK: store i64 {{.*}}, i64* @_ZZN18CrossFuncLabelDiff4testEvE1b, align 8
 }
+
+// PR12012
+namespace VirtualBase {
+  struct B {};
+  struct D : virtual B {};
+  D d;
+  // CHECK: call {{.*}}@_ZN11VirtualBase1DC1Ev
+
+  template<typename T> struct X : T {
+    constexpr X() : T() {}
+  };
+  X<D> x;
+  // CHECK: call {{.*}}@_ZN11VirtualBase1XINS_1DEEC1Ev
+}

Modified: cfe/branches/tooling/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp Mon Feb 20 19:34:24 2012
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
-// XFAIL: *
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fno-limit-debug-info %s -o - | FileCheck %s
+
 class Test
 {
 public:
@@ -19,6 +19,6 @@
 
 Test t;
 
-// CHECK: metadata !"data", metadata !7, i32 13, i64 32, i64 32, i32 0, i32 0
-// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ]
-// CHECK-NOT: metadata !"data", metadata !7, i32 13, i64 0, i64 0, i32 0, i32 4,
+// CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata {{.*}} [ DW_TAG_pointer_type ]
+// CHECK: metadata !"data", metadata !6, i32 14, i64 32, i64 32, i32 0, i32 0
+// CHECK-NOT: metadata !"data", metadata {{.*}}, i32 14, i64 0, i64 0, i32 0, i32 4,

Modified: cfe/branches/tooling/test/CodeGenCXX/debug-info-limit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/debug-info-limit.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/debug-info-limit.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/debug-info-limit.cpp Mon Feb 20 19:34:24 2012
@@ -7,8 +7,8 @@
   int z;
 };
 
-A *foo () {
-  A *a = new A();
+A *foo (A* x) {
+  A *a = new A(*x);
   return a;
 }
 

Modified: cfe/branches/tooling/test/CodeGenCXX/exceptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/exceptions.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/exceptions.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/exceptions.cpp Mon Feb 20 19:34:24 2012
@@ -194,12 +194,9 @@
     // CHECK:      [[SAVED0:%.*]] = alloca i8*
     // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
     // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
-    // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
-    // CHECK:      [[TMPACTIVE:%.*]] = alloca i1
 
     // CHECK:      [[COND:%.*]] = trunc i8 {{.*}} to i1
     // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
-    // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
     // CHECK-NEXT: br i1 [[COND]]
     return (cond ?
 
@@ -209,24 +206,18 @@
     // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
     // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
-    // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[TMP]])
-    // CHECK:      store i1 true, i1* [[TMPACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN5test31AC1ERKS0_([[A]]* [[CAST]], [[A]]* [[TMP]])
-    // CHECK:      store i1 false, i1* [[CLEANUPACTIVE]]
-    // CHECK-NEXT: br label
+    // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]])
+    // CHECK: br label
     //   -> cond.end
             new(foo(),10.0) A(makeA()) :
 
-    // CHECK:      [[MAKE:%.*]] = invoke [[A]]* @_ZN5test38makeAPtrEv()
+    // CHECK:      [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv()
     // CHECK:      br label
     //   -> cond.end
             makeAPtr());
 
     // cond.end:
     // CHECK:      [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
-    // CHECK-NEXT: [[ISACTIVE:%.*]] = load i1* [[TMPACTIVE]]
-    // CHECK-NEXT: br i1 [[ISACTIVE]]
-    // CHECK:      invoke void @_ZN5test31AD1Ev
     // CHECK:      ret [[A]]* [[RESULT]]
 
     // in the EH path:

Modified: cfe/branches/tooling/test/CodeGenCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/lambda-expressions.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/lambda-expressions.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/lambda-expressions.cpp Mon Feb 20 19:34:24 2012
@@ -47,8 +47,26 @@
 // CHECK: invoke i32 @"_ZZ1e1ES_bENK3$_4clEv"
 // CHECK: call void @"_ZZ1e1ES_bEN3$_4D1Ev"
 // CHECK: call void @"_ZZ1e1ES_bEN3$_4D1Ev"
+
 // CHECK: define internal i32 @"_ZZ1e1ES_bENK3$_4clEv"
 // CHECK: trunc i8
 // CHECK: load i32*
 // CHECK: ret i32
+
+void f() {
+  // CHECK: define void @_Z1fv()
+  // CHECK: {{call.*_5cvPFiiiEEv}}
+  // CHECK-NEXT: store i32 (i32, i32)*
+  // CHECK-NEXT: ret void
+  int (*fp)(int, int) = [](int x, int y){ return x + y; };
+}
+
+// CHECK: define internal i32 @"_ZZ1fvEN3$_58__invokeEii"
+// CHECK: store i32
+// CHECK-NEXT: store i32
+// CHECK-NEXT: load i32*
+// CHECK-NEXT: load i32*
+// CHECK-NEXT: call i32 @"_ZZ1fvENK3$_5clEii"
+// CHECK-NEXT: ret i32
+
 // CHECK: define internal void @"_ZZ1e1ES_bEN3$_4D2Ev"

Modified: cfe/branches/tooling/test/CodeGenCXX/member-function-pointers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/member-function-pointers.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/member-function-pointers.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/member-function-pointers.cpp Mon Feb 20 19:34:24 2012
@@ -28,6 +28,16 @@
 // CHECK: @pc3 = global { i64, i64 } { i64 1, i64 0 }, align 8
 void (A::*pc3)() = &A::vf1;
 
+// Tests for test10.
+// CHECK: @_ZN6test101aE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 0 }, align 8
+// CHECK: @_ZN6test101bE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
+// CHECK: @_ZN6test101cE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 8 }, align 8
+// CHECK: @_ZN6test101dE = global { i64, i64 } { i64 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i64), i64 16 }, align 8
+// CHECK-LP32: @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
+// CHECK-LP32: @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
+// CHECK-LP32: @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 4 }, align 4
+// CHECK-LP32: @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
+
 void f() {
   // CHECK: store { i64, i64 } zeroinitializer, { i64, i64 }* @pa
   pa = 0;
@@ -232,3 +242,33 @@
     static S array[] = { (fooptr) &B::foo };
   }
 }
+
+// rdar://problem/10815683 - Verify that we can emit reinterprets of
+// member pointers as constant initializers.  For added trickiness,
+// we also add some non-trivial adjustments.
+namespace test10 {
+  struct A {
+    int nonEmpty;
+    void foo();
+  };
+  struct B : public A {
+    virtual void requireNonZeroAdjustment();
+  };
+  struct C {
+    int nonEmpty;
+  };
+  struct D : public C {
+    virtual void requireNonZeroAdjustment();
+  };
+
+  // Non-ARM tests at top of file.
+  void (A::*a)() = &A::foo;
+  void (B::*b)() = (void (B::*)()) &A::foo;
+  void (C::*c)() = (void (C::*)()) (void (B::*)()) &A::foo;
+  void (D::*d)() = (void (C::*)()) (void (B::*)()) &A::foo;
+}
+// It's not that the offsets are doubled on ARM, it's that they're left-shifted by 1.
+// CHECK-ARM: @_ZN6test101aE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 0 }, align 4
+// CHECK-ARM: @_ZN6test101bE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
+// CHECK-ARM: @_ZN6test101cE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 8 }, align 4
+// CHECK-ARM: @_ZN6test101dE = global { i32, i32 } { i32 ptrtoint (void (%"struct.test10::A"*)* @_ZN6test101A3fooEv to i32), i32 16 }, align 4

Modified: cfe/branches/tooling/test/CodeGenCXX/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/new.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/new.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/new.cpp Mon Feb 20 19:34:24 2012
@@ -239,3 +239,14 @@
   // CHECK: store i64 -1
   NewTy* f() { return new NewTy[2](); }
 }
+
+namespace PR11757 {
+  // Make sure we elide the copy construction.
+  struct X { X(); X(const X&); };
+  X* a(X* x) { return new X(X()); }
+  // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE
+  // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm
+  // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
+  // CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]])
+  // CHECK-NEXT: ret {{.*}} [[CASTED]]
+}

Modified: cfe/branches/tooling/test/CodeGenCXX/pr11676.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/pr11676.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/pr11676.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/pr11676.cpp Mon Feb 20 19:34:24 2012
@@ -1,8 +1,17 @@
 // RUN: %clang_cc1 %s -std=c++11 -emit-llvm-only
 // CHECK that we don't crash.
 
+// PR11676's example is ill-formed:
+/*
 union _XEvent {
 };
 void ProcessEvent() {
   _XEvent pluginEvent = _XEvent();
 }
+*/
+
+// Example from PR11665:
+void f() {
+  union U { int field; } u = U();
+  (void)U().field;
+}

Modified: cfe/branches/tooling/test/CodeGenCXX/static-data-member.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/static-data-member.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/static-data-member.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/static-data-member.cpp Mon Feb 20 19:34:24 2012
@@ -5,6 +5,12 @@
 // CHECK: @_ZN5test31AIiE1xE = weak_odr global i32 0, align 4
 // CHECK: @_ZGVN5test31AIiE1xE = weak_odr global i64 0
 
+// CHECK: _ZN5test51U2k0E = global i32 0
+// CHECK: _ZN5test51U2k1E = global i32 0
+// CHECK: _ZN5test51U2k2E = constant i32 76
+// CHECK-NOT: test51U2k3E
+// CHECK-NOT: test51U2k4E
+
 // PR5564.
 namespace test1 {
   struct A {
@@ -78,3 +84,21 @@
     return a->n;
   }
 }
+
+// Test that static data members in unions behave properly.
+namespace test5 {
+  union U {
+    static int k0;
+    static const int k1;
+    static const int k2 = 76;
+    static const int k3;
+    static const int k4 = 81;
+  };
+  int U::k0;
+  const int U::k1 = (k0 = 9, 42);
+  const int U::k2;
+
+  // CHECK: store i32 9, i32* @_ZN5test51U2k0E
+  // CHECK: store i32 {{.*}}, i32* @_ZN5test51U2k1E
+  // CHECK-NOT: store {{.*}} i32* @_ZN5test51U2k2E
+}

Modified: cfe/branches/tooling/test/CodeGenObjC/arc-ivar-layout.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/arc-ivar-layout.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/arc-ivar-layout.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/arc-ivar-layout.m Mon Feb 20 19:34:24 2012
@@ -42,3 +42,14 @@
 // CHECK-LP64: L_OBJC_CLASS_NAME_15:
 // CHECK-LP64-NEXT: .asciz	"\022"
 
+ at interface UnsafePerson {
+ at public
+    __unsafe_unretained id name;
+    __unsafe_unretained id age;
+    id value;
+}
+ at end
+
+ at implementation UnsafePerson @end
+// CHECK-LP64: L_OBJC_CLASS_NAME_20:
+// CHECK-LP64-NEXT: .asciz      "!"

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

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m Mon Feb 20 19:34:24 2012
@@ -2,4 +2,4 @@
 @class ForwardObjcClass;
 ForwardObjcClass *ptr = 0;
 
-// CHECK: !8 = metadata !{i32 {{.*}}, 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 ]
+// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !"ForwardObjcClass", metadata !{{.*}}, 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/image-info.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/image-info.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/image-info.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/image-info.m Mon Feb 20 19:34:24 2012
@@ -4,5 +4,14 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
 // RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
 
-// CHECK-FRAGILE: @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__OBJC, __image_info,regular"
-// CHECK-NONFRAGILE: @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
+// CHECK-FRAGILE:      !llvm.module.flags = !{!0, !1, !2, !3}
+// CHECK-FRAGILE:      !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 1}
+// CHECK-FRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
+// CHECK-FRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__OBJC, __image_info,regular"}
+// CHECK-FRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
+
+// CHECK-NONFRAGILE:      !llvm.module.flags = !{!0, !1, !2, !3}
+// CHECK-NONFRAGILE:      !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
+// CHECK-NONFRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
+// CHECK-NONFRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
+// CHECK-NONFRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}

Modified: cfe/branches/tooling/test/CodeGenObjC/objc-align.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/objc-align.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/objc-align.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/objc-align.m Mon Feb 20 19:34:24 2012
@@ -6,7 +6,6 @@
 // RUN: grep '@"\\01L_OBJC_CLASS_A" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
 // RUN: grep '@"\\01L_OBJC_CLASS_C" = internal global .*, section "__OBJC,__class,regular,no_dead_strip", align 4' %t
 // RUN: grep '@"\\01L_OBJC_CLASS_PROTOCOLS_C" = internal global .*, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4' %t
-// RUN: grep '@"\\01L_OBJC_IMAGE_INFO" = internal constant .*, section "__OBJC, __image_info,regular"' %t
 // RUN: grep '@"\\01L_OBJC_METACLASS_A" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
 // RUN: grep '@"\\01L_OBJC_METACLASS_C" = internal global .*, section "__OBJC,__meta_class,regular,no_dead_strip", align 4' %t
 // RUN: grep '@"\\01L_OBJC_MODULES" = internal global .*, section "__OBJC,__module_info,regular,no_dead_strip", align 4' %t
@@ -20,7 +19,6 @@
 // RUNX: grep '@"OBJC_METACLASS_$_A" = global' %t &&
 // RUNX: grep '@"OBJC_METACLASS_$_C" = global' %t &&
 // RUNX: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_0" = internal global .*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t &&
-// RUNX: grep '@"\\01L_OBJC_IMAGE_INFO" = internal constant .*, section "__DATA, __objc_imageinfo, regular, no_dead_strip"' %t &&
 // RUNX: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .*, section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t &&
 // RUNX: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .*, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t &&
 // RUNX: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .*, section "__DATA, __objc_const", align 8' %t &&

Modified: cfe/branches/tooling/test/CodeGenObjC/variadic-sends.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/variadic-sends.m?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/variadic-sends.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/variadic-sends.m Mon Feb 20 19:34:24 2012
@@ -20,8 +20,8 @@
 }
 
 void f2(A *a) {
-  // CHECK-X86-32: call void (i8*, i8*, i32, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, i32, ...)*)
-  // CHECK-X86-64: call void (i8*, i8*, i32, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, i32, ...)*)
+  // CHECK-X86-32: call void (i8*, i8*, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*)
+  // CHECK-X86-64: call void (i8*, i8*, i32, ...)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*)
   [a im2: 1, 2];
 }
 
@@ -33,8 +33,8 @@
   [super im1: 1];
 }
 -(void) bar {
-  // CHECK-X86-32: call void (%struct._objc_super*, i8*, i32, i32, ...)* bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, i32, ...)*)
-  // CHECK-X86-64: call void (%struct._objc_super*, i8*, i32, i32, ...)* bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, i32, ...)*)
+  // CHECK-X86-32: call void (%struct._objc_super*, i8*, i32, ...)* bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, ...)*)
+  // CHECK-X86-64: call void (%struct._objc_super*, i8*, i32, ...)* bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper to void (%struct._objc_super*, i8*, i32, ...)*)
   [super im2: 1, 2];
 }
 

Modified: cfe/branches/tooling/test/CodeGenObjCXX/copy.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjCXX/copy.mm?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjCXX/copy.mm (original)
+++ cfe/branches/tooling/test/CodeGenObjCXX/copy.mm Mon Feb 20 19:34:24 2012
@@ -14,8 +14,6 @@
   // CHECK-NEXT: call noalias i8* @_Znwm(
   // CHECK-NEXT: bitcast
   // CHECK-NEXT: bitcast
-  // CHECK-NEXT: call void @llvm.memset.p0i8.i64(
-  // CHECK-NEXT: bitcast
   // CHECK-NEXT: bitcast
   // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(
   // CHECK-NEXT: ret

Modified: cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp Mon Feb 20 19:34:24 2012
@@ -57,4 +57,6 @@
   (void)[=, this]{ this->g(5); }; // expected-error{{'this' cannot be explicitly captured}}
   (void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
   (void)[&, i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
+  (void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}}
+  (void)[] -> int { }; // expected-error{{lambda requires '()' before return type}}
 }

Modified: cfe/branches/tooling/test/FixIt/fixit.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/FixIt/fixit.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/FixIt/fixit.c (original)
+++ cfe/branches/tooling/test/FixIt/fixit.c Mon Feb 20 19:34:24 2012
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -pedantic -Wunused-label -verify -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
 // RUN: grep -v CHECK %t > %t2
@@ -12,22 +13,24 @@
 // FIXME: FIX-IT should add #include <string.h>?
 int strcmp(const char *s1, const char *s2);
 
-void f0(void) { };
+void f0(void) { }; // expected-warning {{';'}}
 
 struct s {
-  int x, y;;
+  int x, y;; // expected-warning {{extra ';'}}
 };
 
 // CHECK: _Complex double cd;
-_Complex cd;
+_Complex cd; // expected-warning {{assuming '_Complex double'}}
 
 // CHECK: struct s s0 = { .y = 5 };
-struct s s0 = { y: 5 };
+struct s s0 = { y: 5 }; // expected-warning {{GNU old-style}}
 
 // CHECK: int array0[5] = { [3] = 3 };
-int array0[5] = { [3] 3 };
+int array0[5] = { [3] 3 }; // expected-warning {{GNU 'missing ='}}
 
-void f1(x, y)
+// CHECK: int x
+// CHECK: int y
+void f1(x, y) // expected-warning 2{{defaulting to type 'int'}}
 {
 }
 
@@ -36,16 +39,16 @@
 #define ONE 1
 #define TWO 2
 
-int test_cond(int y, int fooBar) {
+int test_cond(int y, int fooBar) { // expected-note {{here}}
 // CHECK: int x = y ? 1 : 4+fooBar;
-  int x = y ? 1 4+foobar;
+  int x = y ? 1 4+foobar; // expected-error {{expected ':'}} expected-error {{undeclared identifier}} expected-note {{to match}}
 // CHECK: x = y ? ONE : TWO;
-  x = y ? ONE TWO;
+  x = y ? ONE TWO; // expected-error {{':'}} expected-note {{to match}}
   return x;
 }
 
-// CHECK: typedef int int_t;
-typedef typedef int int_t;
+// CHECK: const typedef int int_t;
+const typedef typedef int int_t; // expected-warning {{duplicate 'typedef'}}
 
 // <rdar://problem/7159693>
 enum Color { 
@@ -61,19 +64,39 @@
 };
 
 void removeUnusedLabels(char c) {
-  L0 /*removed comment*/:        c++;
+  L0 /*removed comment*/:        c++; // expected-warning {{unused label}}
   removeUnusedLabels(c);
-  L1:
+  L1: // expected-warning {{unused label}}
   c++;
-  /*preserved comment*/ L2  :        c++;
-  LL
+  /*preserved comment*/ L2  :        c++; // expected-warning {{unused label}}
+  LL // expected-warning {{unused label}}
   : c++;
-  c = c + 3; L4: return;
+  c = c + 3; L4: return; // expected-warning {{unused label}}
 }
 
-int oopsAComma = 0,
+int oopsAComma = 0, // expected-error {{';'}}
 void oopsMoreCommas() {
-  static int a[] = { 0, 1, 2 },
-  static int b[] = { 3, 4, 5 },
+  static int a[] = { 0, 1, 2 }, // expected-error {{';'}}
+  static int b[] = { 3, 4, 5 }, // expected-error {{';'}}
   &a == &b ? oopsMoreCommas() : removeUnusedLabels(a[0]);
 }
+
+int noSemiAfterLabel(int n) {
+  switch (n) {
+    default:
+      return n % 4;
+    case 0:
+    case 1:
+    case 2:
+    // CHECK: /*FOO*/ case 3: ;
+    /*FOO*/ case 3: // expected-error {{expected statement}}
+  }
+  switch (n) {
+    case 1:
+    case 2:
+      return 0;
+    // CHECK: /*BAR*/ default: ;
+    /*BAR*/ default: // expected-error {{expected statement}}
+  }
+  return 1;
+}

Removed: cfe/branches/tooling/test/Frontend/diagnostic-name.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Frontend/diagnostic-name.c?rev=151015&view=auto
==============================================================================
--- cfe/branches/tooling/test/Frontend/diagnostic-name.c (original)
+++ cfe/branches/tooling/test/Frontend/diagnostic-name.c (removed)
@@ -1,5 +0,0 @@
-// RUN: %clang -fsyntax-only -Wunused-parameter -fdiagnostics-show-name %s 2>&1 | grep "\[warn_unused_parameter\]" | count 1
-// RUN: %clang -fsyntax-only -Wunused-parameter -fno-diagnostics-show-name %s 2>&1 | grep "\[warn_unused_parameter\]" | count 0
-int main(int argc, char *argv[]) {
-  return argc;
-}

Modified: cfe/branches/tooling/test/Index/complete-stmt.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/complete-stmt.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/complete-stmt.c (original)
+++ cfe/branches/tooling/test/Index/complete-stmt.c Mon Feb 20 19:34:24 2012
@@ -7,6 +7,10 @@
   } 
 }
 
-// RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-IF-ELSE %s
+// RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-IF-ELSE %s
 // CHECK-IF-ELSE: NotImplemented:{TypedText else}{HorizontalSpace  }{LeftBrace {}{VerticalSpace  }{Placeholder statements}{VerticalSpace  }{RightBrace }} (40)
 // CHECK-IF-ELSE: NotImplemented:{TypedText else}{HorizontalSpace  }{Text if}{HorizontalSpace  }{LeftParen (}{Placeholder expression}{RightParen )}{HorizontalSpace  }{LeftBrace {}{VerticalSpace  }{Placeholder statements}{VerticalSpace  }{RightBrace }} (40)
+
+// RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-IF-ELSE-SIMPLE %s
+// CHECK-IF-ELSE-SIMPLE: NotImplemented:{TypedText else} (40)
+// CHECK-IF-ELSE-SIMPLE: NotImplemented:{TypedText else}{HorizontalSpace  }{Text if}{HorizontalSpace  }{LeftParen (}{Placeholder expression}{RightParen )} (40)

Modified: cfe/branches/tooling/test/Index/index-refs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/index-refs.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/index-refs.cpp (original)
+++ cfe/branches/tooling/test/Index/index-refs.cpp Mon Feb 20 19:34:24 2012
@@ -55,6 +55,12 @@
   TS<int, int> s;
 }
 
+const int array_size = 3;
+typedef int some_arr[array_size];
+
+const int default_param = 3;
+void foo4(int p = default_param);
+
 // RUN: c-index-test -index-file %s | FileCheck %s
 // CHECK:      [indexDeclaration]: kind: namespace | name: NS
 // CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx
@@ -89,7 +95,16 @@
 // CHECK:      [indexDeclaration]: kind: c++-class-template | name: TS | {{.*}} | loc: 47:8
 // CHECK-NEXT: [indexDeclaration]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T at TS>#t0.0#I | {{.*}} | loc: 50:8
 // CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp at 593@SP>1#T at TS>#t0.0#I at T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
-// CHECK-NEXT: [indexDeclaration]: kind: struct-template-spec | name: TS | USR: c:@S at TS>#I | {{.*}} | loc: 50:8
-// CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp at 593@S at TS>#I at T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
+/* when indexing implicit instantiations
+  [indexDeclaration]: kind: struct-template-spec | name: TS | USR: c:@S at TS>#I | {{.*}} | loc: 50:8
+  [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp at 593@S at TS>#I at T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
+ */
 // CHECK-NEXT: [indexDeclaration]: kind: function | name: foo3
-// CHECK-NEXT: [indexEntityReference]: kind: struct-template-spec | name: TS | USR: c:@S at TS>#I | {{.*}} | loc: 55:3
+/* when indexing implicit instantiations
+  [indexEntityReference]: kind: struct-template-spec | name: TS | USR: c:@S at TS>#I | {{.*}} | loc: 55:3
+*/
+// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T at TS | {{.*}} | loc: 55:3
+
+// CHECK:      [indexEntityReference]: kind: variable | name: array_size | {{.*}} | loc: 59:22
+// CHECK:      [indexEntityReference]: kind: variable | name: default_param | {{.*}} | loc: 62:19
+// CHECK-NOT:  [indexEntityReference]: kind: variable | name: default_param | {{.*}} | loc: 62:19

Modified: cfe/branches/tooling/test/Lexer/has_feature_cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Lexer/has_feature_cxx0x.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Lexer/has_feature_cxx0x.cpp (original)
+++ cfe/branches/tooling/test/Lexer/has_feature_cxx0x.cpp Mon Feb 20 19:34:24 2012
@@ -217,3 +217,12 @@
 
 // CHECK-0X: has_unicode_literals
 // CHECK-NO-0X: no_unicode_literals
+
+#if __has_feature(cxx_constexpr)
+int has_constexpr();
+#else
+int no_constexpr();
+#endif
+
+// CHECK-0X: has_constexpr
+// CHECK-NO-0X: no_constexpr

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Misc/warning-flags.c (original)
+++ cfe/branches/tooling/test/Misc/warning-flags.c Mon Feb 20 19:34:24 2012
@@ -17,9 +17,8 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (258):
+CHECK: Warnings without flags (257):
 CHECK-NEXT:   ext_anonymous_struct_union_qualified
-CHECK-NEXT:   ext_array_init_copy
 CHECK-NEXT:   ext_binary_literal
 CHECK-NEXT:   ext_cast_fn_obj
 CHECK-NEXT:   ext_delete_void_ptr_operand

Modified: cfe/branches/tooling/test/Parser/attributes.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/attributes.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/attributes.c (original)
+++ cfe/branches/tooling/test/Parser/attributes.c Mon Feb 20 19:34:24 2012
@@ -61,3 +61,38 @@
 int __attribute__((vec_type_hint(char, aligned(16) )) missing_rparen_1; // expected-error {{expected ')'}}
 int __attribute__((mode(x aligned(16) )) missing_rparen_2; // expected-error {{expected ')'}}
 int __attribute__((format(printf, 0 aligned(16) )) missing_rparen_3; // expected-error {{expected ')'}}
+
+
+
+int testFundef1(int *a) __attribute__((nonnull(1))) { // \
+    // expected-warning {{GCC does not allow nonnull attribute in this position on a function definition}}
+  return *a;
+}
+
+// noreturn is lifted to type qualifier
+void testFundef2() __attribute__((noreturn)) { // \
+    // expected-warning {{GCC does not allow noreturn attribute in this position on a function definition}}
+  testFundef2();
+}
+
+int testFundef3(int *a) __attribute__((nonnull(1), // \
+    // expected-warning {{GCC does not allow nonnull attribute in this position on a function definition}}
+                                     pure)) { // \
+    // expected-warning {{GCC does not allow pure attribute in this position on a function definition}}
+  return *a;
+}
+
+int testFundef4(int *a) __attribute__((nonnull(1))) // \
+    // expected-warning {{GCC does not allow nonnull attribute in this position on a function definition}}
+                      __attribute((pure)) { // \
+    // expected-warning {{GCC does not allow pure attribute in this position on a function definition}}
+  return *a;
+}
+
+// GCC allows these
+void testFundef5() __attribute__(()) { }
+
+__attribute__((pure)) int testFundef6(int a) { return a; }
+
+
+

Modified: cfe/branches/tooling/test/Parser/cxx-condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/cxx-condition.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/cxx-condition.cpp (original)
+++ cfe/branches/tooling/test/Parser/cxx-condition.cpp Mon Feb 20 19:34:24 2012
@@ -5,7 +5,7 @@
   while (a) ;
   while (int x) ; // expected-error {{expected '=' after declarator}}
   while (float x = 0) ;
-  if (const int x = a) ; // expected-warning{{empty body}}
+  if (const int x = a) ; // expected-warning{{empty body}} expected-note{{put the semicolon on a separate line to silence this warning}}
   switch (int x = a+10) {}
   for (; int x = ++a; ) ;
 }

Modified: cfe/branches/tooling/test/Parser/cxx-using-directive.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/cxx-using-directive.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/cxx-using-directive.cpp (original)
+++ cfe/branches/tooling/test/Parser/cxx-using-directive.cpp Mon Feb 20 19:34:24 2012
@@ -3,7 +3,7 @@
 class A {};
 
 namespace B {
-  namespace A {}
+  namespace A {} // expected-note{{namespace '::B::A' defined here}}
   using namespace A ;
 }
 
@@ -19,8 +19,7 @@
   namespace B {}
   
   using namespace C ;
-  using namespace B::A ; // expected-error{{expected namespace name}}
-  //FIXME: would be nice to note, that A is not member of D::B
+  using namespace B::A ; // expected-error{{no namespace named 'A' in namespace 'D::B'; did you mean '::B::A'?}}
   using namespace ::B::A ;
   using namespace ::D::C ; // expected-error{{expected namespace name}}
 }
@@ -37,4 +36,3 @@
   using namespace B;
   using namespace C;
 }
-

Modified: cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp (original)
+++ cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp Mon Feb 20 19:34:24 2012
@@ -20,8 +20,21 @@
     [&,foo] () {}; 
     [this] () {}; 
 
+    [] -> int { return 0; }; // expected-error{{lambda requires '()' before return type}}
+    [] mutable -> int { return 0; }; // expected-error{{lambda requires '()' before 'mutable'}}
     return 1;
   }
 
+  void designator_or_lambda() {
+    typedef int T; 
+    const int b = 0; 
+    const int c = 1;
+    int a1[1] = {[b] (T()) {}}; // expected-error{{no viable conversion from 'C::<lambda}}
+    int a2[1] = {[b] = 1 };
+    int a3[1] = {[b,c] = 1 }; // expected-error{{expected body of lambda expression}}
+    int a4[1] = {[&b] = 1 }; // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'const int *'}}
+    int a5[3] = { []{return 0;}() };
+    int a6[1] = {[this] = 1 }; // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'C *'}}
+  }
 };
 

Modified: cfe/branches/tooling/test/Parser/statements.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/statements.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/statements.c (original)
+++ cfe/branches/tooling/test/Parser/statements.c Mon Feb 20 19:34:24 2012
@@ -31,20 +31,20 @@
 }
 
 void test4() {
-  if (0);  // expected-warning {{if statement has empty body}}
+  if (0);  // expected-warning {{if statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
   
   int X;  // declaration in a block.
   
-foo:  if (0); // expected-warning {{if statement has empty body}}
+foo:  if (0); // expected-warning {{if statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
 }
 
 typedef int t;
 void test5() {
-  if (0);   // expected-warning {{if statement has empty body}}
+  if (0);   // expected-warning {{if statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
 
   t x = 0;
 
-  if (0);  // expected-warning {{if statement has empty body}}
+  if (0);  // expected-warning {{if statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
 }
 
 

Modified: cfe/branches/tooling/test/Sema/MicrosoftExtensions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/MicrosoftExtensions.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/MicrosoftExtensions.c (original)
+++ cfe/branches/tooling/test/Sema/MicrosoftExtensions.c Mon Feb 20 19:34:24 2012
@@ -21,16 +21,6 @@
 };
 
 
-enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}    
-enum ENUM1 var1 = 3;
-enum ENUM1* var2 = 0;
-
-
-enum ENUM2 {
-  ENUM2_a = (enum ENUM2) 4,
-  ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
-  ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
-};
 
 
 

Modified: cfe/branches/tooling/test/Sema/c89.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/c89.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/c89.c (original)
+++ cfe/branches/tooling/test/Sema/c89.c Mon Feb 20 19:34:24 2012
@@ -89,3 +89,5 @@
 void test16() {
   printg("Hello, world!\n"); /* expected-warning {{implicit declaration of function 'printg'}} */
 }
+
+void main() {} /* expected-error {{'main' must return 'int'}} */

Modified: cfe/branches/tooling/test/Sema/default.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/default.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/default.c (original)
+++ cfe/branches/tooling/test/Sema/default.c Mon Feb 20 19:34:24 2012
@@ -3,6 +3,6 @@
 void f5 (int z) { 
   if (z) 
     default:  // expected-error {{not in switch statement}}
-      ; // expected-warning {{if statement has empty body}}
+      ;
 } 
 

Modified: cfe/branches/tooling/test/Sema/format-strings-fixit.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/format-strings-fixit.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/format-strings-fixit.c (original)
+++ cfe/branches/tooling/test/Sema/format-strings-fixit.c Mon Feb 20 19:34:24 2012
@@ -48,7 +48,7 @@
   printf("%hhs", "foo");
   printf("%1$zp", (void *)0);
 
-  // Perserve the original formatting for unsigned integers.
+  // Preserve the original formatting for unsigned integers.
   unsigned long val = 42;
   printf("%X", val);
 
@@ -60,6 +60,21 @@
 
   // string
   printf("%ld", "foo");
+
+  // Preserve the original choice of conversion specifier.
+  printf("%o", (long) 42);
+  printf("%u", (long) 42);
+  printf("%x", (long) 42);
+  printf("%X", (long) 42);
+  printf("%i", (unsigned long) 42);
+  printf("%d", (unsigned long) 42);
+  printf("%F", (long double) 42);
+  printf("%e", (long double) 42);
+  printf("%E", (long double) 42);
+  printf("%g", (long double) 42);
+  printf("%G", (long double) 42);
+  printf("%a", (long double) 42);
+  printf("%A", (long double) 42);
 }
 
 int scanf(char const *, ...);
@@ -101,20 +116,30 @@
   scanf("%f", &uIntmaxVar);
   scanf("%f", &ptrdiffVar);
 
-  // Perserve the original formatting for unsigned integers.
-  scanf("%o", &uLongVar);
-  scanf("%x", &uLongVar);
-  scanf("%X", &uLongVar);
+  // Preserve the original formatting.
+  scanf("%o", &longVar);
+  scanf("%u", &longVar);
+  scanf("%x", &longVar);
+  scanf("%X", &longVar);
+  scanf("%i", &uLongVar);
+  scanf("%d", &uLongVar);
+  scanf("%F", &longDoubleVar);
+  scanf("%e", &longDoubleVar);
+  scanf("%E", &longDoubleVar);
+  scanf("%g", &longDoubleVar);
+  scanf("%G", &longDoubleVar);
+  scanf("%a", &longDoubleVar);
+  scanf("%A", &longDoubleVar);
 }
 
-// Validate the fixes...
+// Validate the fixes.
 // CHECK: printf("%d", (int) 123);
 // CHECK: printf("abc%s", "testing testing 123");
-// CHECK: printf("%ld", (long) -12);
+// CHECK: printf("%lu", (long) -12);
 // CHECK: printf("%d", 123);
 // CHECK: printf("%s\n", "x");
 // CHECK: printf("%f\n", 1.23);
-// CHECK: printf("%.2llu", (unsigned long long) 123456);
+// CHECK: printf("%+.2lld", (unsigned long long) 123456);
 // CHECK: printf("%1Lf", (long double) 1.23);
 // CHECK: printf("%0u", (unsigned) 31337);
 // CHECK: printf("%p", (void *) 0);
@@ -132,6 +157,19 @@
 // CHECK: printf("%ju", (uintmax_t) 42);
 // CHECK: printf("%td", (ptrdiff_t) 42);
 // CHECK: printf("%s", "foo");
+// CHECK: printf("%lo", (long) 42);
+// CHECK: printf("%lu", (long) 42);
+// CHECK: printf("%lx", (long) 42);
+// CHECK: printf("%lX", (long) 42);
+// CHECK: printf("%li", (unsigned long) 42);
+// CHECK: printf("%ld", (unsigned long) 42);
+// CHECK: printf("%LF", (long double) 42);
+// CHECK: printf("%Le", (long double) 42);
+// CHECK: printf("%LE", (long double) 42);
+// CHECK: printf("%Lg", (long double) 42);
+// CHECK: printf("%LG", (long double) 42);
+// CHECK: printf("%La", (long double) 42);
+// CHECK: printf("%LA", (long double) 42);
 
 // CHECK: scanf("%s", str);
 // CHECK: scanf("%hd", &shortVar);
@@ -149,6 +187,16 @@
 // CHECK: scanf("%jd", &intmaxVar);
 // CHECK: scanf("%ju", &uIntmaxVar);
 // CHECK: scanf("%td", &ptrdiffVar);
-// CHECK: scanf("%lo", &uLongVar);
-// CHECK: scanf("%lx", &uLongVar);
-// CHECK: scanf("%lX", &uLongVar);
+// CHECK: scanf("%lo", &longVar);
+// CHECK: scanf("%lu", &longVar);
+// CHECK: scanf("%lx", &longVar);
+// CHECK: scanf("%lX", &longVar);
+// CHECK: scanf("%li", &uLongVar);
+// CHECK: scanf("%ld", &uLongVar);
+// CHECK: scanf("%LF", &longDoubleVar);
+// CHECK: scanf("%Le", &longDoubleVar);
+// CHECK: scanf("%LE", &longDoubleVar);
+// CHECK: scanf("%Lg", &longDoubleVar);
+// CHECK: scanf("%LG", &longDoubleVar);
+// CHECK: scanf("%La", &longDoubleVar);
+// CHECK: scanf("%LA", &longDoubleVar);

Modified: cfe/branches/tooling/test/Sema/format-strings-scanf.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/format-strings-scanf.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/format-strings-scanf.c (original)
+++ cfe/branches/tooling/test/Sema/format-strings-scanf.c Mon Feb 20 19:34:24 2012
@@ -117,3 +117,7 @@
   scanf("%Ls", "hello"); // expected-warning {{length modifier 'L' results in undefined behavior or no effect with 's' conversion specifier}}
 }
 
+void test_quad(int *x, long long *llx) {
+  scanf("%qd", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+  scanf("%qd", llx); // no-warning
+}

Modified: cfe/branches/tooling/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/format-strings.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/format-strings.c (original)
+++ cfe/branches/tooling/test/Sema/format-strings.c Mon Feb 20 19:34:24 2012
@@ -167,7 +167,9 @@
   printf("%.d", x); // no-warning
   printf("%.", x);  // expected-warning{{incomplete format specifier}}
   printf("%f", 4); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
-  printf("%qd", lli);
+  printf("%qd", lli); // no-warning
+  printf("%qd", x); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%qp", (void *)0); // expected-warning{{length modifier 'q' results in undefined behavior or no effect with 'p' conversion specifier}}
   printf("hhX %hhX", (unsigned char)10); // no-warning
   printf("llX %llX", (long long) 10); // no-warning
   // This is fine, because there is an implicit conversion to an int.

Modified: cfe/branches/tooling/test/Sema/gnu89.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/gnu89.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/gnu89.c (original)
+++ cfe/branches/tooling/test/Sema/gnu89.c Mon Feb 20 19:34:24 2012
@@ -1,3 +1,5 @@
 // RUN: %clang_cc1 %s -std=gnu89 -pedantic -fsyntax-only -verify
 
 int f(int restrict);
+
+void main() {} // expected-warning {{return type of 'main' is not 'int'}}

Modified: cfe/branches/tooling/test/Sema/statements.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/statements.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/statements.c (original)
+++ cfe/branches/tooling/test/Sema/statements.c Mon Feb 20 19:34:24 2012
@@ -36,7 +36,7 @@
 
 // PR6034
 void test11(int bit) {
-  switch (bit)
+  switch (bit) // expected-warning {{switch statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
   switch (env->fpscr)  // expected-error {{use of undeclared identifier 'env'}}
   {
   }

Modified: cfe/branches/tooling/test/Sema/switch.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/switch.c?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/switch.c (original)
+++ cfe/branches/tooling/test/Sema/switch.c Mon Feb 20 19:34:24 2012
@@ -24,7 +24,9 @@
 
 void test3(void) { 
   // empty switch;
-  switch (0); // expected-warning {{no case matching constant switch condition '0'}}
+  switch (0); // expected-warning {{no case matching constant switch condition '0'}} \
+              // expected-warning {{switch statement has empty body}} \
+              // expected-note{{put the semicolon on a separate line to silence this warning}}
 }
 
 extern int g();

Modified: cfe/branches/tooling/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/MicrosoftExtensions.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/MicrosoftExtensions.cpp Mon Feb 20 19:34:24 2012
@@ -92,11 +92,6 @@
   h1(&M::subtractP);
 } 
 
-//MSVC allows forward enum declaration
-enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
-ENUM *var = 0;     
-ENUM var2 = (ENUM)3;
-enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}}
 
 
 

Modified: cfe/branches/tooling/test/SemaCXX/attr-sentinel.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/attr-sentinel.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/attr-sentinel.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/attr-sentinel.cpp Mon Feb 20 19:34:24 2012
@@ -1,6 +1,23 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+
 void f(int, ...) __attribute__((sentinel));
 
 void g() {
   f(1, 2, __null);
 }
+
+typedef __typeof__(sizeof(int)) size_t;
+
+struct S {
+  S(int,...) __attribute__((sentinel)); // expected-note {{marked sentinel}}
+  void a(int,...) __attribute__((sentinel)); // expected-note {{marked sentinel}}
+  void* operator new(size_t,...) __attribute__((sentinel)); // expected-note {{marked sentinel}}
+  void operator()(int,...) __attribute__((sentinel)); // expected-note {{marked sentinel}}
+};
+
+void class_test() {
+  S s(1,2,3); // expected-warning {{missing sentinel in function call}}
+  S* s2 = new (1,2,3) S(1, __null); // expected-warning {{missing sentinel in function call}}
+  s2->a(1,2,3); // expected-warning {{missing sentinel in function call}}
+  s(1,2,3); // expected-warning {{missing sentinel in function call}}
+}

Modified: cfe/branches/tooling/test/SemaCXX/condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/condition.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/condition.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/condition.cpp Mon Feb 20 19:34:24 2012
@@ -20,7 +20,8 @@
   while (struct S {} *x=0) ; // expected-error {{types may not be defined in conditions}}
   while (struct {} *x=0) ; // expected-error {{types may not be defined in conditions}}
   switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \
-  // expected-warning{{enumeration value 'E' not handled in switch}}
+  // expected-warning{{enumeration value 'E' not handled in switch}} expected-warning {{switch statement has empty body}} \
+  // expected-note{{put the semicolon on a separate line}}
 
   if (int x=0) { // expected-note 2 {{previous definition is here}}
     int x;  // expected-error {{redefinition of 'x'}}

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=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp Mon Feb 20 19:34:24 2012
@@ -190,26 +190,21 @@
 namespace ParameterScopes {
 
   const int k = 42;
-  constexpr const int &ObscureTheTruth(const int &a) { return a; } // expected-note 3{{reference to 'a' cannot be returned from a constexpr function}}
+  constexpr const int &ObscureTheTruth(const int &a) { return a; }
   constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}}
-    return ObscureTheTruth(b ? a : k); // expected-note 2{{in call to 'ObscureTheTruth(a)'}}
+    return ObscureTheTruth(b ? a : k);
   }
   static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok
-  constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{in call to 'MaybeReturnJunk(1, 0)'}}
+  constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}}
 
-  constexpr const int MaybeReturnNonstaticRef(bool b, const int a) { // expected-note {{here}}
-    // If ObscureTheTruth returns a reference to 'a', the result is not a
-    // constant expression even though 'a' is still in scope.
-    return ObscureTheTruth(b ? a : k); // expected-note {{in call to 'ObscureTheTruth(a)'}}
+  constexpr const int MaybeReturnNonstaticRef(bool b, const int a) {
+    return ObscureTheTruth(b ? a : k);
   }
   static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok
-  constexpr int b = MaybeReturnNonstaticRef(true, 0); // expected-error {{constant expression}} expected-note {{in call to 'MaybeReturnNonstaticRef(1, 0)'}}
+  constexpr int b = MaybeReturnNonstaticRef(true, 0); // ok
 
   constexpr int InternalReturnJunk(int n) {
-    // TODO: We could reject this: it never produces a constant expression.
-    // However, we currently don't evaluate function calls while testing for
-    // potential constant expressions, for performance.
-    return MaybeReturnJunk(true, n); // expected-note {{in call to 'MaybeReturnJunk(1, 0)'}}
+    return MaybeReturnJunk(true, n); // expected-note {{read of variable whose lifetime has ended}}
   }
   constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}}
 
@@ -413,6 +408,12 @@
 } constexpr u = { { L"test" }, 0 };
 static_assert(u.chars[2] == L's', "");
 
+struct V {
+  char c[4];
+  constexpr V() : c("hi!") {}
+};
+static_assert(V().c[1] == "i"[0], "");
+
 }
 
 namespace Array {
@@ -528,10 +529,10 @@
 static_assert(D().c.n == 42, "");
 
 struct E {
-  constexpr E() : p(&p) {} // expected-note {{pointer to subobject of temporary cannot be used to initialize a member in a constant expression}}
+  constexpr E() : p(&p) {}
   void *p;
 };
-constexpr const E &e1 = E(); // expected-error {{constant expression}} expected-note {{in call to 'E()'}} expected-note {{temporary created here}}
+constexpr const E &e1 = E(); // expected-error {{constant expression}} expected-note {{reference to temporary is not a constant expression}} expected-note {{temporary created here}}
 // This is a constant expression if we elide the copy constructor call, and
 // is not a constant expression if we don't! But we do, so it is.
 constexpr E e2 = E();
@@ -1054,6 +1055,28 @@
   constexpr _Complex int test6 = {5,6};
   typedef _Complex float fcomplex;
   constexpr fcomplex test7 = fcomplex();
+
+  constexpr const double &t2r = __real test3;
+  constexpr const double &t2i = __imag test3;
+  static_assert(&t2r + 1 == &t2i, "");
+  static_assert(t2r == 1.0, "");
+  static_assert(t2i == 2.0, "");
+  constexpr const double *t2p = &t2r;
+  static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}}
+  static_assert(t2p[0] == 1.0, "");
+  static_assert(t2p[1] == 2.0, "");
+  static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}}
+  static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}}
+  constexpr _Complex float *p = 0;
+  constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}}
+  constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}}
+  constexpr const _Complex double *q = &test3 + 1;
+  constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}}
+  constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}}
+
+  static_assert(__real test6 == 5, "");
+  static_assert(__imag test6 == 6, "");
+  static_assert(&__imag test6 == &__real test6 + 1, "");
 }
 
 namespace InstantiateCaseStmt {
@@ -1158,3 +1181,52 @@
   #undef fold
 
 }
+
+namespace DR1454 {
+
+constexpr const int &f(const int &n) { return n; }
+constexpr int k1 = f(0); // ok
+
+struct Wrap {
+  const int &value;
+};
+constexpr const Wrap &g(const Wrap &w) { return w; }
+constexpr int k2 = g({0}).value; // ok
+
+constexpr const int &i = 0; // expected-error {{constant expression}} expected-note {{temporary}} expected-note 2{{here}}
+constexpr const int j = i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}}
+
+}
+
+namespace RecursiveOpaqueExpr {
+  template<typename Iter>
+  constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) {
+    return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}}
+  }
+
+  constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 };
+  static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, "");
+
+  constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
+  static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
+}
+
+namespace VLASizeof {
+
+  void f(int k) {
+    int arr[k]; // expected-warning {{C99}}
+    constexpr int n = 1 +
+        sizeof(arr) // expected-error {{constant expression}}
+        * 3;
+  }
+}
+
+namespace CompoundLiteral {
+  // FIXME:
+  // We don't model the semantics of this correctly: the compound literal is
+  // represented as a prvalue in the AST, but actually behaves like an lvalue.
+  // We treat the compound literal as a temporary and refuse to produce a
+  // pointer to it. This is OK: we're not required to treat this as a constant
+  // in C++, and in C we model compound literals as lvalues.
+  constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
+}

Modified: cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp Mon Feb 20 19:34:24 2012
@@ -29,3 +29,9 @@
 constexpr D d2 = D(); // ok with DR1452
 static_assert(D().c == 0, "");
 static_assert(D().d == 0, "");
+
+struct V : virtual C {};
+template<typename T> struct Z : T {
+  constexpr Z() : V() {}
+};
+constexpr int n = Z<V>().c; // expected-error {{constant expression}} expected-note {{virtual base class}}

Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-cursory-default-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-cursory-default-delete.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-cursory-default-delete.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-cursory-default-delete.cpp Mon Feb 20 19:34:24 2012
@@ -67,3 +67,9 @@
 struct except_spec_d_match : except_spec_a, except_spec_b {
   except_spec_d_match() throw(A, B) = default;
 };  
+
+// gcc-compatibility: allow attributes on default definitions
+// (but not normal definitions)
+struct S { S(); };
+S::S() __attribute((pure)) = default;
+

Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp Mon Feb 20 19:34:24 2012
@@ -7,27 +7,27 @@
   ~non_trivial();
 };
 
-union bad_union { // expected-note {{marked deleted here}}
+union bad_union { // expected-note {{defined here}}
   non_trivial nt;
 };
-bad_union u; // expected-error {{call to deleted constructor}}
-union bad_union2 { // expected-note {{marked deleted here}}
+bad_union u; // expected-error {{call to implicitly-deleted default constructor}}
+union bad_union2 { // expected-note {{defined here}}
   const int i;
 };
-bad_union2 u2; // expected-error {{call to deleted constructor}}
+bad_union2 u2; // expected-error {{call to implicitly-deleted default constructor}}
 
-struct bad_anon { // expected-note {{marked deleted here}}
+struct bad_anon { // expected-note {{defined here}}
   union {
     non_trivial nt;
   };
 };
-bad_anon a; // expected-error {{call to deleted constructor}}
-struct bad_anon2 { // expected-note {{marked deleted here}}
+bad_anon a; // expected-error {{call to implicitly-deleted default constructor}}
+struct bad_anon2 { // expected-note {{defined here}}
   union {
     const int i;
   };
 };
-bad_anon2 a2; // expected-error {{call to deleted constructor}}
+bad_anon2 a2; // expected-error {{call to implicitly-deleted default constructor}}
 
 // This would be great except that we implement
 union good_union {
@@ -48,10 +48,10 @@
 };
 good g;
 
-struct bad_const { // expected-note {{marked deleted here}}
+struct bad_const { // expected-note {{defined here}}
   const good g;
 };
-bad_const bc; // expected-error {{call to deleted constructor}}
+bad_const bc; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct good_const {
   const non_trivial nt;
@@ -65,38 +65,38 @@
   ~no_dtor() = delete;
 };
 
-struct bad_field_default { // expected-note {{marked deleted here}}
+struct bad_field_default { // expected-note {{defined here}}
   no_default nd;
 };
-bad_field_default bfd; // expected-error {{call to deleted constructor}}
-struct bad_base_default : no_default { // expected-note {{marked deleted here}}
+bad_field_default bfd; // expected-error {{call to implicitly-deleted default constructor}}
+struct bad_base_default : no_default { // expected-note {{defined here}}
 };
-bad_base_default bbd; // expected-error {{call to deleted constructor}}
+bad_base_default bbd; // expected-error {{call to implicitly-deleted default constructor}}
 
-struct bad_field_dtor { // expected-note {{marked deleted here}}
+struct bad_field_dtor { // expected-note {{defined here}}
   no_dtor nd;
 };
-bad_field_dtor bfx; // expected-error {{call to deleted constructor}}
-struct bad_base_dtor : no_dtor { // expected-note {{marked deleted here}}
+bad_field_dtor bfx; // expected-error {{call to implicitly-deleted default constructor}}
+struct bad_base_dtor : no_dtor { // expected-note {{defined here}}
 };
-bad_base_dtor bbx; // expected-error {{call to deleted constructor}}
+bad_base_dtor bbx; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct ambiguous_default {
   ambiguous_default();
   ambiguous_default(int = 2);
 };
-struct has_amb_field { // expected-note {{marked deleted here}}
+struct has_amb_field { // expected-note {{defined here}}
   ambiguous_default ad;
 };
-has_amb_field haf; // expected-error {{call to deleted constructor}}
+has_amb_field haf; // expected-error {{call to implicitly-deleted default constructor}}
 
 class inaccessible_default {
   inaccessible_default();
 };
-struct has_inacc_field { // expected-note {{marked deleted here}}
+struct has_inacc_field { // expected-note {{defined here}}
   inaccessible_default id;
 };
-has_inacc_field hif; // expected-error {{call to deleted constructor}}
+has_inacc_field hif; // expected-error {{call to implicitly-deleted default constructor}}
 
 class friend_default {
   friend struct has_friend;
@@ -107,11 +107,11 @@
 };
 has_friend hf;
 
-struct defaulted_delete {
+struct defaulted_delete { // expected-note {{defined here}}
   no_default nd;
-  defaulted_delete() = default; // expected-note {{marked deleted here}}
+  defaulted_delete() = default; // expected-note{{declared here}}
 };
-defaulted_delete dd; // expected-error {{call to deleted constructor}}
+defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct late_delete {
   no_default nd;
@@ -121,12 +121,11 @@
 
 // See also rdar://problem/8125400.
 namespace empty {
-  static union {}; // expected-error {{deleted constructor}} expected-note {{here}}
-  static union { union {}; };
+  static union {}; // expected-error {{implicitly-deleted default constructor}} expected-note {{here}}
+  static union { union {}; }; // expected-error {{implicitly-deleted default constructor}} expected-note {{here}}
   static union { struct {}; };
-  static union { union { union {}; }; };
+  static union { union { union {}; }; }; // expected-error {{implicitly-deleted default constructor}} expected-note {{here}}
   static union { union { struct {}; }; };
-  static union { struct { union {}; }; }; // expected-error {{deleted constructor}} expected-note {{here}}
+  static union { struct { union {}; }; }; // expected-error {{implicitly-deleted default constructor}} expected-note {{here}}
   static union { struct { struct {}; }; };
 }
-

Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp Mon Feb 20 19:34:24 2012
@@ -71,5 +71,5 @@
     static_assert(sizeof(overloaded({1})) == sizeof(one), "bad overload");
   }
 
-  struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{array initializer must be an initializer list}}
+  struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{parenthesized initialization of a member array is a GNU extension}}
 }

Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-nontrivial-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-nontrivial-union.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-nontrivial-union.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-nontrivial-union.cpp Mon Feb 20 19:34:24 2012
@@ -11,8 +11,13 @@
   non_trivial nt;
 };
 
+union static_data_member {
+  static int i;
+};
+int static_data_member::i;
+
 union bad {
-  static int i; // expected-error {{static data member}}
+  int &i; // expected-error {{union member 'i' has reference type 'int &'}}
 };
 
 struct s {

Modified: cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp?rev=151016&r1=151015&r2=151016&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp Mon Feb 20 19:34:24 2012
@@ -34,8 +34,7 @@
 }
 
 void Lambda() {
-  // FIXME: Enable when lambdas are minimally working.
-  //[]{}; // FIXME-warning {{lambda expressions are incompatible with C++98}}
+  []{}(); // expected-warning {{lambda expressions are incompatible with C++98}}
 }
 
 int InitList() {
@@ -239,6 +238,11 @@
       NonTrivDtor ntd; // expected-warning {{anonymous struct member 'ntd' with a non-trivial destructor is incompatible with C++98}}
     };
   };
+  union WithStaticDataMember {
+    static constexpr double d = 0.0; // expected-warning {{static data member 'd' in union is incompatible with C++98}} expected-warning {{'constexpr' specifier is incompatible with C++98}}
+    static const int n = 0; // expected-warning {{static data member 'n' in union is incompatible with C++98}}
+    static int k; // expected-warning {{static data member 'k' in union is incompatible with C++98}}
+  };
 }
 
 int EnumNNS = Enum::enum_val; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}}





More information about the llvm-branch-commits mailing list