[llvm-branch-commits] [cfe-branch] r150465 - in /cfe/branches/tooling: ./ clang.xcodeproj/ docs/ examples/ examples/analyzer-plugin/ examples/clang-interpreter/ examples/wpa/ include/clang/AST/ include/clang/Analysis/ include/clang/Analysis/Analyses/ include/clang/Basic/ include/clang/Driver/ include/clang/Frontend/ include/clang/Lex/ include/clang/Parse/ include/clang/Rewrite/ include/clang/Sema/ include/clang/Serialization/ include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/BugReporter/ include/clang/Stati...
Manuel Klimek
klimek at google.com
Tue Feb 14 01:11:11 PST 2012
Author: klimek
Date: Tue Feb 14 03:11:10 2012
New Revision: 150465
URL: http://llvm.org/viewvc/llvm-project?rev=150465&view=rev
Log:
Merging mainline.
Removed:
cfe/branches/tooling/clang.xcodeproj/
cfe/branches/tooling/include/clang/Sema/MultiInitializer.h
cfe/branches/tooling/lib/CodeGen/CGException.h
cfe/branches/tooling/lib/Sema/MultiInitializer.cpp
cfe/branches/tooling/test/AST/
cfe/branches/tooling/test/Driver/prefixed-tools.c-helper/
cfe/branches/tooling/test/Lexer/Inputs/
cfe/branches/tooling/test/Sema/paren-list-expr-type.cpp
cfe/branches/tooling/test/SemaCXX/constexpr-sysheaders.cpp
cfe/branches/tooling/test/SemaCXX/generalized-initializers.cpp
cfe/branches/tooling/test/Tooling/
cfe/branches/tooling/www/analyzer/downloads/
Modified:
cfe/branches/tooling/ (props changed)
cfe/branches/tooling/docs/UsersManual.html
cfe/branches/tooling/examples/CMakeLists.txt
cfe/branches/tooling/examples/Makefile
cfe/branches/tooling/examples/analyzer-plugin/CMakeLists.txt
cfe/branches/tooling/examples/analyzer-plugin/MainCallChecker.cpp
cfe/branches/tooling/examples/analyzer-plugin/Makefile
cfe/branches/tooling/examples/clang-interpreter/main.cpp
cfe/branches/tooling/examples/wpa/clang-wpa.cpp
cfe/branches/tooling/include/clang/AST/ASTConsumer.h
cfe/branches/tooling/include/clang/AST/ASTContext.h
cfe/branches/tooling/include/clang/AST/ASTDiagnostic.h
cfe/branches/tooling/include/clang/AST/ASTMutationListener.h
cfe/branches/tooling/include/clang/AST/CanonicalType.h
cfe/branches/tooling/include/clang/AST/Decl.h
cfe/branches/tooling/include/clang/AST/DeclBase.h
cfe/branches/tooling/include/clang/AST/DeclCXX.h
cfe/branches/tooling/include/clang/AST/DeclObjC.h
cfe/branches/tooling/include/clang/AST/DeclarationName.h
cfe/branches/tooling/include/clang/AST/Expr.h
cfe/branches/tooling/include/clang/AST/ExprCXX.h
cfe/branches/tooling/include/clang/AST/Mangle.h
cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h
cfe/branches/tooling/include/clang/AST/Type.h
cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h
cfe/branches/tooling/include/clang/Analysis/AnalysisDiagnostic.h
cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def
cfe/branches/tooling/include/clang/Basic/Diagnostic.h
cfe/branches/tooling/include/clang/Basic/Diagnostic.td
cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticAnalysisKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticDriverKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticFrontendKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h
cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h
cfe/branches/tooling/include/clang/Driver/CC1AsOptions.td
cfe/branches/tooling/include/clang/Driver/DriverDiagnostic.h
cfe/branches/tooling/include/clang/Frontend/DiagnosticRenderer.h
cfe/branches/tooling/include/clang/Frontend/FrontendDiagnostic.h
cfe/branches/tooling/include/clang/Frontend/MultiplexConsumer.h
cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h
cfe/branches/tooling/include/clang/Lex/LexDiagnostic.h
cfe/branches/tooling/include/clang/Lex/LiteralSupport.h
cfe/branches/tooling/include/clang/Lex/PPCallbacks.h
cfe/branches/tooling/include/clang/Lex/PTHManager.h
cfe/branches/tooling/include/clang/Lex/Preprocessor.h
cfe/branches/tooling/include/clang/Parse/ParseDiagnostic.h
cfe/branches/tooling/include/clang/Parse/Parser.h
cfe/branches/tooling/include/clang/Rewrite/ASTConsumers.h
cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h
cfe/branches/tooling/include/clang/Sema/DeclSpec.h
cfe/branches/tooling/include/clang/Sema/DelayedDiagnostic.h
cfe/branches/tooling/include/clang/Sema/Initialization.h
cfe/branches/tooling/include/clang/Sema/ScopeInfo.h
cfe/branches/tooling/include/clang/Sema/Sema.h
cfe/branches/tooling/include/clang/Sema/SemaDiagnostic.h
cfe/branches/tooling/include/clang/Sema/SemaFixItUtils.h
cfe/branches/tooling/include/clang/Serialization/ASTReader.h
cfe/branches/tooling/include/clang/Serialization/ASTWriter.h
cfe/branches/tooling/include/clang/Serialization/SerializationDiagnostic.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
cfe/branches/tooling/lib/AST/ASTContext.cpp
cfe/branches/tooling/lib/AST/ASTImporter.cpp
cfe/branches/tooling/lib/AST/Decl.cpp
cfe/branches/tooling/lib/AST/DeclBase.cpp
cfe/branches/tooling/lib/AST/DeclCXX.cpp
cfe/branches/tooling/lib/AST/DeclObjC.cpp
cfe/branches/tooling/lib/AST/DeclPrinter.cpp
cfe/branches/tooling/lib/AST/DeclarationName.cpp
cfe/branches/tooling/lib/AST/DumpXML.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/NestedNameSpecifier.cpp
cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp
cfe/branches/tooling/lib/AST/StmtPrinter.cpp
cfe/branches/tooling/lib/AST/Type.cpp
cfe/branches/tooling/lib/AST/TypePrinter.cpp
cfe/branches/tooling/lib/Basic/Diagnostic.cpp
cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp
cfe/branches/tooling/lib/Basic/Targets.cpp
cfe/branches/tooling/lib/CodeGen/BackendUtil.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/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/CGExprConstant.cpp
cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
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/CodeGenTBAA.cpp
cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp
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/DiagnosticRenderer.cpp
cfe/branches/tooling/lib/Frontend/MultiplexConsumer.cpp
cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp
cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp
cfe/branches/tooling/lib/FrontendTool/ExecuteCompilerInvocation.cpp
cfe/branches/tooling/lib/Headers/avx2intrin.h
cfe/branches/tooling/lib/Headers/avxintrin.h
cfe/branches/tooling/lib/Lex/LiteralSupport.cpp
cfe/branches/tooling/lib/Lex/Preprocessor.cpp
cfe/branches/tooling/lib/Parse/ParseAST.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/ParseObjc.cpp
cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
cfe/branches/tooling/lib/Parse/Parser.cpp
cfe/branches/tooling/lib/Rewrite/CMakeLists.txt
cfe/branches/tooling/lib/Rewrite/FrontendActions.cpp
cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp
cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp
cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp
cfe/branches/tooling/lib/Sema/CMakeLists.txt
cfe/branches/tooling/lib/Sema/Sema.cpp
cfe/branches/tooling/lib/Sema/SemaCast.cpp
cfe/branches/tooling/lib/Sema/SemaChecking.cpp
cfe/branches/tooling/lib/Sema/SemaDecl.cpp
cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
cfe/branches/tooling/lib/Sema/SemaDeclObjC.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/SemaOverload.cpp
cfe/branches/tooling/lib/Sema/SemaStmt.cpp
cfe/branches/tooling/lib/Sema/SemaTemplate.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateDeduction.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.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/ASTReader.cpp
cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
cfe/branches/tooling/lib/Serialization/GeneratePCH.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CMakeLists.txt
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/Checkers.td
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/AnalysisManager.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
cfe/branches/tooling/test/ARCMT/checking.m
cfe/branches/tooling/test/Analysis/free.c
cfe/branches/tooling/test/Analysis/malloc.c
cfe/branches/tooling/test/Analysis/system-header-simulator.h
cfe/branches/tooling/test/CXX/basic/basic.types/p10.cpp
cfe/branches/tooling/test/CXX/class/class.friend/p1.cpp
cfe/branches/tooling/test/CXX/class/class.local/p1-0x.cpp
cfe/branches/tooling/test/CXX/class/class.static/class.static.data/p3.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.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/p10.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/p15.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/p8.cpp
cfe/branches/tooling/test/CXX/special/class.ctor/p6-0x.cpp
cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
cfe/branches/tooling/test/CodeGen/arm-arguments.c
cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c
cfe/branches/tooling/test/CodeGen/avx2-builtins.c
cfe/branches/tooling/test/CodeGen/builtins-x86.c
cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp
cfe/branches/tooling/test/CodeGenCXX/debug-info-limit-type.cpp
cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp
cfe/branches/tooling/test/FixIt/fixit.cpp
cfe/branches/tooling/test/Index/annotate-tokens.cpp
cfe/branches/tooling/test/Index/index-refs.cpp
cfe/branches/tooling/test/Index/recursive-cxx-member-calls.cpp
cfe/branches/tooling/test/Lexer/char-literal-encoding-error.c
cfe/branches/tooling/test/Lexer/hexfloat.cpp
cfe/branches/tooling/test/Lexer/string-literal-encoding.c
cfe/branches/tooling/test/Misc/warning-flags.c
cfe/branches/tooling/test/Parser/cxx-default-delete.cpp
cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp
cfe/branches/tooling/test/Parser/objcxx-lambda-expressions-neg.mm
cfe/branches/tooling/test/Parser/objcxx0x-lambda-expressions.mm
cfe/branches/tooling/test/Sema/atomic-type.c
cfe/branches/tooling/test/Sema/format-strings.c
cfe/branches/tooling/test/Sema/init.c
cfe/branches/tooling/test/Sema/switch.c
cfe/branches/tooling/test/SemaCXX/alias-template.cpp
cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
cfe/branches/tooling/test/SemaCXX/constexpr-nqueens.cpp
cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp
cfe/branches/tooling/test/SemaCXX/copy-initialization.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-defaulted-functions.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-references.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-scalars.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp
cfe/branches/tooling/test/SemaCXX/destructor.cpp
cfe/branches/tooling/test/SemaCXX/format-strings-0x.cpp
cfe/branches/tooling/test/SemaCXX/format-strings.cpp
cfe/branches/tooling/test/SemaCXX/function-type-qual.cpp
cfe/branches/tooling/test/SemaCXX/goto.cpp
cfe/branches/tooling/test/SemaCXX/issue547.cpp
cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp
cfe/branches/tooling/test/SemaCXX/literal-type.cpp
cfe/branches/tooling/test/SemaCXX/trailing-return-0x.cpp
cfe/branches/tooling/test/SemaCXX/undefined-internal.cpp
cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp (props changed)
cfe/branches/tooling/test/SemaObjC/arc-objc-lifetime.m
cfe/branches/tooling/test/SemaObjC/arc.m
cfe/branches/tooling/test/SemaObjC/attr-deprecated.m
cfe/branches/tooling/test/SemaObjC/invalid-code.m
cfe/branches/tooling/test/SemaObjC/method-undef-category-warn-1.m
cfe/branches/tooling/test/SemaObjC/missing-atend-metadata.m
cfe/branches/tooling/test/SemaObjCXX/arc-templates.mm
cfe/branches/tooling/test/SemaTemplate/instantiate-complete.cpp
cfe/branches/tooling/test/lit.cfg
cfe/branches/tooling/tools/arcmt-test/arcmt-test.cpp
cfe/branches/tooling/tools/c-index-test/c-index-test.c
cfe/branches/tooling/tools/driver/CMakeLists.txt
cfe/branches/tooling/tools/driver/cc1_main.cpp
cfe/branches/tooling/tools/driver/cc1as_main.cpp
cfe/branches/tooling/tools/driver/driver.cpp
cfe/branches/tooling/tools/libclang/ARCMigrate.cpp
cfe/branches/tooling/tools/libclang/CIndex.cpp
cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp
cfe/branches/tooling/tools/libclang/CIndexDiagnostic.cpp
cfe/branches/tooling/tools/libclang/CIndexDiagnostic.h
cfe/branches/tooling/tools/libclang/CIndexUSRs.cpp
cfe/branches/tooling/tools/libclang/CXLoadedDiagnostic.cpp
cfe/branches/tooling/tools/libclang/CXString.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/Basic/SourceManagerTest.cpp
cfe/branches/tooling/utils/TableGen/ClangAttrEmitter.cpp
cfe/branches/tooling/utils/TableGen/ClangDiagnosticsEmitter.cpp
cfe/branches/tooling/www/get_started.html
cfe/branches/tooling/www/hacking.html
Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Feb 14 03:11:10 2012
@@ -1,3 +1,3 @@
/cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-149982
+/cfe/trunk:146581-150463
/cfe/trunk/test/SemaTemplate:126920
Modified: cfe/branches/tooling/docs/UsersManual.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/UsersManual.html?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/docs/UsersManual.html (original)
+++ cfe/branches/tooling/docs/UsersManual.html Tue Feb 14 03:11:10 2012
@@ -99,7 +99,7 @@
an end-user, documenting the supported features, command line options, etc. If
you are interested in using Clang to build a tool that processes code, please
see <a href="InternalsManual.html">the Clang Internals Manual</a>. If you are
-interested in the <a href="http://clang.llvm.org/StaticAnalysis.html">Clang
+interested in the <a href="http://clang-analyzer.llvm.org">Clang
Static Analyzer</a>, please see its web page.</p>
<p>Clang is designed to support the C family of programming languages, which
Modified: cfe/branches/tooling/examples/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/CMakeLists.txt?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/CMakeLists.txt (original)
+++ cfe/branches/tooling/examples/CMakeLists.txt Tue Feb 14 03:11:10 2012
@@ -2,5 +2,6 @@
set(EXCLUDE_FROM_ALL ON)
endif()
+add_subdirectory(analyzer-plugin)
add_subdirectory(clang-interpreter)
add_subdirectory(PrintFunctionNames)
Modified: cfe/branches/tooling/examples/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/Makefile?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/Makefile (original)
+++ cfe/branches/tooling/examples/Makefile Tue Feb 14 03:11:10 2012
@@ -9,6 +9,6 @@
CLANG_LEVEL := ..
-PARALLEL_DIRS := clang-interpreter PrintFunctionNames
+PARALLEL_DIRS := analyzer-plugin clang-interpreter PrintFunctionNames
include $(CLANG_LEVEL)/Makefile
Modified: cfe/branches/tooling/examples/analyzer-plugin/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/analyzer-plugin/CMakeLists.txt?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/analyzer-plugin/CMakeLists.txt (original)
+++ cfe/branches/tooling/examples/analyzer-plugin/CMakeLists.txt Tue Feb 14 03:11:10 2012
@@ -6,7 +6,7 @@
set( LLVM_LINK_COMPONENTS support mc)
-add_clang_library(SampleAnalyzerPlugin SampleAnalyzerPlugin)
+add_clang_library(SampleAnalyzerPlugin MainCallChecker.cpp)
set_target_properties(SampleAnalyzerPlugin
PROPERTIES
Modified: cfe/branches/tooling/examples/analyzer-plugin/MainCallChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/analyzer-plugin/MainCallChecker.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/analyzer-plugin/MainCallChecker.cpp (original)
+++ cfe/branches/tooling/examples/analyzer-plugin/MainCallChecker.cpp Tue Feb 14 03:11:10 2012
@@ -8,7 +8,7 @@
namespace {
class MainCallChecker : public Checker < check::PreStmt<CallExpr> > {
- mutable llvm::OwningPtr<BugType> BT;
+ mutable OwningPtr<BugType> BT;
public:
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -16,9 +16,10 @@
} // end anonymous namespace
void MainCallChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
- const ProgramState *state = C.getState();
+ const ProgramStateRef state = C.getState();
+ const LocationContext *LC = C.getLocationContext();
const Expr *Callee = CE->getCallee();
- const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl();
+ const FunctionDecl *FD = state->getSVal(Callee, LC).getAsFunctionDecl();
if (!FD)
return;
Modified: cfe/branches/tooling/examples/analyzer-plugin/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/analyzer-plugin/Makefile?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/analyzer-plugin/Makefile (original)
+++ cfe/branches/tooling/examples/analyzer-plugin/Makefile Tue Feb 14 03:11:10 2012
@@ -11,7 +11,7 @@
LIBRARYNAME = SampleAnalyzerPlugin
LINK_LIBS_IN_SHARED = 0
-SHARED_LIBRARY = 1
+LOADABLE_MODULE = 1
include $(CLANG_LEVEL)/Makefile
Modified: cfe/branches/tooling/examples/clang-interpreter/main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/clang-interpreter/main.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/clang-interpreter/main.cpp (original)
+++ cfe/branches/tooling/examples/clang-interpreter/main.cpp Tue Feb 14 03:11:10 2012
@@ -46,7 +46,7 @@
llvm::InitializeNativeTarget();
std::string Error;
- llvm::OwningPtr<llvm::ExecutionEngine> EE(
+ OwningPtr<llvm::ExecutionEngine> EE(
llvm::ExecutionEngine::createJIT(Mod, &Error));
if (!EE) {
llvm::errs() << "unable to make execution engine: " << Error << "\n";
@@ -83,7 +83,7 @@
// (basically, exactly one input, and the operation mode is hard wired).
llvm::SmallVector<const char *, 16> Args(argv, argv + argc);
Args.push_back("-fsyntax-only");
- llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args));
+ OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args));
if (!C)
return 0;
@@ -93,7 +93,7 @@
// failed. Extract that job from the compilation.
const driver::JobList &Jobs = C->getJobs();
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
- llvm::SmallString<256> Msg;
+ SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
C->PrintJob(OS, C->getJobs(), "; ", true);
Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
@@ -108,7 +108,7 @@
// Initialize a compiler invocation object from the clang (-cc1) arguments.
const driver::ArgStringList &CCArgs = Cmd->getArguments();
- llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
+ OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
CompilerInvocation::CreateFromArgs(*CI,
const_cast<const char **>(CCArgs.data()),
const_cast<const char **>(CCArgs.data()) +
@@ -140,7 +140,7 @@
CompilerInvocation::GetResourcesPath(argv[0], MainAddr);
// Create and execute the frontend to generate an LLVM bitcode module.
- llvm::OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction());
+ OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction());
if (!Clang.ExecuteAction(*Act))
return 1;
Modified: cfe/branches/tooling/examples/wpa/clang-wpa.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/examples/wpa/clang-wpa.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/examples/wpa/clang-wpa.cpp (original)
+++ cfe/branches/tooling/examples/wpa/clang-wpa.cpp Tue Feb 14 03:11:10 2012
@@ -94,7 +94,7 @@
= CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
const std::string &InFile = InputFilenames[i];
- llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags,
+ OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags,
FileSystemOptions(),
false, 0, 0, true));
if (!AST)
@@ -104,7 +104,7 @@
}
if (ViewCallGraph) {
- llvm::OwningPtr<CallGraph> CG;
+ OwningPtr<CallGraph> CG;
CG.reset(new CallGraph(Prog));
for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
@@ -154,7 +154,7 @@
if (PP.getLangOptions().ObjC1)
Opts.CheckersControlList.push_back(std::make_pair("cocoa", true));
- llvm::OwningPtr<ento::CheckerManager> checkerMgr;
+ OwningPtr<ento::CheckerManager> checkerMgr;
checkerMgr.reset(ento::registerCheckers(Opts, PP.getLangOptions(),
PP.getDiagnostics()));
Modified: cfe/branches/tooling/include/clang/AST/ASTConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ASTConsumer.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTConsumer.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTConsumer.h Tue Feb 14 03:11:10 2012
@@ -24,6 +24,7 @@
class SemaConsumer; // layering violation required for safe SemaConsumer
class TagDecl;
class VarDecl;
+ class FunctionDecl;
/// ASTConsumer - This is an abstract interface that should be implemented by
/// clients that read ASTs. This abstraction layer allows the client to be
@@ -67,6 +68,12 @@
/// can be defined in declspecs).
virtual void HandleTagDeclDefinition(TagDecl *D) {}
+ /// \brief Invoked when a function is implicitly instantiated.
+ /// Note that at this point point it does not have a body, its body is
+ /// instantiated at the end of the translation unit and passed to
+ /// HandleTopLevelDecl.
+ virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
+
/// \brief Handle the specified top-level declaration that occurred inside
/// and ObjC container.
/// The default implementation ignored them.
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTContext.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTContext.h Tue Feb 14 03:11:10 2012
@@ -18,6 +18,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/VersionTuple.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
@@ -48,7 +49,6 @@
class ExternalASTSource;
class ASTMutationListener;
class IdentifierTable;
- class PartialDiagnosticStorageAllocator;
class SelectorTable;
class SourceManager;
class TargetInfo;
@@ -346,7 +346,7 @@
mutable llvm::BumpPtrAllocator BumpAlloc;
/// \brief Allocator for partial diagnostics.
- PartialDiagnosticStorageAllocator *DiagAllocator;
+ PartialDiagnostic::StorageAllocator DiagAllocator;
/// \brief The current C++ ABI.
OwningPtr<CXXABI> ABI;
@@ -358,7 +358,8 @@
friend class ASTDeclReader;
friend class ASTReader;
friend class ASTWriter;
-
+ friend class CXXRecordDecl;
+
const TargetInfo *Target;
clang::PrintingPolicy PrintingPolicy;
@@ -391,8 +392,8 @@
/// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const;
- PartialDiagnosticStorageAllocator &getDiagAllocator() {
- return *DiagAllocator;
+ PartialDiagnostic::StorageAllocator &getDiagAllocator() {
+ return DiagAllocator;
}
const TargetInfo &getTargetInfo() const { return *Target; }
@@ -870,7 +871,7 @@
QualType getTypeOfType(QualType t) const;
/// getDecltypeType - C++0x decltype.
- QualType getDecltypeType(Expr *e) const;
+ QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
/// getUnaryTransformType - unary type transforms
QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
@@ -1134,6 +1135,11 @@
return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
}
+ /// getQualifiedType - Un-split a SplitQualType.
+ QualType getQualifiedType(SplitQualType split) const {
+ return getQualifiedType(split.Ty, split.Quals);
+ }
+
/// getQualifiedType - Returns a type with additional qualifiers.
QualType getQualifiedType(QualType T, Qualifiers Qs) const {
if (!Qs.hasNonFastQualifiers())
Modified: cfe/branches/tooling/include/clang/AST/ASTDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ASTDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define ASTSTART
#include "clang/Basic/DiagnosticASTKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/AST/ASTMutationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ASTMutationListener.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTMutationListener.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTMutationListener.h Tue Feb 14 03:11:10 2012
@@ -74,6 +74,9 @@
virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
const ObjCPropertyDecl *OrigProp,
const ObjCCategoryDecl *ClassExt) {}
+
+ // NOTE: If new methods are added they should also be added to
+ // MultiplexASTMutationListener.
};
} // end namespace clang
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/CanonicalType.h (original)
+++ cfe/branches/tooling/include/clang/AST/CanonicalType.h Tue Feb 14 03:11:10 2012
@@ -200,7 +200,11 @@
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
}
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, CanQualType T);
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ CanQualType T) {
+ DB << static_cast<QualType>(T);
+ return DB;
+}
//----------------------------------------------------------------------------//
// Internal proxy classes used by canonical types
Modified: cfe/branches/tooling/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Decl.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Decl.h (original)
+++ cfe/branches/tooling/include/clang/AST/Decl.h Tue Feb 14 03:11:10 2012
@@ -41,11 +41,7 @@
class UnresolvedSetImpl;
class LabelStmt;
class Module;
-
-// Forward declare PartialDiagnosticAt.
-// FIXME: This shouldn't be here.
-typedef std::pair<SourceLocation, PartialDiagnostic> PartialDiagnosticAt;
-
+
/// \brief A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
@@ -685,6 +681,13 @@
/// It is illegal to call this function with SC == None.
static const char *getStorageClassSpecifierString(StorageClass SC);
+ /// \brief Initialization styles.
+ enum InitializationStyle {
+ CInit, ///< C-style initialization with assignment
+ CallInit, ///< Call-style initialization (C++98)
+ ListInit ///< Direct list-initialization (C++11)
+ };
+
protected:
/// \brief Placeholder type used in Init to denote an unparsed C++ default
/// argument.
@@ -710,7 +713,7 @@
unsigned SClass : 3;
unsigned SClassAsWritten : 3;
unsigned ThreadSpecified : 1;
- unsigned HasCXXDirectInit : 1;
+ unsigned InitStyle : 2;
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
@@ -732,7 +735,7 @@
/// \brief Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
};
- enum { NumVarDeclBits = 13 };
+ enum { NumVarDeclBits = 14 };
friend class ASTDeclReader;
friend class StmtIteratorBase;
@@ -760,7 +763,7 @@
/// Otherwise, the number of function parameter scopes enclosing
/// the function parameter scope in which this parameter was
/// declared.
- unsigned ScopeDepthOrObjCQuals : 8;
+ unsigned ScopeDepthOrObjCQuals : 7;
/// The number of parameters preceding this parameter in the
/// function parameter scope in which it was declared.
@@ -1077,16 +1080,27 @@
/// declaration is an integral constant expression.
bool checkInitIsICE() const;
- void setCXXDirectInitializer(bool T) { VarDeclBits.HasCXXDirectInit = T; }
+ void setInitStyle(InitializationStyle Style) {
+ VarDeclBits.InitStyle = Style;
+ }
- /// hasCXXDirectInitializer - If true, the initializer was a direct
- /// initializer, e.g: "int x(1);". The Init expression will be the expression
- /// inside the parens or a "ClassType(a,b,c)" class constructor expression for
- /// class types. Clients can distinguish between "int x(1);" and "int x=1;"
- /// by checking hasCXXDirectInitializer.
+ /// \brief The style of initialization for this declaration.
///
- bool hasCXXDirectInitializer() const {
- return VarDeclBits.HasCXXDirectInit;
+ /// C-style initialization is "int x = 1;". Call-style initialization is
+ /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
+ /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
+ /// expression for class types. List-style initialization is C++11 syntax,
+ /// e.g. "int x{1};". Clients can distinguish between different forms of
+ /// initialization by checking this value. In particular, "int x = {1};" is
+ /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
+ /// Init expression in all three cases is an InitListExpr.
+ InitializationStyle getInitStyle() const {
+ return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
+ }
+
+ /// \brief Whether the initializer is a direct-initializer (list or call).
+ bool isDirectInit() const {
+ return getInitStyle() != CInit;
}
/// \brief Determine whether this variable is the exception variable in a
@@ -2373,9 +2387,11 @@
/// a definition until the definition has been fully processed.
bool IsCompleteDefinition : 1;
+protected:
/// IsBeingDefined - True if this is currently being defined.
bool IsBeingDefined : 1;
+private:
/// IsEmbeddedInDeclarator - True if this tag declaration is
/// "embedded" (i.e., defined or declared for the very first time)
/// in the syntax of a declarator.
@@ -3179,11 +3195,18 @@
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const NamedDecl* ND);
-
-const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const NamedDecl* ND);
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const NamedDecl* ND) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+ DiagnosticsEngine::ak_nameddecl);
+ return DB;
+}
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const NamedDecl* ND) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+ DiagnosticsEngine::ak_nameddecl);
+ return PD;
+}
template<typename decl_type>
void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
Modified: cfe/branches/tooling/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclBase.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclBase.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclBase.h Tue Feb 14 03:11:10 2012
@@ -389,7 +389,9 @@
}
bool hasAttrs() const { return HasAttrs; }
- void setAttrs(const AttrVec& Attrs);
+ void setAttrs(const AttrVec& Attrs) {
+ return setAttrsImpl(Attrs, getASTContext());
+ }
AttrVec &getAttrs() {
return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
}
@@ -852,6 +854,9 @@
private:
const Attr *getAttrsImpl() const;
+ void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
+ void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
+ ASTContext &Ctx);
protected:
ASTMutationListener *getASTMutationListener() const;
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclCXX.h Tue Feb 14 03:11:10 2012
@@ -16,9 +16,11 @@
#define LLVM_CLANG_AST_DECLCXX_H
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/Decl.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/UnresolvedSet.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -37,6 +39,7 @@
class CXXFinalOverriderMap;
class CXXIndirectPrimaryBaseSet;
class FriendDecl;
+class LambdaExpr;
/// \brief Represents any kind of function declaration, whether it is a
/// concrete function or a function template.
@@ -467,7 +470,8 @@
bool HasTrivialDestructor : 1;
/// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
- /// one non-static data member or base class of non literal type.
+ /// one non-static data member or base class of non-literal or volatile
+ /// type.
bool HasNonLiteralTypeFieldsOrBases : 1;
/// ComputedVisibleConversions - True when visible conversion functions are
@@ -552,6 +556,27 @@
}
} *DefinitionData;
+ /// \brief Describes a C++ closure type (generated by a lambda expression).
+ struct LambdaDefinitionData : public DefinitionData {
+ typedef LambdaExpr::Capture Capture;
+
+ LambdaDefinitionData(CXXRecordDecl *D)
+ : DefinitionData(D), NumCaptures(0), NumExplicitCaptures(0), Captures(0) {
+ IsLambda = true;
+ }
+
+ /// \brief The number of captures in this lambda.
+ unsigned NumCaptures : 16;
+
+ /// \brief The number of explicit captures in this lambda.
+ unsigned NumExplicitCaptures : 15;
+
+ /// \brief The "extra" data associated with the lambda, including
+ /// captures, capture initializers, the body of the lambda, and the
+ /// array-index variables for array captures.
+ Capture *Captures;
+ };
+
struct DefinitionData &data() {
assert(DefinitionData && "queried property of class with no definition");
return *DefinitionData;
@@ -562,6 +587,13 @@
return *DefinitionData;
}
+ struct LambdaDefinitionData &getLambdaData() const {
+ assert(DefinitionData && "queried property of lambda with no definition");
+ assert(DefinitionData->IsLambda &&
+ "queried lambda property of non-lambda class");
+ return static_cast<LambdaDefinitionData &>(*DefinitionData);
+ }
+
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
@@ -575,6 +607,7 @@
TemplateOrInstantiation;
friend class DeclContext;
+ friend class LambdaExpr;
/// \brief Notify the class that member has been added.
///
@@ -644,6 +677,8 @@
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
+ static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
+ SourceLocation Loc);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
bool isDynamicClass() const {
@@ -925,7 +960,17 @@
/// \brief Determine whether this class describes a lambda function object.
bool isLambda() const { return hasDefinition() && data().IsLambda; }
- void setLambda(bool Lambda = true) { data().IsLambda = Lambda; }
+ /// \brief For a closure type, retrieve the mapping from captured
+ /// variables and this to the non-static data members that store the
+ /// values or references of the captures.
+ ///
+ /// \param Captures Will be populated with the mapping from captured
+ /// variables to the corresponding fields.
+ ///
+ /// \param ThisCapture Will be set to the field declaration for the
+ /// 'this' capture.
+ void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
+ FieldDecl *&ThisCapture) const;
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
@@ -1077,8 +1122,8 @@
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
- // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal type
- // non-static data member or base class.
+ // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or
+ // volatile type non-static data member or base class.
bool hasNonLiteralTypeFieldsOrBases() const {
return data().HasNonLiteralTypeFieldsOrBases;
}
@@ -1098,20 +1143,23 @@
// isLiteral - Whether this class is a literal type.
//
- // C++0x [basic.types]p10
+ // C++11 [basic.types]p10
// A class type that has all the following properties:
- // -- a trivial destructor
+ // -- it has a trivial destructor
// -- every constructor call and full-expression in the
// brace-or-equal-intializers for non-static data members (if any) is
// a constant expression.
// -- it is an aggregate type or has at least one constexpr constructor or
// constructor template that is not a copy or move constructor, and
- // -- all non-static data members and base classes of literal types
+ // -- all of its non-static data members and base classes are of literal
+ // types
//
- // We resolve DR1361 by ignoring the second bullet.
+ // We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
+ // treating types with trivial default constructors as literal types.
bool isLiteral() const {
return hasTrivialDestructor() &&
- (isAggregate() || hasConstexprNonCopyMoveConstructor()) &&
+ (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
+ hasTrivialDefaultConstructor()) &&
!hasNonLiteralTypeFieldsOrBases();
}
@@ -1761,6 +1809,11 @@
assert(I < getNumArrayIndices() && "Out of bounds member array index");
reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
}
+ ArrayRef<VarDecl *> getArrayIndexes() {
+ assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
+ return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
+ getNumArrayIndices());
+ }
/// \brief Get the initializer. This is 0 if this is an in-class initializer
/// for a non-static data member which has not yet been parsed.
Modified: cfe/branches/tooling/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclObjC.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclObjC.h Tue Feb 14 03:11:10 2012
@@ -898,12 +898,15 @@
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
+ ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
+ bool noCategoryLookup= false) const;
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
+ bool noCategoryLookup = false) const {
+ return lookupMethod(Sel, true/*isInstance*/, noCategoryLookup);
+ }
+ ObjCMethodDecl *lookupClassMethod(Selector Sel,
+ bool noCategoryLookup = false) const {
+ return lookupMethod(Sel, false/*isInstance*/, noCategoryLookup);
}
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
Modified: cfe/branches/tooling/include/clang/AST/DeclarationName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclarationName.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclarationName.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclarationName.h Tue Feb 14 03:11:10 2012
@@ -16,6 +16,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
+#include "clang/Basic/PartialDiagnostic.h"
namespace llvm {
template <typename T> struct DenseMapInfo;
@@ -510,22 +511,32 @@
SourceLocation getEndLoc() const;
/// getSourceRange - The range of the declaration name.
SourceRange getSourceRange() const {
- return SourceRange(getBeginLoc(), getEndLoc());
+ SourceLocation BeginLoc = getBeginLoc();
+ SourceLocation EndLoc = getEndLoc();
+ return SourceRange(BeginLoc, EndLoc.isValid() ? EndLoc : BeginLoc);
}
};
/// Insertion operator for diagnostics. This allows sending DeclarationName's
/// into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- DeclarationName N);
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ DeclarationName N) {
+ DB.AddTaggedVal(N.getAsOpaqueInteger(),
+ DiagnosticsEngine::ak_declarationname);
+ return DB;
+}
/// Insertion operator for partial diagnostics. This allows binding
/// DeclarationName's into a partial diagnostic with <<.
-const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- DeclarationName N);
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ DeclarationName N) {
+ PD.AddTaggedVal(N.getAsOpaqueInteger(),
+ DiagnosticsEngine::ak_declarationname);
+ return PD;
+}
inline raw_ostream &operator<<(raw_ostream &OS,
- DeclarationNameInfo DNInfo) {
+ DeclarationNameInfo DNInfo) {
DNInfo.printName(OS);
return OS;
}
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Expr.h (original)
+++ cfe/branches/tooling/include/clang/AST/Expr.h Tue Feb 14 03:11:10 2012
@@ -3977,7 +3977,7 @@
public:
ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
- unsigned numexprs, SourceLocation rparenloc, QualType T);
+ unsigned numexprs, SourceLocation rparenloc);
/// \brief Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ExprCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/ExprCXX.h Tue Feb 14 03:11:10 2012
@@ -812,6 +812,7 @@
unsigned NumArgs : 16;
bool Elidable : 1;
bool HadMultipleCandidates : 1;
+ bool ListInitialization : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
@@ -822,32 +823,36 @@
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
bool HadMultipleCandidates,
- bool ZeroInitialization = false,
- ConstructionKind ConstructKind = CK_Complete,
- SourceRange ParenRange = SourceRange());
+ bool ListInitialization,
+ bool ZeroInitialization,
+ ConstructionKind ConstructKind,
+ SourceRange ParenRange);
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(0),
- HadMultipleCandidates(false), ZeroInitialization(0),
- ConstructKind(0), Args(0) { }
+ : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(false),
+ HadMultipleCandidates(false), ListInitialization(false),
+ ZeroInitialization(false), ConstructKind(0), Args(0)
+ { }
public:
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
: Expr(CXXConstructExprClass, Empty), Constructor(0),
- NumArgs(0), Elidable(0), HadMultipleCandidates(false),
- ZeroInitialization(0), ConstructKind(0), Args(0) { }
+ NumArgs(0), Elidable(false), HadMultipleCandidates(false),
+ ListInitialization(false), ZeroInitialization(false),
+ ConstructKind(0), Args(0)
+ { }
static CXXConstructExpr *Create(ASTContext &C, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool HadMultipleCandidates,
- bool ZeroInitialization = false,
- ConstructionKind ConstructKind = CK_Complete,
- SourceRange ParenRange = SourceRange());
-
+ bool ListInitialization,
+ bool ZeroInitialization,
+ ConstructionKind ConstructKind,
+ SourceRange ParenRange);
CXXConstructorDecl* getConstructor() const { return Constructor; }
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
@@ -864,6 +869,10 @@
bool hadMultipleCandidates() const { return HadMultipleCandidates; }
void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+ /// \brief Whether this constructor call was written as list-initialization.
+ bool isListInitialization() const { return ListInitialization; }
+ void setListInitialization(bool V) { ListInitialization = V; }
+
/// \brief Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
@@ -1039,12 +1048,9 @@
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
- /// \brief The number of captures in this lambda.
+ /// \brief The number of captures.
unsigned NumCaptures : 16;
-
- /// \brief The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 13;
-
+
/// \brief The default capture kind, which is a value of type
/// LambdaCaptureDefault.
unsigned CaptureDefault : 2;
@@ -1053,6 +1059,13 @@
/// implicit (and empty) parameter list.
unsigned ExplicitParams : 1;
+ /// \brief Whether this lambda had the result type explicitly specified.
+ unsigned ExplicitResultType : 1;
+
+ /// \brief Whether there are any array index variables stored at the end of
+ /// this lambda expression.
+ unsigned HasArrayIndexVars : 1;
+
/// \brief The location of the closing brace ('}') that completes
/// the lambda.
///
@@ -1063,11 +1076,9 @@
/// module file just to determine the source range.
SourceLocation ClosingBrace;
- // Note: The Create method allocates storage after the LambdaExpr
- // object, which contains the captures, followed by the capture
- // initializers, and finally the body of the lambda. The capture
- // initializers and lambda body are placed next to each other so
- // that the children() function can visit all of them easily.
+ // Note: The capture initializers are stored directly after the lambda
+ // expression, along with the index variables used to initialize by-copy
+ // array captures.
public:
/// \brief Describes the capture of either a variable or 'this'.
@@ -1075,10 +1086,10 @@
llvm::PointerIntPair<VarDecl *, 2> VarAndBits;
SourceLocation Loc;
SourceLocation EllipsisLoc;
-
+
friend class ASTStmtReader;
friend class ASTStmtWriter;
-
+
public:
/// \brief Create a new capture.
///
@@ -1151,13 +1162,26 @@
LambdaCaptureDefault CaptureDefault,
ArrayRef<Capture> Captures,
bool ExplicitParams,
+ bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace);
Stmt **getStoredStmts() const {
- LambdaExpr *This = const_cast<LambdaExpr *>(this);
- return reinterpret_cast<Stmt **>(reinterpret_cast<Capture *>(This + 1)
- + NumCaptures);
+ return reinterpret_cast<Stmt **>(const_cast<LambdaExpr *>(this) + 1);
+ }
+
+ /// \brief Retrieve the mapping from captures to the first array index
+ /// variable.
+ unsigned *getArrayIndexStarts() const {
+ return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1);
+ }
+
+ /// \brief Retrieve the complete set of array-index variables.
+ VarDecl **getArrayIndexVars() const {
+ return reinterpret_cast<VarDecl **>(
+ getArrayIndexStarts() + NumCaptures + 1);
}
public:
@@ -1168,7 +1192,10 @@
LambdaCaptureDefault CaptureDefault,
ArrayRef<Capture> Captures,
bool ExplicitParams,
+ bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace);
/// \brief Determine the default capture kind for this lambda.
@@ -1181,39 +1208,30 @@
typedef const Capture *capture_iterator;
/// \brief Retrieve an iterator pointing to the first lambda capture.
- capture_iterator capture_begin() const {
- return reinterpret_cast<const Capture *>(this + 1);
- }
+ capture_iterator capture_begin() const;
/// \brief Retrieve an iterator pointing past the end of the
/// sequence of lambda captures.
- capture_iterator capture_end() const {
- return capture_begin() + NumCaptures;
- }
+ capture_iterator capture_end() const;
+ /// \brief Determine the number of captures in this lambda.
+ unsigned capture_size() const { return NumCaptures; }
+
/// \brief Retrieve an iterator pointing to the first explicit
/// lambda capture.
- capture_iterator explicit_capture_begin() const {
- return capture_begin();
- }
+ capture_iterator explicit_capture_begin() const;
/// \brief Retrieve an iterator pointing past the end of the sequence of
/// explicit lambda captures.
- capture_iterator explicit_capture_end() const {
- return capture_begin() + NumExplicitCaptures;
- }
+ capture_iterator explicit_capture_end() const;
/// \brief Retrieve an iterator pointing to the first implicit
/// lambda capture.
- capture_iterator implicit_capture_begin() const {
- return explicit_capture_end();
- }
+ capture_iterator implicit_capture_begin() const;
/// \brief Retrieve an iterator pointing past the end of the sequence of
/// implicit lambda captures.
- capture_iterator implicit_capture_end() const {
- return capture_end();
- }
+ capture_iterator implicit_capture_end() const;
/// \brief Iterator that walks over the capture initialization
/// arguments.
@@ -1222,16 +1240,22 @@
/// \brief Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr **>(getStoredStmts() + 1);
+ return reinterpret_cast<Expr **>(getStoredStmts());
}
/// \brief Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression (which
- /// initializes the first capture field).
+ /// initialization argument for this lambda expression.
capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
+ return capture_init_begin() + NumCaptures;
}
+ /// \brief Retrieve the set of index variables used in the capture
+ /// initializer of an array captured by copy.
+ ///
+ /// \param Iter The iterator that points at the capture initializer for
+ /// which we are extracting the corresponding index variables.
+ ArrayRef<VarDecl *> getCaptureInitIndexVars(capture_init_iterator Iter) const;
+
/// \brief Retrieve the source range covering the lambda introducer,
/// which contains the explicit capture list surrounded by square
/// brackets ([...]).
@@ -1259,6 +1283,9 @@
/// list vs. an implicit (empty) parameter list.
bool hasExplicitParameters() const { return ExplicitParams; }
+ /// \brief Whether this lambda had its result type explicitly specified.
+ bool hasExplicitResultType() const { return ExplicitResultType; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == LambdaExprClass;
}
@@ -1268,7 +1295,7 @@
return SourceRange(IntroducerRange.getBegin(), ClosingBrace);
}
- child_range children() {
+ child_range children() {
return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
}
Modified: cfe/branches/tooling/include/clang/AST/Mangle.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Mangle.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Mangle.h (original)
+++ cfe/branches/tooling/include/clang/AST/Mangle.h Tue Feb 14 03:11:10 2012
@@ -27,8 +27,6 @@
class CXXConstructorDecl;
class CXXDestructorDecl;
class CXXMethodDecl;
- class DeclContext;
- class DiagnosticsEngine;
class FunctionDecl;
class NamedDecl;
class ObjCMethodDecl;
Modified: cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h (original)
+++ cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h Tue Feb 14 03:11:10 2012
@@ -14,14 +14,13 @@
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
namespace clang {
class ASTContext;
-class DiagnosticBuilder;
class NamespaceAliasDecl;
class NamespaceDecl;
class IdentifierInfo;
@@ -465,8 +464,12 @@
/// Insertion operator for diagnostics. This allows sending
/// NestedNameSpecifiers into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- NestedNameSpecifier *NNS);
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ NestedNameSpecifier *NNS) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
+ DiagnosticsEngine::ak_nestednamespec);
+ return DB;
+}
}
Modified: cfe/branches/tooling/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Type.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Type.h (original)
+++ cfe/branches/tooling/include/clang/AST/Type.h Tue Feb 14 03:11:10 2012
@@ -14,9 +14,11 @@
#ifndef LLVM_CLANG_AST_TYPE_H
#define LLVM_CLANG_AST_TYPE_H
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Linkage.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Visibility.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
@@ -92,7 +94,6 @@
class ExtQuals;
class ExtQualsTypeCommonBase;
struct PrintingPolicy;
- class PartialDiagnostic;
template <typename> class CanQual;
typedef CanQual<Type> CanQualType;
@@ -235,7 +236,7 @@
qs.removeObjCGCAttr();
return qs;
}
- Qualifiers withoutObjCGLifetime() const {
+ Qualifiers withoutObjCLifetime() const {
Qualifiers qs = *this;
qs.removeObjCLifetime();
return qs;
@@ -251,7 +252,8 @@
void removeObjCLifetime() { setObjCLifetime(OCL_None); }
void addObjCLifetime(ObjCLifetime type) {
assert(type);
- setObjCLifetime(type);
+ assert(!hasObjCLifetime());
+ Mask |= (type << LifetimeShift);
}
/// True if the lifetime is neither None or ExplicitNone.
@@ -446,7 +448,32 @@
CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp")))
};
-typedef std::pair<const Type*, Qualifiers> SplitQualType;
+/// A std::pair-like structure for storing a qualified type split
+/// into its local qualifiers and its locally-unqualified type.
+struct SplitQualType {
+ /// The locally-unqualified type.
+ const Type *Ty;
+
+ /// The local qualifiers.
+ Qualifiers Quals;
+
+ SplitQualType() : Ty(0), Quals() {}
+ SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
+
+ SplitQualType getSingleStepDesugaredType() const; // end of this file
+
+ // Make llvm::tie work.
+ operator std::pair<const Type *,Qualifiers>() const {
+ return std::pair<const Type *,Qualifiers>(Ty, Quals);
+ }
+
+ friend bool operator==(SplitQualType a, SplitQualType b) {
+ return a.Ty == b.Ty && a.Quals == b.Quals;
+ }
+ friend bool operator!=(SplitQualType a, SplitQualType b) {
+ return a.Ty != b.Ty || a.Quals != b.Quals;
+ }
+};
/// QualType - For efficiency, we don't store CV-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
@@ -768,7 +795,9 @@
///
/// This routine takes off the first typedef, typeof, etc. If the outer level
/// of the type is already concrete, it returns it unmodified.
- QualType getSingleStepDesugaredType(const ASTContext &Context) const;
+ QualType getSingleStepDesugaredType(const ASTContext &Context) const {
+ return getSingleStepDesugaredTypeImpl(*this, Context);
+ }
/// IgnoreParens - Returns the specified type after dropping any
/// outer-level parentheses.
@@ -790,7 +819,7 @@
return getAsString(split());
}
static std::string getAsString(SplitQualType split) {
- return getAsString(split.first, split.second);
+ return getAsString(split.Ty, split.Quals);
}
static std::string getAsString(const Type *ty, Qualifiers qs);
@@ -805,7 +834,7 @@
}
static void getAsStringInternal(SplitQualType split, std::string &out,
const PrintingPolicy &policy) {
- return getAsStringInternal(split.first, split.second, out, policy);
+ return getAsStringInternal(split.Ty, split.Quals, out, policy);
}
static void getAsStringInternal(const Type *ty, Qualifiers qs,
std::string &out,
@@ -886,6 +915,8 @@
static QualType getDesugaredType(QualType T, const ASTContext &Context);
static SplitQualType getSplitDesugaredType(QualType T);
static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
+ static QualType getSingleStepDesugaredTypeImpl(QualType type,
+ const ASTContext &C);
static QualType IgnoreParens(QualType T);
static DestructionKind isDestructedTypeImpl(QualType type);
};
@@ -1166,9 +1197,6 @@
/// regparm and the calling convention.
unsigned ExtInfo : 8;
- /// Whether the function is variadic. Only used by FunctionProtoType.
- unsigned Variadic : 1;
-
/// TypeQuals - Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
/// The qualifiers are part of FunctionProtoType because...
@@ -1332,6 +1360,11 @@
return CanonicalType == QualType(this, 0);
}
+ /// Pull a single level of sugar off of this locally-unqualified type.
+ /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
+ /// or QualType::getSingleStepDesugaredType(const ASTContext&).
+ QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
+
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -2579,7 +2612,7 @@
};
protected:
- FunctionType(TypeClass tc, QualType res, bool variadic,
+ FunctionType(TypeClass tc, QualType res,
unsigned typeQuals, RefQualifierKind RefQualifier,
QualType Canonical, bool Dependent,
bool InstantiationDependent,
@@ -2589,11 +2622,9 @@
ContainsUnexpandedParameterPack),
ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
- FunctionTypeBits.Variadic = variadic;
FunctionTypeBits.TypeQuals = typeQuals;
FunctionTypeBits.RefQualifier = static_cast<unsigned>(RefQualifier);
}
- bool isVariadic() const { return FunctionTypeBits.Variadic; }
unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
RefQualifierKind getRefQualifier() const {
@@ -2629,7 +2660,7 @@
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical,
+ : FunctionType(FunctionNoProto, Result, 0, RQ_None, Canonical,
/*Dependent=*/false, /*InstantiationDependent=*/false,
Result->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false, Info) {}
@@ -2667,12 +2698,13 @@
/// ExtProtoInfo - Extra information about a function prototype.
struct ExtProtoInfo {
ExtProtoInfo() :
- Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0),
- RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0),
- ConsumedArguments(0) {}
+ Variadic(false), HasTrailingReturn(false), ExceptionSpecType(EST_None),
+ TypeQuals(0), RefQualifier(RQ_None), NumExceptions(0), Exceptions(0),
+ NoexceptExpr(0), ConsumedArguments(0) {}
FunctionType::ExtInfo ExtInfo;
bool Variadic;
+ bool HasTrailingReturn;
ExceptionSpecificationType ExceptionSpecType;
unsigned char TypeQuals;
RefQualifierKind RefQualifier;
@@ -2698,7 +2730,7 @@
QualType canonical, const ExtProtoInfo &epi);
/// NumArgs - The number of arguments this function has, not counting '...'.
- unsigned NumArgs : 19;
+ unsigned NumArgs : 17;
/// NumExceptions - The number of types in the exception spec, if any.
unsigned NumExceptions : 9;
@@ -2709,6 +2741,12 @@
/// HasAnyConsumedArgs - Whether this function has any consumed arguments.
unsigned HasAnyConsumedArgs : 1;
+ /// Variadic - Whether the function is variadic.
+ unsigned Variadic : 1;
+
+ /// HasTrailingReturn - Whether this function has a trailing return type.
+ unsigned HasTrailingReturn : 1;
+
// ArgInfo - There is an variable size array after the class in memory that
// holds the argument types.
@@ -2748,6 +2786,7 @@
ExtProtoInfo EPI;
EPI.ExtInfo = getExtInfo();
EPI.Variadic = isVariadic();
+ EPI.HasTrailingReturn = hasTrailingReturn();
EPI.ExceptionSpecType = getExceptionSpecType();
EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
EPI.RefQualifier = getRefQualifier();
@@ -2809,16 +2848,18 @@
return getNoexceptSpec(Ctx) == NR_Nothrow;
}
- using FunctionType::isVariadic;
+ bool isVariadic() const { return Variadic; }
/// \brief Determines whether this function prototype contains a
/// parameter pack at the end.
///
/// A function template whose last parameter is a parameter pack can be
/// called with an arbitrary number of arguments, much like a variadic
- /// function. However,
+ /// function.
bool isTemplateVariadic() const;
+ bool hasTrailingReturn() const { return HasTrailingReturn; }
+
unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
@@ -2999,10 +3040,6 @@
/// DecltypeType (C++0x)
class DecltypeType : public Type {
Expr *E;
-
- // FIXME: We could get rid of UnderlyingType if we wanted to: We would have to
- // Move getDesugaredType to ASTContext so that it can call getDecltypeForExpr
- // from it.
QualType UnderlyingType;
protected:
@@ -4405,6 +4442,13 @@
// Inline function definitions.
+inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
+ SplitQualType desugar =
+ Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
+ desugar.Quals.addConsistentQualifiers(Quals);
+ return desugar;
+}
+
inline const Type *QualType::getTypePtr() const {
return getCommonPtr()->BaseType;
}
@@ -4489,7 +4533,7 @@
if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
return QualType(getTypePtr(), 0);
- return QualType(getSplitUnqualifiedTypeImpl(*this).first, 0);
+ return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
}
inline SplitQualType QualType::getSplitUnqualifiedType() const {
@@ -4801,11 +4845,21 @@
/// Insertion operator for diagnostics. This allows sending QualType's into a
/// diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, QualType T);
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ QualType T) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+ DiagnosticsEngine::ak_qualtype);
+ return DB;
+}
/// Insertion operator for partial diagnostics. This allows sending QualType's
/// into a diagnostic with <<.
-const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, QualType T);
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ QualType T) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+ DiagnosticsEngine::ak_qualtype);
+ return PD;
+}
// Helper class template that is used by Type::getAs to ensure that one does
// not try to look through a qualified type to get to an array type.
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h Tue Feb 14 03:11:10 2012
@@ -368,7 +368,7 @@
bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
bool isDoubleArg() const { return kind >= DoubleArgBeg &&
- kind <= DoubleArgBeg; }
+ kind <= DoubleArgEnd; }
unsigned getLength() const {
// Conversion specifiers currently only are represented by
// single characters, but we be flexible.
Modified: cfe/branches/tooling/include/clang/Analysis/AnalysisDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/AnalysisDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/AnalysisDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/AnalysisDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define ANALYSISSTART
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def (original)
+++ cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def Tue Feb 14 03:11:10 2012
@@ -411,13 +411,6 @@
BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "")
BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "")
BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "")
-BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "")
-BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "")
-BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "")
-BUILTIN(__builtin_ia32_vpermilpd, "V2dV2dIc", "")
-BUILTIN(__builtin_ia32_vpermilps, "V4fV4fIc", "")
-BUILTIN(__builtin_ia32_vpermilpd256, "V4dV4dIc", "")
-BUILTIN(__builtin_ia32_vpermilps256, "V8fV8fIc", "")
BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dIc", "")
BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fIc", "")
BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4iIc", "")
@@ -569,7 +562,6 @@
BUILTIN(__builtin_ia32_permdf256, "V4dV4dIc", "")
BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8f", "")
BUILTIN(__builtin_ia32_permdi256, "V4LLiV4LLiIc", "")
-BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "")
BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIc", "")
BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIc", "")
BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "")
Modified: cfe/branches/tooling/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Diagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Diagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Diagnostic.h Tue Feb 14 03:11:10 2012
@@ -464,12 +464,20 @@
bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map,
SourceLocation Loc = SourceLocation());
+ /// \brief Set the warning-as-error flag for the given diagnostic. This
+ /// function always only operates on the current diagnostic state.
+ void setDiagnosticWarningAsError(diag::kind Diag, bool Enabled);
+
/// \brief Set the warning-as-error flag for the given diagnostic group. This
/// function always only operates on the current diagnostic state.
///
/// \returns True if the given group is unknown, false otherwise.
bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
+ /// \brief Set the error-as-fatal flag for the given diagnostic. This function
+ /// always only operates on the current diagnostic state.
+ void setDiagnosticErrorAsFatal(diag::kind Diag, bool Enabled);
+
/// \brief Set the error-as-fatal flag for the given diagnostic group. This
/// function always only operates on the current diagnostic state.
///
@@ -593,7 +601,6 @@
friend class DiagnosticBuilder;
friend class Diagnostic;
friend class PartialDiagnostic;
- friend struct PartialDiagnosticStorage;
friend class DiagnosticErrorTrap;
/// CurDiagLoc - This is the location of the current diagnostic that is in
@@ -1050,11 +1057,20 @@
range_iterator range_begin() const { return Ranges.begin(); }
range_iterator range_end() const { return Ranges.end(); }
unsigned range_size() const { return Ranges.size(); }
+
+ ArrayRef<CharSourceRange> getRanges() const {
+ return llvm::makeArrayRef(Ranges);
+ }
+
typedef std::vector<FixItHint>::const_iterator fixit_iterator;
fixit_iterator fixit_begin() const { return FixIts.begin(); }
fixit_iterator fixit_end() const { return FixIts.end(); }
unsigned fixit_size() const { return FixIts.size(); }
+
+ ArrayRef<FixItHint> getFixIts() const {
+ return llvm::makeArrayRef(FixIts);
+ }
};
/// DiagnosticConsumer - This is an abstract interface implemented by clients of
Modified: cfe/branches/tooling/include/clang/Basic/Diagnostic.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Diagnostic.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Diagnostic.td (original)
+++ cfe/branches/tooling/include/clang/Basic/Diagnostic.td Tue Feb 14 03:11:10 2012
@@ -62,8 +62,6 @@
DiagMapping DefaultMapping = defaultmapping;
DiagGroup Group;
string CategoryName = "";
- string Brief = "";
- string Explanation = "";
}
class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>;
@@ -87,12 +85,6 @@
class NoSFINAE { bit SFINAE = 0; }
class AccessControl { bit AccessControl = 1; }
-class Brief<string str> { string Brief = str; }
-class FullExplanation<string brief, string full> {
- string Brief = brief;
- string Explanation = full;
-}
-
// Definitions for Diagnostics.
include "DiagnosticASTKinds.td"
include "DiagnosticAnalysisKinds.td"
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td Tue Feb 14 03:11:10 2012
@@ -10,8 +10,6 @@
let Component = "AST" in {
// Constant expression diagnostics. These (and their users) belong in Sema.
-//def note_comma_in_ice : Note<
-// "C does not permit evaluated commas in an integer constant expression">;
def note_expr_divide_by_zero : Note<"division by zero">;
def note_constexpr_invalid_cast : Note<
"%select{reinterpret_cast|dynamic_cast|cast which performs the conversions of"
@@ -24,9 +22,15 @@
def note_constexpr_large_shift : Note<
"shift count %0 >= width of type %1 (%2 bit%s2)">;
def note_constexpr_lshift_of_negative : Note<"left shift of negative value %0">;
+def note_constexpr_lshift_discards : Note<"signed left shift discards bits">;
def note_constexpr_invalid_function : Note<
"%select{non-constexpr|undefined}0 %select{function|constructor}1 %2 cannot "
"be used in a constant expression">;
+def note_constexpr_virtual_call : Note<
+ "cannot evaluate virtual function call in a constant expression">;
+def note_constexpr_virtual_base : Note<
+ "cannot construct object of type %0 with virtual base class "
+ "in a constant expression">;
def note_constexpr_nonliteral : Note<
"non-literal type %0 cannot be used in a constant expression">;
def note_constexpr_non_global : Note<
@@ -38,9 +42,6 @@
"%select{array of %2 elements|non-array object}1 in a constant expression">;
def note_constexpr_float_arithmetic : Note<
"floating point arithmetic produces %select{an infinity|a NaN}0">;
-def note_constexpr_pointer_arithmetic : Note<
- "cannot refer to element %0 of non-array object in a constant "
- "expression">;
def note_constexpr_pointer_subtraction_not_same_array : Note<
"subtracted pointers are not elements of the same array">;
def note_constexpr_pointer_comparison_base_classes : Note<
@@ -73,7 +74,6 @@
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_literal_here : Note<"literal written here">;
def note_constexpr_depth_limit_exceeded : Note<
"constexpr evaluation exceeded maximum depth of %0 calls">;
def note_constexpr_ltor_volatile_type : Note<
@@ -81,6 +81,8 @@
def note_constexpr_ltor_volatile_obj : Note<
"read of volatile %select{temporary|object %1|member %1}0 is not allowed in "
"a constant expression">;
+def note_constexpr_ltor_mutable : Note<
+ "read of mutable member %0 is not allowed in a constant expression">;
def note_constexpr_ltor_non_const_int : Note<
"read of non-const variable %0 is not allowed in a constant expression">;
def note_constexpr_ltor_non_constexpr : Note<
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticAnalysisKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticAnalysisKinds.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticAnalysisKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticAnalysisKinds.td Tue Feb 14 03:11:10 2012
@@ -9,7 +9,4 @@
let Component = "Analysis" in {
-// CHECK: use of uninitialized values
-def warn_uninit_val : Warning<"use of uninitialized variable">;
-
}
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td Tue Feb 14 03:11:10 2012
@@ -59,8 +59,6 @@
InGroup<CXX98Compat>, DefaultIgnore;
def err_default_special_members : Error<
"only special member functions may be defaulted">;
-def err_friends_define_only_namespace_scope : Error<
- "cannot define a function with non-namespace scope in a friend declaration">;
def err_deleted_non_function : Error<
"only functions can have deleted definitions">;
def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticDriverKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticDriverKinds.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticDriverKinds.td Tue Feb 14 03:11:10 2012
@@ -98,8 +98,6 @@
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for c++ and objective-c++ only">;
-def warn_drv_unsupported_option_argument : Warning<
- "ignoring unsupported argument '%1' to option '%0'">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
def warn_drv_preprocessed_input_file_unused : Warning<
@@ -107,8 +105,6 @@
def warn_drv_unused_argument : Warning<
"argument unused during compilation: '%0'">,
InGroup<DiagGroup<"unused-command-line-argument">>;
-def warn_drv_pipe_ignored_with_save_temps : Warning<
- "-pipe ignored because -save-temps specified">;
def warn_drv_not_using_clang_cpp : Warning<
"not using the clang preprocessor due to user override">;
def warn_drv_not_using_clang_cxx : Warning<
@@ -121,8 +117,6 @@
"unknown platform, assuming -mfloat-abi=%0">;
def warn_ignoring_ftabstop_value : Warning<
"ignoring invalid -ftabstop value '%0', using default value %1">;
-def warn_drv_conflicting_deployment_targets : Warning<
- "conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticFrontendKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticFrontendKinds.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticFrontendKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticFrontendKinds.td Tue Feb 14 03:11:10 2012
@@ -13,9 +13,7 @@
def err_fe_error_reading : Error<"error reading '%0'">;
def err_fe_error_reading_stdin : Error<"error reading stdin">;
def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
-def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
-def err_fe_invalid_ast_action : Error<"invalid action for AST input">,
- DefaultFatal;
+
// Error generated by the backend.
def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
def note_fe_inline_asm_here : Note<"instantiated into assembly here">;
@@ -28,16 +26,8 @@
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
DefaultFatal;
-def err_fe_stderr_binary : Error<"unable to change standard error to binary">,
- DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
"-dependency-file requires at least one -MT or -MQ option">;
-def err_fe_incompatible_options : Error<
- "'%0' cannot be used with '%1'">, DefaultFatal;
-def err_fe_no_fixit_and_codegen : Error<
- "FIX-ITs cannot be applied when generating code">;
-def err_fe_unable_to_find_fixit_file : Error<
- "FIX-IT could not find file '%0'">;
def err_fe_invalid_plugin_name : Error<
"unable to find plugin '%0'">;
def err_fe_expected_compiler_job : Error<
@@ -91,13 +81,9 @@
def note_fixit_failed : Note<
"FIX-IT unable to apply suggested code changes">;
def note_fixit_unfixed_error : Note<"FIX-IT detected an error it cannot fix">;
-def note_fixit_main_file_unchanged : Note<
- "main file unchanged">;
def warn_fixit_no_changes : Note<
"FIX-IT detected errors it could not fix; no output will be generated">;
-def err_fe_invoking : Error<"error invoking%0: %1">, DefaultFatal;
-
// PCH reader
def err_relocatable_without_isysroot : Error<
"must specify system root with -isysroot when building a relocatable "
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td Tue Feb 14 03:11:10 2012
@@ -142,7 +142,8 @@
DiagCategory<"#pragma message Directive">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
-def ReturnType : DiagGroup<"return-type">;
+def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">;
+def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy",
[CXX98CompatBindToTemporaryCopy]>;
def SelfAssignment : DiagGroup<"self-assign">;
@@ -184,9 +185,9 @@
def : DiagGroup<"strict-prototypes">;
def StrictSelector : DiagGroup<"strict-selector-match">;
def MethodDuplicate : DiagGroup<"duplicate-method-match">;
-def SwitchEnum : DiagGroup<"switch-enum">;
def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
-def Switch : DiagGroup<"switch", [CoveredSwitchDefault]>;
+def SwitchEnum : DiagGroup<"switch-enum">;
+def Switch : DiagGroup<"switch">;
def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
@@ -259,7 +260,8 @@
def Parentheses : DiagGroup<"parentheses",
[LogicalOpParentheses,
BitwiseOpParentheses,
- ParenthesesOnEquality]>;
+ ParenthesesOnEquality,
+ DanglingElse]>;
// -Wconversion has its own warnings, but we split a few out for
// legacy reasons:
@@ -317,7 +319,6 @@
Reorder,
ReturnType,
SelfAssignment,
- Switch,
SizeofArrayArgument,
Trigraphs,
Uninitialized,
@@ -331,8 +332,8 @@
// Thread Safety warnings
def ThreadSafety : DiagGroup<"thread-safety">;
-// -Wall is -Wmost -Wparentheses -Wdangling-else
-def : DiagGroup<"all", [DanglingElse, Most, Parentheses]>;
+// -Wall is -Wmost -Wparentheses -Wdangling-else -Wswitch
+def : DiagGroup<"all", [Most, Parentheses, Switch]>;
// Aliases.
def : DiagGroup<"", [Extra]>; // -W = -Wextra
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h Tue Feb 14 03:11:10 2012
@@ -50,7 +50,7 @@
// Get typedefs for common diagnostics.
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM,
#include "clang/Basic/DiagnosticCommonKinds.inc"
NUM_BUILTIN_COMMON_DIAGNOSTICS
#undef DIAG
@@ -229,14 +229,6 @@
/// getIdFromName - Given a diagnostic name, return its ID, or 0
static unsigned getIdFromName(StringRef Name);
- /// getBriefExplanation - Given a diagnostic ID, return a brief explanation
- /// of the issue
- static StringRef getBriefExplanation(unsigned DiagID);
-
- /// getFullExplanation - Given a diagnostic ID, return a full explanation
- /// of the issue
- static StringRef getFullExplanation(unsigned DiagID);
-
/// Iterator class used for traversing all statically declared
/// diagnostics.
class diag_iterator {
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td Tue Feb 14 03:11:10 2012
@@ -95,7 +95,6 @@
def err_ucn_escape_no_digits : Error<"\\u used with no following hex digits">;
def err_ucn_escape_invalid : Error<"invalid universal character">;
def err_ucn_escape_incomplete : Error<"incomplete universal character name">;
-def err_ucn_escape_too_big : Error<"universal character name is too long">;
def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
@@ -113,6 +112,8 @@
def ext_imaginary_constant : Extension<"imaginary constants are an extension">;
def err_hexconstant_requires_exponent : Error<
"hexadecimal floating constants require an exponent">;
+def err_hexconstant_requires_digits : Error<
+ "hexadecimal floating constants require a significand">;
def ext_hexconstant_invalid : Extension<
"hexadecimal floating constants are a C99 feature">;
def ext_binary_literal : Extension<
@@ -134,14 +135,19 @@
"unsupported non-standard concatenation of string literals">;
def err_bad_string_encoding : Error<
"illegal character encoding in string literal">;
+def warn_bad_string_encoding : ExtWarn<
+ "illegal character encoding in string literal">,
+ InGroup<DiagGroup<"invalid-source-encoding">>;
def err_bad_character_encoding : Error<
"illegal character encoding in character literal">;
-
+def warn_bad_character_encoding : ExtWarn<
+ "illegal character encoding in character literal">,
+ InGroup<DiagGroup<"invalid-source-encoding">>;
+
+
//===----------------------------------------------------------------------===//
// PTH Diagnostics
//===----------------------------------------------------------------------===//
-def err_pth_cannot_read : Error<
- "PTH file '%0' could not be read">;
def err_invalid_pth_file : Error<
"invalid or corrupt PTH file '%0'">;
@@ -257,7 +263,6 @@
def pp_err_elif_without_if : Error<"#elif without #if">;
def err_pp_endif_without_if : Error<"#endif without #if">;
def err_pp_expected_value_in_expr : Error<"expected value in expression">;
-def err_pp_missing_val_before_operator : Error<"missing value before operator">;
def err_pp_expected_rparen : Error<"expected ')' in preprocessor expression">;
def err_pp_expected_eol : Error<
"expected end of line in preprocessor expression">;
@@ -400,7 +405,6 @@
def err_mmap_expected_member : Error<
"expected umbrella, header, submodule, or module export">;
def err_mmap_expected_header : Error<"expected a header name after '%0'">;
-def err_mmap_expected_dir : Error<"expected a directory name after '%0'">;
def err_mmap_module_redefinition : Error<
"redefinition of module '%0'">;
def note_mmap_prev_definition : Note<"previously defined here">;
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td Tue Feb 14 03:11:10 2012
@@ -195,8 +195,6 @@
def err_expected_string_literal : Error<"expected string literal">;
def err_asm_operand_wide_string_literal : Error<
"cannot use wide string literal in 'asm'">;
-def err_expected_asm_operand : Error<
- "expected string literal or '[' for asm operand">, CatInlineAsm;
def err_expected_selector_for_method : Error<
"expected selector for Objective-C method">;
def err_expected_property_name : Error<"expected property name">;
@@ -300,8 +298,6 @@
"cannot template a using directive">;
def err_templated_using_declaration : Error<
"cannot template a using declaration">;
-def err_expected_ident_in_using : Error<
- "expected an identifier in using directive">;
def err_unexected_colon_in_nested_name_spec : Error<
"unexpected ':' in nested name specifier">;
def err_bool_redeclaration : Error<
@@ -358,11 +354,6 @@
def err_missing_catch_finally : Error<
"@try statement without a @catch and @finally clause">;
def err_objc_concat_string : Error<"unexpected token after Objective-C string">;
-def err_missing_sel_definition : Error<"cannot find definition of 'SEL'">;
-def err_missing_id_definition : Error<"cannot find definition of 'id'">;
-def err_missing_proto_definition : Error<
- "cannot find definition of 'Protocol'">;
-def err_missing_class_definition : Error<"cannot find definition of 'Class'">;
def err_expected_objc_container : Error<
"'@end' must appear in an Objective-C context">;
def error_property_ivar_decl : Error<
@@ -461,7 +452,6 @@
"unknown template name %0">;
def err_expected_comma_greater : Error<
"expected ',' or '>' in template-parameter-list">;
-def err_expected_type_id_after : Error<"expected type-id after '%0'">;
def err_expected_class_before : Error<"expected 'class' before '%0'">;
def err_template_spec_syntax_non_template : Error<
"identifier followed by '<' indicates a class template specialization but "
@@ -469,10 +459,6 @@
"template|<unused>|refers to a template template parameter}1">;
def err_id_after_template_in_nested_name_spec : Error<
"expected template name after 'template' keyword in nested name specifier">;
-def err_id_after_template_in_typename_spec : Error<
- "expected template name after 'template' keyword in typename specifier">;
-def err_less_after_template_name_in_nested_name_spec : Error<
- "expected '<' after 'template %0' in nested name specifier">;
def err_two_right_angle_brackets_need_space : Error<
"a space is required between consecutive right angle brackets (use '> >')">;
def warn_cxx0x_right_shift_in_template_arg : Warning<
@@ -588,8 +574,6 @@
def err_duplicate_virt_specifier : Error<
"class member already marked '%0'">;
-def err_duplicate_class_virt_specifier : Error<
- "class already marked '%0'">;
def err_scoped_enum_missing_identifier : Error<
"scoped enumeration requires a name">;
@@ -655,8 +639,6 @@
// - #pragma pack
def warn_pragma_pack_invalid_action : Warning<
"unknown action for '#pragma pack' - ignored">;
-def warn_pragma_pack_invalid_constant : Warning<
- "invalid constant for '#pragma pack', expected %0 - ignored">;
def warn_pragma_pack_malformed : Warning<
"expected integer or identifier in '#pragma pack' - ignored">;
// - #pragma unused
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 14 03:11:10 2012
@@ -120,8 +120,6 @@
"flexible array initialization is a GNU extension">, InGroup<GNU>;
// Declarations.
-def ext_anon_param_requires_type_specifier : Extension<
- "type specifier required for unnamed parameter, defaults to int">;
def err_bad_variable_name : Error<
"%0 cannot be the name of a variable or data member">;
def err_bad_parameter_name : Error<
@@ -163,7 +161,9 @@
def warn_return_value_size: Warning<
"return value of %0 is a large (%1 bytes) pass-by-value object; "
"pass it by reference instead ?">, InGroup<LargeByValueCopy>;
-
+def warn_return_value_udt: Warning<
+ "%0 has C-linkage specified, but returns user-defined type %1 which is "
+ "incompatible with C">, InGroup<ReturnTypeCLinkage>;
def warn_implicit_function_decl : Warning<
"implicit declaration of function %0">,
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
@@ -384,8 +384,6 @@
"undeclared variable %0 used as an argument for '#pragma unused'">;
def warn_pragma_unused_expected_var_arg : Warning<
"only variables can be arguments to '#pragma unused'">;
-def err_unsupported_pragma_weak : Error<
- "using '#pragma weak' to refer to an undeclared identifier is not yet supported">;
def err_pragma_push_visibility_mismatch : Error<
"#pragma visibility push with no matching #pragma visibility pop">;
def note_surrounding_namespace_ends_here : Note<
@@ -831,9 +829,6 @@
"%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor">,
AccessControl;
-def err_access_ctor_field :
- Error<"field of type %1 has %select{private|protected}2 constructor">,
- AccessControl;
def err_access_dtor : Error<
"calling a %select{private|protected}1 destructor of class %0">,
AccessControl;
@@ -856,29 +851,12 @@
def err_access_dtor_var :
Error<"variable of type %1 has %select{private|protected}2 destructor">,
AccessControl;
-def err_access_assign_field :
- Error<"field of type %1 has %select{private|protected}2 copy assignment"
- " operator">,
- AccessControl;
-def err_access_assign_base :
- Error<"base class %0 has %select{private|protected}1 copy assignment"
- " operator">,
- AccessControl;
-def err_access_copy_field :
- Error<"field of type %1 has %select{private|protected}2 copy constructor">,
- AccessControl;
-def err_access_copy_base :
- Error<"base class %0 has %select{private|protected}1 copy constructor">,
- AccessControl;
def err_access_dtor_ivar :
Error<"instance variable of type %0 has %select{private|protected}1 "
"destructor">,
AccessControl;
def note_previous_access_declaration : Note<
"previously declared '%1' here">;
-def err_access_outside_class : Error<
- "access to %select{private|protected}0 member outside any class context">,
- AccessControl;
def note_access_natural : Note<
"%select{|implicitly }1declared %select{private|protected}0 here">;
def note_access_constrained_by_path : Note<
@@ -1094,13 +1072,6 @@
def err_lvalue_to_rvalue_ref : Error<"rvalue reference to type %0 cannot bind "
"to lvalue of type %1">;
-def err_invalid_initialization : Error<
-"invalid initialization of reference of type %0 from expression of type %1">;
-def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
- "due to multiple conversion functions">;
-def err_not_reference_to_const_init : Error<
- "%select{non-const|volatile}0 lvalue reference to type %1 cannot be "
- "initialized with a %select{value|temporary}2 of type %3">;
def err_lvalue_reference_bind_to_initlist : Error<
"%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to an "
"initializer list temporary">;
@@ -1125,17 +1096,12 @@
"%select{const|restrict|const or restrict|volatile|const or volatile|"
"volatile or restrict|const, volatile, or restrict}2">;
-def err_reference_init_drops_quals : Error<
- "initialization of reference to type %0 with a %select{value|temporary}1 of type %2 drops "
- "qualifiers">;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
def err_reference_bind_to_vector_element : Error<
"%select{non-const|volatile}0 reference cannot bind to vector element">;
def err_reference_var_requires_init : Error<
"declaration of reference variable %0 requires an initializer">;
-def err_const_var_requires_init : Error<
- "declaration of const variable '%0' requires an initializer">;
def err_reference_without_init : Error<
"reference to type %0 requires an initializer">;
def err_reference_has_multiple_inits : Error<
@@ -1203,8 +1169,6 @@
InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
// C++11 decltype
-def err_cannot_determine_declared_type_of_overloaded_function : Error<
- "cannot determine the type of an overloaded function">;
def warn_cxx98_compat_decltype : Warning<
"'decltype' type specifier is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
@@ -1230,6 +1194,8 @@
"declaration of variable %0 with type %1 requires an initializer">;
def err_auto_new_requires_ctor_arg : Error<
"new expression for type %0 requires a constructor argument">;
+def err_auto_new_requires_parens : Error<
+ "new expression for type %0 cannot use list-initialization">;
def err_auto_var_init_no_expression : Error<
"initializer for variable %0 with type %1 is empty">;
def err_auto_var_init_multiple_expressions : Error<
@@ -1255,6 +1221,10 @@
"not found; include <initializer_list>">;
def err_malformed_std_initializer_list : Error<
"std::initializer_list must be a class template with a single type parameter">;
+def warn_dangling_std_initializer_list : Warning<
+ "array backing the initializer list will be destroyed at the end of "
+ "%select{the full-expression|the constructor}0">,
+ InGroup<DiagGroup<"dangling-initializer-list">>;
// C++11 override control
def override_keyword_only_allowed_on_virtual_member_functions : Error<
@@ -1267,11 +1237,9 @@
// C++11 attributes
def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
-// C++11 [[final]]
+// C++11 final
def err_final_function_overridden : Error<
"declaration of %0 overrides a 'final' function">;
-def err_final_base : Error<
- "derivation from 'final' %0">;
// C++11 scoped enumerations
def err_enum_invalid_underlying : Error<
@@ -1294,8 +1262,6 @@
"not 'enum class'">;
def err_only_enums_have_underlying_types : Error<
"only enumeration types have underlying types">;
-def err_incomplete_type_no_underlying_type : Error<
- "an incomplete enumeration type has no underlying type yet">;
// C++11 delegating constructors
def err_delegating_ctor : Error<
@@ -1312,8 +1278,6 @@
"it delegates to">, InGroup<DelegatingCtorCycles>;
def note_which_delegates_to : Note<
"which delegates to">, InGroup<DelegatingCtorCycles>;
-def err_delegating_codegen_not_implemented : Error<
- "code generation for delegating constructors not implemented">;
// C++11 range-based for loop
def err_for_range_decl_must_be_var : Error<
@@ -1353,37 +1317,25 @@
"constexpr variable declaration must be a definition">;
def err_constexpr_static_mem_var_requires_init : Error<
"declaration of constexpr static data member %0 requires an initializer">;
+def err_constexpr_var_non_literal : Error<
+ "constexpr variable cannot have non-literal type %0">;
def err_constexpr_var_requires_const_init : Error<
"constexpr variable %0 must be initialized by a constant expression">;
def err_constexpr_redecl_mismatch : Error<
"%select{non-constexpr declaration of %0 follows constexpr declaration"
"|constexpr declaration of %0 follows non-constexpr declaration}1">;
-def note_constexpr_redecl_mismatch : Note<
- "previous declaration was %select{not |}0marked constexpr">;
def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
-def note_constexpr_tmpl_virtual : Note<"function template instantiation is not "
- "constexpr because it is virtual">;
def err_constexpr_virtual_base : Error<
"constexpr %select{member function|constructor}0 not allowed in "
"%select{class|struct}1 with virtual base %plural{1:class|:classes}2">;
-def note_constexpr_tmpl_virtual_base : Note<
- "%select{function|constructor}0 template instantiation is "
- "not constexpr because %select{class|struct}1 has virtual base "
- "%plural{1:class|:classes}2">;
def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual "
"base %plural{1:class|:classes}1 is not a literal type">;
def note_constexpr_virtual_base_here : Note<"virtual base class declared here">;
def err_constexpr_non_literal_return : Error<
"constexpr function's return type %0 is not a literal type">;
-def note_constexpr_tmpl_non_literal_return : Note<
- "function template instantiation is not constexpr because return type %0 is "
- "not a literal type">;
def err_constexpr_non_literal_param : Error<
"constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is "
"not a literal type">;
-def note_constexpr_tmpl_non_literal_param : Note<
- "%select{function|constructor}1 template instantiation is not constexpr "
- "because %ordinal0 parameter type %2 is not a literal type">;
def err_constexpr_body_invalid_stmt : Error<
"statement not allowed in constexpr %select{function|constructor}0">;
def err_constexpr_type_definition : Error<
@@ -1418,13 +1370,12 @@
def note_non_literal_base_class : Note<
"%0 is not literal because it has base class %1 of non-literal type">;
def note_non_literal_field : Note<
- "%0 is not literal because it has data member %1 of non-literal type %2">;
+ "%0 is not literal because it has data member %1 of "
+ "%select{non-literal|volatile}3 type %2">;
def note_non_literal_user_provided_dtor : Note<
"%0 is not literal because it has a user-provided destructor">;
def note_non_literal_nontrivial_dtor : Note<
"%0 is not literal because it has a non-trivial destructor">;
-def note_non_literal_mutable_field : Note<
- "%0 is not literal because it has a mutable data member">;
// C++11 char16_t/char32_t
def warn_cxx98_compat_unicode_type : Warning<
@@ -1503,8 +1454,6 @@
"can't convert between vector values of different size (%0 and %1)">;
def err_typecheck_ext_vector_not_typedef : Error<
"ext_vector_type only applies to types, not variables">;
-def err_unsupported_vector_size : Error<
- "unsupported type %0 for vector_size attribute, please use on typedef">;
def err_ext_vector_component_exceeds_length : Error<
"vector component access exceeds type %0">;
def err_ext_vector_component_name_illegal : Error<
@@ -1523,10 +1472,8 @@
"automatic variable qualified with an address space">;
def err_arg_with_address_space : Error<
"parameter may not be qualified with an address space">;
-def err_attr_objc_ownership_bad_type : Error<
- "the type %0 cannot be retained">;
def err_attr_objc_ownership_redundant : Error<
- "the type %0 already has retainment attributes set on it">;
+ "the type %0 is already explicitly ownership-qualified">;
def err_attribute_not_string : Error<
"argument to %0 attribute was not a string literal">;
def err_only_annotate_after_access_spec : Error<
@@ -1616,8 +1563,6 @@
def warn_objc_precise_lifetime_meaningless : Error<
"objc_precise_lifetime is not meaningful for "
"%select{__unsafe_unretained|__autoreleasing}0 objects">;
-def warn_label_attribute_not_unused : Warning<
- "The only valid attribute for labels is 'unused'">;
def err_invalid_pcs : Error<"Invalid PCS type">;
def err_attribute_can_be_applied_only_to_value_decl : Error<
"%0 attribute can only be applied to value declarations">;
@@ -1789,9 +1734,6 @@
"'nonnull' attribute applied to function with no pointer arguments">;
def warn_attribute_malloc_pointer_only : Warning<
"'malloc' attribute only applies to functions returning a pointer type">;
-def warn_transparent_union_nonpointer : Warning<
- "'transparent_union' attribute support incomplete; only supported for "
- "pointer unions">;
def warn_attribute_sentinel_named_arguments : Warning<
"'sentinel' attribute requires named arguments">;
def warn_attribute_sentinel_not_variadic : Warning<
@@ -1886,8 +1828,6 @@
"cannot define the implicit default assignment operator for %0, because "
"non-static %select{reference|const}1 member %2 can't use default "
"assignment operator">;
-def note_first_required_here : Note<
- "synthesized method is first required here">;
def err_uninitialized_member_in_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{reference|const}2 member %3">;
@@ -2667,8 +2607,6 @@
def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
-def err_template_kw_refers_to_function_template : Error<
- "%0 following the 'template' keyword refers to a function template">;
def err_template_kw_refers_to_class_template : Error<
"'%0%1' instantiated to a class template, not a function template">;
def note_referenced_class_template : Error<
@@ -2948,8 +2886,6 @@
def warn_typecheck_zero_static_array_size : Warning<
"'static' has no effect on zero-length arrays">,
InGroup<DiagGroup<"array-bounds">>;
-def err_at_least_one_initializer_needed_to_size_array : Error<
- "at least one initializer value required to size array">;
def err_array_size_non_int : Error<"size of array has non-integer type %0">;
def err_init_element_not_constant : Error<
"initializer element is not a compile-time constant">;
@@ -2960,8 +2896,6 @@
def warn_extern_init : Warning<"'extern' variable has an initializer">;
def err_variable_object_no_init : Error<
"variable-sized object may not be initialized">;
-def err_array_init_list_required : Error<
- "initialization with '{...}' expected for array">;
def err_excess_initializers : Error<
"excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
def warn_excess_initializers : ExtWarn<
@@ -3387,15 +3321,11 @@
def err_mempointer_in_nonclass_type : Error<
"member pointer refers into non-class type %0">;
def err_reference_to_void : Error<"cannot form a reference to 'void'">;
-def err_qualified_block_pointer_type : Error<
- "qualifier specification on block pointer type not allowed">;
def err_nonfunction_block_type : Error<
"block pointer to non-function type is invalid">;
def err_return_block_has_expr : Error<"void block should not return a value">;
def err_block_return_missing_expr : Error<
"non-void block should return a value">;
-def err_block_with_return_type_requires_args : Error<
- "block with explicit return type requires argument list">;
def err_func_def_incomplete_result : Error<
"incomplete result type %0 in function definition">;
def err_atomic_specifier_bad_type : Error<
@@ -3406,9 +3336,6 @@
// Expressions.
def ext_sizeof_function_type : Extension<
"invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
-def err_sizeof_alignof_overloaded_function_type : Error<
- "invalid application of '%select{sizeof|__alignof|vec_step}0' to an "
- "overloaded function">;
def ext_sizeof_void_type : Extension<
"invalid application of '%select{sizeof|__alignof|vec_step}0' to a void "
"type">, InGroup<PointerArith>;
@@ -3559,8 +3486,6 @@
"out-of-line definition of %q0 differs from the declaration in the return type">;
def err_nonstatic_member_out_of_line : Error<
"non-static data member defined out-of-line">;
-def err_nonstatic_flexible_variable : Error<
- "non-static initialization of a variable with flexible array member">;
def err_qualified_typedef_declarator : Error<
"typedef declarator cannot be qualified">;
def err_qualified_param_declarator : Error<
@@ -3659,12 +3584,8 @@
def err_objc_object_assignment : Error<
"cannot assign to class object (%0 invalid)">;
-def err_direct_interface_unsupported : Error<
- "indirection to an interface is not supported (%0 invalid)">;
def err_typecheck_invalid_operands : Error<
"invalid operands to binary expression (%0 and %1)">;
-def err_typecheck_sub_ptr_object : Error<
- "subtraction of pointer %0 requires pointee to be a complete object type">;
def err_typecheck_sub_ptr_compatible : Error<
"%0 and %1 are not pointers to compatible types">;
def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
@@ -3690,8 +3611,6 @@
def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
"comparison of distinct pointer types (%0 and %1) uses non-standard "
"composite pointer type %2">;
-def err_typecheck_vector_comparison : Error<
- "comparison of vector types (%0 and %1) not supported yet">;
def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
@@ -3720,22 +3639,11 @@
def err_invalid_member_use_in_static_method : Error<
"invalid use of member %0 in static member function">;
def err_invalid_qualified_function_type : Error<
- "type qualifier is not allowed on this function">;
-def err_invalid_ref_qualifier_function_type : Error<
- "ref-qualifier '%select{&&|&}0' is only allowed on non-static member functions,"
- " member function pointers, and typedefs of function types">;
-def ext_qualified_function_type_template_arg : ExtWarn<
- "template argument of '%0' qualified function type is a GNU extension">,
- InGroup<GNU>;
-
-def err_invalid_qualified_function_pointer : Error<
- "type qualifier is not allowed on this function %select{pointer|reference}0">;
-def err_invalid_qualified_typedef_function_type_use : Error<
- "a qualified function type cannot be used to declare a "
- "%select{static member|nonmember}0 function">;
-def err_invalid_ref_qualifier_typedef_function_type_use : Error<
- "%select{static member|nonmember}0 function cannot have a ref-qualifier "
- "'%select{&&|&}1'">;
+ "%select{static |non-}0member function %select{of type %2 |}1"
+ "cannot have '%3' qualifier">;
+def err_compound_qualified_function_type : Error<
+ "%select{block pointer|pointer|reference}0 to function type %select{%2 |}1"
+ "cannot have '%3' qualifier">;
def err_ref_qualifier_overload : Error<
"cannot overload a member function %select{without a ref-qualifier|with "
@@ -3748,8 +3656,6 @@
"invalid use of incomplete type %0">;
def err_builtin_func_cast_more_than_one_arg : Error<
"function-style cast to a builtin type can only take one argument">;
-def err_builtin_direct_init_more_than_one_arg : Error<
- "initializer of a builtin type can only take one argument">;
def err_value_init_for_array_type : Error<
"array types cannot be value-initialized">;
def warn_format_nonliteral_noargs : Warning<
@@ -3861,8 +3767,6 @@
"'register' storage specifier on @catch parameter will be ignored">;
def err_qualified_objc_catch_parm : Error<
"@catch parameter declarator cannot be qualified">;
-def err_objc_pointer_cxx_catch_gnu : Error<
- "can't catch Objective C exceptions in C++ in the GNU runtime">;
def warn_objc_pointer_cxx_catch_fragile : Warning<
"can not catch an exception thrown with @throw in C++ in the non-unified "
"exception model">, InGroup<ObjCNonUnifiedException>;
@@ -3880,8 +3784,6 @@
"property %0 requires method %1 to be defined - "
"use @dynamic or provide a method implementation in this category">,
InGroup<ObjCPropertyImpl>;
-def note_property_impl_required : Note<
- "implementation is here">;
def note_parameter_named_here : Note<
"passing argument to parameter %0 here">;
def note_parameter_here : Note<
@@ -3938,7 +3840,6 @@
def err_bad_cxx_cast_member_pointer_size : Error<
"cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer "
"type %1 to member pointer type %2 of different size">;
-def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">;
def err_bad_reinterpret_cast_reference : Error<
"reinterpret_cast of a %0 to %1 needs its address which is not allowed">;
def warn_undefined_reinterpret_cast : Warning<
@@ -4047,8 +3948,6 @@
def err_early_catch_all : Error<"catch-all handler must come last">;
def err_bad_memptr_rhs : Error<
"right hand operand to %0 has non pointer-to-member type %1">;
-def err_memptr_rhs_to_incomplete : Error<
- "cannot dereference pointer into incomplete class type %0">;
def err_bad_memptr_lhs : Error<
"left hand operand to %0 must be a %select{|pointer to }1class "
"compatible with the right hand operand, but is %2">;
@@ -4080,7 +3979,6 @@
"type %0 requires %1 bytes of alignment and the default allocator only "
"guarantees %2 bytes">,
InGroup<OveralignedType>, DefaultIgnore;
-def note_overaligned_type : Note<"over-aligned here">;
def err_conditional_void_nonvoid : Error<
"%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
@@ -4099,13 +3997,12 @@
def err_return_in_constructor_handler : Error<
"return in the catch of a function try block of a constructor is illegal">;
-def err_lambda_unsupported : Error<"lambda expressions are not supported yet">;
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 appear in a capture list when the capture default is '='">;
+ "'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<
@@ -4125,7 +4022,16 @@
"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">;
def err_operator_arrow_circular : Error<
"circular pointer delegation detected">;
@@ -4146,9 +4052,6 @@
def err_pseudo_dtor_destructor_non_type : Error<
"%0 does not refer to a type name in pseudo-destructor expression; expected "
"the name of type %1">;
-def err_pseudo_dtor_template : Error<
- "specialization of template %0 does not refer to a scalar type in pseudo-"
- "destructor expression">;
def err_invalid_use_of_function_type : Error<
"a function type is not allowed here">;
def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
@@ -4166,8 +4069,6 @@
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
def err_expected_class : Error<"%0 is not a class%select{ or namespace|, "
"namespace, or scoped enumeration}1">;
-def err_missing_qualified_for_redecl : Error<
- "must qualify the name %0 to declare %q1 in this scope">;
def err_invalid_declarator_scope : Error<
"definition or redeclaration of %0 not in a namespace enclosing %1">;
def err_invalid_declarator_global_scope : Error<
@@ -4181,8 +4082,6 @@
"cannot form a pointer-to-member to member %0 of reference type %1">;
def err_incomplete_object_call : Error<
"incomplete type in call to object of type %0">;
-def err_incomplete_pointer_to_member_return : Error<
- "incomplete return type %0 of pointer-to-member constant">;
def warn_condition_is_assignment : Warning<"using the result of an "
"assignment as a condition without parentheses">,
@@ -4205,12 +4104,6 @@
def note_equality_comparison_silence : Note<
"remove extraneous parentheses around the comparison to silence this warning">;
-def warn_synthesized_ivar_access : Warning<
- "direct access of synthesized ivar by using property access %0">,
- InGroup<NonfragileAbi2>, DefaultIgnore;
-
-def note_global_declared_at : Note<"global variable declared here">;
-
// assignment related diagnostics (also for argument passing, returning, etc).
// In most of these diagnostics the %2 is a value from the
// Sema::AssignmentAction enumeration
@@ -4340,8 +4233,6 @@
"|sending %0 to parameter of type %1"
"|casting %0 to type %1}2"
" changes retain/release properties of pointer">;
-def err_typecheck_convert_ambiguous : Error<
- "ambiguity in initializing value of type %0 with initializer of type %1">;
def err_typecheck_comparison_of_distinct_blocks : Error<
"comparison of distinct block types (%0 and %1)">;
@@ -4475,9 +4366,6 @@
InGroup<DiagGroup<"conditional-type-mismatch">>;
def err_typecheck_choose_expr_requires_constant : Error<
"'__builtin_choose_expr' requires a constant expression">;
-def ext_typecheck_expression_not_constant : Extension<
- "expression is not a constant; folding it to one is a GNU extension">,
- InGroup<GNU>;
def warn_unused_expr : Warning<"expression result unused">,
InGroup<UnusedValue>;
def warn_unused_voidptr : Warning<
@@ -4545,10 +4433,6 @@
def err_invalid_conversion_between_vector_and_scalar : Error<
"invalid conversion between vector type %0 and scalar type %1">;
-def err_overload_expr_requires_non_zero_constant : Error<
- "overload requires a non-zero constant expression as first argument">;
-def err_overload_incorrect_fntype : Error<
- "argument is not a function, or has wrong number of parameters">;
// C++ member initializers.
def err_only_constructors_take_base_inits : Error<
@@ -4667,14 +4551,6 @@
"conversion from pointer to member of class %0 to pointer to member "
"of class %1 via virtual base %2 is not allowed">;
-// C++ access control
-def err_conv_to_inaccessible_base : Error<
- "conversion from %0 to inaccessible base class %1">, AccessControl;
-def note_inheritance_specifier_here : Note<
- "'%0' inheritance specifier here">;
-def note_inheritance_implicitly_private_here : Note<
- "inheritance is implicitly 'private'">;
-
// C++ member name lookup
def err_ambiguous_member_multiple_subobjects : Error<
"non-static member %0 found in multiple base-class subobjects of type %1:%2">;
@@ -5000,9 +4876,6 @@
// Blocks
def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
" or pick a deployment target that supports them">;
-def err_expected_block_lbrace : Error<"expected '{' in block literal">;
-def err_return_in_block_expression : Error<
- "return not allowed in block expression literal">;
def err_block_returning_array_function : Error<
"block cannot return %select{array|function}0 type %1">;
@@ -5064,7 +4937,7 @@
def warn_unreachable_default : Warning<
"default label in switch which covers all enumeration values">,
- InGroup<CoveredSwitchDefault>;
+ InGroup<CoveredSwitchDefault>, DefaultIgnore;
def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
InGroup<Switch>;
def err_typecheck_statement_requires_scalar : Error<
@@ -5189,8 +5062,6 @@
"GNU decimal type extension not supported">;
def err_missing_type_specifier : Error<
"C++ requires a type specifier for all declarations">;
-def err_missing_param_declspec : Error<
- "parameter requires a declaration specifier">;
def err_objc_array_of_interfaces : Error<
"array of interface %0 is invalid (probably should be an array of pointers)">;
def ext_c99_array_usage : Extension<
Modified: cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -23,87 +23,91 @@
namespace clang {
-struct PartialDiagnosticStorage {
- PartialDiagnosticStorage() : NumDiagArgs(0), NumDiagRanges(0) { }
-
+class PartialDiagnostic {
+public:
enum {
- /// MaxArguments - The maximum number of arguments we can hold. We
- /// currently only support up to 10 arguments (%0-%9).
- /// A single diagnostic with more than that almost certainly has to
- /// be simplified anyway.
+ // The MaxArguments and MaxFixItHints member enum values from
+ // DiagnosticsEngine are private but DiagnosticsEngine declares
+ // PartialDiagnostic a friend. These enum values are redeclared
+ // here so that the nested Storage class below can access them.
MaxArguments = DiagnosticsEngine::MaxArguments
};
- /// NumDiagArgs - This contains the number of entries in Arguments.
- unsigned char NumDiagArgs;
-
- /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
- unsigned char NumDiagRanges;
+ struct Storage {
+ Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
- /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
- /// values, with one for each argument. This specifies whether the argument
- /// is in DiagArgumentsStr or in DiagArguments.
- unsigned char DiagArgumentsKind[MaxArguments];
-
- /// DiagArgumentsVal - The values for the various substitution positions.
- /// This is used when the argument is not an std::string. The specific value
- /// is mangled into an intptr_t and the interpretation depends on exactly
- /// what sort of argument kind it is.
- intptr_t DiagArgumentsVal[MaxArguments];
-
- /// \brief The values for the various substitution positions that have
- /// string arguments.
- std::string DiagArgumentsStr[MaxArguments];
-
- /// DiagRanges - The list of ranges added to this diagnostic. It currently
- /// only support 10 ranges, could easily be extended if needed.
- CharSourceRange DiagRanges[10];
-
- /// FixItHints - If valid, provides a hint with some code
- /// to insert, remove, or modify at a particular position.
- SmallVector<FixItHint, 6> FixItHints;
-};
-
-/// \brief An allocator for Storage objects, which uses a small cache to
-/// objects, used to reduce malloc()/free() traffic for partial diagnostics.
-class PartialDiagnosticStorageAllocator {
- static const unsigned NumCached = 16;
- typedef PartialDiagnosticStorage Storage;
- Storage Cached[NumCached];
- Storage *FreeList[NumCached];
- unsigned NumFreeListEntries;
-
-public:
- PartialDiagnosticStorageAllocator();
- ~PartialDiagnosticStorageAllocator();
+ enum {
+ /// MaxArguments - The maximum number of arguments we can hold. We
+ /// currently only support up to 10 arguments (%0-%9).
+ /// A single diagnostic with more than that almost certainly has to
+ /// be simplified anyway.
+ MaxArguments = PartialDiagnostic::MaxArguments
+ };
+
+ /// NumDiagArgs - This contains the number of entries in Arguments.
+ unsigned char NumDiagArgs;
+
+ /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
+ unsigned char NumDiagRanges;
+
+ /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+ /// values, with one for each argument. This specifies whether the argument
+ /// is in DiagArgumentsStr or in DiagArguments.
+ unsigned char DiagArgumentsKind[MaxArguments];
+
+ /// DiagArgumentsVal - The values for the various substitution positions.
+ /// This is used when the argument is not an std::string. The specific value
+ /// is mangled into an intptr_t and the interpretation depends on exactly
+ /// what sort of argument kind it is.
+ intptr_t DiagArgumentsVal[MaxArguments];
+
+ /// \brief The values for the various substitution positions that have
+ /// string arguments.
+ std::string DiagArgumentsStr[MaxArguments];
+
+ /// DiagRanges - The list of ranges added to this diagnostic. It currently
+ /// only support 10 ranges, could easily be extended if needed.
+ CharSourceRange DiagRanges[10];
+
+ /// FixItHints - If valid, provides a hint with some code
+ /// to insert, remove, or modify at a particular position.
+ SmallVector<FixItHint, 6> FixItHints;
+ };
- /// \brief Allocate new storage.
- Storage *Allocate() {
- if (NumFreeListEntries == 0)
- return new Storage;
-
- Storage *Result = FreeList[--NumFreeListEntries];
- Result->NumDiagArgs = 0;
- Result->NumDiagRanges = 0;
- Result->FixItHints.clear();
- return Result;
- }
-
- /// \brief Free the given storage object.
- void Deallocate(Storage *S) {
- if (S >= Cached && S <= Cached + NumCached) {
- FreeList[NumFreeListEntries++] = S;
- return;
+ /// \brief An allocator for Storage objects, which uses a small cache to
+ /// objects, used to reduce malloc()/free() traffic for partial diagnostics.
+ class StorageAllocator {
+ static const unsigned NumCached = 16;
+ Storage Cached[NumCached];
+ Storage *FreeList[NumCached];
+ unsigned NumFreeListEntries;
+
+ public:
+ StorageAllocator();
+ ~StorageAllocator();
+
+ /// \brief Allocate new storage.
+ Storage *Allocate() {
+ if (NumFreeListEntries == 0)
+ return new Storage;
+
+ Storage *Result = FreeList[--NumFreeListEntries];
+ Result->NumDiagArgs = 0;
+ Result->NumDiagRanges = 0;
+ Result->FixItHints.clear();
+ return Result;
}
- delete S;
- }
-};
+ /// \brief Free the given storage object.
+ void Deallocate(Storage *S) {
+ if (S >= Cached && S <= Cached + NumCached) {
+ FreeList[NumFreeListEntries++] = S;
+ return;
+ }
-class PartialDiagnostic {
-public:
- typedef PartialDiagnosticStorage Storage;
- typedef PartialDiagnosticStorageAllocator StorageAllocator;
+ delete S;
+ }
+ };
private:
// NOTE: Sema assumes that PartialDiagnostic is location-invariant
Modified: cfe/branches/tooling/include/clang/Driver/CC1AsOptions.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/CC1AsOptions.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/CC1AsOptions.td (original)
+++ cfe/branches/tooling/include/clang/Driver/CC1AsOptions.td Tue Feb 14 03:11:10 2012
@@ -20,6 +20,10 @@
def triple : Separate<"-triple">,
HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">;
+def target_cpu : Separate<"-target-cpu">,
+ HelpText<"Target a specific cpu type">;
+def target_feature : Separate<"-target-feature">,
+ HelpText<"Target specific attributes">;
//===----------------------------------------------------------------------===//
// Language Options
Modified: cfe/branches/tooling/include/clang/Driver/DriverDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/DriverDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/DriverDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Driver/DriverDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define DRIVERSTART
#include "clang/Basic/DiagnosticDriverKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/Frontend/DiagnosticRenderer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/DiagnosticRenderer.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/DiagnosticRenderer.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/DiagnosticRenderer.h Tue Feb 14 03:11:10 2012
@@ -19,12 +19,17 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerUnion.h"
namespace clang {
- class DiagnosticOptions;
- class LangOptions;
- class SourceManager;
+class DiagnosticOptions;
+class LangOptions;
+class SourceManager;
+
+typedef llvm::PointerUnion<const Diagnostic *,
+ const StoredDiagnostic *> DiagOrStoredDiag;
+
/// \brief Class to encapsulate the logic for formatting a diagnostic message.
/// Actual "printing" logic is implemented by subclasses.
///
@@ -71,7 +76,7 @@
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
- const Diagnostic *Info) = 0;
+ DiagOrStoredDiag Info) = 0;
virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
@@ -86,9 +91,9 @@
virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc) = 0;
- virtual void beginDiagnostic(const Diagnostic *Info,
+ virtual void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {}
- virtual void endDiagnostic(const Diagnostic *Info,
+ virtual void endDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {}
@@ -117,7 +122,28 @@
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
- const Diagnostic *Info = 0);
+ DiagOrStoredDiag D = (Diagnostic *)0);
+
+ void emitStoredDiagnostic(StoredDiagnostic &Diag);
+};
+
+/// Subclass of DiagnosticRender that turns all subdiagostics into explicit
+/// notes. It is up to subclasses to further define the behavior.
+class DiagnosticNoteRenderer : public DiagnosticRenderer {
+public:
+ DiagnosticNoteRenderer(const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const DiagnosticOptions &DiagOpts)
+ : DiagnosticRenderer(SM, LangOpts, DiagOpts) {}
+
+ virtual ~DiagnosticNoteRenderer();
+
+ virtual void emitBasicNote(StringRef Message);
+
+ virtual void emitIncludeLocation(SourceLocation Loc,
+ PresumedLoc PLoc);
+
+ virtual void emitNote(SourceLocation Loc, StringRef Message) = 0;
};
} // end clang namespace
#endif
Modified: cfe/branches/tooling/include/clang/Frontend/FrontendDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/FrontendDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/FrontendDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/FrontendDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define FRONTENDSTART
#include "clang/Basic/DiagnosticFrontendKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/Frontend/MultiplexConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/MultiplexConsumer.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/MultiplexConsumer.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/MultiplexConsumer.h Tue Feb 14 03:11:10 2012
@@ -39,6 +39,7 @@
virtual void HandleInterestingDecl(DeclGroupRef D);
virtual void HandleTranslationUnit(ASTContext &Ctx);
virtual void HandleTagDeclDefinition(TagDecl *D);
+ virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D);
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
virtual void CompleteTentativeDefinition(VarDecl *D);
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);
Modified: cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -81,7 +81,7 @@
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
- const Diagnostic *Info);
+ DiagOrStoredDiag D);
virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
Modified: cfe/branches/tooling/include/clang/Lex/LexDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/LexDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/LexDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Lex/LexDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define LEXSTART
#include "clang/Basic/DiagnosticLexKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/LiteralSupport.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/branches/tooling/include/clang/Lex/LiteralSupport.h Tue Feb 14 03:11:10 2012
@@ -199,6 +199,7 @@
private:
void init(const Token *StringToks, unsigned NumStringToks);
bool CopyStringFragment(StringRef Fragment);
+ bool DiagnoseBadString(const Token& Tok);
};
} // end namespace clang
Modified: cfe/branches/tooling/include/clang/Lex/PPCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/PPCallbacks.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/PPCallbacks.h (original)
+++ cfe/branches/tooling/include/clang/Lex/PPCallbacks.h Tue Feb 14 03:11:10 2012
@@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -157,10 +158,9 @@
}
/// PragmaDiagnostic - This callback is invoked when a
- /// #pragma gcc diagnostic directive is read.
- /// Mapping is an element of the diag::Mapping enum.
+ /// #pragma gcc dianostic directive is read.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
- unsigned mapping, StringRef Str) {
+ diag::Mapping mapping, StringRef Str) {
}
/// MacroExpands - This is called by
@@ -303,7 +303,7 @@
}
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
- unsigned mapping, StringRef Str) {
+ diag::Mapping mapping, StringRef Str) {
First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
}
Modified: cfe/branches/tooling/include/clang/Lex/PTHManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/PTHManager.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/PTHManager.h (original)
+++ cfe/branches/tooling/include/clang/Lex/PTHManager.h Tue Feb 14 03:11:10 2012
@@ -17,6 +17,7 @@
#include "clang/Lex/PTHLexer.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
#include <string>
Modified: cfe/branches/tooling/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/Preprocessor.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/Preprocessor.h (original)
+++ cfe/branches/tooling/include/clang/Lex/Preprocessor.h Tue Feb 14 03:11:10 2012
@@ -21,6 +21,7 @@
#include "clang/Lex/TokenLexer.h"
#include "clang/Lex/PTHManager.h"
#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
@@ -60,7 +61,7 @@
/// like the #include stack, token expansion, etc.
///
class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
- DiagnosticsEngine *Diags;
+ DiagnosticsEngine *Diags;
LangOptions &Features;
const TargetInfo *Target;
FileManager &FileMgr;
@@ -728,7 +729,12 @@
bool isCodeCompletionReached() const { return CodeCompletionReached; }
/// \brief Note that we hit the code-completion point.
- void setCodeCompletionReached();
+ void setCodeCompletionReached() {
+ assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
+ CodeCompletionReached = true;
+ // Silence any diagnostics that occur after we hit the code-completion.
+ getDiagnostics().setSuppressAllDiagnostics(true);
+ }
/// \brief The location of the currently-active #pragma clang
/// arc_cf_code_audited begin. Returns an invalid location if there
@@ -758,9 +764,13 @@
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
/// the specified Token's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const;
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
+ return Diags->Report(Loc, DiagID);
+ }
- DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const;
+ DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
+ return Diags->Report(Tok.getLocation(), DiagID);
+ }
/// getSpelling() - Return the 'spelling' of the token at the given
/// location; does not go up to the spelling location or down to the
Modified: cfe/branches/tooling/include/clang/Parse/ParseDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Parse/ParseDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Parse/ParseDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Parse/ParseDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define PARSESTART
#include "clang/Basic/DiagnosticParseKinds.inc"
#undef DIAG
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Parse/Parser.h (original)
+++ cfe/branches/tooling/include/clang/Parse/Parser.h Tue Feb 14 03:11:10 2012
@@ -258,8 +258,6 @@
/// the EOF was encountered.
bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
- DeclGroupPtrTy FinishPendingObjCActions();
-
private:
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
@@ -404,9 +402,6 @@
Tok.setKind(tok::eof);
}
- /// \brief Clear and free the cached objc methods.
- void clearLateParsedObjCMethods();
-
/// \brief Handle the annotation token produced for #pragma unused(...)
void HandlePragmaUnused();
@@ -1227,12 +1222,28 @@
DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
ParsedAttributes &prefixAttrs);
- Decl *ObjCImpDecl;
- SmallVector<Decl *, 4> PendingObjCImpDecl;
- typedef SmallVector<LexedMethod*, 2> LateParsedObjCMethodContainer;
- LateParsedObjCMethodContainer LateParsedObjCMethods;
+ struct ObjCImplParsingDataRAII {
+ Parser &P;
+ Decl *Dcl;
+ typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
+ LateParsedObjCMethodContainer LateParsedObjCMethods;
+
+ ObjCImplParsingDataRAII(Parser &parser, Decl *D)
+ : P(parser), Dcl(D) {
+ P.CurParsedObjCImpl = this;
+ Finished = false;
+ }
+ ~ObjCImplParsingDataRAII();
+
+ void finish(SourceRange AtEnd);
+ bool isFinished() const { return Finished; }
+
+ private:
+ bool Finished;
+ };
+ ObjCImplParsingDataRAII *CurParsedObjCImpl;
- Decl *ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
+ DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
Modified: cfe/branches/tooling/include/clang/Rewrite/ASTConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Rewrite/ASTConsumers.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Rewrite/ASTConsumers.h (original)
+++ cfe/branches/tooling/include/clang/Rewrite/ASTConsumers.h Tue Feb 14 03:11:10 2012
@@ -31,6 +31,11 @@
DiagnosticsEngine &Diags,
const LangOptions &LOpts,
bool SilenceRewriteMacroWarning);
+ASTConsumer *CreateModernObjCRewriter(const std::string &InFile,
+ raw_ostream *OS,
+ DiagnosticsEngine &Diags,
+ const LangOptions &LOpts,
+ bool SilenceRewriteMacroWarning);
/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
/// HTML with syntax highlighting suitable for viewing in a web-browser.
Modified: cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h Tue Feb 14 03:11:10 2012
@@ -24,7 +24,6 @@
namespace clang {
class Decl;
-class Preprocessor;
/// \brief Default priority values for code-completion results based
/// on their kind.
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/DeclSpec.h (original)
+++ cfe/branches/tooling/include/clang/Sema/DeclSpec.h Tue Feb 14 03:11:10 2012
@@ -1933,6 +1933,7 @@
/// LambdaIntroducer - Represents a complete lambda introducer.
struct LambdaIntroducer {
SourceRange Range;
+ SourceLocation DefaultLoc;
LambdaCaptureDefault Default;
llvm::SmallVector<LambdaCapture, 4> Captures;
Modified: cfe/branches/tooling/include/clang/Sema/DelayedDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/DelayedDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/DelayedDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Sema/DelayedDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -22,7 +22,6 @@
#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
#include "clang/AST/DeclCXX.h"
-#include "clang/Basic/PartialDiagnostic.h"
namespace clang {
namespace sema {
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Initialization.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Initialization.h Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-//===--- SemaInit.h - Semantic Analysis for Initializers --------*- C++ -*-===//
+//===--- Initialization.h - Semantic Analysis for Initializers --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -326,36 +326,35 @@
public:
/// \brief The kind of initialization being performed.
enum InitKind {
- IK_Direct, ///< Direct initialization
- IK_Copy, ///< Copy initialization
- IK_Default, ///< Default initialization
- IK_Value ///< Value initialization
+ IK_Direct, ///< Direct initialization
+ IK_DirectList, ///< Direct list-initialization
+ IK_Copy, ///< Copy initialization
+ IK_Default, ///< Default initialization
+ IK_Value ///< Value initialization
};
private:
- /// \brief The kind of initialization that we're storing.
- enum StoredInitKind {
- SIK_Direct = IK_Direct, ///< Direct initialization
- SIK_Copy = IK_Copy, ///< Copy initialization
- SIK_Default = IK_Default, ///< Default initialization
- SIK_Value = IK_Value, ///< Value initialization
- SIK_ImplicitValue, ///< Implicit value initialization
- SIK_DirectCast, ///< Direct initialization due to a cast
- /// \brief Direct initialization due to a C-style cast.
- SIK_DirectCStyleCast,
- /// \brief Direct initialization due to a functional-style cast.
- SIK_DirectFunctionalCast
+ /// \brief The context of the initialization.
+ enum InitContext {
+ IC_Normal, ///< Normal context
+ IC_Implicit, ///< Implicit context (value initialization)
+ IC_StaticCast, ///< Static cast context
+ IC_CStyleCast, ///< C-style cast context
+ IC_FunctionalCast ///< Functional cast context
};
/// \brief The kind of initialization being performed.
- StoredInitKind Kind;
+ InitKind Kind : 8;
+
+ /// \brief The context of the initialization.
+ InitContext Context : 8;
/// \brief The source locations involved in the initialization.
SourceLocation Locations[3];
- InitializationKind(StoredInitKind Kind, SourceLocation Loc1,
+ InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1,
SourceLocation Loc2, SourceLocation Loc3)
- : Kind(Kind)
+ : Kind(Kind), Context(Context)
{
Locations[0] = Loc1;
Locations[1] = Loc2;
@@ -367,41 +366,50 @@
static InitializationKind CreateDirect(SourceLocation InitLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc) {
- return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
+ return InitializationKind(IK_Direct, IC_Normal,
+ InitLoc, LParenLoc, RParenLoc);
+ }
+
+ static InitializationKind CreateDirectList(SourceLocation InitLoc) {
+ return InitializationKind(IK_DirectList, IC_Normal,
+ InitLoc, InitLoc, InitLoc);
}
/// \brief Create a direct initialization due to a cast that isn't a C-style
/// or functional cast.
static InitializationKind CreateCast(SourceRange TypeRange) {
- return InitializationKind(SIK_DirectCast,
- TypeRange.getBegin(), TypeRange.getBegin(),
- TypeRange.getEnd());
+ return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
+ TypeRange.getBegin(), TypeRange.getEnd());
}
/// \brief Create a direct initialization for a C-style cast.
static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
- SourceRange TypeRange) {
- return InitializationKind(SIK_DirectCStyleCast,
- StartLoc, TypeRange.getBegin(),
+ SourceRange TypeRange,
+ bool InitList) {
+ // C++ cast syntax doesn't permit init lists, but C compound literals are
+ // exactly that.
+ return InitializationKind(InitList ? IK_DirectList : IK_Direct,
+ IC_CStyleCast, StartLoc, TypeRange.getBegin(),
TypeRange.getEnd());
}
/// \brief Create a direct initialization for a functional cast.
- static InitializationKind CreateFunctionalCast(SourceRange TypeRange) {
- return InitializationKind(SIK_DirectFunctionalCast,
- TypeRange.getBegin(), TypeRange.getBegin(),
- TypeRange.getEnd());
+ static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
+ bool InitList) {
+ return InitializationKind(InitList ? IK_DirectList : IK_Direct,
+ IC_FunctionalCast, TypeRange.getBegin(),
+ TypeRange.getBegin(), TypeRange.getEnd());
}
/// \brief Create a copy initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc,
SourceLocation EqualLoc) {
- return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
+ return InitializationKind(IK_Copy, IC_Normal, InitLoc, EqualLoc, EqualLoc);
}
/// \brief Create a default initialization.
static InitializationKind CreateDefault(SourceLocation InitLoc) {
- return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
+ return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
}
/// \brief Create a value initialization.
@@ -409,46 +417,39 @@
SourceLocation LParenLoc,
SourceLocation RParenLoc,
bool isImplicit = false) {
- return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value,
+ return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
InitLoc, LParenLoc, RParenLoc);
}
/// \brief Determine the initialization kind.
InitKind getKind() const {
- if (Kind > SIK_ImplicitValue)
- return IK_Direct;
- if (Kind == SIK_ImplicitValue)
- return IK_Value;
-
- return (InitKind)Kind;
+ return Kind;
}
/// \brief Determine whether this initialization is an explicit cast.
bool isExplicitCast() const {
- return Kind == SIK_DirectCast ||
- Kind == SIK_DirectCStyleCast ||
- Kind == SIK_DirectFunctionalCast;
+ return Context >= IC_StaticCast;
}
/// \brief Determine whether this initialization is a C-style cast.
bool isCStyleOrFunctionalCast() const {
- return Kind == SIK_DirectCStyleCast || Kind == SIK_DirectFunctionalCast;
+ return Context >= IC_CStyleCast;
}
- /// brief Determine whether this is a C-style cast.
+ /// \brief Determine whether this is a C-style cast.
bool isCStyleCast() const {
- return Kind == SIK_DirectCStyleCast;
+ return Context == IC_CStyleCast;
}
- /// brief Determine whether this is a functional-style cast.
+ /// \brief Determine whether this is a functional-style cast.
bool isFunctionalCast() const {
- return Kind == SIK_DirectFunctionalCast;
+ return Context == IC_FunctionalCast;
}
/// \brief Determine whether this initialization is an implicit
/// value-initialization, e.g., as occurs during aggregate
/// initialization.
- bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
+ bool isImplicitValueInit() const { return Context == IC_Implicit; }
/// \brief Retrieve the location at which initialization is occurring.
SourceLocation getLocation() const { return Locations[0]; }
@@ -461,16 +462,20 @@
/// \brief Retrieve the location of the equal sign for copy initialization
/// (if present).
SourceLocation getEqualLoc() const {
- assert(Kind == SIK_Copy && "Only copy initialization has an '='");
+ assert(Kind == IK_Copy && "Only copy initialization has an '='");
return Locations[1];
}
-
- bool isCopyInit() const { return Kind == SIK_Copy; }
-
+
+ bool isCopyInit() const { return Kind == IK_Copy; }
+
+ /// \brief Retrieve whether this initialization allows the use of explicit
+ /// constructors.
+ bool AllowExplicit() const { return !isCopyInit(); }
+
/// \brief Retrieve the source range containing the locations of the open
/// and closing parentheses for value and direct initializations.
SourceRange getParenRange() const {
- assert((getKind() == IK_Direct || Kind == SIK_Value) &&
+ assert((Kind == IK_Direct || Kind == IK_Value) &&
"Only direct- and value-initialization have parentheses");
return SourceRange(Locations[1], Locations[2]);
}
Removed: cfe/branches/tooling/include/clang/Sema/MultiInitializer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/MultiInitializer.h?rev=150464&view=auto
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/MultiInitializer.h (original)
+++ cfe/branches/tooling/include/clang/Sema/MultiInitializer.h (removed)
@@ -1,72 +0,0 @@
-//===--- MultiInitializer.h - Initializer expression group ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the MultiInitializer class, which can represent a list
-// initializer or a parentheses-wrapped group of expressions in a C++ member
-// initializer.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_MULTIINITIALIZER_H
-#define LLVM_CLANG_SEMA_MULTIINITIALIZER_H
-
-#include "clang/Sema/Ownership.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
- class ASTContext;
- class Expr;
- class InitializationKind;
- class InitializedEntity;
- class InitListExpr;
- class Sema;
-
-class MultiInitializer {
- llvm::PointerUnion<Expr*, Expr**> InitListOrExpressions;
- unsigned NumInitializers;
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-
- InitListExpr *getInitList() const;
- Expr **getExpressions() const { return InitListOrExpressions.get<Expr**>(); }
-
-public:
- MultiInitializer(Expr* InitList)
- : InitListOrExpressions(InitList)
- {}
-
- MultiInitializer(SourceLocation LParenLoc, Expr **Exprs, unsigned NumInits,
- SourceLocation RParenLoc)
- : InitListOrExpressions(Exprs), NumInitializers(NumInits),
- LParenLoc(LParenLoc), RParenLoc(RParenLoc)
- {}
-
- bool isInitializerList() const { return InitListOrExpressions.is<Expr*>(); }
-
- SourceLocation getStartLoc() const;
- SourceLocation getEndLoc() const;
-
- typedef Expr **iterator;
- iterator begin() const;
- iterator end() const;
-
- bool isTypeDependent() const;
-
- bool DiagnoseUnexpandedParameterPack(Sema &SemaRef) const;
-
- // Return the InitListExpr or create a ParenListExpr.
- Expr *CreateInitExpr(ASTContext &Ctx, QualType T) const;
-
- ExprResult PerformInit(Sema &SemaRef, InitializedEntity Entity,
- InitializationKind Kind) const;
-};
-}
-
-#endif
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/branches/tooling/include/clang/Sema/ScopeInfo.h Tue Feb 14 03:11:10 2012
@@ -22,11 +22,13 @@
namespace clang {
class BlockDecl;
+class CXXMethodDecl;
class IdentifierInfo;
class LabelDecl;
class ReturnStmt;
class Scope;
class SwitchStmt;
+class VarDecl;
namespace sema {
@@ -156,8 +158,8 @@
CopyExprAndNested(Cpy, isNested) {}
enum IsThisCapture { ThisCapture };
- Capture(IsThisCapture, bool isNested, SourceLocation Loc)
- : VarAndKind(0, Cap_This), CopyExprAndNested(0, isNested), Loc(Loc) {
+ Capture(IsThisCapture, bool isNested, SourceLocation Loc, Expr *Cpy)
+ : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc) {
}
bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
@@ -208,8 +210,8 @@
CaptureMap[Var] = Captures.size();
}
- void AddThisCapture(bool isNested, SourceLocation Loc) {
- Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc));
+ void AddThisCapture(bool isNested, SourceLocation Loc, Expr *Cpy) {
+ Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, Cpy));
CXXThisCaptureIndex = Captures.size();
}
@@ -280,6 +282,9 @@
/// \brief The class that describes the lambda.
CXXRecordDecl *Lambda;
+ /// \brief The class that describes the lambda.
+ CXXMethodDecl *CallOperator;
+
/// \brief Source range covering the lambda introducer [...].
SourceRange IntroducerRange;
@@ -287,14 +292,27 @@
/// explicit captures.
unsigned NumExplicitCaptures;
+ /// \brief Whether this is a mutable lambda.
bool Mutable;
/// \brief Whether the (empty) parameter list is explicit.
bool ExplicitParams;
- LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda)
+ /// \brief Whether any of the capture expressions requires cleanups.
+ bool ExprNeedsCleanups;
+
+ /// \brief Variables used to index into by-copy array captures.
+ llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
+
+ /// \brief Offsets into the ArrayIndexVars array at which each capture starts
+ /// its list of array index variables.
+ llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
+
+ LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
+ CXXMethodDecl *CallOperator)
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
- NumExplicitCaptures(0), Mutable(false)
+ CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
+ ExprNeedsCleanups(false)
{
Kind = SK_Lambda;
}
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Sema.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Sema.h Tue Feb 14 03:11:10 2012
@@ -22,7 +22,6 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/LocInfoType.h"
-#include "clang/Sema/MultiInitializer.h"
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "clang/AST/Expr.h"
@@ -30,7 +29,6 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Lex/ModuleLoader.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TypeTraits.h"
@@ -103,6 +101,7 @@
class InitializedEntity;
class IntegerLiteral;
class LabelStmt;
+ class LambdaExpr;
class LangOptions;
class LocalInstantiationScope;
class LookupResult;
@@ -561,6 +560,10 @@
llvm::SmallPtrSet<Expr*, 8> SavedMaybeODRUseExprs;
+ /// \brief The lambdas that are present within this context, if it
+ /// is indeed an unevaluated context.
+ llvm::SmallVector<LambdaExpr *, 2> Lambdas;
+
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumCleanupObjects,
bool ParentNeedsCleanups)
@@ -733,7 +736,7 @@
void PushFunctionScope();
void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
- void PushLambdaScope(CXXRecordDecl *Lambda);
+ void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator);
void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0,
const Decl *D = 0, const BlockExpr *blkExpr = 0);
@@ -771,8 +774,8 @@
SourceLocation AttrLoc);
QualType BuildFunctionType(QualType T,
QualType *ParamTypes, unsigned NumParamTypes,
- bool Variadic, unsigned Quals,
- RefQualifierKind RefQualifier,
+ bool Variadic, bool HasTrailingReturn,
+ unsigned Quals, RefQualifierKind RefQualifier,
SourceLocation Loc, DeclarationName Entity,
FunctionType::ExtInfo Info);
QualType BuildMemberPointerType(QualType T, QualType Class,
@@ -832,8 +835,7 @@
PartialDiagnostic> Note);
bool RequireLiteralType(SourceLocation Loc, QualType T,
- const PartialDiagnostic &PD,
- bool AllowIncompleteType = false);
+ const PartialDiagnostic &PD);
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
const CXXScopeSpec &SS, QualType T);
@@ -1001,23 +1003,8 @@
bool &AddToScope);
bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
- /// \brief The kind of constexpr declaration checking we are performing.
- ///
- /// The kind affects which diagnostics (if any) are emitted if the function
- /// does not satisfy the requirements of a constexpr function declaration.
- enum CheckConstexprKind {
- /// \brief Check a constexpr function declaration, and produce errors if it
- /// does not satisfy the requirements.
- CCK_Declaration,
- /// \brief Check a constexpr function template instantiation.
- CCK_Instantiation,
- /// \brief Produce notes explaining why an instantiation was not constexpr.
- CCK_NoteNonConstexprInstantiation
- };
- bool CheckConstexprFunctionDecl(const FunctionDecl *FD,
- CheckConstexprKind CCK);
- bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body,
- bool IsInstantiation);
+ bool CheckConstexprFunctionDecl(const FunctionDecl *FD);
+ bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body);
void DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
// Returns true if the function declaration is a redeclaration
@@ -1960,7 +1947,7 @@
ObjCContainerDecl* IDecl,
bool &IncompleteImpl,
bool ImmediateClass,
- bool WarnExactMatch=false);
+ bool WarnCategoryMethodImpl=false);
/// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
/// category matches with those implemented in its primary class and
@@ -2247,9 +2234,6 @@
bool CanUseDecl(NamedDecl *D);
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass=0);
- AvailabilityResult DiagnoseAvailabilityOfDecl(NamedDecl *D,
- SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass);
std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
ObjCMethodDecl *Getter,
@@ -2282,6 +2266,34 @@
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
};
@@ -2386,9 +2398,9 @@
ExprResult ActOnNumericConstant(const Token &Tok);
ExprResult ActOnCharacterConstant(const Token &Tok);
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
- ExprResult ActOnParenOrParenListExpr(SourceLocation L,
- SourceLocation R,
- MultiExprArg Val);
+ ExprResult ActOnParenListExpr(SourceLocation L,
+ SourceLocation R,
+ MultiExprArg Val);
/// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz").
@@ -2768,15 +2780,6 @@
UnqualifiedId &Name,
TypeResult Type);
- /// AddCXXDirectInitializerToDecl - This action is called immediately after
- /// ActOnDeclarator, when a C++ direct initializer is present.
- /// e.g: "int x(1);"
- void AddCXXDirectInitializerToDecl(Decl *Dcl,
- SourceLocation LParenLoc,
- MultiExprArg Exprs,
- SourceLocation RParenLoc,
- bool TypeMayContainAuto);
-
/// InitializeVarWithConstructor - Creates an CXXConstructExpr
/// and sets it as the initializer for the the passed in VarDecl.
bool InitializeVarWithConstructor(VarDecl *VD,
@@ -3464,6 +3467,31 @@
/// initializer for the declaration 'Dcl'.
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
+ /// \brief Create a new lambda closure type.
+ CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange);
+
+ /// \brief Start the definition of a lambda expression.
+ CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
+ SourceRange IntroducerRange,
+ TypeSourceInfo *MethodType,
+ SourceLocation EndLoc);
+
+ /// \brief Introduce the scope for a lambda expression.
+ sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator,
+ SourceRange IntroducerRange,
+ LambdaCaptureDefault CaptureDefault,
+ bool ExplicitParams,
+ bool ExplicitResultType,
+ bool Mutable);
+
+ /// \brief Note that we have finished the explicit captures for the
+ /// given lambda.
+ void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
+
+ /// \brief Introduce the lambda parameters into scope.
+ void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope,
+ llvm::ArrayRef<ParmVarDecl *> Params);
+
/// ActOnStartOfLambdaDefinition - This is called just before we start
/// parsing the body of a lambda; it analyzes the explicit captures and
/// arguments, and sets up various data-structures for the body of the
@@ -3473,12 +3501,13 @@
/// ActOnLambdaError - If there is an error parsing a lambda, this callback
/// is invoked to pop the information about the lambda.
- void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope);
+ void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
+ bool IsInstantiation = false);
/// ActOnLambdaExpr - This is called when the body of a lambda expression
/// was successfully completed.
ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
- Scope *CurScope);
+ Scope *CurScope, bool IsInstantiation = false);
// ParseObjCStringLiteral - Parse Objective-C string literals.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
@@ -3573,21 +3602,21 @@
ParsedType TemplateTypeTy,
const DeclSpec &DS,
SourceLocation IdLoc,
- const MultiInitializer &Init,
+ Expr *Init,
SourceLocation EllipsisLoc);
MemInitResult BuildMemberInitializer(ValueDecl *Member,
- const MultiInitializer &Args,
+ Expr *Init,
SourceLocation IdLoc);
MemInitResult BuildBaseInitializer(QualType BaseType,
TypeSourceInfo *BaseTInfo,
- const MultiInitializer &Args,
+ Expr *Init,
CXXRecordDecl *ClassDecl,
SourceLocation EllipsisLoc);
MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo,
- const MultiInitializer &Args,
+ Expr *Init,
CXXRecordDecl *ClassDecl);
bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
@@ -5185,6 +5214,10 @@
Decl *SubstDecl(Decl *D, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs);
+ ExprResult SubstInitializer(Expr *E,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ bool CXXDirectInit);
+
bool
SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
CXXRecordDecl *Pattern,
@@ -5258,11 +5291,6 @@
void InstantiateMemInitializers(CXXConstructorDecl *New,
const CXXConstructorDecl *Tmpl,
const MultiLevelTemplateArgumentList &TemplateArgs);
- bool InstantiateInitializer(Expr *Init,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation &LParenLoc,
- ASTOwningVector<Expr*> &NewArgs,
- SourceLocation &RParenLoc);
NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
const MultiLevelTemplateArgumentList &TemplateArgs);
Modified: cfe/branches/tooling/include/clang/Sema/SemaDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/SemaDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/SemaDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Sema/SemaDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define SEMASTART
#include "clang/Basic/DiagnosticSemaKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/Sema/SemaFixItUtils.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/SemaFixItUtils.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/SemaFixItUtils.h (original)
+++ cfe/branches/tooling/include/clang/Sema/SemaFixItUtils.h Tue Feb 14 03:11:10 2012
@@ -14,7 +14,6 @@
#define LLVM_CLANG_SEMA_FIXITUTILS_H
#include "clang/AST/Expr.h"
-#include "clang/Basic/Diagnostic.h"
namespace clang {
Modified: cfe/branches/tooling/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Serialization/ASTReader.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Serialization/ASTReader.h (original)
+++ cfe/branches/tooling/include/clang/Serialization/ASTReader.h Tue Feb 14 03:11:10 2012
@@ -639,6 +639,12 @@
/// \brief Number of Decl/types that are currently deserializing.
unsigned NumCurrentElementsDeserializing;
+ /// \brief Set true while we are in the process of passing deserialized
+ /// "interesting" decls to consumer inside FinishedDeserializing().
+ /// This is used as a guard to avoid recursively repeating the process of
+ /// passing decls to consumer.
+ bool PassingDeclsToConsumer;
+
/// Number of CXX base specifiers currently loaded
unsigned NumCXXBaseSpecifiersLoaded;
Modified: cfe/branches/tooling/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Serialization/ASTWriter.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/branches/tooling/include/clang/Serialization/ASTWriter.h Tue Feb 14 03:11:10 2012
@@ -43,7 +43,6 @@
class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXCtorInitializer;
-class DiagnosticsEngine;
class FPOptions;
class HeaderSearch;
class IdentifierResolver;
Modified: cfe/branches/tooling/include/clang/Serialization/SerializationDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Serialization/SerializationDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Serialization/SerializationDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Serialization/SerializationDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM,
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define SERIALIZATIONSTART
#include "clang/Basic/DiagnosticSerializationKinds.inc"
#undef DIAG
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -16,6 +16,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerUnion.h"
#include <deque>
#include <iterator>
@@ -259,7 +260,7 @@
// Path "pieces" for path-sensitive diagnostics.
//===----------------------------------------------------------------------===//
-class PathDiagnosticPiece {
+class PathDiagnosticPiece : public llvm::RefCountedBaseVPTR {
public:
enum Kind { ControlFlow, Event, Macro, CallEnter, CallExit };
enum DisplayHint { Above, Below };
@@ -322,6 +323,13 @@
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
+
+
+class PathPieces :
+ public std::deque<llvm::IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+public:
+ ~PathPieces();
+};
class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
private:
@@ -440,30 +448,22 @@
};
class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
- std::vector<PathDiagnosticPiece*> SubPieces;
public:
PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
: PathDiagnosticSpotPiece(pos, "", Macro) {}
~PathDiagnosticMacroPiece();
+ PathPieces subPieces;
+
bool containsEvent() const;
- void push_back(PathDiagnosticPiece *P) { SubPieces.push_back(P); }
-
- typedef std::vector<PathDiagnosticPiece*>::iterator iterator;
- iterator begin() { return SubPieces.begin(); }
- iterator end() { return SubPieces.end(); }
-
virtual void flattenLocations() {
PathDiagnosticSpotPiece::flattenLocations();
- for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
+ for (PathPieces::iterator I = subPieces.begin(),
+ E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
}
- typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
- const_iterator begin() const { return SubPieces.begin(); }
- const_iterator end() const { return SubPieces.end(); }
-
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Macro;
}
@@ -475,16 +475,14 @@
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
/// each which represent the pieces of the path.
class PathDiagnostic : public llvm::FoldingSetNode {
- std::deque<PathDiagnosticPiece*> path;
- unsigned Size;
std::string BugType;
std::string Desc;
std::string Category;
std::deque<std::string> OtherDesc;
-
public:
- PathDiagnostic();
+ PathPieces path;
+ PathDiagnostic();
PathDiagnostic(StringRef bugtype, StringRef desc,
StringRef category);
@@ -493,6 +491,7 @@
StringRef getDescription() const { return Desc; }
StringRef getBugType() const { return BugType; }
StringRef getCategory() const { return Category; }
+
typedef std::deque<std::string>::const_iterator meta_iterator;
meta_iterator meta_begin() const { return OtherDesc.begin(); }
@@ -500,106 +499,14 @@
void addMeta(StringRef s) { OtherDesc.push_back(s); }
PathDiagnosticLocation getLocation() const {
- assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
- return rbegin()->getLocation();
- }
-
- void push_front(PathDiagnosticPiece *piece) {
- assert(piece);
- path.push_front(piece);
- ++Size;
- }
-
- void push_back(PathDiagnosticPiece *piece) {
- assert(piece);
- path.push_back(piece);
- ++Size;
+ assert(path.size() > 0 &&
+ "getLocation() requires a non-empty PathDiagnostic.");
+ return (*path.rbegin())->getLocation();
}
- PathDiagnosticPiece *back() {
- return path.back();
- }
-
- const PathDiagnosticPiece *back() const {
- return path.back();
- }
-
- unsigned size() const { return Size; }
- bool empty() const { return Size == 0; }
-
- void resetPath(bool deletePieces = true);
-
- class iterator {
- public:
- typedef std::deque<PathDiagnosticPiece*>::iterator ImplTy;
-
- typedef PathDiagnosticPiece value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- private:
- ImplTy I;
-
- public:
- iterator(const ImplTy& i) : I(i) {}
-
- bool operator==(const iterator &X) const { return I == X.I; }
- bool operator!=(const iterator &X) const { return I != X.I; }
-
- PathDiagnosticPiece& operator*() const { return **I; }
- PathDiagnosticPiece *operator->() const { return *I; }
-
- iterator &operator++() { ++I; return *this; }
- iterator &operator--() { --I; return *this; }
- };
-
- class const_iterator {
- public:
- typedef std::deque<PathDiagnosticPiece*>::const_iterator ImplTy;
-
- typedef const PathDiagnosticPiece value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- private:
- ImplTy I;
-
- public:
- const_iterator(const ImplTy& i) : I(i) {}
-
- bool operator==(const const_iterator &X) const { return I == X.I; }
- bool operator!=(const const_iterator &X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
-
- const_iterator &operator++() { ++I; return *this; }
- const_iterator &operator--() { --I; return *this; }
- };
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- // forward iterator creation methods.
-
- iterator begin() { return path.begin(); }
- iterator end() { return path.end(); }
-
- const_iterator begin() const { return path.begin(); }
- const_iterator end() const { return path.end(); }
-
- // reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-
void flattenLocations() {
- for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
+ for (PathPieces::iterator I = path.begin(), E = path.end();
+ I != E; ++I) (*I)->flattenLocations();
}
void Profile(llvm::FoldingSetNodeID &ID) const;
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerRegistry.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerRegistry.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerRegistry.h Tue Feb 14 03:11:10 2012
@@ -107,7 +107,9 @@
/// checker does not require any custom initialization.
template <class T>
void addChecker(StringRef fullName, StringRef desc) {
- addChecker(&initializeManager<T>, fullName, desc);
+ // Avoid MSVC's Compiler Error C2276:
+ // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
+ addChecker(&CheckerRegistry::initializeManager<T>, fullName, desc);
}
/// Initializes a CheckerManager by calling the initialization functions for
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Tue Feb 14 03:11:10 2012
@@ -195,8 +195,7 @@
bool MarkAsSink,
ExplodedNode *P = 0,
const ProgramPointTag *Tag = 0) {
- assert(State);
- if (State == Pred->getState() && !Tag && !MarkAsSink)
+ if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
return Pred;
Changed = true;
Modified: cfe/branches/tooling/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTContext.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTContext.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTContext.cpp Tue Feb 14 03:11:10 2012
@@ -24,7 +24,6 @@
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Mangle.h"
#include "clang/Basic/Builtins.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallString.h"
@@ -242,9 +241,6 @@
LastSDM(0, 0),
UniqueBlockByRefTypeID(0)
{
- // Create a new allocator for partial diagnostics.
- DiagAllocator = new (BumpAlloc) PartialDiagnosticStorageAllocator;
-
if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this);
@@ -289,9 +285,6 @@
AEnd = DeclAttrs.end();
A != AEnd; ++A)
A->second->~AttrVec();
-
- // Destroy the partial diagnostic allocator.
- DiagAllocator->~PartialDiagnosticStorageAllocator();
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
@@ -1394,8 +1387,8 @@
QualType canon;
if (!baseType->isCanonicalUnqualified()) {
SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split();
- canonSplit.second.addConsistentQualifiers(quals);
- canon = getExtQualType(canonSplit.first, canonSplit.second);
+ canonSplit.Quals.addConsistentQualifiers(quals);
+ canon = getExtQualType(canonSplit.Ty, canonSplit.Quals);
// Re-find the insert position.
(void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos);
@@ -1697,9 +1690,9 @@
QualType Canon;
if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(EltTy).split();
- Canon = getConstantArrayType(QualType(canonSplit.first, 0), ArySize,
+ Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize,
ASM, IndexTypeQuals);
- Canon = getQualifiedType(Canon, canonSplit.second);
+ Canon = getQualifiedType(Canon, canonSplit.Quals);
// Get the new insert position for the node we care about.
ConstantArrayType *NewIP =
@@ -1724,7 +1717,7 @@
QualType result;
SplitQualType split = type.getSplitDesugaredType();
- const Type *ty = split.first;
+ const Type *ty = split.Ty;
switch (ty->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
@@ -1843,7 +1836,7 @@
}
// Apply the top-level qualifiers from the original.
- return getQualifiedType(result, split.second);
+ return getQualifiedType(result, split.Quals);
}
/// getVariableArrayType - Returns a non-unique reference to the type for a
@@ -1860,9 +1853,9 @@
// Be sure to pull qualifiers off the element type.
if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(EltTy).split();
- Canon = getVariableArrayType(QualType(canonSplit.first, 0), NumElts, ASM,
+ Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM,
IndexTypeQuals, Brackets);
- Canon = getQualifiedType(Canon, canonSplit.second);
+ Canon = getQualifiedType(Canon, canonSplit.Quals);
}
VariableArrayType *New = new(*this, TypeAlignment)
@@ -1907,7 +1900,7 @@
void *insertPos = 0;
llvm::FoldingSetNodeID ID;
DependentSizedArrayType::Profile(ID, *this,
- QualType(canonElementType.first, 0),
+ QualType(canonElementType.Ty, 0),
ASM, elementTypeQuals, numElements);
// Look for an existing type with these properties.
@@ -1917,7 +1910,7 @@
// If we don't have one, build one.
if (!canonTy) {
canonTy = new (*this, TypeAlignment)
- DependentSizedArrayType(*this, QualType(canonElementType.first, 0),
+ DependentSizedArrayType(*this, QualType(canonElementType.Ty, 0),
QualType(), numElements, ASM, elementTypeQuals,
brackets);
DependentSizedArrayTypes.InsertNode(canonTy, insertPos);
@@ -1926,11 +1919,11 @@
// Apply qualifiers from the element type to the array.
QualType canon = getQualifiedType(QualType(canonTy,0),
- canonElementType.second);
+ canonElementType.Quals);
// If we didn't need extra canonicalization for the element type,
// then just use that as our result.
- if (QualType(canonElementType.first, 0) == elementType)
+ if (QualType(canonElementType.Ty, 0) == elementType)
return canon;
// Otherwise, we need to build a type which follows the spelling
@@ -1961,9 +1954,9 @@
if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(elementType).split();
- canon = getIncompleteArrayType(QualType(canonSplit.first, 0),
+ canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0),
ASM, elementTypeQuals);
- canon = getQualifiedType(canon, canonSplit.second);
+ canon = getQualifiedType(canon, canonSplit.Quals);
// Get the new insert position for the node we care about.
IncompleteArrayType *existing =
@@ -2139,7 +2132,9 @@
return QualType(FTP, 0);
// Determine whether the type being created is already canonical or not.
- bool isCanonical= EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical();
+ bool isCanonical =
+ EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical() &&
+ !EPI.HasTrailingReturn;
for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
if (!ArgArray[i].isCanonicalAsParam())
isCanonical = false;
@@ -2158,6 +2153,7 @@
CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i]));
FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI;
+ CanonicalEPI.HasTrailingReturn = false;
CanonicalEPI.ExceptionSpecType = EST_None;
CanonicalEPI.NumExceptions = 0;
CanonicalEPI.ExtInfo
@@ -2917,44 +2913,13 @@
return QualType(tot, 0);
}
-/// getDecltypeForExpr - Given an expr, will return the decltype for that
-/// expression, according to the rules in C++0x [dcl.type.simple]p4
-static QualType getDecltypeForExpr(const Expr *e, const ASTContext &Context) {
- if (e->isTypeDependent())
- return Context.DependentTy;
-
- // If e is an id expression or a class member access, decltype(e) is defined
- // as the type of the entity named by e.
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(e)) {
- if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
- return VD->getType();
- }
- if (const MemberExpr *ME = dyn_cast<MemberExpr>(e)) {
- if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
- return FD->getType();
- }
- // If e is a function call or an invocation of an overloaded operator,
- // (parentheses around e are ignored), decltype(e) is defined as the
- // return type of that function.
- if (const CallExpr *CE = dyn_cast<CallExpr>(e->IgnoreParens()))
- return CE->getCallReturnType();
-
- QualType T = e->getType();
-
- // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is
- // defined as T&, otherwise decltype(e) is defined as T.
- if (e->isLValue())
- T = Context.getLValueReferenceType(T);
-
- return T;
-}
/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
/// DecltypeType AST's. The only motivation to unique these nodes would be
/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
/// an issue. This doesn't effect the type checker, since it operates
/// on canonical types (which are always unique).
-QualType ASTContext::getDecltypeType(Expr *e) const {
+QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
DecltypeType *dt;
// C++0x [temp.type]p2:
@@ -2980,8 +2945,8 @@
dt = Canon;
}
} else {
- QualType T = getDecltypeForExpr(e, *this);
- dt = new (*this, TypeAlignment) DecltypeType(e, T, getCanonicalType(T));
+ dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
+ getCanonicalType(UnderlyingType));
}
Types.push_back(dt);
return QualType(dt, 0);
@@ -3141,12 +3106,12 @@
// We then have to strip that sugar back off with
// getUnqualifiedDesugaredType(), which is silly.
const ArrayType *AT =
- dyn_cast<ArrayType>(splitType.first->getUnqualifiedDesugaredType());
+ dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());
// If we don't have an array, just use the results in splitType.
if (!AT) {
- quals = splitType.second;
- return QualType(splitType.first, 0);
+ quals = splitType.Quals;
+ return QualType(splitType.Ty, 0);
}
// Otherwise, recurse on the array's element type.
@@ -3157,13 +3122,13 @@
// can just use the results in splitType.
if (elementType == unqualElementType) {
assert(quals.empty()); // from the recursive call
- quals = splitType.second;
- return QualType(splitType.first, 0);
+ quals = splitType.Quals;
+ return QualType(splitType.Ty, 0);
}
// Otherwise, add in the qualifiers from the outermost type, then
// build the type back up.
- quals.addConsistentQualifiers(splitType.second);
+ quals.addConsistentQualifiers(splitType.Quals);
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
return getConstantArrayType(unqualElementType, CAT->getSize(),
@@ -3465,10 +3430,10 @@
// we must propagate them down into the element type.
SplitQualType split = T.getSplitDesugaredType();
- Qualifiers qs = split.second;
+ Qualifiers qs = split.Quals;
// If we have a simple case, just return now.
- const ArrayType *ATy = dyn_cast<ArrayType>(split.first);
+ const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
if (ATy == 0 || qs.empty())
return ATy;
@@ -3555,11 +3520,11 @@
Qualifiers qs;
while (true) {
SplitQualType split = type.getSplitDesugaredType();
- const ArrayType *array = split.first->getAsArrayTypeUnsafe();
+ const ArrayType *array = split.Ty->getAsArrayTypeUnsafe();
if (!array) break;
type = array->getElementType();
- qs.addConsistentQualifiers(split.second);
+ qs.addConsistentQualifiers(split.Quals);
}
return getQualifiedType(type, qs);
Modified: cfe/branches/tooling/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTImporter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTImporter.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTImporter.cpp Tue Feb 14 03:11:10 2012
@@ -1581,7 +1581,11 @@
if (!ToExpr)
return QualType();
- return Importer.getToContext().getDecltypeType(ToExpr);
+ QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
+ if (UnderlyingType.isNull())
+ return QualType();
+
+ return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
}
QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
Modified: cfe/branches/tooling/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Decl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Decl.cpp (original)
+++ cfe/branches/tooling/lib/AST/Decl.cpp Tue Feb 14 03:11:10 2012
@@ -25,7 +25,6 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Module.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
@@ -3002,17 +3001,3 @@
return SourceRange(getLocation(), getIdentifierLocs().back());
}
-
-const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
- const NamedDecl* ND) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
- DiagnosticsEngine::ak_nameddecl);
- return DB;
-}
-
-const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &PD,
- const NamedDecl* ND) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
- DiagnosticsEngine::ak_nameddecl);
- return PD;
-}
Modified: cfe/branches/tooling/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclBase.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclBase.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclBase.cpp Tue Feb 14 03:11:10 2012
@@ -203,15 +203,24 @@
return;
if (isInSemaDC()) {
- MultipleDC *MDC = new (getASTContext()) MultipleDC();
- MDC->SemanticDC = getDeclContext();
- MDC->LexicalDC = DC;
- DeclCtx = MDC;
+ setDeclContextsImpl(getDeclContext(), DC, getASTContext());
} else {
getMultipleDC()->LexicalDC = DC;
}
}
+void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
+ ASTContext &Ctx) {
+ if (SemaDC == LexicalDC) {
+ DeclCtx = SemaDC;
+ } else {
+ Decl::MultipleDC *MDC = new (Ctx) Decl::MultipleDC();
+ MDC->SemanticDC = SemaDC;
+ MDC->LexicalDC = LexicalDC;
+ DeclCtx = MDC;
+ }
+}
+
bool Decl::isInAnonymousNamespace() const {
const DeclContext *DC = getDeclContext();
do {
@@ -532,10 +541,10 @@
llvm_unreachable("Invalid DeclKind!");
}
-void Decl::setAttrs(const AttrVec &attrs) {
+void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
assert(!HasAttrs && "Decl already contains attrs.");
- AttrVec &AttrBlank = getASTContext().getDeclAttrs(this);
+ AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
assert(AttrBlank.empty() && "HasAttrs was wrong?");
AttrBlank = attrs;
Modified: cfe/branches/tooling/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclCXX.cpp Tue Feb 14 03:11:10 2012
@@ -20,7 +20,6 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
using namespace clang;
@@ -36,7 +35,6 @@
return new (Mem) AccessSpecDecl(EmptyShell());
}
-
CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
: UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
UserDeclaredMoveConstructor(false), UserDeclaredCopyAssignment(false),
@@ -84,6 +82,16 @@
return R;
}
+CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
+ SourceLocation Loc) {
+ CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
+ 0, 0);
+ R->IsBeingDefined = true;
+ R->DefinitionData = new (C) struct LambdaDefinitionData(R);
+ C.getTypeDeclType(R, /*PrevDecl=*/0);
+ return R;
+}
+
CXXRecordDecl *
CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl));
@@ -800,12 +808,8 @@
data().IsStandardLayout = false;
}
- // Record if this field is the first non-literal field or base.
- // As a slight variation on the standard, we regard mutable members as being
- // non-literal, since mutating a constexpr variable would break C++11
- // constant expression semantics.
- if ((!hasNonLiteralTypeFieldsOrBases() && !T->isLiteralType()) ||
- Field->isMutable())
+ // Record if this field is the first non-literal or volatile field or base.
+ if (!T->isLiteralType() || T.isVolatileQualified())
data().HasNonLiteralTypeFieldsOrBases = true;
if (Field->hasInClassInitializer()) {
@@ -974,6 +978,26 @@
return isPOD() && data().HasOnlyCMembers;
}
+void CXXRecordDecl::getCaptureFields(
+ llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
+ FieldDecl *&ThisCapture) const {
+ Captures.clear();
+ ThisCapture = 0;
+
+ LambdaDefinitionData &Lambda = getLambdaData();
+ RecordDecl::field_iterator Field = field_begin();
+ for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
+ C != CEnd; ++C, ++Field) {
+ if (C->capturesThis()) {
+ ThisCapture = *Field;
+ continue;
+ }
+
+ Captures[C->getCapturedVar()] = *Field;
+ }
+}
+
+
static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
QualType T;
if (isa<UsingShadowDecl>(Conv))
Modified: cfe/branches/tooling/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclObjC.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclObjC.cpp Tue Feb 14 03:11:10 2012
@@ -317,7 +317,8 @@
/// lookupMethod - This method returns an instance/class method by looking in
/// the class, its categories, and its super classes (using a linear search).
ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
- bool isInstance) const {
+ bool isInstance,
+ bool noCategoryLookup) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
return 0;
@@ -339,21 +340,22 @@
E = Protocols.end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
-
- // Didn't find one yet - now look through categories.
- ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
- while (CatDecl) {
- if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
- return MethodDecl;
-
- // Didn't find one yet - look through protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- CatDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+ if (!noCategoryLookup) {
+ // Didn't find one yet - now look through categories.
+ ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
+ while (CatDecl) {
+ if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
return MethodDecl;
- CatDecl = CatDecl->getNextClassCategory();
+
+ // Didn't find one yet - look through protocols.
+ const ObjCList<ObjCProtocolDecl> &Protocols =
+ CatDecl->getReferencedProtocols();
+ for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+ E = Protocols.end(); I != E; ++I)
+ if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+ return MethodDecl;
+ CatDecl = CatDecl->getNextClassCategory();
+ }
}
ClassDecl = ClassDecl->getSuperClass();
}
Modified: cfe/branches/tooling/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclPrinter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclPrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclPrinter.cpp Tue Feb 14 03:11:10 2012
@@ -621,16 +621,20 @@
Out << Name;
Expr *Init = D->getInit();
if (!Policy.SuppressInitializers && Init) {
- if (D->hasCXXDirectInitializer())
- Out << "(";
- else {
- CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init);
- if (!CCE || CCE->getConstructor()->isCopyOrMoveConstructor())
- Out << " = ";
- }
- Init->printPretty(Out, Context, 0, Policy, Indentation);
- if (D->hasCXXDirectInitializer())
- Out << ")";
+ bool ImplicitInit = false;
+ if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
+ ImplicitInit = D->getInitStyle() == VarDecl::CallInit &&
+ Construct->getNumArgs() == 0 && !Construct->isListInitialization();
+ if (!ImplicitInit) {
+ if (D->getInitStyle() == VarDecl::CallInit)
+ Out << "(";
+ else if (D->getInitStyle() == VarDecl::CInit) {
+ Out << " = ";
+ }
+ Init->printPretty(Out, Context, 0, Policy, Indentation);
+ if (D->getInitStyle() == VarDecl::CallInit)
+ Out << ")";
+ }
}
prettyPrintAttributes(D);
}
Modified: cfe/branches/tooling/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclarationName.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclarationName.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclarationName.cpp Tue Feb 14 03:11:10 2012
@@ -18,7 +18,6 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/ErrorHandling.h"
@@ -621,17 +620,3 @@
}
llvm_unreachable("Unexpected declaration name kind");
}
-
-const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
- DeclarationName N) {
- DB.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return DB;
-}
-
-const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &PD,
- DeclarationName N) {
- PD.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return PD;
-}
Modified: cfe/branches/tooling/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DumpXML.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DumpXML.cpp (original)
+++ cfe/branches/tooling/lib/AST/DumpXML.cpp Tue Feb 14 03:11:10 2012
@@ -461,7 +461,13 @@
if (D->getStorageClass() != SC_None)
set("storage",
VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
- setFlag("directinit", D->hasCXXDirectInitializer());
+ StringRef initStyle = "";
+ switch (D->getInitStyle()) {
+ case VarDecl::CInit: initStyle = "c"; break;
+ case VarDecl::CallInit: initStyle = "call"; break;
+ case VarDecl::ListInit: initStyle = "list"; break;
+ }
+ set("initstyle", initStyle);
setFlag("nrvo", D->isNRVOVariable());
// TODO: instantiation, etc.
}
Modified: cfe/branches/tooling/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Expr.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Expr.cpp (original)
+++ cfe/branches/tooling/lib/AST/Expr.cpp Tue Feb 14 03:11:10 2012
@@ -3414,11 +3414,10 @@
ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
Expr **exprs, unsigned nexprs,
- SourceLocation rparenloc, QualType T)
- : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
+ SourceLocation rparenloc)
+ : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
false, false, false, false),
NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
- assert(!T.isNull() && "ParenListExpr must have a valid type");
Exprs = new (C) Stmt*[nexprs];
for (unsigned i = 0; i != nexprs; ++i) {
if (exprs[i]->isTypeDependent())
Modified: cfe/branches/tooling/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprCXX.cpp Tue Feb 14 03:11:10 2012
@@ -653,7 +653,7 @@
Type->getType().getNonReferenceType(),
Type->getTypeLoc().getBeginLoc(),
Cons, false, Args, NumArgs,
- HadMultipleCandidates, ZeroInitialization,
+ HadMultipleCandidates, /*FIXME*/false, ZeroInitialization,
CXXConstructExpr::CK_Complete, parenRange),
Type(Type) {
}
@@ -668,13 +668,15 @@
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool HadMultipleCandidates,
+ bool ListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenRange) {
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Elidable, Args, NumArgs,
- HadMultipleCandidates, ZeroInitialization,
- ConstructKind, ParenRange);
+ HadMultipleCandidates, ListInitialization,
+ ZeroInitialization, ConstructKind,
+ ParenRange);
}
CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
@@ -682,6 +684,7 @@
CXXConstructorDecl *D, bool elidable,
Expr **args, unsigned numargs,
bool HadMultipleCandidates,
+ bool ListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenRange)
@@ -691,6 +694,7 @@
T->containsUnexpandedParameterPack()),
Constructor(D), Loc(Loc), ParenRange(ParenRange), NumArgs(numargs),
Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
+ ListInitialization(ListInitialization),
ZeroInitialization(ZeroInitialization),
ConstructKind(ConstructKind), Args(0)
{
@@ -748,36 +752,58 @@
LambdaCaptureDefault CaptureDefault,
ArrayRef<Capture> Captures,
bool ExplicitParams,
+ bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace)
: Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
T->isDependentType(), T->isDependentType(), T->isDependentType(),
/*ContainsUnexpandedParameterPack=*/false),
IntroducerRange(IntroducerRange),
NumCaptures(Captures.size()),
- NumExplicitCaptures(0),
CaptureDefault(CaptureDefault),
ExplicitParams(ExplicitParams),
+ ExplicitResultType(ExplicitResultType),
ClosingBrace(ClosingBrace)
{
assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
-
+ CXXRecordDecl *Class = getLambdaClass();
+ CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
+
+ // FIXME: Propagate "has unexpanded parameter pack" bit.
+
// Copy captures.
- // FIXME: Do we need to update "contains unexpanded parameter pack" here?
- Capture *ToCapture = reinterpret_cast<Capture *>(this + 1);
+ ASTContext &Context = Class->getASTContext();
+ Data.NumCaptures = NumCaptures;
+ Data.NumExplicitCaptures = 0;
+ Data.Captures = (Capture *)Context.Allocate(sizeof(Capture) * NumCaptures);
+ Capture *ToCapture = Data.Captures;
for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
if (Captures[I].isExplicit())
- ++NumExplicitCaptures;
+ ++Data.NumExplicitCaptures;
+
*ToCapture++ = Captures[I];
}
-
+
// Copy initialization expressions for the non-static data members.
Stmt **Stored = getStoredStmts();
for (unsigned I = 0, N = CaptureInits.size(); I != N; ++I)
*Stored++ = CaptureInits[I];
-
+
// Copy the body of the lambda.
*Stored++ = getCallOperator()->getBody();
+
+ // Copy the array index variables, if any.
+ HasArrayIndexVars = !ArrayIndexVars.empty();
+ if (HasArrayIndexVars) {
+ assert(ArrayIndexStarts.size() == NumCaptures);
+ memcpy(getArrayIndexVars(), ArrayIndexVars.data(),
+ sizeof(VarDecl *) * ArrayIndexVars.size());
+ memcpy(getArrayIndexStarts(), ArrayIndexStarts.data(),
+ sizeof(unsigned) * Captures.size());
+ getArrayIndexStarts()[Captures.size()] = ArrayIndexVars.size();
+ }
}
LambdaExpr *LambdaExpr::Create(ASTContext &Context,
@@ -786,20 +812,65 @@
LambdaCaptureDefault CaptureDefault,
ArrayRef<Capture> Captures,
bool ExplicitParams,
+ bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace) {
// Determine the type of the expression (i.e., the type of the
// function object we're creating).
QualType T = Context.getTypeDeclType(Class);
- size_t Size = sizeof(LambdaExpr) + sizeof(Capture) * Captures.size()
- + sizeof(Stmt *) * (Captures.size() + 1);
- void *Mem = Context.Allocate(Size, llvm::alignOf<LambdaExpr>());
+ unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (Captures.size() + 1);
+ if (!ArrayIndexVars.empty())
+ Size += sizeof(VarDecl *) * ArrayIndexVars.size()
+ + sizeof(unsigned) * (Captures.size() + 1);
+ void *Mem = Context.Allocate(Size);
return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault,
- Captures, ExplicitParams, CaptureInits,
+ Captures, ExplicitParams, ExplicitResultType,
+ CaptureInits, ArrayIndexVars, ArrayIndexStarts,
ClosingBrace);
}
+LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
+ return getLambdaClass()->getLambdaData().Captures;
+}
+
+LambdaExpr::capture_iterator LambdaExpr::capture_end() const {
+ return capture_begin() + NumCaptures;
+}
+
+LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
+ return capture_begin();
+}
+
+LambdaExpr::capture_iterator LambdaExpr::explicit_capture_end() const {
+ struct CXXRecordDecl::LambdaDefinitionData &Data
+ = getLambdaClass()->getLambdaData();
+ return Data.Captures + Data.NumExplicitCaptures;
+}
+
+LambdaExpr::capture_iterator LambdaExpr::implicit_capture_begin() const {
+ return explicit_capture_end();
+}
+
+LambdaExpr::capture_iterator LambdaExpr::implicit_capture_end() const {
+ return capture_end();
+}
+
+ArrayRef<VarDecl *>
+LambdaExpr::getCaptureInitIndexVars(capture_init_iterator Iter) const {
+ assert(HasArrayIndexVars && "No array index-var data?");
+
+ unsigned Index = Iter - capture_init_begin();
+ assert(Index < getLambdaClass()->getLambdaData().NumCaptures &&
+ "Capture index out-of-range");
+ VarDecl **IndexVars = getArrayIndexVars();
+ unsigned *IndexStarts = getArrayIndexStarts();
+ return ArrayRef<VarDecl *>(IndexVars + IndexStarts[Index],
+ IndexVars + IndexStarts[Index + 1]);
+}
+
CXXRecordDecl *LambdaExpr::getLambdaClass() const {
return getType()->getAsCXXRecordDecl();
}
Modified: cfe/branches/tooling/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprConstant.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprConstant.cpp Tue Feb 14 03:11:10 2012
@@ -42,7 +42,6 @@
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/Builtins.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallString.h"
#include <cstring>
@@ -856,7 +855,8 @@
static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
const LValue &This, const Expr *E,
CheckConstantExpressionKind CCEK
- = CCEK_Constant);
+ = 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,
@@ -1454,6 +1454,13 @@
O = &O->getArrayFiller();
ObjType = CAT->getElementType();
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
+ if (Field->isMutable()) {
+ Info.Diag(E->getExprLoc(), diag::note_constexpr_ltor_mutable, 1)
+ << Field;
+ Info.Note(Field->getLocation(), diag::note_declared_at);
+ return false;
+ }
+
// Next subobject is a class, struct or union field.
RecordDecl *RD = ObjType->castAs<RecordType>()->getDecl();
if (RD->isUnion()) {
@@ -2027,6 +2034,12 @@
if (!Info.CheckCallLimit(CallLoc))
return false;
+ const CXXRecordDecl *RD = Definition->getParent();
+ if (RD->getNumVBases()) {
+ Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD;
+ return false;
+ }
+
CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data());
// If it's a delegating constructor, just delegate.
@@ -2038,7 +2051,6 @@
// For a trivial copy or move constructor, perform an APValue copy. This is
// essential for unions, where the operations performed by the constructor
// cannot be represented by ctor-initializers.
- const CXXRecordDecl *RD = Definition->getParent();
if (Definition->isDefaulted() &&
((Definition->isCopyConstructor() && RD->hasTrivialCopyConstructor()) ||
(Definition->isMoveConstructor() && RD->hasTrivialMoveConstructor()))) {
@@ -2077,7 +2089,7 @@
QualType BaseType((*I)->getBaseClass(), 0);
#ifndef NDEBUG
// Non-virtual base classes are initialized in the order in the class
- // definition. We cannot have a virtual base class for a literal type.
+ // definition. We have already checked for virtual base classes.
assert(!BaseIt->isVirtual() && "virtual base for literal type");
assert(Info.Ctx.hasSameType(BaseIt->getType(), BaseType) &&
"base class initializers not in expected order");
@@ -2408,6 +2420,7 @@
const FunctionDecl *FD = 0;
LValue *This = 0, ThisVal;
llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
+ bool HasQualifier = false;
// Extract function decl and 'this' pointer from the callee.
if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
@@ -2418,6 +2431,7 @@
return false;
Member = ME->getMemberDecl();
This = &ThisVal;
+ HasQualifier = ME->hasQualifier();
} else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
// Indirect bound member calls ('.*' or '->*').
Member = HandleMemberPointerAccess(Info, BE, ThisVal, false);
@@ -2466,6 +2480,12 @@
if (This && !This->checkSubobject(Info, E, CSK_This))
return false;
+ // DR1358 allows virtual constexpr functions in some cases. Don't allow
+ // calls to such functions in constant expressions.
+ if (This && !HasQualifier &&
+ isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
+ return Error(E, diag::note_constexpr_virtual_call);
+
const FunctionDecl *Definition = 0;
Stmt *Body = FD->getBody(Definition);
APValue Result;
@@ -4705,12 +4725,11 @@
<< RHS << E->getType() << LHS.getBitWidth();
} else if (LHS.isSigned()) {
// C++11 [expr.shift]p2: A signed left shift must have a non-negative
- // operand, and must not overflow.
+ // operand, and must not overflow the corresponding unsigned type.
if (LHS.isNegative())
CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
- else if (LHS.countLeadingZeros() <= SA)
- HandleOverflow(Info, E, LHS.extend(LHS.getBitWidth() + SA) << SA,
- E->getType());
+ else if (LHS.countLeadingZeros() < SA)
+ CCEDiag(E, diag::note_constexpr_lshift_discards);
}
return Success(LHS << SA, E);
@@ -5811,8 +5830,9 @@
/// which were initialized earlier.
static bool EvaluateConstantExpression(APValue &Result, EvalInfo &Info,
const LValue &This, const Expr *E,
- CheckConstantExpressionKind CCEK) {
- if (!CheckLiteralType(Info, E))
+ CheckConstantExpressionKind CCEK,
+ bool AllowNonLiteralTypes) {
+ if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E))
return false;
if (E->isRValue()) {
@@ -5923,9 +5943,6 @@
EvalInfo InitInfo(Ctx, EStatus);
InitInfo.setEvaluatingDecl(VD, Value);
- if (!CheckLiteralType(InitInfo, this))
- return false;
-
LValue LVal;
LVal.set(VD);
@@ -5936,11 +5953,13 @@
if (Ctx.getLangOptions().CPlusPlus && !VD->hasLocalStorage() &&
!VD->getType()->isReferenceType()) {
ImplicitValueInitExpr VIE(VD->getType());
- if (!EvaluateConstantExpression(Value, InitInfo, LVal, &VIE))
+ if (!EvaluateConstantExpression(Value, InitInfo, LVal, &VIE, CCEK_Constant,
+ /*AllowNonLiteralTypes=*/true))
return false;
}
- return EvaluateConstantExpression(Value, InitInfo, LVal, this) &&
+ return EvaluateConstantExpression(Value, InitInfo, LVal, this, CCEK_Constant,
+ /*AllowNonLiteralTypes=*/true) &&
!EStatus.HasSideEffects;
}
Modified: cfe/branches/tooling/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ItaniumMangle.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/branches/tooling/lib/AST/ItaniumMangle.cpp Tue Feb 14 03:11:10 2012
@@ -24,7 +24,6 @@
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/ABI.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringExtras.h"
@@ -1656,8 +1655,8 @@
} while (true);
}
SplitQualType split = T.split();
- Qualifiers quals = split.second;
- const Type *ty = split.first;
+ Qualifiers quals = split.Quals;
+ const Type *ty = split.Ty;
bool isSubstitutable = quals || !isa<BuiltinType>(T);
if (isSubstitutable && mangleSubstitution(T))
Modified: cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp Tue Feb 14 03:11:10 2012
@@ -18,7 +18,6 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/Diagnostic.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -640,9 +639,3 @@
return NestedNameSpecifierLoc(Representation, Mem);
}
-const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
- NestedNameSpecifier *NNS) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
- DiagnosticsEngine::ak_nestednamespec);
- return DB;
-}
Modified: cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp Tue Feb 14 03:11:10 2012
@@ -2187,6 +2187,10 @@
// as soon as we begin to parse the definition. That definition is
// not a complete definition (which is what isDefinition() tests)
// until we *finish* parsing the definition.
+
+ if (D->hasExternalLexicalStorage() && !D->getDefinition())
+ getExternalSource()->CompleteType(const_cast<RecordDecl*>(D));
+
D = D->getDefinition();
assert(D && "Cannot get layout of forward declarations!");
assert(D->isCompleteDefinition() && "Cannot layout type before complete!");
Modified: cfe/branches/tooling/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtPrinter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtPrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtPrinter.cpp Tue Feb 14 03:11:10 2012
@@ -1344,9 +1344,9 @@
// FIXME: Attributes
- // FIXME: Suppress trailing return type if it wasn't specified in
- // the source.
- OS << " -> " << Proto->getResultType().getAsString(Policy);
+ // Print the trailing return type if it was specified in the source.
+ if (Node->hasExplicitResultType())
+ OS << " -> " << Proto->getResultType().getAsString(Policy);
}
// Print the body.
Modified: cfe/branches/tooling/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Type.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Type.cpp (original)
+++ cfe/branches/tooling/lib/AST/Type.cpp Tue Feb 14 03:11:10 2012
@@ -20,7 +20,6 @@
#include "clang/AST/Expr.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TypeVisitor.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/StringExtras.h"
@@ -198,27 +197,28 @@
/// concrete.
QualType QualType::getDesugaredType(QualType T, const ASTContext &Context) {
SplitQualType split = getSplitDesugaredType(T);
- return Context.getQualifiedType(split.first, split.second);
+ return Context.getQualifiedType(split.Ty, split.Quals);
}
-QualType QualType::getSingleStepDesugaredType(const ASTContext &Context) const {
- QualifierCollector Qs;
-
- const Type *CurTy = Qs.strip(*this);
- switch (CurTy->getTypeClass()) {
+QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
+ const ASTContext &Context) {
+ SplitQualType split = type.split();
+ QualType desugar = split.Ty->getLocallyUnqualifiedSingleStepDesugaredType();
+ return Context.getQualifiedType(desugar, split.Quals);
+}
+
+QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const {
+ switch (getTypeClass()) {
#define ABSTRACT_TYPE(Class, Parent)
#define TYPE(Class, Parent) \
case Type::Class: { \
- const Class##Type *Ty = cast<Class##Type>(CurTy); \
- if (!Ty->isSugared()) \
- return *this; \
- return Context.getQualifiedType(Ty->desugar(), Qs); \
- break; \
+ const Class##Type *ty = cast<Class##Type>(this); \
+ if (!ty->isSugared()) return QualType(ty, 0); \
+ return ty->desugar(); \
}
#include "clang/AST/TypeNodes.def"
}
-
- return *this;
+ llvm_unreachable("bad type kind!");
}
SplitQualType QualType::getSplitDesugaredType(QualType T) {
@@ -246,21 +246,21 @@
SplitQualType split = type.split();
// All the qualifiers we've seen so far.
- Qualifiers quals = split.second;
+ Qualifiers quals = split.Quals;
// The last type node we saw with any nodes inside it.
- const Type *lastTypeWithQuals = split.first;
+ const Type *lastTypeWithQuals = split.Ty;
while (true) {
QualType next;
// Do a single-step desugar, aborting the loop if the type isn't
// sugared.
- switch (split.first->getTypeClass()) {
+ switch (split.Ty->getTypeClass()) {
#define ABSTRACT_TYPE(Class, Parent)
#define TYPE(Class, Parent) \
case Type::Class: { \
- const Class##Type *ty = cast<Class##Type>(split.first); \
+ const Class##Type *ty = cast<Class##Type>(split.Ty); \
if (!ty->isSugared()) goto done; \
next = ty->desugar(); \
break; \
@@ -271,9 +271,9 @@
// Otherwise, split the underlying type. If that yields qualifiers,
// update the information.
split = next.split();
- if (!split.second.empty()) {
- lastTypeWithQuals = split.first;
- quals.addConsistentQualifiers(split.second);
+ if (!split.Quals.empty()) {
+ lastTypeWithQuals = split.Ty;
+ quals.addConsistentQualifiers(split.Quals);
}
}
@@ -1557,8 +1557,8 @@
FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
unsigned numArgs, QualType canonical,
const ExtProtoInfo &epi)
- : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals,
- epi.RefQualifier, canonical,
+ : FunctionType(FunctionProto, result, epi.TypeQuals, epi.RefQualifier,
+ canonical,
result->isDependentType(),
result->isInstantiationDependentType(),
result->isVariablyModifiedType(),
@@ -1566,7 +1566,8 @@
epi.ExtInfo),
NumArgs(numArgs), NumExceptions(epi.NumExceptions),
ExceptionSpecType(epi.ExceptionSpecType),
- HasAnyConsumedArgs(epi.ConsumedArguments != 0)
+ HasAnyConsumedArgs(epi.ConsumedArguments != 0),
+ Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn)
{
// Fill in the trailing argument array.
QualType *argSlot = reinterpret_cast<QualType*>(this+1);
@@ -1664,8 +1665,8 @@
// This is followed by an optional "consumed argument" section of the
// same length as the first type sequence:
// bool*
- // Finally, we have the ext info:
- // int
+ // Finally, we have the ext info and trailing return type flag:
+ // int bool
//
// There is no ambiguity between the consumed arguments and an empty EH
// spec because of the leading 'bool' which unambiguously indicates
@@ -1697,6 +1698,7 @@
ID.AddBoolean(epi.ConsumedArguments[i]);
}
epi.ExtInfo.Profile(ID);
+ ID.AddBoolean(epi.HasTrailingReturn);
}
void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
@@ -2310,23 +2312,3 @@
return true;
}
-
-const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
- QualType T) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- DiagnosticsEngine::ak_qualtype);
- return DB;
-}
-
-const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &PD,
- QualType T) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- DiagnosticsEngine::ak_qualtype);
- return PD;
-}
-
-const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
- CanQualType T) {
- DB << static_cast<QualType>(T);
- return DB;
-}
Modified: cfe/branches/tooling/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/TypePrinter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/TypePrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/TypePrinter.cpp Tue Feb 14 03:11:10 2012
@@ -75,7 +75,7 @@
void TypePrinter::print(QualType t, std::string &buffer) {
SplitQualType split = t.split();
- print(split.first, split.second, buffer);
+ print(split.Ty, split.Quals, buffer);
}
void TypePrinter::print(const Type *T, Qualifiers Quals, std::string &buffer) {
@@ -500,7 +500,12 @@
break;
}
T->printExceptionSpecification(S, Policy);
- print(T->getResultType(), S);
+ if (T->hasTrailingReturn()) {
+ std::string ResultS;
+ print(T->getResultType(), ResultS);
+ S = "auto " + S + " -> " + ResultS;
+ } else
+ print(T->getResultType(), S);
}
void TypePrinter::printFunctionNoProto(const FunctionNoProtoType *T,
Modified: cfe/branches/tooling/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Diagnostic.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Diagnostic.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Diagnostic.cpp Tue Feb 14 03:11:10 2012
@@ -119,7 +119,7 @@
}
void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
- StringRef Arg2) {
+ StringRef Arg2) {
if (DelayedDiagID)
return;
@@ -162,7 +162,7 @@
/// \param The source location that this change of diagnostic state should
/// take affect. It can be null if we are setting the latest state.
void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
- SourceLocation L) {
+ SourceLocation L) {
assert(Diag < diag::DIAG_UPPER_LIMIT &&
"Can only map builtin diagnostics");
assert((Diags->isBuiltinWarningOrExtension(Diag) ||
@@ -243,6 +243,24 @@
return false;
}
+void DiagnosticsEngine::setDiagnosticWarningAsError(diag::kind Diag,
+ bool Enabled) {
+ // If we are enabling this feature, just set the diagnostic mappings to map to
+ // errors.
+ if (Enabled)
+ setDiagnosticMapping(Diag, diag::MAP_ERROR, SourceLocation());
+
+ // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
+ // potentially downgrade anything already mapped to be a warning.
+ DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
+
+ if (Info.getMapping() == diag::MAP_ERROR ||
+ Info.getMapping() == diag::MAP_FATAL)
+ Info.setMapping(diag::MAP_WARNING);
+
+ Info.setNoWarningAsError(true);
+}
+
bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
bool Enabled) {
// If we are enabling this feature, just set the diagnostic mappings to map to
@@ -273,6 +291,23 @@
return false;
}
+void DiagnosticsEngine::setDiagnosticErrorAsFatal(diag::kind Diag,
+ bool Enabled) {
+ // If we are enabling this feature, just set the diagnostic mappings to map to
+ // errors.
+ if (Enabled)
+ setDiagnosticMapping(Diag, diag::MAP_FATAL, SourceLocation());
+
+ // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
+ // potentially downgrade anything already mapped to be a warning.
+ DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
+
+ if (Info.getMapping() == diag::MAP_FATAL)
+ Info.setMapping(diag::MAP_ERROR);
+
+ Info.setNoErrorAsFatal(true);
+}
+
bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
bool Enabled) {
// If we are enabling this feature, just set the diagnostic mappings to map to
@@ -842,14 +877,16 @@
void IgnoringDiagConsumer::anchor() { }
-PartialDiagnosticStorageAllocator::PartialDiagnosticStorageAllocator() {
+PartialDiagnostic::StorageAllocator::StorageAllocator() {
for (unsigned I = 0; I != NumCached; ++I)
FreeList[I] = Cached + I;
NumFreeListEntries = NumCached;
}
-PartialDiagnosticStorageAllocator::~PartialDiagnosticStorageAllocator() {
- // Don't assert if we are in a CrashRecovery context, as this
- // invariant may be invalidated during a crash.
- assert((NumFreeListEntries == NumCached || llvm::CrashRecoveryContext::isRecoveringFromCrash()) && "A partial is on the lamb");
+PartialDiagnostic::StorageAllocator::~StorageAllocator() {
+ // Don't assert if we are in a CrashRecovery context, as this invariant may
+ // be invalidated during a crash.
+ assert((NumFreeListEntries == NumCached ||
+ llvm::CrashRecoveryContext::isRecoveringFromCrash()) &&
+ "A partial is on the lamb");
}
Modified: cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp (original)
+++ cfe/branches/tooling/lib/Basic/DiagnosticIDs.cpp Tue Feb 14 03:11:10 2012
@@ -56,15 +56,11 @@
uint8_t OptionGroupLen;
uint16_t DescriptionLen;
- uint16_t BriefExplanationLen;
- uint16_t FullExplanationLen;
const char *NameStr;
const char *OptionGroupStr;
const char *DescriptionStr;
- const char *BriefExplanationStr;
- const char *FullExplanationStr;
StringRef getName() const {
return StringRef(NameStr, NameLen);
@@ -76,12 +72,6 @@
StringRef getDescription() const {
return StringRef(DescriptionStr, DescriptionLen);
}
- StringRef getBriefExplanation() const {
- return StringRef(BriefExplanationStr, BriefExplanationLen);
- }
- StringRef getFullExplanation() const {
- return StringRef(FullExplanationStr, FullExplanationLen);
- }
bool operator<(const StaticDiagInfoRec &RHS) const {
return DiagID < RHS.DiagID;
@@ -120,13 +110,12 @@
static const StaticDiagInfoRec StaticDiagInfo[] = {
#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER, \
- CATEGORY,BRIEF,FULL) \
+ 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), STR_SIZE(BRIEF, uint16_t), \
- STR_SIZE(FULL, uint16_t), \
- #ENUM, GROUP, DESC, BRIEF, FULL },
+ STR_SIZE(DESC, uint16_t), \
+ #ENUM, GROUP, DESC },
#include "clang/Basic/DiagnosticCommonKinds.inc"
#include "clang/Basic/DiagnosticDriverKinds.inc"
#include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -137,7 +126,7 @@
#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, 0, 0, 0, 0, 0, 0, 0}
};
static const unsigned StaticDiagInfoSize =
@@ -175,7 +164,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, 0, 0, 0, 0, 0, 0, 0};
const StaticDiagInfoRec *Found =
std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
@@ -325,22 +314,6 @@
return Found->DiagID;
}
-/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
-/// of the issue
-StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
- if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->getBriefExplanation();
- return StringRef();
-}
-
-/// getFullExplanation - Given a diagnostic ID, return a full explanation
-/// of the issue
-StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) {
- if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->getFullExplanation();
- return StringRef();
-}
-
/// getBuiltinDiagClass - Return the class field of the diagnostic.
///
static unsigned getBuiltinDiagClass(unsigned DiagID) {
Modified: cfe/branches/tooling/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Targets.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Targets.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Targets.cpp Tue Feb 14 03:11:10 2012
@@ -222,7 +222,18 @@
}
public:
DragonFlyBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {}
+ : OSTargetInfo<Target>(triple) {
+ this->UserLabelPrefix = "";
+
+ llvm::Triple Triple(triple);
+ switch (Triple.getArch()) {
+ default:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->MCountName = ".mcount";
+ break;
+ }
+ }
};
// FreeBSD Target
Modified: cfe/branches/tooling/lib/CodeGen/BackendUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/BackendUtil.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/BackendUtil.cpp Tue Feb 14 03:11:10 2012
@@ -246,8 +246,7 @@
CM = llvm::CodeModel::Default;
}
- std::vector<const char *> BackendArgs;
- BackendArgs.reserve(16);
+ SmallVector<const char *, 16> BackendArgs;
BackendArgs.push_back("clang"); // Fake program name.
if (!CodeGenOpts.DebugPass.empty()) {
BackendArgs.push_back("-debug-pass");
@@ -265,7 +264,7 @@
BackendArgs.push_back("-global-merge=false");
BackendArgs.push_back(0);
llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
- const_cast<char **>(&BackendArgs[0]));
+ BackendArgs.data());
std::string FeaturesStr;
if (TargetOpts.Features.size()) {
Modified: cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCXXABI.cpp Tue Feb 14 03:11:10 2012
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "CGCXXABI.h"
-#include "clang/Basic/Diagnostic.h"
using namespace clang;
using namespace CodeGen;
@@ -169,6 +168,7 @@
void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
- llvm::GlobalVariable *GV) {
+ llvm::GlobalVariable *GV,
+ bool PerformInit) {
ErrorUnsupportedABI(CGF, "static local variable initialization");
}
Modified: cfe/branches/tooling/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCXXABI.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCXXABI.h Tue Feb 14 03:11:10 2012
@@ -49,10 +49,10 @@
protected:
ImplicitParamDecl *&getThisDecl(CodeGenFunction &CGF) {
- return CGF.CXXThisDecl;
+ return CGF.CXXABIThisDecl;
}
llvm::Value *&getThisValue(CodeGenFunction &CGF) {
- return CGF.CXXThisValue;
+ return CGF.CXXABIThisValue;
}
ImplicitParamDecl *&getVTTDecl(CodeGenFunction &CGF) {
@@ -226,12 +226,14 @@
/// Emits the guarded initializer and destructor setup for the given
/// variable, given that it couldn't be emitted as a constant.
+ /// If \p PerformInit is false, the initialization has been folded to a
+ /// constant and should not be performed.
///
/// The variable may be:
/// - a static local variable
/// - a static data member of a class template instantiation
virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
- llvm::GlobalVariable *DeclPtr);
+ llvm::GlobalVariable *DeclPtr, bool PerformInit);
};
Modified: cfe/branches/tooling/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCall.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCall.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCall.cpp Tue Feb 14 03:11:10 2012
@@ -1013,7 +1013,7 @@
break;
}
- llvm::AllocaInst *Alloca = CreateMemTemp(Ty, "coerce");
+ llvm::AllocaInst *Alloca = CreateMemTemp(Ty, Arg->getName());
// The alignment we need to use is the max of the requested alignment for
// the argument plus the alignment required by our access code below.
@@ -1037,15 +1037,36 @@
// If the coerce-to type is a first class aggregate, we flatten it and
// pass the elements. Either way is semantically identical, but fast-isel
// and the optimizer generally likes scalar values better than FCAs.
- if (llvm::StructType *STy =
- dyn_cast<llvm::StructType>(ArgI.getCoerceToType())) {
- Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy));
+ llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
+ if (STy && STy->getNumElements() > 1) {
+ uint64_t SrcSize = CGM.getTargetData().getTypeAllocSize(STy);
+ llvm::Type *DstTy =
+ cast<llvm::PointerType>(Ptr->getType())->getElementType();
+ uint64_t DstSize = CGM.getTargetData().getTypeAllocSize(DstTy);
+
+ if (SrcSize <= DstSize) {
+ Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy));
+
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+ assert(AI != Fn->arg_end() && "Argument mismatch!");
+ AI->setName(Arg->getName() + ".coerce" + Twine(i));
+ llvm::Value *EltPtr = Builder.CreateConstGEP2_32(Ptr, 0, i);
+ Builder.CreateStore(AI++, EltPtr);
+ }
+ } else {
+ llvm::AllocaInst *TempAlloca =
+ CreateTempAlloca(ArgI.getCoerceToType(), "coerce");
+ TempAlloca->setAlignment(AlignmentToUse);
+ llvm::Value *TempV = TempAlloca;
+
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+ assert(AI != Fn->arg_end() && "Argument mismatch!");
+ AI->setName(Arg->getName() + ".coerce" + Twine(i));
+ llvm::Value *EltPtr = Builder.CreateConstGEP2_32(TempV, 0, i);
+ Builder.CreateStore(AI++, EltPtr);
+ }
- for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- assert(AI != Fn->arg_end() && "Argument mismatch!");
- AI->setName(Arg->getName() + ".coerce" + Twine(i));
- llvm::Value *EltPtr = Builder.CreateConstGEP2_32(Ptr, 0, i);
- Builder.CreateStore(AI++, EltPtr);
+ Builder.CreateMemCpy(Ptr, TempV, DstSize, AlignmentToUse);
}
} else {
// Simple case, just do a coerced store of the argument into the alloca.
Modified: cfe/branches/tooling/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGClass.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGClass.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGClass.cpp Tue Feb 14 03:11:10 2012
@@ -412,11 +412,12 @@
static void EmitAggMemberInitializer(CodeGenFunction &CGF,
LValue LHS,
+ Expr *Init,
llvm::Value *ArrayIndexVar,
- CXXCtorInitializer *MemberInit,
QualType T,
+ ArrayRef<VarDecl *> ArrayIndexes,
unsigned Index) {
- if (Index == MemberInit->getNumArrayIndices()) {
+ if (Index == ArrayIndexes.size()) {
CodeGenFunction::RunCleanupsScope Cleanups(CGF);
LValue LV = LHS;
@@ -437,9 +438,9 @@
}
if (!CGF.hasAggregateLLVMType(T)) {
- CGF.EmitScalarInit(MemberInit->getInit(), /*decl*/ 0, LV, false);
+ CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
} else if (T->isAnyComplexType()) {
- CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LV.getAddress(),
+ CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(),
LV.isVolatileQualified());
} else {
AggValueSlot Slot =
@@ -448,7 +449,7 @@
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased);
- CGF.EmitAggExpr(MemberInit->getInit(), Slot);
+ CGF.EmitAggExpr(Init, Slot);
}
return;
@@ -457,7 +458,7 @@
const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
assert(Array && "Array initialization without the array type?");
llvm::Value *IndexVar
- = CGF.GetAddrOfLocalVar(MemberInit->getArrayIndex(Index));
+ = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]);
assert(IndexVar && "Array index variable not loaded");
// Initialize this index variable to zero.
@@ -493,8 +494,8 @@
// Inside the loop body recurse to emit the inner loop or, eventually, the
// constructor call.
- EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit,
- Array->getElementType(), Index + 1);
+ EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
+ Array->getElementType(), ArrayIndexes, Index + 1);
}
CGF.EmitBlock(ContinueBlock);
@@ -514,19 +515,15 @@
namespace {
struct CallMemberDtor : EHScopeStack::Cleanup {
- FieldDecl *Field;
+ llvm::Value *V;
CXXDestructorDecl *Dtor;
- CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor)
- : Field(Field), Dtor(Dtor) {}
+ CallMemberDtor(llvm::Value *V, CXXDestructorDecl *Dtor)
+ : V(V), Dtor(Dtor) {}
void Emit(CodeGenFunction &CGF, Flags flags) {
- // FIXME: Is this OK for C++0x delegating constructors?
- llvm::Value *ThisPtr = CGF.LoadCXXThis();
- LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
-
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
- LHS.getAddress());
+ V);
}
};
}
@@ -536,7 +533,7 @@
return Moving ? Record->hasTrivialMoveConstructor() :
Record->hasTrivialCopyConstructor();
}
-
+
static void EmitMemberInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
CXXCtorInitializer *MemberInit,
@@ -548,7 +545,7 @@
// non-static data member initializers.
FieldDecl *Field = MemberInit->getAnyMember();
- QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
+ QualType FieldType = Field->getType();
llvm::Value *ThisPtr = CGF.LoadCXXThis();
LValue LHS;
@@ -562,67 +559,83 @@
LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
}
- if (!CGF.hasAggregateLLVMType(Field->getType())) {
+ // Special case: if we are in a copy or move constructor, and we are copying
+ // an array of PODs or classes with trivial copy constructors, ignore the
+ // AST and perform the copy we know is equivalent.
+ // FIXME: This is hacky at best... if we had a bit more explicit information
+ // in the AST, we could generalize it more easily.
+ const ConstantArrayType *Array
+ = CGF.getContext().getAsConstantArrayType(FieldType);
+ if (Array && Constructor->isImplicitlyDefined() &&
+ Constructor->isCopyOrMoveConstructor()) {
+ QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
+ const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl();
+ if (BaseElementTy.isPODType(CGF.getContext()) ||
+ (Record && hasTrivialCopyOrMoveConstructor(Record,
+ Constructor->isMoveConstructor()))) {
+ // Find the source pointer. We knows it's the last argument because
+ // we know we're in a copy constructor.
+ unsigned SrcArgIndex = Args.size() - 1;
+ llvm::Value *SrcPtr
+ = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
+ LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
+
+ // Copy the aggregate.
+ CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
+ LHS.isVolatileQualified());
+ return;
+ }
+ }
+
+ ArrayRef<VarDecl *> ArrayIndexes;
+ if (MemberInit->getNumArrayIndices())
+ ArrayIndexes = MemberInit->getArrayIndexes();
+ CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes);
+}
+
+void CodeGenFunction::EmitInitializerForField(FieldDecl *Field,
+ LValue LHS, Expr *Init,
+ ArrayRef<VarDecl *> ArrayIndexes) {
+ QualType FieldType = Field->getType();
+ if (!hasAggregateLLVMType(FieldType)) {
if (LHS.isSimple()) {
- CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS, false);
+ EmitExprAsInit(Init, Field, LHS, false);
} else {
- RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit()));
- CGF.EmitStoreThroughLValue(RHS, LHS);
+ RValue RHS = RValue::get(EmitScalarExpr(Init));
+ EmitStoreThroughLValue(RHS, LHS);
}
- } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
- CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
- LHS.isVolatileQualified());
+ } else if (FieldType->isAnyComplexType()) {
+ EmitComplexExprIntoAddr(Init, LHS.getAddress(), LHS.isVolatileQualified());
} else {
llvm::Value *ArrayIndexVar = 0;
- const ConstantArrayType *Array
- = CGF.getContext().getAsConstantArrayType(FieldType);
- if (Array && Constructor->isImplicitlyDefined() &&
- Constructor->isCopyOrMoveConstructor()) {
- llvm::Type *SizeTy
- = CGF.ConvertType(CGF.getContext().getSizeType());
+ if (ArrayIndexes.size()) {
+ llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
// The LHS is a pointer to the first object we'll be constructing, as
// a flat array.
- QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
- llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy);
+ QualType BaseElementTy = getContext().getBaseElementType(FieldType);
+ llvm::Type *BasePtr = ConvertType(BaseElementTy);
BasePtr = llvm::PointerType::getUnqual(BasePtr);
- llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(LHS.getAddress(),
- BasePtr);
- LHS = CGF.MakeAddrLValue(BaseAddrPtr, BaseElementTy);
+ llvm::Value *BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(),
+ BasePtr);
+ LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy);
// Create an array index that will be used to walk over all of the
// objects we're constructing.
- ArrayIndexVar = CGF.CreateTempAlloca(SizeTy, "object.index");
+ ArrayIndexVar = CreateTempAlloca(SizeTy, "object.index");
llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
- CGF.Builder.CreateStore(Zero, ArrayIndexVar);
+ Builder.CreateStore(Zero, ArrayIndexVar);
- // If we are copying an array of PODs or classes with trivial copy
- // constructors, perform a single aggregate copy.
- const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl();
- if (BaseElementTy.isPODType(CGF.getContext()) ||
- (Record && hasTrivialCopyOrMoveConstructor(Record,
- Constructor->isMoveConstructor()))) {
- // Find the source pointer. We knows it's the last argument because
- // we know we're in a copy constructor.
- unsigned SrcArgIndex = Args.size() - 1;
- llvm::Value *SrcPtr
- = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
- LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
-
- // Copy the aggregate.
- CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
- LHS.isVolatileQualified());
- return;
- }
// Emit the block variables for the array indices, if any.
- for (unsigned I = 0, N = MemberInit->getNumArrayIndices(); I != N; ++I)
- CGF.EmitAutoVarDecl(*MemberInit->getArrayIndex(I));
+ for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I)
+ EmitAutoVarDecl(*ArrayIndexes[I]);
}
- EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, FieldType, 0);
+ EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType,
+ ArrayIndexes, 0);
- if (!CGF.CGM.getLangOptions().Exceptions)
+ if (!CGM.getLangOptions().Exceptions)
return;
// FIXME: If we have an array of classes w/ non-trivial destructors,
@@ -634,8 +647,8 @@
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
if (!RD->hasTrivialDestructor())
- CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, Field,
- RD->getDestructor());
+ EHStack.pushCleanup<CallMemberDtor>(EHCleanup, LHS.getAddress(),
+ RD->getDestructor());
}
}
Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp Tue Feb 14 03:11:10 2012
@@ -21,9 +21,8 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/Constants.h"
@@ -75,7 +74,7 @@
llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(LB);
llvm::DIDescriptor D
= DBuilder.createLexicalBlockFile(LBF.getScope(),
- getOrCreateFile(CurLoc));
+ getOrCreateFile(CurLoc));
llvm::MDNode *N = D;
LexicalBlockStack.pop_back();
LexicalBlockStack.push_back(N);
@@ -164,8 +163,8 @@
/// getClassName - Get class name including template argument list.
StringRef
-CGDebugInfo::getClassName(RecordDecl *RD) {
- ClassTemplateSpecializationDecl *Spec
+CGDebugInfo::getClassName(const RecordDecl *RD) {
+ const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(RD);
if (!Spec)
return RD->getName();
@@ -483,27 +482,28 @@
// Creates a forward declaration for a RecordDecl in the given context.
llvm::DIType CGDebugInfo::createRecordFwdDecl(const RecordDecl *RD,
- llvm::DIDescriptor Ctx) {
-
+ llvm::DIDescriptor Ctx) {
llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
unsigned Line = getLineNumber(RD->getLocation());
+ StringRef RDName = RD->getName();
+
+ // Get the tag.
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
-
- if (CXXDecl)
- return DBuilder.createClassType(Ctx, RD->getName(), DefUnit,
- Line, 0, 0, 0,
- llvm::DIType::FlagFwdDecl,
- llvm::DIType(), llvm::DIArray());
+ unsigned Tag = 0;
+ if (CXXDecl) {
+ RDName = getClassName(RD);
+ Tag = llvm::dwarf::DW_TAG_class_type;
+ }
else if (RD->isStruct())
- return DBuilder.createStructType(Ctx, RD->getName(), DefUnit,
- Line, 0, 0, llvm::DIType::FlagFwdDecl,
- llvm::DIArray());
+ Tag = llvm::dwarf::DW_TAG_structure_type;
else if (RD->isUnion())
- return DBuilder.createUnionType(Ctx, RD->getName(), DefUnit,
- Line, 0, 0, llvm::DIType::FlagFwdDecl,
- llvm::DIArray());
+ Tag = llvm::dwarf::DW_TAG_union_type;
else
llvm_unreachable("Unknown RecordDecl type!");
+
+ // Create the type.
+ return DBuilder.createForwardDecl(Tag, RDName, DefUnit,
+ Line);
}
// Walk up the context chain and create forward decls for record decls,
@@ -673,12 +673,8 @@
if (isa<FunctionNoProtoType>(Ty))
EltTys.push_back(DBuilder.createUnspecifiedParameter());
else if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
- for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) {
- if (CGM.getCodeGenOpts().LimitDebugInfo)
- EltTys.push_back(getOrCreateLimitedType(FTP->getArgType(i), Unit));
- else
- EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
- }
+ for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+ EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
}
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -687,6 +683,7 @@
return DbgTy;
}
+
void CGDebugInfo::
CollectRecordStaticVars(const RecordDecl *RD, llvm::DIType FwdDecl) {
@@ -828,15 +825,17 @@
uint64_t Size = CGM.getContext().getTargetInfo().getPointerWidth(AS);
uint64_t Align = CGM.getContext().getTypeAlign(ThisPtrTy);
llvm::DIType PointeeType = getOrCreateType(PointeeTy, Unit);
- llvm::DIType ThisPtrType =
- DBuilder.createArtificialType
- (DBuilder.createPointerType(PointeeType, Size, Align));
+ llvm::DIType ThisPtrType = DBuilder.createPointerType(PointeeType, Size, Align);
TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;
+ // TODO: This and the artificial type below are misleading, the
+ // types aren't artificial the argument is, but the current
+ // metadata doesn't represent that.
+ ThisPtrType = DBuilder.createArtificialType(ThisPtrType);
Elts.push_back(ThisPtrType);
} else {
- llvm::DIType ThisPtrType =
- DBuilder.createArtificialType(getOrCreateType(ThisPtr, Unit));
+ llvm::DIType ThisPtrType = getOrCreateType(ThisPtr, Unit);
TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;
+ ThisPtrType = DBuilder.createArtificialType(ThisPtrType);
Elts.push_back(ThisPtrType);
}
}
@@ -1307,8 +1306,18 @@
EltTys.push_back(InhTag);
}
+ for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(),
+ E = ID->prop_end(); I != E; ++I) {
+ const ObjCPropertyDecl *PD = *I;
+ llvm::MDNode *PropertyNode =
+ DBuilder.createObjCProperty(PD->getName(),
+ getSelectorName(PD->getGetterName()),
+ getSelectorName(PD->getSetterName()),
+ PD->getPropertyAttributes());
+ EltTys.push_back(PropertyNode);
+ }
+
const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
- ObjCImplementationDecl *ImpD = ID->getImplementation();
unsigned FieldNo = 0;
for (ObjCIvarDecl *Field = ID->all_declared_ivar_begin(); Field;
Field = Field->getNextIvar(), ++FieldNo) {
@@ -1351,26 +1360,18 @@
else if (Field->getAccessControl() == ObjCIvarDecl::Private)
Flags = llvm::DIDescriptor::FlagPrivate;
- StringRef PropertyName;
- StringRef PropertyGetter;
- StringRef PropertySetter;
- unsigned PropertyAttributes = 0;
- ObjCPropertyDecl *PD = NULL;
llvm::MDNode *PropertyNode = NULL;
- if (ImpD)
+ if (ObjCImplementationDecl *ImpD = ID->getImplementation()) {
if (ObjCPropertyImplDecl *PImpD =
- ImpD->FindPropertyImplIvarDecl(Field->getIdentifier()))
- PD = PImpD->getPropertyDecl();
- if (PD) {
- PropertyName = PD->getName();
- PropertyGetter = getSelectorName(PD->getGetterName());
- PropertySetter = getSelectorName(PD->getSetterName());
- PropertyAttributes = PD->getPropertyAttributes();
- PropertyNode =
- DBuilder.createObjCProperty(PropertyName, PropertyGetter,
- PropertySetter,
- PropertyAttributes);
- EltTys.push_back(PropertyNode);
+ ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
+ if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
+ PropertyNode =
+ DBuilder.createObjCProperty(PD->getName(),
+ getSelectorName(PD->getGetterName()),
+ getSelectorName(PD->getSetterName()),
+ PD->getPropertyAttributes());
+ }
+ }
}
FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit,
FieldLine, FieldSize, FieldAlign,
@@ -1644,12 +1645,9 @@
// Unwrap the type as needed for debug information.
Ty = UnwrapTypeForDebugInfo(Ty);
-
- // Check if we already have the type. If we've gotten here and
- // have a forward declaration of the type we may want the full type.
- // Go ahead and create it if that's the case.
+
llvm::DIType T = getTypeOrNull(Ty);
- if (T.Verify() && !T.isForwardDecl()) return T;
+ if (T.Verify()) return T;
// Otherwise create the type.
llvm::DIType Res = CreateTypeNode(Ty, Unit);
@@ -1659,64 +1657,6 @@
return Res;
}
-/// 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);
- if (T.Verify()) return T;
-
- // Otherwise create the type.
- llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);
-
- // And update the type cache.
- TypeCache[Ty.getAsOpaquePtr()] = Res;
- return Res;
-}
-
-// TODO: Not safe to use for inner types or for fields. Currently only
-// used for by value arguments to functions anything else needs to be
-// audited carefully.
-llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
-
- // For templated records we want the full type information and
- // our forward decls don't handle this correctly.
- if (isa<ClassTemplateSpecializationDecl>(RD))
- return CreateType(Ty);
-
- llvm::DIDescriptor RDContext
- = createContextChain(cast<Decl>(RD->getDeclContext()));
-
- return createRecordFwdDecl(RD, RDContext);
-}
-
-/// 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);
- }
-}
-
/// CreateTypeNode - Create a new debug type node.
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
// Handle qualifiers, which recursively handles what they refer to.
@@ -1979,11 +1919,11 @@
void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
llvm::DIDescriptor D =
DBuilder.createLexicalBlock(LexicalBlockStack.empty() ?
- llvm::DIDescriptor() :
- llvm::DIDescriptor(LexicalBlockStack.back()),
- getOrCreateFile(CurLoc),
- getLineNumber(CurLoc),
- getColumnNumber(CurLoc));
+ llvm::DIDescriptor() :
+ llvm::DIDescriptor(LexicalBlockStack.back()),
+ getOrCreateFile(CurLoc),
+ getLineNumber(CurLoc),
+ getColumnNumber(CurLoc));
llvm::MDNode *DN = D;
LexicalBlockStack.push_back(DN);
}
@@ -1999,8 +1939,8 @@
// Emit a line table change for the current location inside the new scope.
Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(getLineNumber(Loc),
- getColumnNumber(Loc),
- LexicalBlockStack.back()));
+ getColumnNumber(Loc),
+ LexicalBlockStack.back()));
}
/// EmitLexicalBlockEnd - Constructs the debug code for exiting a declarative
Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h Tue Feb 14 03:11:10 2012
@@ -73,9 +73,6 @@
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache;
llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache;
- /// Helper functions for getOrCreateLimitedType.
- llvm::DIType CreateLimitedType(const RecordType *Ty);
-
/// Helper functions for getOrCreateType.
llvm::DIType CreateType(const BuiltinType *Ty);
llvm::DIType CreateType(const ComplexType *Ty);
@@ -260,17 +257,9 @@
/// necessary.
llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);
- /// getOrCreateLimitedType - Get the type from the cache or create a flat
- /// limited type.
- 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 create as little as possible.
- 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);
@@ -293,7 +282,7 @@
StringRef getSelectorName(Selector S);
/// getClassName - Get class name including template argument list.
- StringRef getClassName(RecordDecl *RD);
+ StringRef getClassName(const RecordDecl *RD);
/// getVTableName - Get vtable name for the given Class.
StringRef getVTableName(const CXXRecordDecl *Decl);
Modified: cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDecl.cpp Tue Feb 14 03:11:10 2012
@@ -196,6 +196,14 @@
return GV;
}
+/// hasNontrivialDestruction - Determine whether a type's destruction is
+/// non-trivial. If so, and the variable uses static initialization, we must
+/// register its destructor to run on exit.
+static bool hasNontrivialDestruction(QualType T) {
+ CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+ return RD && !RD->hasTrivialDestructor();
+}
+
/// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
/// global variable that has already been created for it. If the initializer
/// has a different type than GV does, this may free GV and return a different
@@ -215,7 +223,7 @@
// be constant.
GV->setConstant(false);
- EmitCXXGuardedInit(D, GV);
+ EmitCXXGuardedInit(D, GV, /*PerformInit*/true);
}
return GV;
}
@@ -248,6 +256,16 @@
}
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);
+ EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
+ }
+
return GV;
}
@@ -773,11 +791,15 @@
// emit it as a global instead.
if (CGM.getCodeGenOpts().MergeAllConstants && Ty.isConstQualified() &&
!NRVO && !isByRef && Ty->isLiteralType()) {
- EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
-
- emission.Address = 0; // signal this condition to later callbacks
- assert(emission.wasEmittedAsGlobal());
- return emission;
+ 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;
+ }
}
// Otherwise, tell the initialization code that we're in this case.
Modified: cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp Tue Feb 14 03:11:10 2012
@@ -102,17 +102,21 @@
}
void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
- llvm::Constant *DeclPtr) {
+ llvm::Constant *DeclPtr,
+ bool PerformInit) {
const Expr *Init = D.getInit();
QualType T = D.getType();
if (!T->isReferenceType()) {
- EmitDeclInit(*this, D, DeclPtr);
+ if (PerformInit)
+ EmitDeclInit(*this, D, DeclPtr);
EmitDeclDestroy(*this, D, DeclPtr);
return;
}
+ assert(PerformInit && "cannot have constant initializer which needs "
+ "destruction for reference");
unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
RValue RV = EmitReferenceBindingToExpr(Init, &D);
EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T);
@@ -152,7 +156,8 @@
}
void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
- llvm::GlobalVariable *DeclPtr) {
+ llvm::GlobalVariable *DeclPtr,
+ bool PerformInit) {
// If we've been asked to forbid guard variables, emit an error now.
// This diagnostic is hard-coded for Darwin's use case; we can find
// better phrasing if someone else needs it.
@@ -161,7 +166,7 @@
"this initialization requires a guard variable, which "
"the kernel does not support");
- CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr);
+ CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
}
static llvm::Function *
@@ -186,14 +191,16 @@
void
CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
- llvm::GlobalVariable *Addr) {
+ llvm::GlobalVariable *Addr,
+ bool PerformInit) {
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
// Create a variable initialization function.
llvm::Function *Fn =
CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init");
- CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr);
+ CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
+ PerformInit);
if (D->hasAttr<InitPriorityAttr>()) {
unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority();
@@ -267,7 +274,8 @@
/// Emit the code necessary to initialize the given global variable.
void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
const VarDecl *D,
- llvm::GlobalVariable *Addr) {
+ llvm::GlobalVariable *Addr,
+ bool PerformInit) {
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
getTypes().getNullaryFunctionInfo(),
FunctionArgList(), SourceLocation());
@@ -277,9 +285,9 @@
// definitions explicitly marked weak.
if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage ||
Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) {
- EmitCXXGuardedInit(*D, Addr);
+ EmitCXXGuardedInit(*D, Addr, PerformInit);
} else {
- EmitCXXGlobalVarDeclInit(*D, Addr);
+ EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
}
FinishFunction();
@@ -357,4 +365,3 @@
return fn;
}
-
Modified: cfe/branches/tooling/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGException.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGException.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGException.cpp Tue Feb 14 03:11:10 2012
@@ -11,17 +11,13 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/StmtCXX.h"
-
-#include "llvm/Intrinsics.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Support/CallSite.h"
-
-#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
-#include "CGException.h"
#include "CGCleanup.h"
+#include "CGObjCRuntime.h"
#include "TargetInfo.h"
+#include "clang/AST/StmtCXX.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Support/CallSite.h"
using namespace clang;
using namespace CodeGen;
@@ -145,14 +141,37 @@
return CGF.CGM.CreateRuntimeFunction(FTy, Name);
}
-const EHPersonality EHPersonality::GNU_C("__gcc_personality_v0");
-const EHPersonality EHPersonality::GNU_C_SJLJ("__gcc_personality_sj0");
-const EHPersonality EHPersonality::NeXT_ObjC("__objc_personality_v0");
-const EHPersonality EHPersonality::GNU_CPlusPlus("__gxx_personality_v0");
-const EHPersonality EHPersonality::GNU_CPlusPlus_SJLJ("__gxx_personality_sj0");
-const EHPersonality EHPersonality::GNU_ObjC("__gnu_objc_personality_v0",
- "objc_exception_throw");
-const EHPersonality EHPersonality::GNU_ObjCXX("__gnustep_objcxx_personality_v0");
+namespace {
+ /// The exceptions personality for a function.
+ struct EHPersonality {
+ const char *PersonalityFn;
+
+ // If this is non-null, this personality requires a non-standard
+ // function for rethrowing an exception after a catchall cleanup.
+ // This function must have prototype void(void*).
+ const char *CatchallRethrowFn;
+
+ static const EHPersonality &get(const LangOptions &Lang);
+ static const EHPersonality GNU_C;
+ static const EHPersonality GNU_C_SJLJ;
+ static const EHPersonality GNU_ObjC;
+ static const EHPersonality GNU_ObjCXX;
+ static const EHPersonality NeXT_ObjC;
+ static const EHPersonality GNU_CPlusPlus;
+ static const EHPersonality GNU_CPlusPlus_SJLJ;
+ };
+}
+
+const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", 0 };
+const EHPersonality EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", 0 };
+const EHPersonality EHPersonality::NeXT_ObjC = { "__objc_personality_v0", 0 };
+const EHPersonality EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", 0};
+const EHPersonality
+EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", 0 };
+const EHPersonality
+EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
+const EHPersonality
+EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", 0 };
static const EHPersonality &getCPersonality(const LangOptions &L) {
if (L.SjLjExceptions)
@@ -212,7 +231,7 @@
const EHPersonality &Personality) {
llvm::Constant *Fn =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
- Personality.getPersonalityFnName());
+ Personality.PersonalityFn);
return Fn;
}
@@ -286,12 +305,13 @@
const EHPersonality &ObjCXX = EHPersonality::get(Features);
const EHPersonality &CXX = getCXXPersonality(Features);
- if (&ObjCXX == &CXX ||
- ObjCXX.getPersonalityFnName() == CXX.getPersonalityFnName())
+ if (&ObjCXX == &CXX)
return;
- llvm::Function *Fn =
- getModule().getFunction(ObjCXX.getPersonalityFnName());
+ assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&
+ "Different EHPersonalities using the same personality function.");
+
+ llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);
// Nothing to do if it's unused.
if (!Fn || Fn->use_empty()) return;
@@ -1529,8 +1549,8 @@
// This can always be a call because we necessarily didn't find
// anything on the EH stack which needs our help.
- StringRef RethrowName = Personality.getCatchallRethrowFnName();
- if (!RethrowName.empty()) {
+ const char *RethrowName = Personality.CatchallRethrowFn;
+ if (RethrowName != 0) {
Builder.CreateCall(getCatchallRethrowFn(*this, RethrowName),
getExceptionFromSlot())
->setDoesNotReturn();
Removed: cfe/branches/tooling/lib/CodeGen/CGException.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGException.h?rev=150464&view=auto
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGException.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGException.h (removed)
@@ -1,56 +0,0 @@
-//===-- CGException.h - Classes for exceptions IR generation ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// These classes support the generation of LLVM IR for exceptions in
-// C++ and Objective C.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CGEXCEPTION_H
-#define CLANG_CODEGEN_CGEXCEPTION_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-class LangOptions;
-
-namespace CodeGen {
-
-/// The exceptions personality for a function. When
-class EHPersonality {
- StringRef PersonalityFn;
-
- // If this is non-null, this personality requires a non-standard
- // function for rethrowing an exception after a catchall cleanup.
- // This function must have prototype void(void*).
- StringRef CatchallRethrowFn;
-
- EHPersonality(StringRef PersonalityFn,
- StringRef CatchallRethrowFn = StringRef())
- : PersonalityFn(PersonalityFn),
- CatchallRethrowFn(CatchallRethrowFn) {}
-
-public:
- static const EHPersonality &get(const LangOptions &Lang);
- static const EHPersonality GNU_C;
- static const EHPersonality GNU_C_SJLJ;
- static const EHPersonality GNU_ObjC;
- static const EHPersonality GNU_ObjCXX;
- static const EHPersonality NeXT_ObjC;
- static const EHPersonality GNU_CPlusPlus;
- static const EHPersonality GNU_CPlusPlus_SJLJ;
-
- StringRef getPersonalityFnName() const { return PersonalityFn; }
- StringRef getCatchallRethrowFnName() const { return CatchallRethrowFn; }
-};
-
-}
-}
-
-#endif
Modified: cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExpr.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExpr.cpp Tue Feb 14 03:11:10 2012
@@ -686,6 +686,8 @@
return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
case Expr::CXXBindTemporaryExprClass:
return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
+ case Expr::LambdaExprClass:
+ return EmitLambdaLValue(cast<LambdaExpr>(E));
case Expr::ExprWithCleanupsClass: {
const ExprWithCleanups *cleanups = cast<ExprWithCleanups>(E);
@@ -1394,6 +1396,12 @@
llvm::Value *V = LocalDeclMap[VD];
if (!V && VD->isStaticLocal())
V = CGM.getStaticLocalDeclAddress(VD);
+
+ // Use special handling for lambdas.
+ if (!V)
+ if (FieldDecl *FD = LambdaCaptureFields.lookup(VD))
+ return EmitLValueForField(CXXABIThisValue, FD, 0);
+
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
if (VD->hasAttr<BlocksAttr>())
@@ -2359,6 +2367,13 @@
return MakeAddrLValue(Slot.getAddr(), E->getType());
}
+LValue
+CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) {
+ AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
+ EmitLambdaExpr(E, Slot);
+ return MakeAddrLValue(Slot.getAddr(), E->getType());
+}
+
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
RValue RV = EmitObjCMessageExpr(E);
Modified: cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp Tue Feb 14 03:11:10 2012
@@ -142,6 +142,7 @@
}
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
void VisitCXXConstructExpr(const CXXConstructExpr *E);
+ void VisitLambdaExpr(LambdaExpr *E);
void VisitExprWithCleanups(ExprWithCleanups *E);
void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
@@ -538,6 +539,12 @@
CGF.EmitCXXConstructExpr(E, Slot);
}
+void
+AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
+ AggValueSlot Slot = EnsureSlot(E->getType());
+ CGF.EmitLambdaExpr(E, Slot);
+}
+
void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
CGF.enterFullExpression(E);
CodeGenFunction::RunCleanupsScope cleanups(CGF);
Modified: cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp Tue Feb 14 03:11:10 2012
@@ -1764,3 +1764,19 @@
return Value;
}
+
+void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) {
+ RunCleanupsScope Scope(*this);
+
+ CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
+ for (LambdaExpr::capture_init_iterator i = E->capture_init_begin(),
+ e = E->capture_init_end();
+ i != e; ++i, ++CurField) {
+ // Emit initialization
+ LValue LV = EmitLValueForFieldInitialization(Slot.getAddr(), *CurField, 0);
+ ArrayRef<VarDecl *> ArrayIndexes;
+ if (CurField->getType()->isArrayType())
+ ArrayIndexes = E->getCaptureInitIndexVars(i);
+ EmitInitializerForField(*CurField, LV, *i, ArrayIndexes);
+ }
+}
Modified: cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp Tue Feb 14 03:11:10 2012
@@ -939,6 +939,15 @@
if (const APValue *Value = D.evaluateValue())
return EmitConstantValue(*Value, D.getType(), CGF);
+ // FIXME: Implement C++11 [basic.start.init]p2: if the initializer of a
+ // reference is a constant expression, and the reference binds to a temporary,
+ // then constant initialization is performed. ConstExprEmitter will
+ // incorrectly emit a prvalue constant in this case, and the calling code
+ // interprets that as the (pointer) value of the reference, rather than the
+ // desired value of the referee.
+ if (D.getType()->isReferenceType())
+ return 0;
+
const Expr *E = D.getInit();
assert(E && "No initializer to emit");
Modified: cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjC.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjC.cpp Tue Feb 14 03:11:10 2012
@@ -2740,7 +2740,8 @@
CXXConstExpr->getConstructor(),
CXXConstExpr->isElidable(),
&ConstructorArgs[0], ConstructorArgs.size(),
- CXXConstExpr->hadMultipleCandidates(),
+ CXXConstExpr->hadMultipleCandidates(),
+ CXXConstExpr->isListInitialization(),
CXXConstExpr->requiresZeroInitialization(),
CXXConstExpr->getConstructionKind(), SourceRange());
Modified: cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp Tue Feb 14 03:11:10 2012
@@ -855,11 +855,12 @@
const ObjCCommonTypesHelper &ObjCTypes);
/// PushProtocolProperties - Push protocol's property on the input stack.
- void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
- std::vector<llvm::Constant*> &Properties,
- const Decl *Container,
- const ObjCProtocolDecl *PROTO,
- const ObjCCommonTypesHelper &ObjCTypes);
+ void PushProtocolProperties(
+ llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
+ llvm::SmallVectorImpl<llvm::Constant*> &Properties,
+ const Decl *Container,
+ const ObjCProtocolDecl *PROTO,
+ const ObjCCommonTypesHelper &ObjCTypes);
/// GetProtocolRef - Return a reference to the internal protocol
/// description, creating an empty one if it has not been
@@ -2023,16 +2024,16 @@
/*
struct objc_protocol_list {
- struct objc_protocol_list *next;
- long count;
- Protocol *list[];
+ struct objc_protocol_list *next;
+ long count;
+ Protocol *list[];
};
*/
llvm::Constant *
CGObjCMac::EmitProtocolList(Twine Name,
ObjCProtocolDecl::protocol_iterator begin,
ObjCProtocolDecl::protocol_iterator end) {
- std::vector<llvm::Constant*> ProtocolRefs;
+ llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
for (; begin != end; ++begin)
ProtocolRefs.push_back(GetProtocolRef(*begin));
@@ -2063,7 +2064,7 @@
void CGObjCCommonMac::
PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
- std::vector<llvm::Constant*> &Properties,
+ llvm::SmallVectorImpl<llvm::Constant*> &Properties,
const Decl *Container,
const ObjCProtocolDecl *PROTO,
const ObjCCommonTypesHelper &ObjCTypes) {
@@ -2085,21 +2086,21 @@
/*
struct _objc_property {
- const char * const name;
- const char * const attributes;
+ const char * const name;
+ const char * const attributes;
};
struct _objc_property_list {
- uint32_t entsize; // sizeof (struct _objc_property)
- uint32_t prop_count;
- struct _objc_property[prop_count];
+ uint32_t entsize; // sizeof (struct _objc_property)
+ uint32_t prop_count;
+ struct _objc_property[prop_count];
};
*/
llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
const Decl *Container,
const ObjCContainerDecl *OCD,
const ObjCCommonTypesHelper &ObjCTypes) {
- std::vector<llvm::Constant*> Properties;
+ llvm::SmallVector<llvm::Constant*, 16> Properties;
llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
E = OCD->prop_end(); I != E; ++I) {
@@ -2234,7 +2235,7 @@
llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
<< OCD->getName();
- std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+ llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
for (ObjCCategoryImplDecl::instmeth_iterator
i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
@@ -2340,7 +2341,7 @@
if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
Flags |= eClassFlags_Hidden;
- std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+ llvm::SmallVector<llvm::Constant*, 16> InstanceMethods, ClassMethods;
for (ObjCImplementationDecl::instmeth_iterator
i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
@@ -4157,9 +4158,7 @@
llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
bool Extended) {
std::string TypeStr;
- if (CGM.getContext().getObjCEncodingForMethodDecl(
- const_cast<ObjCMethodDecl*>(D),
- TypeStr, Extended))
+ if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
return 0;
llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
@@ -5614,7 +5613,7 @@
CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
ObjCProtocolDecl::protocol_iterator begin,
ObjCProtocolDecl::protocol_iterator end) {
- std::vector<llvm::Constant*> ProtocolRefs;
+ llvm::SmallVector<llvm::Constant*, 16> ProtocolRefs;
// Just return null for empty protocol lists
if (begin == end)
@@ -5639,10 +5638,9 @@
Values[0] =
llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
Values[1] =
- llvm::ConstantArray::get(
- llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
- ProtocolRefs.size()),
- ProtocolRefs);
+ llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
+ ProtocolRefs.size()),
+ ProtocolRefs);
llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
Modified: cfe/branches/tooling/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGVTables.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGVTables.cpp Tue Feb 14 03:11:10 2012
@@ -329,6 +329,7 @@
SourceLocation());
CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
+ CXXThisValue = CXXABIThisValue;
// Adjust the 'this' pointer if necessary.
llvm::Value *AdjustedThisPtr =
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp Tue Feb 14 03:11:10 2012
@@ -16,7 +16,6 @@
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGDebugInfo.h"
-#include "CGException.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -30,15 +29,16 @@
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
: CodeGenTypeCache(cgm), CGM(cgm),
- Target(CGM.getContext().getTargetInfo()), Builder(cgm.getModule().getContext()),
+ Target(CGM.getContext().getTargetInfo()),
+ Builder(cgm.getModule().getContext()),
AutoreleaseResult(false), BlockInfo(0), BlockPointer(0),
- NormalCleanupDest(0), NextCleanupDestIndex(1), FirstBlockInfo(0),
- EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0),
+ LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1),
+ FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0),
DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false),
IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
- CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
- OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0),
- TrapBB(0) {
+ CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), CXXVTTDecl(0),
+ CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0),
+ TerminateHandler(0), TrapBB(0) {
CatchUndefined = getContext().getLangOptions().CatchUndefined;
CGM.getCXXABI().getMangleContext().startNewFunction();
@@ -351,8 +351,27 @@
PrologueCleanupDepth = EHStack.stable_begin();
EmitFunctionProlog(*CurFnInfo, CurFn, Args);
- if (D && isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
+ if (D && isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) {
CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
+ const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
+ if (MD->getParent()->isLambda() &&
+ MD->getOverloadedOperator() == OO_Call) {
+ // We're in a lambda; figure out the captures.
+ MD->getParent()->getCaptureFields(LambdaCaptureFields,
+ LambdaThisCaptureField);
+ if (LambdaThisCaptureField) {
+ // If this lambda captures this, load it.
+ LValue ThisLValue = EmitLValueForField(CXXABIThisValue,
+ LambdaThisCaptureField, 0);
+ CXXThisValue = EmitLoadOfLValue(ThisLValue).getScalarVal();
+ }
+ } else {
+ // Not in a lambda; just use 'this' from the method.
+ // FIXME: Should we generate a new load for each use of 'this'? The
+ // fast register allocator would be happier...
+ CXXThisValue = CXXABIThisValue;
+ }
+ }
// If any of the arguments have a variably modified type, make sure to
// emit the type size.
@@ -617,29 +636,24 @@
}
if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
- // Handle ?: operator.
+ // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
+ llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
+ llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
+
+ ConditionalEvaluation cond(*this);
+ EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
+
+ cond.begin(*this);
+ EmitBlock(LHSBlock);
+ EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
+ cond.end(*this);
+
+ cond.begin(*this);
+ EmitBlock(RHSBlock);
+ EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
+ cond.end(*this);
- // Just ignore GNU ?: extension.
- if (CondOp->getLHS()) {
- // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
- llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
- llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
-
- ConditionalEvaluation cond(*this);
- EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
-
- cond.begin(*this);
- EmitBlock(LHSBlock);
- EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
- cond.end(*this);
-
- cond.begin(*this);
- EmitBlock(RHSBlock);
- EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
- cond.end(*this);
-
- return;
- }
+ return;
}
// Emit the code with the fully general case.
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h Tue Feb 14 03:11:10 2012
@@ -599,6 +599,9 @@
const CodeGen::CGBlockInfo *BlockInfo;
llvm::Value *BlockPointer;
+ llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
+ FieldDecl *LambdaThisCaptureField;
+
/// \brief A mapping from NRVO variables to the flags used to indicate
/// when the NRVO has been applied to this variable.
llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags;
@@ -1164,7 +1167,8 @@
/// CXXThisDecl - When generating code for a C++ member function,
/// this will hold the implicit 'this' declaration.
- ImplicitParamDecl *CXXThisDecl;
+ ImplicitParamDecl *CXXABIThisDecl;
+ llvm::Value *CXXABIThisValue;
llvm::Value *CXXThisValue;
/// CXXVTTDecl - When generating code for a base object constructor or
@@ -1390,6 +1394,9 @@
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
FunctionArgList &Args);
+ void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init,
+ ArrayRef<VarDecl *> ArrayIndexes);
+
/// InitializeVTablePointer - Initialize the vtable pointer of the given
/// subobject.
///
@@ -2117,6 +2124,7 @@
LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
+ LValue EmitLambdaLValue(const LambdaExpr *E);
LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
@@ -2356,7 +2364,8 @@
/// EmitCXXGlobalVarDeclInit - Create the initializer for a C++
/// variable with global storage.
- void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr);
+ void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr,
+ bool PerformInit);
/// EmitCXXGlobalDtorRegistration - Emits a call to register the global ptr
/// with the C++ runtime so that its destructor will be called at exit.
@@ -2368,7 +2377,8 @@
/// possible to prove that an initialization will be done exactly
/// once, e.g. with a static local variable or a static data member
/// of a class template.
- void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr);
+ void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr,
+ bool PerformInit);
/// GenerateCXXGlobalInitFunc - Generates code for initializing global
/// variables.
@@ -2384,7 +2394,8 @@
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
const VarDecl *D,
- llvm::GlobalVariable *Addr);
+ llvm::GlobalVariable *Addr,
+ bool PerformInit);
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
@@ -2399,6 +2410,8 @@
void EmitCXXThrowExpr(const CXXThrowExpr *E);
+ void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest);
+
RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0);
//===--------------------------------------------------------------------===//
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp Tue Feb 14 03:11:10 2012
@@ -1359,7 +1359,9 @@
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::Constant *Init = 0;
QualType ASTTy = D->getType();
- bool NonConstInit = false;
+ CXXRecordDecl *RD = ASTTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+ bool NeedsGlobalCtor = false;
+ bool NeedsGlobalDtor = RD && !RD->hasTrivialDestructor();
const VarDecl *InitDecl;
const Expr *InitExpr = D->getAnyInitializer(InitDecl);
@@ -1385,15 +1387,16 @@
if (getLangOptions().CPlusPlus) {
Init = EmitNullConstant(T);
- NonConstInit = true;
+ NeedsGlobalCtor = true;
} else {
ErrorUnsupported(D, "static initializer");
Init = llvm::UndefValue::get(getTypes().ConvertType(T));
}
} else {
// We don't need an initializer, so remove the entry for the delayed
- // initializer position (just in case this entry was delayed).
- if (getLangOptions().CPlusPlus)
+ // initializer position (just in case this entry was delayed) if we
+ // also don't need to register a destructor.
+ if (getLangOptions().CPlusPlus && !NeedsGlobalDtor)
DelayedCXXInitPosition.erase(D);
}
}
@@ -1448,7 +1451,8 @@
// If it is safe to mark the global 'constant', do so now.
GV->setConstant(false);
- if (!NonConstInit && DeclIsConstantGlobal(Context, D, true))
+ if (!NeedsGlobalCtor && !NeedsGlobalDtor &&
+ DeclIsConstantGlobal(Context, D, true))
GV->setConstant(true);
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
@@ -1464,8 +1468,8 @@
SetCommonAttributes(D, GV);
// Emit the initializer function if necessary.
- if (NonConstInit)
- EmitCXXGlobalVarDeclInitFunc(D, GV);
+ if (NeedsGlobalCtor || NeedsGlobalDtor)
+ EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
// Emit global variable debug information.
if (CGDebugInfo *DI = getModuleDebugInfo())
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.h Tue Feb 14 03:11:10 2012
@@ -900,8 +900,11 @@
/// EmitCXXGlobalDtorFunc - Emit the function that destroys C++ globals.
void EmitCXXGlobalDtorFunc();
+ /// EmitCXXGlobalVarDeclInitFunc - Emit the function that initializes the
+ /// specified global (if PerformInit is true) and registers its destructor.
void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
- llvm::GlobalVariable *Addr);
+ llvm::GlobalVariable *Addr,
+ bool PerformInit);
// FIXME: Hardcoding priority here is gross.
void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535);
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenTBAA.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenTBAA.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenTBAA.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenTBAA.cpp Tue Feb 14 03:11:10 2012
@@ -22,7 +22,6 @@
#include "llvm/Metadata.h"
#include "llvm/Constants.h"
#include "llvm/Type.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace CodeGen;
Modified: cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp Tue Feb 14 03:11:10 2012
@@ -121,7 +121,7 @@
llvm::Value *&AllocPtr, CharUnits &CookieSize);
void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
- llvm::GlobalVariable *DeclPtr);
+ llvm::GlobalVariable *DeclPtr, bool PerformInit);
};
class ARMCXXABI : public ItaniumCXXABI {
@@ -734,7 +734,7 @@
/// Initialize the return slot to 'this' at the start of the
/// function.
if (HasThisReturn(CGF.CurGD))
- CGF.Builder.CreateStore(CGF.LoadCXXThis(), CGF.ReturnValue);
+ CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
}
void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
@@ -979,7 +979,8 @@
llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
GuardPtrTy, /*isVarArg=*/false);
- return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
+ return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire",
+ llvm::Attribute::NoUnwind);
}
static llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
@@ -988,7 +989,8 @@
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
- return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
+ return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release",
+ llvm::Attribute::NoUnwind);
}
static llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
@@ -997,7 +999,8 @@
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
- return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
+ return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort",
+ llvm::Attribute::NoUnwind);
}
namespace {
@@ -1016,7 +1019,8 @@
/// just special-case it at particular places.
void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
- llvm::GlobalVariable *GV) {
+ llvm::GlobalVariable *GV,
+ bool PerformInit) {
CGBuilderTy &Builder = CGF.Builder;
// We only need to use thread-safe statics for local variables;
@@ -1129,7 +1133,7 @@
}
// Emit the initializer and add a global destructor if appropriate.
- CGF.EmitCXXGlobalVarDeclInit(D, GV);
+ CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
if (threadsafe) {
// Pop the guard-abort cleanup if we pushed one.
Modified: cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp Tue Feb 14 03:11:10 2012
@@ -3065,9 +3065,10 @@
if (Ty->isComplexType())
return CGT.ConvertType(Ty);
- const RecordType *RT = Ty->getAsStructureType();
+ const RecordType *RT = Ty->getAs<RecordType>();
- if (!RT)
+ // Unions are passed in integer registers.
+ if (!RT || !RT->isStructureOrClassType())
return 0;
const RecordDecl *RD = RT->getDecl();
@@ -3080,6 +3081,8 @@
llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
SmallVector<llvm::Type*, 8> ArgList;
+ // Iterate over fields in the struct/class and check if there are any aligned
+ // double fields.
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i, ++idx) {
const QualType Ty = (*i)->getType();
@@ -3101,7 +3104,7 @@
LastOffset = Offset + 64;
}
- // This structure doesn't have an aligned double field.
+ // This struct/class doesn't have an aligned double field.
if (!LastOffset)
return 0;
@@ -3173,27 +3176,40 @@
llvm::Type*
MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
- const RecordType *RT = RetTy->getAsStructureType();
+ const RecordType *RT = RetTy->getAs<RecordType>();
SmallVector<llvm::Type*, 2> RTList;
- if (RT) {
+ if (RT && RT->isStructureOrClassType()) {
const RecordDecl *RD = RT->getDecl();
- RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end(), i;
+ const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+ unsigned FieldCnt = Layout.getFieldCount();
- for (i = b; (i != e) && (std::distance(b, i) < 2); ++i) {
- const BuiltinType *BT = (*i)->getType()->getAs<BuiltinType>();
+ // N32/64 returns struct/classes in floating point registers if the
+ // following conditions are met:
+ // 1. The size of the struct/class is no larger than 128-bit.
+ // 2. The struct/class has one or two fields all of which are floating
+ // point types.
+ // 3. The offset of the first field is zero (this follows what gcc does).
+ //
+ // Any other composite results are returned in integer registers.
+ //
+ if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
+ RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
+ for (; b != e; ++b) {
+ const BuiltinType *BT = (*b)->getType()->getAs<BuiltinType>();
- if (!BT || !BT->isFloatingPoint())
- break;
+ if (!BT || !BT->isFloatingPoint())
+ break;
- RTList.push_back(CGT.ConvertType((*i)->getType()));
- }
+ RTList.push_back(CGT.ConvertType((*b)->getType()));
+ }
- if (i == e)
- return llvm::StructType::get(getVMContext(), RTList,
- RD->hasAttr<PackedAttr>());
+ if (b == e)
+ return llvm::StructType::get(getVMContext(), RTList,
+ RD->hasAttr<PackedAttr>());
- RTList.clear();
+ RTList.clear();
+ }
}
RTList.push_back(llvm::IntegerType::get(getVMContext(),
@@ -3215,7 +3231,7 @@
if (RetTy->isAnyComplexType())
return ABIArgInfo::getDirect();
- if (!IsO32)
+ if (!IsO32 && !isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy))
return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
}
Modified: cfe/branches/tooling/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Driver.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Driver.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Driver.cpp Tue Feb 14 03:11:10 2012
@@ -65,7 +65,7 @@
CCCUsePCH(true), SuppressMissingInputWarning(false) {
if (IsProduction) {
// In a "production" build, only use clang on architectures we expect to
- // work, and don't use clang C++.
+ // work.
//
// During development its more convenient to always have the driver use
// clang, but we don't want users to be confused when things don't work, or
@@ -410,21 +410,22 @@
}
// Don't attempt to generate preprocessed files if multiple -arch options are
- // used.
- int Archs = 0;
+ // used, unless they're all duplicates.
+ llvm::StringSet<> ArchNames;
for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end();
it != ie; ++it) {
Arg *A = *it;
if (A->getOption().matches(options::OPT_arch)) {
- Archs++;
- if (Archs > 1) {
- Diag(clang::diag::note_drv_command_failed_diag_msg)
- << "Error generating preprocessed source(s) - cannot generate "
- "preprocessed source with multiple -arch options.";
- return;
- }
+ StringRef ArchName = A->getValue(C.getArgs());
+ ArchNames.insert(ArchName);
}
}
+ if (ArchNames.size() > 1) {
+ Diag(clang::diag::note_drv_command_failed_diag_msg)
+ << "Error generating preprocessed source(s) - cannot generate "
+ "preprocessed source with multiple -arch options.";
+ return;
+ }
if (Inputs.empty()) {
Diag(clang::diag::note_drv_command_failed_diag_msg)
Modified: cfe/branches/tooling/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChains.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChains.cpp (original)
+++ cfe/branches/tooling/lib/Driver/ToolChains.cpp Tue Feb 14 03:11:10 2012
@@ -1091,18 +1091,6 @@
return false;
}
-// FIXME: Factor this helper into llvm::Triple itself.
-static llvm::Triple getMultiarchAlternateTriple(llvm::Triple Triple) {
- switch (Triple.getArch()) {
- default: break;
- case llvm::Triple::x86: Triple.setArchName("x86_64"); break;
- case llvm::Triple::x86_64: Triple.setArchName("i386"); break;
- case llvm::Triple::ppc: Triple.setArchName("powerpc64"); break;
- case llvm::Triple::ppc64: Triple.setArchName("powerpc"); break;
- }
- return Triple;
-}
-
/// \brief Construct a GCCInstallationDetector from the driver.
///
/// This performs all of the autodetection and sets up the various paths.
@@ -1116,7 +1104,9 @@
const Driver &D,
const llvm::Triple &TargetTriple)
: IsValid(false) {
- llvm::Triple MultiarchTriple = getMultiarchAlternateTriple(TargetTriple);
+ llvm::Triple MultiarchTriple
+ = TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
+ : TargetTriple.get32BitArchVariant();
llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
// The library directories which may contain GCC installations.
SmallVector<StringRef, 4> CandidateLibDirs, CandidateMultiarchLibDirs;
@@ -2001,12 +1991,7 @@
// to the link paths.
path_list &Paths = getFilePaths();
- const bool Is32Bits = (Arch == llvm::Triple::x86 ||
- Arch == llvm::Triple::mips ||
- Arch == llvm::Triple::mipsel ||
- Arch == llvm::Triple::ppc);
-
- const std::string Multilib = Is32Bits ? "lib32" : "lib64";
+ const std::string Multilib = Triple.isArch32Bit() ? "lib32" : "lib64";
const std::string MultiarchTriple = getMultiarchTriple(Triple, SysRoot);
// Add the multilib suffixed paths where they are available.
Modified: cfe/branches/tooling/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChains.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChains.h (original)
+++ cfe/branches/tooling/lib/Driver/ToolChains.h Tue Feb 14 03:11:10 2012
@@ -134,13 +134,10 @@
/// @{
/// \brief Check whether the target triple's architecture is 64-bits.
- bool isTarget64Bit() const {
- return (getTriple().getArch() == llvm::Triple::x86_64 ||
- getTriple().getArch() == llvm::Triple::ppc64);
- }
+ bool isTarget64Bit() const { return getTriple().isArch64Bit(); }
+
/// \brief Check whether the target triple's architecture is 32-bits.
- /// FIXME: This should likely do more than just negate the 64-bit query.
- bool isTarget32Bit() const { return !isTarget64Bit(); }
+ bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
/// @}
};
Modified: cfe/branches/tooling/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Tools.cpp Tue Feb 14 03:11:10 2012
@@ -2545,6 +2545,56 @@
Args.ClaimAllArgs(options::OPT_emit_llvm);
}
+void ClangAs::AddARMTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ const Driver &D = getToolChain().getDriver();
+ llvm::Triple Triple = getToolChain().getTriple();
+
+ // Set the CPU based on -march= and -mcpu=.
+ CmdArgs.push_back("-target-cpu");
+ CmdArgs.push_back(getARMTargetCPU(Args, Triple));
+
+ // Honor -mfpu=.
+ //
+ // FIXME: Centralize feature selection, defaulting shouldn't be also in the
+ // frontend target.
+ if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
+ StringRef FPU = A->getValue(Args);
+
+ // Set the target features based on the FPU.
+ if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
+ // Disable any default FPU support.
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-vfp2");
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-vfp3");
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-neon");
+ } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+vfp3");
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+d16");
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-neon");
+ } else if (FPU == "vfp") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+vfp2");
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-neon");
+ } else if (FPU == "vfp3" || FPU == "vfpv3") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+vfp3");
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("-neon");
+ } else if (FPU == "neon") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+neon");
+ } else
+ D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+ }
+}
+
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -2581,6 +2631,17 @@
if (UseRelaxAll(C, Args))
CmdArgs.push_back("-relax-all");
+ // Add target specific cpu and features flags.
+ switch(getToolChain().getTriple().getArch()) {
+ default:
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ AddARMTargetArgs(Args, CmdArgs);
+ break;
+ }
+
// Ignore explicit -force_cpusubtype_ALL option.
(void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
Modified: cfe/branches/tooling/lib/Driver/Tools.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.h (original)
+++ cfe/branches/tooling/lib/Driver/Tools.h Tue Feb 14 03:11:10 2012
@@ -59,6 +59,7 @@
/// \brief Clang integrated assembler tool.
class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
+ void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
public:
ClangAs(const ToolChain &TC) : Tool("clang::as",
"clang integrated assembler", TC) {}
Modified: cfe/branches/tooling/lib/Frontend/DiagnosticRenderer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/DiagnosticRenderer.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/DiagnosticRenderer.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/DiagnosticRenderer.cpp Tue Feb 14 03:11:10 2012
@@ -133,9 +133,9 @@
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
- const Diagnostic *Info) {
+ DiagOrStoredDiag D) {
- beginDiagnostic(Info, Level);
+ beginDiagnostic(D, Level);
PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc);
@@ -144,7 +144,7 @@
emitIncludeStack(PLoc.getIncludeLoc(), Level);
// Next, emit the actual diagnostic message.
- emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, Info);
+ emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D);
// Only recurse if we have a valid location.
if (Loc.isValid()) {
@@ -166,7 +166,14 @@
LastLoc = Loc;
LastLevel = Level;
- endDiagnostic(Info, Level);
+ endDiagnostic(D, Level);
+}
+
+
+void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
+ emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
+ Diag.getRanges(), Diag.getFixIts(),
+ &Diag);
}
/// \brief Prints an include stack when appropriate for a particular
@@ -304,3 +311,19 @@
Ranges, ArrayRef<FixItHint>());
}
+DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
+
+void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
+ PresumedLoc PLoc) {
+ // Generate a note indicating the include location.
+ SmallString<200> MessageStorage;
+ llvm::raw_svector_ostream Message(MessageStorage);
+ Message << "in file included from " << PLoc.getFilename() << ':'
+ << PLoc.getLine() << ":";
+ emitNote(Loc, Message.str());
+}
+
+void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) {
+ emitNote(SourceLocation(), Message);
+}
+
Modified: cfe/branches/tooling/lib/Frontend/MultiplexConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/MultiplexConsumer.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/MultiplexConsumer.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/MultiplexConsumer.cpp Tue Feb 14 03:11:10 2012
@@ -89,7 +89,7 @@
class MultiplexASTMutationListener : public ASTMutationListener {
public:
// Does NOT take ownership of the elements in L.
- MultiplexASTMutationListener(const std::vector<ASTMutationListener*>& L);
+ MultiplexASTMutationListener(ArrayRef<ASTMutationListener*> L);
virtual void CompletedTagDefinition(const TagDecl *D);
virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
@@ -99,13 +99,18 @@
const FunctionDecl *D);
virtual void CompletedImplicitDefinition(const FunctionDecl *D);
virtual void StaticDataMemberInstantiated(const VarDecl *D);
+ virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+ const ObjCInterfaceDecl *IFD);
+ virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+ const ObjCPropertyDecl *OrigProp,
+ const ObjCCategoryDecl *ClassExt);
private:
std::vector<ASTMutationListener*> Listeners;
};
MultiplexASTMutationListener::MultiplexASTMutationListener(
- const std::vector<ASTMutationListener*>& L)
- : Listeners(L) {
+ ArrayRef<ASTMutationListener*> L)
+ : Listeners(L.begin(), L.end()) {
}
void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) {
@@ -144,6 +149,19 @@
for (size_t i = 0, e = Listeners.size(); i != e; ++i)
Listeners[i]->StaticDataMemberInstantiated(D);
}
+void MultiplexASTMutationListener::AddedObjCCategoryToInterface(
+ const ObjCCategoryDecl *CatD,
+ const ObjCInterfaceDecl *IFD) {
+ for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+ Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD);
+}
+void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension(
+ const ObjCPropertyDecl *Prop,
+ const ObjCPropertyDecl *OrigProp,
+ const ObjCCategoryDecl *ClassExt) {
+ for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+ Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt);
+}
} // end namespace clang
@@ -206,6 +224,11 @@
Consumers[i]->HandleTagDeclDefinition(D);
}
+void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){
+ for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+ Consumers[i]->HandleCXXImplicitFunctionInstantiation(D);
+}
+
void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
for (size_t i = 0, e = Consumers.size(); i != e; ++i)
Consumers[i]->HandleTopLevelDeclInObjCContainer(D);
Modified: cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp Tue Feb 14 03:11:10 2012
@@ -128,7 +128,7 @@
virtual void PragmaDiagnosticPop(SourceLocation Loc,
StringRef Namespace);
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
- unsigned Map, StringRef Str);
+ diag::Mapping Map, StringRef Str);
bool HandleFirstTokOnLine(Token &Tok);
bool MoveToLine(SourceLocation Loc) {
@@ -385,10 +385,10 @@
void PrintPPOutputPPCallbacks::
PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
- unsigned Map, StringRef Str) {
+ diag::Mapping Map, StringRef Str) {
MoveToLine(Loc);
OS << "#pragma " << Namespace << " diagnostic ";
- switch ((diag::Mapping)Map) {
+ switch (Map) {
case diag::MAP_WARNING:
OS << "warning";
break;
Modified: cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp Tue Feb 14 03:11:10 2012
@@ -48,7 +48,7 @@
class SDiagsWriter;
-class SDiagsRenderer : public DiagnosticRenderer {
+class SDiagsRenderer : public DiagnosticNoteRenderer {
SDiagsWriter &Writer;
RecordData &Record;
public:
@@ -56,7 +56,7 @@
const SourceManager &SM,
const LangOptions &LangOpts,
const DiagnosticOptions &DiagOpts)
- : DiagnosticRenderer(SM, LangOpts, DiagOpts),
+ : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts),
Writer(Writer), Record(Record){}
virtual ~SDiagsRenderer() {}
@@ -67,27 +67,22 @@
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
- const Diagnostic *Info);
+ DiagOrStoredDiag D);
virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges) {}
- virtual void emitBasicNote(StringRef Message);
-
void emitNote(SourceLocation Loc, StringRef Message);
- virtual void emitIncludeLocation(SourceLocation Loc,
- PresumedLoc PLoc);
-
virtual void emitCodeContext(SourceLocation Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints);
- virtual void beginDiagnostic(const Diagnostic *Info,
+ virtual void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level);
- virtual void endDiagnostic(const Diagnostic *Info,
+ virtual void endDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level);
};
@@ -505,14 +500,14 @@
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<clang::CharSourceRange> Ranges,
- const Diagnostic *Info) {
+ DiagOrStoredDiag D) {
// Emit the RECORD_DIAG record.
Writer.Record.clear();
Writer.Record.push_back(RECORD_DIAG);
Writer.Record.push_back(Level);
Writer.AddLocToRecord(Loc, SM, PLoc, Record);
- if (Info) {
+ if (const Diagnostic *Info = D.dyn_cast<const Diagnostic*>()) {
// Emit the category string lazily and get the category ID.
unsigned DiagID = DiagnosticIDs::getCategoryNumberForDiag(Info->getID());
Writer.Record.push_back(Writer.getEmitCategory(DiagID));
@@ -529,14 +524,14 @@
Writer.Record, Message);
}
-void SDiagsRenderer::beginDiagnostic(const Diagnostic *Info,
+void SDiagsRenderer::beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {
Writer.Stream.EnterSubblock(BLOCK_DIAG, 4);
}
-void SDiagsRenderer::endDiagnostic(const Diagnostic *Info,
+void SDiagsRenderer::endDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {
- if (Info && Level != DiagnosticsEngine::Note)
+ if (D && Level != DiagnosticsEngine::Note)
return;
Writer.Stream.ExitBlock();
}
@@ -581,20 +576,6 @@
Writer.Stream.ExitBlock();
}
-void SDiagsRenderer::emitIncludeLocation(SourceLocation Loc,
- PresumedLoc PLoc) {
- // Generate a note indicating the include location.
- SmallString<200> MessageStorage;
- llvm::raw_svector_ostream Message(MessageStorage);
- Message << "in file included from " << PLoc.getFilename() << ':'
- << PLoc.getLine() << ":";
- emitNote(Loc, Message.str());
-}
-
-void SDiagsRenderer::emitBasicNote(StringRef Message) {
- emitNote(SourceLocation(), Message);
-}
-
void SDiagsWriter::finish() {
if (inNonNoteDiagnostic) {
// Finish off any diagnostics we were in the process of emitting.
Modified: cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp Tue Feb 14 03:11:10 2012
@@ -339,7 +339,7 @@
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<clang::CharSourceRange> Ranges,
- const Diagnostic *Info) {
+ DiagOrStoredDiag D) {
uint64_t StartOfLocationInfo = OS.tell();
// Emit the location of this particular diagnostic.
Modified: cfe/branches/tooling/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/branches/tooling/lib/FrontendTool/ExecuteCompilerInvocation.cpp Tue Feb 14 03:11:10 2012
@@ -157,7 +157,7 @@
for (unsigned i = 0; i != NumArgs; ++i)
Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
Args[NumArgs + 1] = 0;
- llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args));
+ llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
}
// Honor -analyzer-checker-help.
Modified: cfe/branches/tooling/lib/Headers/avx2intrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/avx2intrin.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/avx2intrin.h (original)
+++ cfe/branches/tooling/lib/Headers/avx2intrin.h Tue Feb 14 03:11:10 2012
@@ -837,7 +837,11 @@
#define _mm256_permute2x128_si256(V1, V2, M) __extension__ ({ \
__m256i __V1 = (V1); \
__m256i __V2 = (V2); \
- (__m256i)__builtin_ia32_permti256(__V1, __V2, (M)); })
+ __builtin_shufflevector(__V1, __V2, \
+ ((M) & 0x3) * 2, \
+ ((M) & 0x3) * 2 + 1, \
+ (((M) & 0x30) >> 4) * 2, \
+ (((M) & 0x30) >> 4) * 2 + 1); })
#define _mm256_extracti128_si256(A, O) __extension__ ({ \
__m256i __A = (A); \
Modified: cfe/branches/tooling/lib/Headers/avxintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/avxintrin.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/avxintrin.h (original)
+++ cfe/branches/tooling/lib/Headers/avxintrin.h Tue Feb 14 03:11:10 2012
@@ -260,34 +260,66 @@
#define _mm_permute_pd(A, C) __extension__ ({ \
__m128d __A = (A); \
- (__m128d)__builtin_ia32_vpermilpd((__v2df)__A, (C)); })
+ (__m128d)__builtin_shufflevector((__v2df)__A, (__v2df) _mm_setzero_pd(), \
+ (C) & 0x1, ((C) & 0x2) >> 1); })
#define _mm256_permute_pd(A, C) __extension__ ({ \
__m256d __A = (A); \
- (__m256d)__builtin_ia32_vpermilpd256((__v4df)__A, (C)); })
+ (__m256d)__builtin_shufflevector((__v4df)__A, (__v4df) _mm256_setzero_pd(), \
+ (C) & 0x1, ((C) & 0x2) >> 1, \
+ 2 + (((C) & 0x4) >> 2), \
+ 2 + (((C) & 0x8) >> 3)); })
#define _mm_permute_ps(A, C) __extension__ ({ \
__m128 __A = (A); \
- (__m128)__builtin_ia32_vpermilps((__v4sf)__A, (C)); })
+ (__m128)__builtin_shufflevector((__v4sf)__A, (__v4sf) _mm_setzero_ps(), \
+ (C) & 0x3, ((C) & 0xc) >> 2, \
+ ((C) & 0x30) >> 4, ((C) & 0xc0) >> 8); })
#define _mm256_permute_ps(A, C) __extension__ ({ \
__m256 __A = (A); \
- (__m256)__builtin_ia32_vpermilps256((__v8sf)__A, (C)); })
+ (__m256)__builtin_shufflevector((__v8sf)__A, (__v8sf) _mm256_setzero_ps(), \
+ (C) & 0x3, ((C) & 0xc) >> 2, \
+ ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6, \
+ 4 + (((C) & 0x03) >> 0), \
+ 4 + (((C) & 0x0c) >> 2), \
+ 4 + (((C) & 0x30) >> 4), \
+ 4 + (((C) & 0xc0) >> 6)); })
#define _mm256_permute2f128_pd(V1, V2, M) __extension__ ({ \
__m256d __V1 = (V1); \
__m256d __V2 = (V2); \
- (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)__V1, (__v4df)__V2, (M)); })
+ (__m256d)__builtin_shufflevector((__v4df)__V1, (__v4df)__V2, \
+ ((M) & 0x3) * 2, \
+ ((M) & 0x3) * 2 + 1, \
+ (((M) & 0x30) >> 4) * 2, \
+ (((M) & 0x30) >> 4) * 2 + 1); })
#define _mm256_permute2f128_ps(V1, V2, M) __extension__ ({ \
__m256 __V1 = (V1); \
__m256 __V2 = (V2); \
- (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)__V1, (__v8sf)__V2, (M)); })
+ (__m256)__builtin_shufflevector((__v8sf)__V1, (__v8sf)__V2, \
+ ((M) & 0x3) * 4, \
+ ((M) & 0x3) * 4 + 1, \
+ ((M) & 0x3) * 4 + 2, \
+ ((M) & 0x3) * 4 + 3, \
+ (((M) & 0x30) >> 4) * 4, \
+ (((M) & 0x30) >> 4) * 4 + 1, \
+ (((M) & 0x30) >> 4) * 4 + 2, \
+ (((M) & 0x30) >> 4) * 4 + 3); })
#define _mm256_permute2f128_si256(V1, V2, M) __extension__ ({ \
__m256i __V1 = (V1); \
__m256i __V2 = (V2); \
- (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)__V1, (__v8si)__V2, (M)); })
+ (__m256i)__builtin_shufflevector((__v8si)__V1, (__v8si)__V2, \
+ ((M) & 0x3) * 4, \
+ ((M) & 0x3) * 4 + 1, \
+ ((M) & 0x3) * 4 + 2, \
+ ((M) & 0x3) * 4 + 3, \
+ (((M) & 0x30) >> 4) * 4, \
+ (((M) & 0x30) >> 4) * 4 + 1, \
+ (((M) & 0x30) >> 4) * 4 + 2, \
+ (((M) & 0x30) >> 4) * 4 + 3); })
/* Vector Blend */
#define _mm256_blend_pd(V1, V2, M) __extension__ ({ \
Modified: cfe/branches/tooling/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/LiteralSupport.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/branches/tooling/lib/Lex/LiteralSupport.cpp Tue Feb 14 03:11:10 2012
@@ -549,13 +549,24 @@
radix = 16;
DigitsBegin = s;
s = SkipHexDigits(s);
+ bool noSignificand = (s == DigitsBegin);
if (s == ThisTokEnd) {
// Done.
} else if (*s == '.') {
s++;
saw_period = true;
+ const char *floatDigitsBegin = s;
s = SkipHexDigits(s);
+ noSignificand &= (floatDigitsBegin == s);
}
+
+ if (noSignificand) {
+ PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin), \
+ diag::err_hexconstant_requires_digits);
+ hadError = true;
+ return;
+ }
+
// A binary exponent can appear with or with a '.'. If dotted, the
// binary exponent is required.
if (*s == 'p' || *s == 'P') {
@@ -811,17 +822,32 @@
++begin;
} while (begin != end && *begin != '\\');
- uint32_t *tmp_begin = buffer_begin;
+ char const *tmp_in_start = start;
+ uint32_t *tmp_out_start = buffer_begin;
ConversionResult res =
ConvertUTF8toUTF32(reinterpret_cast<UTF8 const **>(&start),
reinterpret_cast<UTF8 const *>(begin),
&buffer_begin,buffer_end,strictConversion);
if (res!=conversionOK) {
- PP.Diag(Loc, diag::err_bad_character_encoding);
- HadError = true;
+ // If we see bad encoding for unprefixed character literals, warn and
+ // simply copy the byte values, for compatibility with gcc and
+ // older versions of clang.
+ bool NoErrorOnBadEncoding = isAscii();
+ unsigned Msg = diag::err_bad_character_encoding;
+ if (NoErrorOnBadEncoding)
+ Msg = diag::warn_bad_character_encoding;
+ PP.Diag(Loc, Msg);
+ if (NoErrorOnBadEncoding) {
+ start = tmp_in_start;
+ buffer_begin = tmp_out_start;
+ for ( ; start != begin; ++start, ++buffer_begin)
+ *buffer_begin = static_cast<uint8_t>(*start);
+ } else {
+ HadError = true;
+ }
} else {
- for (; tmp_begin<buffer_begin; ++tmp_begin) {
- if (*tmp_begin > largest_character_for_kind) {
+ for (; tmp_out_start <buffer_begin; ++tmp_out_start) {
+ if (*tmp_out_start > largest_character_for_kind) {
HadError = true;
PP.Diag(Loc, diag::err_character_too_large);
}
@@ -1086,10 +1112,8 @@
// Copy the string over
if (CopyStringFragment(StringRef(ThisTokBuf,ThisTokEnd-ThisTokBuf)))
{
- if (Diags)
- Diags->Report(FullSourceLoc(StringToks[i].getLocation(), SM),
- diag::err_bad_string_encoding);
- hadError = true;
+ if (DiagnoseBadString(StringToks[i]))
+ hadError = true;
}
} else {
@@ -1120,10 +1144,8 @@
// Copy the character span over.
if (CopyStringFragment(StringRef(InStart,ThisTokBuf-InStart)))
{
- if (Diags)
- Diags->Report(FullSourceLoc(StringToks[i].getLocation(), SM),
- diag::err_bad_string_encoding);
- hadError = true;
+ if (DiagnoseBadString(StringToks[i]))
+ hadError = true;
}
continue;
}
@@ -1208,6 +1230,9 @@
ConversionResult result = conversionOK;
// Copy the character span over.
if (CharByteWidth == 1) {
+ if (!isLegalUTF8Sequence(reinterpret_cast<const UTF8*>(Fragment.begin()),
+ reinterpret_cast<const UTF8*>(Fragment.end())))
+ result = sourceIllegal;
memcpy(ResultPtr, Fragment.data(), Fragment.size());
ResultPtr += Fragment.size();
} else if (CharByteWidth == 2) {
@@ -1215,7 +1240,7 @@
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
- ConversionFlags flags = lenientConversion;
+ ConversionFlags flags = strictConversion;
result = ConvertUTF8toUTF16(
&sourceStart,sourceStart + Fragment.size(),
&targetStart,targetStart + 2*Fragment.size(),flags);
@@ -1226,7 +1251,7 @@
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
- ConversionFlags flags = lenientConversion;
+ ConversionFlags flags = strictConversion;
result = ConvertUTF8toUTF32(
&sourceStart,sourceStart + Fragment.size(),
&targetStart,targetStart + 4*Fragment.size(),flags);
@@ -1238,6 +1263,17 @@
return result != conversionOK;
}
+bool StringLiteralParser::DiagnoseBadString(const Token &Tok) {
+ // If we see bad encoding for unprefixed string literals, warn and
+ // simply copy the byte values, for compatibility with gcc and older
+ // versions of clang.
+ bool NoErrorOnBadEncoding = isAscii();
+ unsigned Msg = NoErrorOnBadEncoding ? diag::warn_bad_string_encoding :
+ diag::err_bad_string_encoding;
+ if (Diags)
+ Diags->Report(FullSourceLoc(Tok.getLocation(), SM), Msg);
+ return !NoErrorOnBadEncoding;
+}
/// getOffsetOfStringByte - This function returns the offset of the
/// specified byte of the string data represented by Token. This handles
Modified: cfe/branches/tooling/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/Preprocessor.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/Preprocessor.cpp (original)
+++ cfe/branches/tooling/lib/Lex/Preprocessor.cpp Tue Feb 14 03:11:10 2012
@@ -336,21 +336,6 @@
setCodeCompletionReached();
}
-void Preprocessor::setCodeCompletionReached() {
- assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
- CodeCompletionReached = true;
- // Silence any diagnostics that occur after we hit the code-completion.
- getDiagnostics().setSuppressAllDiagnostics(true);
-}
-
-DiagnosticBuilder Preprocessor::Diag(SourceLocation Loc, unsigned DiagID) const{
- return Diags->Report(Loc, DiagID);
-}
-
-DiagnosticBuilder Preprocessor::Diag(const Token &Tok, unsigned DiagID) const {
- return Diags->Report(Tok.getLocation(), DiagID);
-}
-
/// getSpelling - This method is used to get the spelling of a token into a
/// SmallVector. Note that the returned StringRef may not point to the
/// supplied buffer if a copy can be avoided.
Modified: cfe/branches/tooling/lib/Parse/ParseAST.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseAST.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseAST.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseAST.cpp Tue Feb 14 03:11:10 2012
@@ -96,10 +96,6 @@
if (Abort)
return;
-
- // Check for any pending objective-c implementation decl.
- while ((ADecl = P.FinishPendingObjCActions()))
- Consumer->HandleTopLevelDecl(ADecl.get());
// Process any TopLevelDecls generated by #pragma weak.
for (SmallVector<Decl*,2>::iterator
Modified: cfe/branches/tooling/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseDecl.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseDecl.cpp Tue Feb 14 03:11:10 2012
@@ -1282,8 +1282,8 @@
Diag(ConsumeToken(), diag::err_deleted_non_function);
} else if (Tok.is(tok::kw_default)) {
if (D.isFunctionDeclarator())
- Diag(Tok, diag::err_default_delete_in_multiple_declaration)
- << 1 /* delete */;
+ Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
+ << 0 /* default */;
else
Diag(ConsumeToken(), diag::err_default_special_members);
} else {
@@ -1344,10 +1344,11 @@
ExitScope();
}
- Actions.AddCXXDirectInitializerToDecl(ThisDecl, T.getOpenLocation(),
- move_arg(Exprs),
- T.getCloseLocation(),
- TypeContainsAuto);
+ ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
+ T.getCloseLocation(),
+ move_arg(Exprs));
+ Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
+ /*DirectInit=*/true, TypeContainsAuto);
}
} else if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
// Parse C++0x braced-init-list.
@@ -1723,7 +1724,7 @@
: Sema::PCC_Template;
else if (DSContext == DSC_class)
CCC = Sema::PCC_Class;
- else if (ObjCImpDecl)
+ else if (CurParsedObjCImpl)
CCC = Sema::PCC_ObjCImplementation;
Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
Modified: cfe/branches/tooling/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExpr.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExpr.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExpr.cpp Tue Feb 14 03:11:10 2012
@@ -1416,7 +1416,8 @@
if (!LHS.isInvalid())
LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc,
OpKind, SS, TemplateKWLoc, Name,
- ObjCImpDecl, Tok.is(tok::l_paren));
+ CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : 0,
+ Tok.is(tok::l_paren));
break;
}
case tok::plusplus: // postfix-expression: postfix-expression '++'
@@ -2005,8 +2006,8 @@
if (!ParseExpressionList(ArgExprs, CommaLocs)) {
ExprType = SimpleExpr;
- Result = Actions.ActOnParenOrParenListExpr(OpenLoc, Tok.getLocation(),
- move_arg(ArgExprs));
+ Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
+ move_arg(ArgExprs));
}
} else {
InMessageExpressionRAIIObject InMessage(*this, false);
Modified: cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp Tue Feb 14 03:11:10 2012
@@ -630,11 +630,11 @@
if (Tok.is(tok::amp) &&
(NextToken().is(tok::comma) || NextToken().is(tok::r_square))) {
Intro.Default = LCD_ByRef;
- ConsumeToken();
+ Intro.DefaultLoc = ConsumeToken();
first = false;
} else if (Tok.is(tok::equal)) {
Intro.Default = LCD_ByCopy;
- ConsumeToken();
+ Intro.DefaultLoc = ConsumeToken();
first = false;
}
@@ -1151,10 +1151,13 @@
&& "Expected '(' or '{'!");
if (Tok.is(tok::l_brace)) {
-
- // FIXME: Convert to a proper type construct expression.
- return ParseBraceInitializer();
-
+ ExprResult Init = ParseBraceInitializer();
+ if (Init.isInvalid())
+ return Init;
+ Expr *InitList = Init.take();
+ return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(),
+ MultiExprArg(&InitList, 1),
+ SourceLocation());
} else {
GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
@@ -2182,8 +2185,10 @@
} else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) {
Diag(Tok.getLocation(),
diag::warn_cxx98_compat_generalized_initializer_lists);
- // FIXME: Have to communicate the init-list to ActOnCXXNew.
- ParseBraceInitializer();
+ ExprResult InitList = ParseBraceInitializer();
+ if (InitList.isInvalid())
+ return InitList;
+ ConstructorArgs.push_back(InitList.take());
}
return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
Modified: cfe/branches/tooling/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseObjc.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseObjc.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseObjc.cpp Tue Feb 14 03:11:10 2012
@@ -52,8 +52,7 @@
return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
}
case tok::objc_implementation:
- SingleDecl = ParseObjCAtImplementationDeclaration(AtLoc);
- break;
+ return ParseObjCAtImplementationDeclaration(AtLoc);
case tok::objc_end:
return ParseObjCAtEndDeclaration(AtLoc);
case tok::objc_compatibility_alias:
@@ -122,15 +121,17 @@
if (ock == Sema::OCK_None)
return;
- Decl *Decl = Actions.ActOnAtEnd(getCurScope(), AtLoc);
+ Decl *Decl = Actions.getObjCDeclContext();
+ if (CurParsedObjCImpl) {
+ CurParsedObjCImpl->finish(AtLoc);
+ } else {
+ Actions.ActOnAtEnd(getCurScope(), AtLoc);
+ }
Diag(AtLoc, diag::err_objc_missing_end)
<< FixItHint::CreateInsertion(AtLoc, "@end\n");
if (Decl)
Diag(Decl->getLocStart(), diag::note_objc_container_start)
<< (int) ock;
- if (!PendingObjCImpDecl.empty())
- PendingObjCImpDecl.pop_back();
- ObjCImpDecl = 0;
}
///
@@ -403,7 +404,7 @@
// Code completion within an Objective-C interface.
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(getCurScope(),
- ObjCImpDecl? Sema::PCC_ObjCImplementation
+ CurParsedObjCImpl? Sema::PCC_ObjCImplementation
: Sema::PCC_ObjCInterface);
return cutOffParsing();
}
@@ -1441,7 +1442,8 @@
///
/// objc-category-implementation-prologue:
/// @implementation identifier ( identifier )
-Decl *Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
+Parser::DeclGroupPtrTy
+Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
"ParseObjCAtImplementationDeclaration(): Expected @implementation");
CheckNestedObjCContexts(AtLoc);
@@ -1451,16 +1453,17 @@
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCImplementationDecl(getCurScope());
cutOffParsing();
- return 0;
+ return DeclGroupPtrTy();
}
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing class or category name.
- return 0;
+ return DeclGroupPtrTy();
}
// We have a class or category name - consume it.
IdentifierInfo *nameId = Tok.getIdentifierInfo();
SourceLocation nameLoc = ConsumeToken(); // consume class or category name
+ Decl *ObjCImpDecl = 0;
if (Tok.is(tok::l_paren)) {
// we have a category implementation.
@@ -1471,7 +1474,7 @@
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
cutOffParsing();
- return 0;
+ return DeclGroupPtrTy();
}
if (Tok.is(tok::identifier)) {
@@ -1479,45 +1482,59 @@
categoryLoc = ConsumeToken();
} else {
Diag(Tok, diag::err_expected_ident); // missing category name.
- return 0;
+ return DeclGroupPtrTy();
}
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
SkipUntil(tok::r_paren, false); // don't stop at ';'
- return 0;
+ return DeclGroupPtrTy();
}
rparenLoc = ConsumeParen();
- Decl *ImplCatType = Actions.ActOnStartCategoryImplementation(
+ ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
AtLoc, nameId, nameLoc, categoryId,
categoryLoc);
- ObjCImpDecl = ImplCatType;
- PendingObjCImpDecl.push_back(ObjCImpDecl);
- return 0;
- }
- // We have a class implementation
- SourceLocation superClassLoc;
- IdentifierInfo *superClassId = 0;
- if (Tok.is(tok::colon)) {
- // We have a super class
- ConsumeToken();
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing super class name.
- return 0;
+ } else {
+ // We have a class implementation
+ SourceLocation superClassLoc;
+ IdentifierInfo *superClassId = 0;
+ if (Tok.is(tok::colon)) {
+ // We have a super class
+ ConsumeToken();
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok, diag::err_expected_ident); // missing super class name.
+ return DeclGroupPtrTy();
+ }
+ superClassId = Tok.getIdentifierInfo();
+ superClassLoc = ConsumeToken(); // Consume super class name
}
- superClassId = Tok.getIdentifierInfo();
- superClassLoc = ConsumeToken(); // Consume super class name
+ ObjCImpDecl = Actions.ActOnStartClassImplementation(
+ AtLoc, nameId, nameLoc,
+ superClassId, superClassLoc);
+
+ if (Tok.is(tok::l_brace)) // we have ivars
+ ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
}
- Decl *ImplClsType = Actions.ActOnStartClassImplementation(
- AtLoc, nameId, nameLoc,
- superClassId, superClassLoc);
+ assert(ObjCImpDecl);
- if (Tok.is(tok::l_brace)) // we have ivars
- ParseObjCClassInstanceVariables(ImplClsType, tok::objc_private, AtLoc);
+ SmallVector<Decl *, 8> DeclsInGroup;
- ObjCImpDecl = ImplClsType;
- PendingObjCImpDecl.push_back(ObjCImpDecl);
- return 0;
+ {
+ ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
+ while (!ObjCImplParsing.isFinished() && Tok.isNot(tok::eof)) {
+ ParsedAttributesWithRange attrs(AttrFactory);
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
+ if (DeclGroupPtrTy DGP = ParseExternalDeclaration(attrs)) {
+ DeclGroupRef DG = DGP.get();
+ DeclsInGroup.append(DG.begin(), DG.end());
+ }
+ }
+ }
+
+ DeclsInGroup.push_back(ObjCImpDecl);
+ return Actions.BuildDeclaratorGroup(
+ DeclsInGroup.data(), DeclsInGroup.size(), false);
}
Parser::DeclGroupPtrTy
@@ -1525,51 +1542,44 @@
assert(Tok.isObjCAtKeyword(tok::objc_end) &&
"ParseObjCAtEndDeclaration(): Expected @end");
ConsumeToken(); // the "end" identifier
- SmallVector<Decl *, 8> DeclsInGroup;
- Actions.DefaultSynthesizeProperties(getCurScope(), ObjCImpDecl);
- for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) {
- Decl *D = ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i]);
- if (D)
- DeclsInGroup.push_back(D);
- }
- DeclsInGroup.push_back(ObjCImpDecl);
-
- if (ObjCImpDecl) {
- Actions.ActOnAtEnd(getCurScope(), atEnd);
- PendingObjCImpDecl.pop_back();
- }
+ if (CurParsedObjCImpl)
+ CurParsedObjCImpl->finish(atEnd);
else
// missing @implementation
Diag(atEnd.getBegin(), diag::err_expected_objc_container);
-
- clearLateParsedObjCMethods();
- ObjCImpDecl = 0;
- return Actions.BuildDeclaratorGroup(
- DeclsInGroup.data(), DeclsInGroup.size(), false);
+ return DeclGroupPtrTy();
}
-Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() {
- Actions.DiagnoseUseOfUnimplementedSelectors();
- if (PendingObjCImpDecl.empty())
- return Actions.ConvertDeclToDeclGroup(0);
+Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
+ if (!Finished) {
+ finish(P.Tok.getLocation());
+ if (P.Tok.is(tok::eof)) {
+ P.Diag(P.Tok, diag::err_objc_missing_end)
+ << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n at end\n");
+ P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
+ << Sema::OCK_Implementation;
+ }
+ }
+ P.CurParsedObjCImpl = 0;
+ assert(LateParsedObjCMethods.empty());
+}
- Decl *ImpDecl = PendingObjCImpDecl.pop_back_val();
- Actions.ActOnAtEnd(getCurScope(), SourceRange(Tok.getLocation()));
- Diag(Tok, diag::err_objc_missing_end)
- << FixItHint::CreateInsertion(Tok.getLocation(), "\n at end\n");
- if (ImpDecl)
- Diag(ImpDecl->getLocStart(), diag::note_objc_container_start)
- << Sema::OCK_Implementation;
+void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
+ assert(!Finished);
+ P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl);
+ for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
+ P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i]);
- return Actions.ConvertDeclToDeclGroup(ImpDecl);
-}
+ P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
-void Parser::clearLateParsedObjCMethods() {
+ /// \brief Clear and free the cached objc methods.
for (LateParsedObjCMethodContainer::iterator
I = LateParsedObjCMethods.begin(),
E = LateParsedObjCMethods.end(); I != E; ++I)
delete *I;
LateParsedObjCMethods.clear();
+
+ Finished = true;
}
/// compatibility-alias-decl:
@@ -1908,7 +1918,7 @@
// parse optional ';'
if (Tok.is(tok::semi)) {
- if (ObjCImpDecl) {
+ if (CurParsedObjCImpl) {
Diag(Tok, diag::warn_semicolon_before_method_body)
<< FixItHint::CreateRemoval(Tok.getLocation());
}
@@ -1926,19 +1936,32 @@
if (Tok.isNot(tok::l_brace))
return 0;
}
+
+ if (!MDecl) {
+ ConsumeBrace();
+ SkipUntil(tok::r_brace, /*StopAtSemi=*/false);
+ return 0;
+ }
+
// Allow the rest of sema to find private method decl implementations.
- if (MDecl)
- Actions.AddAnyMethodToGlobalPool(MDecl);
-
- // Consume the tokens and store them for later parsing.
- LexedMethod* LM = new LexedMethod(this, MDecl);
- LateParsedObjCMethods.push_back(LM);
- CachedTokens &Toks = LM->Toks;
- // Begin by storing the '{' token.
- Toks.push_back(Tok);
- ConsumeBrace();
- // Consume everything up to (and including) the matching right brace.
- ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+ Actions.AddAnyMethodToGlobalPool(MDecl);
+
+ if (CurParsedObjCImpl) {
+ // Consume the tokens and store them for later parsing.
+ LexedMethod* LM = new LexedMethod(this, MDecl);
+ CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
+ CachedTokens &Toks = LM->Toks;
+ // Begin by storing the '{' token.
+ Toks.push_back(Tok);
+ ConsumeBrace();
+ // Consume everything up to (and including) the matching right brace.
+ ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+
+ } else {
+ ConsumeBrace();
+ SkipUntil(tok::r_brace, /*StopAtSemi=*/false);
+ }
+
return MDecl;
}
Modified: cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseTemplate.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseTemplate.cpp Tue Feb 14 03:11:10 2012
@@ -498,9 +498,10 @@
ParsedType DefaultArg;
if (Tok.is(tok::equal)) {
EqualLoc = ConsumeToken();
- DefaultArg = ParseTypeName().get();
+ DefaultArg = ParseTypeName(/*Range=*/0,
+ Declarator::TemplateTypeArgContext).get();
}
-
+
return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, Ellipsis,
EllipsisLoc, KeyLoc, ParamName, NameLoc,
Depth, Position, EqualLoc, DefaultArg);
Modified: cfe/branches/tooling/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/Parser.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/Parser.cpp (original)
+++ cfe/branches/tooling/lib/Parse/Parser.cpp Tue Feb 14 03:11:10 2012
@@ -39,7 +39,7 @@
Actions.CurScope = 0;
NumCachedScopes = 0;
ParenCount = BracketCount = BraceCount = 0;
- ObjCImpDecl = 0;
+ CurParsedObjCImpl = 0;
// Add #pragma handlers. These are removed and destroyed in the
// destructor.
@@ -367,8 +367,6 @@
it != LateParsedTemplateMap.end(); ++it)
delete it->second;
- clearLateParsedObjCMethods();
-
// Remove the pragma handlers we installed.
PP.RemovePragmaHandler(AlignHandler.get());
AlignHandler.reset();
@@ -595,7 +593,7 @@
break;
case tok::code_completion:
Actions.CodeCompleteOrdinaryName(getCurScope(),
- ObjCImpDecl? Sema::PCC_ObjCImplementation
+ CurParsedObjCImpl? Sema::PCC_ObjCImplementation
: Sema::PCC_Namespace);
cutOffParsing();
return DeclGroupPtrTy();
Modified: cfe/branches/tooling/lib/Rewrite/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/CMakeLists.txt?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/Rewrite/CMakeLists.txt Tue Feb 14 03:11:10 2012
@@ -7,6 +7,7 @@
HTMLPrint.cpp
HTMLRewrite.cpp
RewriteMacros.cpp
+ RewriteModernObjC.cpp
RewriteObjC.cpp
RewriteRope.cpp
RewriteTest.cpp
Modified: cfe/branches/tooling/lib/Rewrite/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/FrontendActions.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/FrontendActions.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/FrontendActions.cpp Tue Feb 14 03:11:10 2012
@@ -154,10 +154,15 @@
ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
- if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp"))
+ if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) {
+ if (CI.getLangOpts().ObjCNonFragileABI)
+ return CreateModernObjCRewriter(InFile, OS,
+ CI.getDiagnostics(), CI.getLangOpts(),
+ CI.getDiagnosticOpts().NoRewriteMacros);
return CreateObjCRewriter(InFile, OS,
CI.getDiagnostics(), CI.getLangOpts(),
CI.getDiagnosticOpts().NoRewriteMacros);
+ }
return 0;
}
Modified: cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp Tue Feb 14 03:11:10 2012
@@ -17,7 +17,6 @@
#include "clang/Rewrite/HTMLRewrite.h"
#include "clang/Lex/TokenConcatenation.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/OwningPtr.h"
Modified: cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp Tue Feb 14 03:11:10 2012
@@ -590,12 +590,7 @@
DiagnosticsEngine &Diags,
const LangOptions &LOpts,
bool SilenceRewriteMacroWarning) {
- if (true /*!LOpts.ObjCNonFragileABI*/)
- return new RewriteObjCFragileABI(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
- else {
- assert(false && "objective-C rewriter for nonfragile ABI = NYI");
- return 0;
- }
+ return new RewriteObjCFragileABI(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
}
void RewriteObjC::InitializeCommon(ASTContext &context) {
@@ -4927,6 +4922,9 @@
// definitions using the same code.
RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+ if (!FD->isThisDeclarationADefinition())
+ break;
+
// FIXME: If this should support Obj-C++, support CXXTryStmt
if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
CurFunctionDef = FD;
Modified: cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp Tue Feb 14 03:11:10 2012
@@ -16,7 +16,6 @@
#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/ScopeInfo.h"
-#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Preprocessor.h"
Modified: cfe/branches/tooling/lib/Sema/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/CMakeLists.txt?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/Sema/CMakeLists.txt Tue Feb 14 03:11:10 2012
@@ -8,7 +8,6 @@
DelayedDiagnostic.cpp
IdentifierResolver.cpp
JumpDiagnostics.cpp
- MultiInitializer.cpp
Scope.cpp
Sema.cpp
SemaAccess.cpp
@@ -29,6 +28,7 @@
SemaExprObjC.cpp
SemaFixItUtils.cpp
SemaInit.cpp
+ SemaLambda.cpp
SemaLookup.cpp
SemaObjCProperty.cpp
SemaOverload.cpp
Removed: cfe/branches/tooling/lib/Sema/MultiInitializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/MultiInitializer.cpp?rev=150464&view=auto
==============================================================================
--- cfe/branches/tooling/lib/Sema/MultiInitializer.cpp (original)
+++ cfe/branches/tooling/lib/Sema/MultiInitializer.cpp (removed)
@@ -1,93 +0,0 @@
-//===--- MultiInitializer.cpp - Initializer expression group ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MultiInitializer class, which can represent a list
-// initializer or a parentheses-wrapped group of expressions in a C++ member
-// initializer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Sema/MultiInitializer.h"
-#include "clang/Sema/Initialization.h"
-#include "clang/Sema/Sema.h"
-#include "clang/AST/Expr.h"
-
-using namespace clang;
-
-InitListExpr *MultiInitializer::getInitList() const {
- return cast<InitListExpr>(InitListOrExpressions.get<Expr*>());
-}
-
-SourceLocation MultiInitializer::getStartLoc() const {
- return isInitializerList() ? getInitList()->getLBraceLoc() : LParenLoc;
-}
-
-SourceLocation MultiInitializer::getEndLoc() const {
- return isInitializerList() ? getInitList()->getRBraceLoc() : RParenLoc;
-}
-
-MultiInitializer::iterator MultiInitializer::begin() const {
- return isInitializerList() ? getInitList()->getInits() : getExpressions();
-}
-
-MultiInitializer::iterator MultiInitializer::end() const {
- if (isInitializerList()) {
- InitListExpr *ILE = getInitList();
- return ILE->getInits() + ILE->getNumInits();
- }
- return getExpressions() + NumInitializers;
-}
-
-bool MultiInitializer::isTypeDependent() const {
- if (isInitializerList())
- return getInitList()->isTypeDependent();
- for (iterator I = begin(), E = end(); I != E; ++I) {
- if ((*I)->isTypeDependent())
- return true;
- }
- return false;
-}
-
-bool MultiInitializer::DiagnoseUnexpandedParameterPack(Sema &SemaRef) const {
- if (isInitializerList())
- return SemaRef.DiagnoseUnexpandedParameterPack(getInitList(),
- Sema::UPPC_Initializer);
- for (iterator I = begin(), E = end(); I != E; ++I) {
- if (SemaRef.DiagnoseUnexpandedParameterPack(*I, Sema::UPPC_Initializer))
- return true;
- }
- return false;
-}
-
-Expr *MultiInitializer::CreateInitExpr(ASTContext &Ctx, QualType T) const {
- if (isInitializerList())
- return InitListOrExpressions.get<Expr*>();
-
- return new (Ctx) ParenListExpr(Ctx, LParenLoc, getExpressions(),
- NumInitializers, RParenLoc, T);
-}
-
-ExprResult MultiInitializer::PerformInit(Sema &SemaRef,
- InitializedEntity Entity,
- InitializationKind Kind) const {
- Expr *Single;
- Expr **Args;
- unsigned NumArgs;
- if (isInitializerList()) {
- Single = InitListOrExpressions.get<Expr*>();
- Args = &Single;
- NumArgs = 1;
- } else {
- Args = getExpressions();
- NumArgs = NumInitializers;
- }
- InitializationSequence InitSeq(SemaRef, Entity, Kind, Args, NumArgs);
- return InitSeq.Perform(SemaRef, Entity, Kind,
- MultiExprArg(SemaRef, Args, NumArgs), 0);
-}
Modified: cfe/branches/tooling/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/Sema.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/Sema.cpp (original)
+++ cfe/branches/tooling/lib/Sema/Sema.cpp Tue Feb 14 03:11:10 2012
@@ -418,6 +418,8 @@
// Only complete translation units define vtables and perform implicit
// instantiations.
if (TUKind == TU_Complete) {
+ DiagnoseUseOfUnimplementedSelectors();
+
// If any dynamic classes have their key function defined within
// this translation unit, then those vtables are considered "used" and must
// be emitted.
@@ -633,6 +635,7 @@
if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) {
DC = DC->getParent();
} else if (isa<CXXMethodDecl>(DC) &&
+ cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
cast<CXXRecordDecl>(DC->getParent())->isLambda()) {
DC = DC->getParent()->getParent();
}
@@ -829,8 +832,10 @@
BlockScope, Block));
}
-void Sema::PushLambdaScope(CXXRecordDecl *Lambda) {
- FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda));
+void Sema::PushLambdaScope(CXXRecordDecl *Lambda,
+ CXXMethodDecl *CallOperator) {
+ FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda,
+ CallOperator));
}
void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
Modified: cfe/branches/tooling/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCast.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCast.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCast.cpp Tue Feb 14 03:11:10 2012
@@ -77,7 +77,7 @@
void CheckReinterpretCast();
void CheckStaticCast();
void CheckDynamicCast();
- void CheckCXXCStyleCast(bool FunctionalCast);
+ void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);
void CheckCStyleCast();
/// Complete an apparently-successful cast operation that yields
@@ -190,15 +190,15 @@
QualType DestType,
Sema::CheckedConversionKind CCK,
const SourceRange &OpRange,
- unsigned &msg,
- CastKind &Kind);
+ unsigned &msg, CastKind &Kind,
+ bool ListInitialization);
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType,
Sema::CheckedConversionKind CCK,
const SourceRange &OpRange,
- unsigned &msg,
- CastKind &Kind,
- CXXCastPath &BasePath);
+ unsigned &msg, CastKind &Kind,
+ CXXCastPath &BasePath,
+ bool ListInitialization);
static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
bool CStyle, unsigned &msg);
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
@@ -301,7 +301,8 @@
/// diagnostics were emitted.
static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
SourceRange range, Expr *src,
- QualType destType) {
+ QualType destType,
+ bool listInitialization) {
switch (CT) {
// These cast kinds don't consider user-defined conversions.
case CT_Const:
@@ -323,8 +324,9 @@
InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);
InitializationKind initKind
= (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
- range)
- : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range)
+ range, listInitialization)
+ : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range,
+ listInitialization)
: InitializationKind::CreateCast(/*type range?*/ range);
InitializationSequence sequence(S, entity, initKind, &src, 1);
@@ -374,14 +376,16 @@
/// Diagnose a failed cast.
static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType,
- SourceRange opRange, Expr *src, QualType destType) {
+ SourceRange opRange, Expr *src, QualType destType,
+ bool listInitialization) {
if (src->getType() == S.Context.BoundMemberTy) {
(void) S.CheckPlaceholderExpr(src); // will always fail
return;
}
if (msg == diag::err_bad_cxx_cast_generic &&
- tryDiagnoseOverloadedCast(S, castType, opRange, src, destType))
+ tryDiagnoseOverloadedCast(S, castType, opRange, src, destType,
+ listInitialization))
return;
S.Diag(opRange.getBegin(), msg) << castType
@@ -703,7 +707,8 @@
Self.NoteAllOverloadCandidates(SrcExpr.get());
} else {
- diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType);
+ diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(),
+ DestType, /*listInitialization=*/false);
}
} else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) {
checkObjCARCConversion(Sema::CCK_OtherCast);
@@ -750,7 +755,7 @@
unsigned msg = diag::err_bad_cxx_cast_generic;
TryCastResult tcr
= TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg,
- Kind, BasePath);
+ Kind, BasePath, /*ListInitialization=*/false);
if (tcr != TC_Success && msg != 0) {
if (SrcExpr.isInvalid())
return;
@@ -761,7 +766,8 @@
<< oe->getQualifierLoc().getSourceRange();
Self.NoteAllOverloadCandidates(SrcExpr.get());
} else {
- diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType);
+ diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType,
+ /*listInitialization=*/false);
}
} else if (tcr == TC_Success) {
if (Kind == CK_BitCast)
@@ -780,8 +786,8 @@
QualType DestType,
Sema::CheckedConversionKind CCK,
const SourceRange &OpRange, unsigned &msg,
- CastKind &Kind,
- CXXCastPath &BasePath) {
+ CastKind &Kind, CXXCastPath &BasePath,
+ bool ListInitialization) {
// Determine whether we have the semantics of a C-style cast.
bool CStyle
= (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
@@ -806,23 +812,23 @@
// C++ 5.2.9p5, reference downcast.
// See the function for details.
// DR 427 specifies that this is to be applied before paragraph 2.
- tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle, OpRange,
- msg, Kind, BasePath);
+ tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle,
+ OpRange, msg, Kind, BasePath);
if (tcr != TC_NotApplicable)
return tcr;
// C++0x [expr.static.cast]p3:
// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2
// T2" if "cv2 T2" is reference-compatible with "cv1 T1".
- tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, BasePath,
- msg);
+ tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind,
+ BasePath, msg);
if (tcr != TC_NotApplicable)
return tcr;
// C++ 5.2.9p2: An expression e can be explicitly converted to a type T
// [...] if the declaration "T t(e);" is well-formed, [...].
tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg,
- Kind);
+ Kind, ListInitialization);
if (SrcExpr.isInvalid())
return TC_Failed;
if (tcr != TC_NotApplicable)
@@ -1293,7 +1299,7 @@
TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
Sema::CheckedConversionKind CCK,
const SourceRange &OpRange, unsigned &msg,
- CastKind &Kind) {
+ CastKind &Kind, bool ListInitialization) {
if (DestType->isRecordType()) {
if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
diag::err_bad_dynamic_cast_incomplete)) {
@@ -1301,13 +1307,14 @@
return TC_Failed;
}
}
-
+
InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
InitializationKind InitKind
= (CCK == Sema::CCK_CStyleCast)
- ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange)
+ ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
+ ListInitialization)
: (CCK == Sema::CCK_FunctionalCast)
- ? InitializationKind::CreateFunctionalCast(OpRange)
+ ? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization)
: InitializationKind::CreateCast(OpRange);
Expr *SrcExprRaw = SrcExpr.get();
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
@@ -1751,7 +1758,8 @@
return TC_Success;
}
-void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) {
+void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
+ bool ListInitialization) {
// Handle placeholders.
if (isPlaceholder()) {
// C-style casts can resolve __unknown_any types.
@@ -1834,7 +1842,7 @@
if (tcr == TC_NotApplicable) {
// ... or if that is not possible, a static_cast, ignoring const, ...
tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange,
- msg, Kind, BasePath);
+ msg, Kind, BasePath, ListInitialization);
if (SrcExpr.isInvalid())
return;
@@ -1863,7 +1871,7 @@
} else {
diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),
- OpRange, SrcExpr.get(), DestType);
+ OpRange, SrcExpr.get(), DestType, ListInitialization);
}
} else if (Kind == CK_BitCast) {
checkCastAlign();
@@ -2068,7 +2076,8 @@
Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd());
if (getLangOptions().CPlusPlus) {
- Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false);
+ Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false,
+ isa<InitListExpr>(CastExpr));
} else {
Op.CheckCStyleCast();
}
@@ -2085,11 +2094,12 @@
SourceLocation LPLoc,
Expr *CastExpr,
SourceLocation RPLoc) {
+ assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);
Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
- Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ true);
+ Op.CheckCXXCStyleCast(/*FunctionalStyle=*/true, /*ListInit=*/false);
if (Op.SrcExpr.isInvalid())
return ExprError();
Modified: cfe/branches/tooling/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaChecking.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaChecking.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaChecking.cpp Tue Feb 14 03:11:10 2012
@@ -1369,6 +1369,13 @@
E = E->IgnoreParenCasts();
+ if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
+ // Technically -Wformat-nonliteral does not warn about this case.
+ // The behavior of printf and friends in this case is implementation
+ // dependent. Ideally if the format string cannot be null then
+ // it should have a 'nonnull' attribute in the function prototype.
+ return true;
+
switch (E->getStmtClass()) {
case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass: {
@@ -1381,13 +1388,6 @@
inFunctionCall);
}
- case Stmt::IntegerLiteralClass:
- // Technically -Wformat-nonliteral does not warn about this case.
- // The behavior of printf and friends in this case is implementation
- // dependent. Ideally if the format string cannot be null then
- // it should have a 'nonnull' attribute in the function prototype.
- return true;
-
case Stmt::ImplicitCastExprClass: {
E = cast<ImplicitCastExpr>(E)->getSubExpr();
goto tryAgain;
@@ -1459,21 +1459,20 @@
return false;
}
- case Stmt::CallExprClass: {
+ case Stmt::CallExprClass:
+ case Stmt::CXXMemberCallExprClass: {
const CallExpr *CE = cast<CallExpr>(E);
- if (const ImplicitCastExpr *ICE
- = dyn_cast<ImplicitCastExpr>(CE->getCallee())) {
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) {
- unsigned ArgIndex = FA->getFormatIdx();
- const Expr *Arg = CE->getArg(ArgIndex - 1);
-
- return SemaCheckStringLiteral(Arg, Args, NumArgs, HasVAListArg,
- format_idx, firstDataArg, Type,
- inFunctionCall);
- }
- }
+ if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {
+ if (const FormatArgAttr *FA = ND->getAttr<FormatArgAttr>()) {
+ unsigned ArgIndex = FA->getFormatIdx();
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
+ if (MD->isInstance())
+ --ArgIndex;
+ const Expr *Arg = CE->getArg(ArgIndex - 1);
+
+ return SemaCheckStringLiteral(Arg, Args, NumArgs, HasVAListArg,
+ format_idx, firstDataArg, Type,
+ inFunctionCall);
}
}
@@ -1534,11 +1533,7 @@
// The way the format attribute works in GCC, the implicit this argument
// of member functions is counted. However, it doesn't appear in our own
// lists, so decrement format_idx in that case.
- if (isa<CXXMemberCallExpr>(TheCall)) {
- const CXXMethodDecl *method_decl =
- dyn_cast<CXXMethodDecl>(TheCall->getCalleeDecl());
- IsCXXMember = method_decl && method_decl->isInstance();
- }
+ IsCXXMember = isa<CXXMemberCallExpr>(TheCall);
CheckFormatArguments(Format, TheCall->getArgs(), TheCall->getNumArgs(),
IsCXXMember, TheCall->getRParenLoc(),
TheCall->getCallee()->getSourceRange());
@@ -1589,6 +1584,11 @@
format_idx, firstDataArg, Type))
return; // Literal format string found, check done!
+ // Strftime is particular as it always uses a single 'time' argument,
+ // so it is safe to pass a non-literal string.
+ if (Type == FST_Strftime)
+ return;
+
// Do not emit diag when the string param is a macro expansion and the
// format is either NSString or CFString. This is a hack to prevent
// diag when using the NSLocalizedString and CFCopyLocalizedString macros
@@ -4185,7 +4185,10 @@
BinaryOperator *BO = dyn_cast<BinaryOperator>(E);
bool IsLogicalOperator = BO && BO->isLogicalOp();
for (Stmt::child_range I = E->children(); I; ++I) {
- Expr *ChildExpr = cast<Expr>(*I);
+ Expr *ChildExpr = dyn_cast_or_null<Expr>(*I);
+ if (!ChildExpr)
+ continue;
+
if (IsLogicalOperator &&
isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts()))
// Ignore checking string literals that are in logical operators.
Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Tue Feb 14 03:11:10 2012
@@ -2139,9 +2139,8 @@
/// emitting diagnostics as appropriate.
///
/// Declarations using the auto type specifier (C++ [decl.spec.auto]) call back
-/// to here in AddInitializerToDecl and AddCXXDirectInitializerToDecl. We can't
-/// check them before the initializer is attached.
-///
+/// to here in AddInitializerToDecl. We can't check them before the initializer
+/// is attached.
void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old) {
if (New->isInvalidDecl() || Old->isInvalidDecl())
return;
@@ -4341,20 +4340,9 @@
return false;
}
- // Function pointers and references cannot have qualified function type, only
- // function pointer-to-members can do that.
- QualType Pointee;
- unsigned PtrOrRef = 0;
- if (const PointerType *Ptr = T->getAs<PointerType>())
- Pointee = Ptr->getPointeeType();
- else if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
- Pointee = Ref->getPointeeType();
- PtrOrRef = 1;
- }
- if (!Pointee.isNull() && Pointee->isFunctionProtoType() &&
- Pointee->getAs<FunctionProtoType>()->getTypeQuals() != 0) {
- Diag(NewVD->getLocation(), diag::err_invalid_qualified_function_pointer)
- << PtrOrRef;
+ if (NewVD->isConstexpr() && !T->isDependentType() &&
+ RequireLiteralType(NewVD->getLocation(), T,
+ PDiag(diag::err_constexpr_var_non_literal))) {
NewVD->setInvalidDecl();
return false;
}
@@ -5366,10 +5354,6 @@
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
"previous declaration set still overloaded");
- if (NewFD->isConstexpr() && !NewFD->isInvalidDecl() &&
- !CheckConstexprFunctionDecl(NewFD, CCK_Declaration))
- NewFD->setInvalidDecl();
-
NamedDecl *PrincipalDecl = (FunctionTemplate
? cast<NamedDecl>(FunctionTemplate)
: NewFD);
@@ -5774,6 +5758,17 @@
Context.BuiltinInfo.ForgetBuiltin(BuiltinID, Context.Idents);
}
}
+
+ // If this function is declared as being extern "C", then check to see if
+ // the function returns a UDT (class, struct, or union type) that is not C
+ // compatible, and if it does, warn the user.
+ if (NewFD->isExternC()) {
+ QualType R = NewFD->getResultType();
+ if (!R.isPODType(Context) &&
+ !R->isVoidType())
+ Diag( NewFD->getLocation(), diag::warn_return_value_udt )
+ << NewFD << R;
+ }
}
return Redeclaration;
}
@@ -5990,17 +5985,6 @@
if (RealDecl == 0 || RealDecl->isInvalidDecl())
return;
- // Check for self-references within variable initializers.
- if (VarDecl *vd = dyn_cast<VarDecl>(RealDecl)) {
- // Variables declared within a function/method body are handled
- // by a dataflow analysis.
- if (!vd->hasLocalStorage() && !vd->isStaticLocal())
- CheckSelfReference(RealDecl, Init);
- }
- else {
- CheckSelfReference(RealDecl, Init);
- }
-
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
// With declarators parsed the way they are, the parser cannot
// distinguish between a normal initializer and a pure-specifier.
@@ -6025,12 +6009,44 @@
return;
}
+ // Check for self-references within variable initializers.
+ // Variables declared within a function/method body are handled
+ // by a dataflow analysis.
+ if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal())
+ CheckSelfReference(RealDecl, Init);
+
+ ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
+
// C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
+ Expr *DeduceInit = Init;
+ // Initializer could be a C++ direct-initializer. Deduction only works if it
+ // contains exactly one expression.
+ if (CXXDirectInit) {
+ if (CXXDirectInit->getNumExprs() == 0) {
+ // It isn't possible to write this directly, but it is possible to
+ // end up in this situation with "auto x(some_pack...);"
+ Diag(CXXDirectInit->getSourceRange().getBegin(),
+ diag::err_auto_var_init_no_expression)
+ << VDecl->getDeclName() << VDecl->getType()
+ << VDecl->getSourceRange();
+ RealDecl->setInvalidDecl();
+ return;
+ } else if (CXXDirectInit->getNumExprs() > 1) {
+ Diag(CXXDirectInit->getExpr(1)->getSourceRange().getBegin(),
+ diag::err_auto_var_init_multiple_expressions)
+ << VDecl->getDeclName() << VDecl->getType()
+ << VDecl->getSourceRange();
+ RealDecl->setInvalidDecl();
+ return;
+ } else {
+ DeduceInit = CXXDirectInit->getExpr(0);
+ }
+ }
TypeSourceInfo *DeducedType = 0;
- if (DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType) ==
+ if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) ==
DAR_Failed)
- DiagnoseAutoDeductionFailure(VDecl, Init);
+ DiagnoseAutoDeductionFailure(VDecl, DeduceInit);
if (!DeducedType) {
RealDecl->setInvalidDecl();
return;
@@ -6055,25 +6071,26 @@
return;
}
+ if (!VDecl->getType()->isDependentType()) {
+ // A definition must end up with a complete type, which means it must be
+ // complete with the restriction that an array type might be completed by
+ // the initializer; note that later code assumes this restriction.
+ QualType BaseDeclType = VDecl->getType();
+ if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType))
+ BaseDeclType = Array->getElementType();
+ if (RequireCompleteType(VDecl->getLocation(), BaseDeclType,
+ diag::err_typecheck_decl_incomplete_type)) {
+ RealDecl->setInvalidDecl();
+ return;
+ }
- // A definition must end up with a complete type, which means it must be
- // complete with the restriction that an array type might be completed by the
- // initializer; note that later code assumes this restriction.
- QualType BaseDeclType = VDecl->getType();
- if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType))
- BaseDeclType = Array->getElementType();
- if (RequireCompleteType(VDecl->getLocation(), BaseDeclType,
- diag::err_typecheck_decl_incomplete_type)) {
- RealDecl->setInvalidDecl();
- return;
+ // The variable can not have an abstract class type.
+ if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
+ diag::err_abstract_type_in_decl,
+ AbstractVariableType))
+ VDecl->setInvalidDecl();
}
- // The variable can not have an abstract class type.
- if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
- diag::err_abstract_type_in_decl,
- AbstractVariableType))
- VDecl->setInvalidDecl();
-
const VarDecl *Def;
if ((Def = VDecl->getDefinition()) && Def != VDecl) {
Diag(VDecl->getLocation(), diag::err_redefinition)
@@ -6129,15 +6146,24 @@
if (!VDecl->isInvalidDecl()) {
InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
InitializationKind Kind
- = DirectInit ? InitializationKind::CreateDirect(VDecl->getLocation(),
- Init->getLocStart(),
- Init->getLocEnd())
+ = DirectInit ?
+ CXXDirectInit ? InitializationKind::CreateDirect(VDecl->getLocation(),
+ Init->getLocStart(),
+ Init->getLocEnd())
+ : InitializationKind::CreateDirectList(
+ VDecl->getLocation())
: InitializationKind::CreateCopy(VDecl->getLocation(),
Init->getLocStart());
- InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+ Expr **Args = &Init;
+ unsigned NumArgs = 1;
+ if (CXXDirectInit) {
+ Args = CXXDirectInit->getExprs();
+ NumArgs = CXXDirectInit->getNumExprs();
+ }
+ InitializationSequence InitSeq(*this, Entity, Kind, Args, NumArgs);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, &Init, 1),
+ MultiExprArg(*this, Args,NumArgs),
&DclT);
if (Result.isInvalid()) {
VDecl->setInvalidDecl();
@@ -6200,8 +6226,8 @@
if (DclT->isDependentType()) {
// Allow any 'static constexpr' members, whether or not they are of literal
- // type. We separately check that the initializer is a constant expression,
- // which implicitly requires the member to be of literal type.
+ // type. We separately check that every constexpr variable is of literal
+ // type.
} else if (VDecl->isConstexpr()) {
// Require constness.
@@ -6273,6 +6299,28 @@
CheckForConstantInitializer(Init, DclT);
}
+ // We will represent direct-initialization similarly to copy-initialization:
+ // int x(1); -as-> int x = 1;
+ // ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
+ //
+ // Clients that want to distinguish between the two forms, can check for
+ // direct initializer using VarDecl::getInitStyle().
+ // A major benefit is that clients that don't particularly care about which
+ // exactly form was it (like the CodeGen) can handle both cases without
+ // special case code.
+
+ // C++ 8.5p11:
+ // The form of initialization (using parentheses or '=') is generally
+ // insignificant, but does matter when the entity being initialized has a
+ // class type.
+ if (CXXDirectInit) {
+ assert(DirectInit && "Call-style initializer must be direct init.");
+ VDecl->setInitStyle(VarDecl::CallInit);
+ } else if (DirectInit) {
+ // This must be list-initialization. No other way is direct-initialization.
+ VDecl->setInitStyle(VarDecl::ListInit);
+ }
+
CheckCompleteVariableDeclaration(VDecl);
}
@@ -6503,8 +6551,11 @@
MultiExprArg(*this, 0, 0));
if (Init.isInvalid())
Var->setInvalidDecl();
- else if (Init.get())
+ else if (Init.get()) {
Var->setInit(MaybeCreateExprWithCleanups(Init.get()));
+ // This is important for template substitution.
+ Var->setInitStyle(VarDecl::CallInit);
+ }
CheckCompleteVariableDeclaration(Var);
}
@@ -7236,7 +7287,8 @@
computeNRVO(Body, getCurFunction());
}
- assert(FD == getCurFunctionDecl() && "Function parsing confused");
+ assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
+ "Function parsing confused");
} else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
assert(MD == getCurMethodDecl() && "Method parsing confused");
MD->setBody(Body);
@@ -7301,8 +7353,9 @@
ActivePolicy = &WP;
}
- if (FD && FD->isConstexpr() && !FD->isInvalidDecl() &&
- !CheckConstexprFunctionBody(FD, Body, IsInstantiation))
+ if (!IsInstantiation && FD && FD->isConstexpr() && !FD->isInvalidDecl() &&
+ (!CheckConstexprFunctionDecl(FD) ||
+ !CheckConstexprFunctionBody(FD, Body)))
FD->setInvalidDecl();
assert(ExprCleanupObjects.empty() && "Leftover temporaries in function");
Modified: cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp Tue Feb 14 03:11:10 2012
@@ -16,6 +16,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ScopeInfo.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
@@ -61,6 +62,7 @@
bool VisitExpr(Expr *Node);
bool VisitDeclRefExpr(DeclRefExpr *DRE);
bool VisitCXXThisExpr(CXXThisExpr *ThisE);
+ bool VisitLambdaExpr(LambdaExpr *Lambda);
};
/// VisitExpr - Visit all of the children of this expression.
@@ -110,6 +112,17 @@
diag::err_param_default_argument_references_this)
<< ThisE->getSourceRange();
}
+
+ bool CheckDefaultArgumentVisitor::VisitLambdaExpr(LambdaExpr *Lambda) {
+ // C++11 [expr.lambda.prim]p13:
+ // A lambda-expression appearing in a default argument shall not
+ // implicitly or explicitly capture any entity.
+ if (Lambda->capture_begin() == Lambda->capture_end())
+ return false;
+
+ return S->Diag(Lambda->getLocStart(),
+ diag::err_lambda_capture_default_arg);
+ }
}
void Sema::ImplicitExceptionSpecification::CalledDecl(CXXMethodDecl *Method) {
@@ -619,9 +632,9 @@
// CheckConstexprParameterTypes - Check whether a function's parameter types
// are all literal types. If so, return true. If not, produce a suitable
-// diagnostic depending on @p CCK and return false.
-static bool CheckConstexprParameterTypes(Sema &SemaRef, const FunctionDecl *FD,
- Sema::CheckConstexprKind CCK) {
+// diagnostic and return false.
+static bool CheckConstexprParameterTypes(Sema &SemaRef,
+ const FunctionDecl *FD) {
unsigned ArgIndex = 0;
const FunctionProtoType *FT = FD->getType()->getAs<FunctionProtoType>();
for (FunctionProtoType::arg_type_iterator i = FT->arg_type_begin(),
@@ -629,63 +642,37 @@
const ParmVarDecl *PD = FD->getParamDecl(ArgIndex);
SourceLocation ParamLoc = PD->getLocation();
if (!(*i)->isDependentType() &&
- SemaRef.RequireLiteralType(ParamLoc, *i, CCK == Sema::CCK_Declaration ?
+ SemaRef.RequireLiteralType(ParamLoc, *i,
SemaRef.PDiag(diag::err_constexpr_non_literal_param)
<< ArgIndex+1 << PD->getSourceRange()
- << isa<CXXConstructorDecl>(FD) :
- SemaRef.PDiag(),
- /*AllowIncompleteType*/ true)) {
- if (CCK == Sema::CCK_NoteNonConstexprInstantiation)
- SemaRef.Diag(ParamLoc, diag::note_constexpr_tmpl_non_literal_param)
- << ArgIndex+1 << PD->getSourceRange()
- << isa<CXXConstructorDecl>(FD) << *i;
+ << isa<CXXConstructorDecl>(FD)))
return false;
- }
}
return true;
}
// CheckConstexprFunctionDecl - Check whether a function declaration satisfies
-// the requirements of a constexpr function declaration or a constexpr
-// constructor declaration. Return true if it does, false if not.
-//
-// This implements C++11 [dcl.constexpr]p3,4, as amended by N3308.
+// the requirements of a constexpr function definition or a constexpr
+// constructor definition. If so, return true. If not, produce appropriate
+// diagnostics and return false.
//
-// \param CCK Specifies whether to produce diagnostics if the function does not
-// satisfy the requirements.
-bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD,
- CheckConstexprKind CCK) {
- assert((CCK != CCK_NoteNonConstexprInstantiation ||
- (NewFD->getTemplateInstantiationPattern() &&
- NewFD->getTemplateInstantiationPattern()->isConstexpr())) &&
- "only constexpr templates can be instantiated non-constexpr");
-
+// This implements C++11 [dcl.constexpr]p3,4, as amended by DR1360.
+bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) {
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
if (MD && MD->isInstance()) {
- // C++11 [dcl.constexpr]p4: In the definition of a constexpr constructor...
- // In addition, either its function-body shall be = delete or = default or
- // it shall satisfy the following constraints:
+ // C++11 [dcl.constexpr]p4:
+ // The definition of a constexpr constructor shall satisfy the following
+ // constraints:
// - the class shall not have any virtual base classes;
- //
- // We apply this to constexpr member functions too: the class cannot be a
- // literal type, so the members are not permitted to be constexpr.
const CXXRecordDecl *RD = MD->getParent();
if (RD->getNumVBases()) {
- // Note, this is still illegal if the body is = default, since the
- // implicit body does not satisfy the requirements of a constexpr
- // constructor. We also reject cases where the body is = delete, as
- // required by N3308.
- if (CCK != CCK_Instantiation) {
- Diag(NewFD->getLocation(),
- CCK == CCK_Declaration ? diag::err_constexpr_virtual_base
- : diag::note_constexpr_tmpl_virtual_base)
- << isa<CXXConstructorDecl>(NewFD) << RD->isStruct()
- << RD->getNumVBases();
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I)
- Diag(I->getSourceRange().getBegin(),
- diag::note_constexpr_virtual_base_here) << I->getSourceRange();
- }
+ Diag(NewFD->getLocation(), diag::err_constexpr_virtual_base)
+ << isa<CXXConstructorDecl>(NewFD) << RD->isStruct()
+ << RD->getNumVBases();
+ for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+ E = RD->vbases_end(); I != E; ++I)
+ Diag(I->getSourceRange().getBegin(),
+ diag::note_constexpr_virtual_base_here) << I->getSourceRange();
return false;
}
}
@@ -697,39 +684,29 @@
// - it shall not be virtual;
const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD);
if (Method && Method->isVirtual()) {
- if (CCK != CCK_Instantiation) {
- Diag(NewFD->getLocation(),
- CCK == CCK_Declaration ? diag::err_constexpr_virtual
- : diag::note_constexpr_tmpl_virtual);
-
- // If it's not obvious why this function is virtual, find an overridden
- // function which uses the 'virtual' keyword.
- const CXXMethodDecl *WrittenVirtual = Method;
- while (!WrittenVirtual->isVirtualAsWritten())
- WrittenVirtual = *WrittenVirtual->begin_overridden_methods();
- if (WrittenVirtual != Method)
- Diag(WrittenVirtual->getLocation(),
- diag::note_overridden_virtual_function);
- }
+ Diag(NewFD->getLocation(), diag::err_constexpr_virtual);
+
+ // If it's not obvious why this function is virtual, find an overridden
+ // function which uses the 'virtual' keyword.
+ const CXXMethodDecl *WrittenVirtual = Method;
+ while (!WrittenVirtual->isVirtualAsWritten())
+ WrittenVirtual = *WrittenVirtual->begin_overridden_methods();
+ if (WrittenVirtual != Method)
+ Diag(WrittenVirtual->getLocation(),
+ diag::note_overridden_virtual_function);
return false;
}
// - its return type shall be a literal type;
QualType RT = NewFD->getResultType();
if (!RT->isDependentType() &&
- RequireLiteralType(NewFD->getLocation(), RT, CCK == CCK_Declaration ?
- PDiag(diag::err_constexpr_non_literal_return) :
- PDiag(),
- /*AllowIncompleteType*/ true)) {
- if (CCK == CCK_NoteNonConstexprInstantiation)
- Diag(NewFD->getLocation(),
- diag::note_constexpr_tmpl_non_literal_return) << RT;
+ RequireLiteralType(NewFD->getLocation(), RT,
+ PDiag(diag::err_constexpr_non_literal_return)))
return false;
- }
}
// - each of its parameter types shall be a literal type;
- if (!CheckConstexprParameterTypes(*this, NewFD, CCK))
+ if (!CheckConstexprParameterTypes(*this, NewFD))
return false;
return true;
@@ -815,7 +792,11 @@
bool &Diagnosed) {
if (Field->isUnnamedBitfield())
return;
-
+
+ if (Field->isAnonymousStructOrUnion() &&
+ Field->getType()->getAsCXXRecordDecl()->isEmpty())
+ return;
+
if (!Inits.count(Field)) {
if (!Diagnosed) {
SemaRef.Diag(Dcl->getLocation(), diag::err_constexpr_ctor_missing_init);
@@ -837,8 +818,7 @@
/// the permitted types of statement. C++11 [dcl.constexpr]p3,p4.
///
/// \return true if the body is OK, false if we have diagnosed a problem.
-bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body,
- bool IsInstantiation) {
+bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
if (isa<CXXTryStmt>(Body)) {
// C++11 [dcl.constexpr]p3:
// The definition of a constexpr function shall satisfy the following
@@ -901,11 +881,14 @@
if (const CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(Dcl)) {
const CXXRecordDecl *RD = Constructor->getParent();
- // - every non-static data member and base class sub-object shall be
- // initialized;
+ // DR1359:
+ // - every non-variant non-static data member and base class sub-object
+ // shall be initialized;
+ // - if the class is a non-empty union, or for each non-empty anonymous
+ // union member of a non-union class, exactly one non-static data member
+ // shall be initialized;
if (RD->isUnion()) {
- // DR1359: Exactly one member of a union shall be initialized.
- if (Constructor->getNumCtorInitializers() == 0) {
+ if (Constructor->getNumCtorInitializers() == 0 && !RD->isEmpty()) {
Diag(Dcl->getLocation(), diag::err_constexpr_union_ctor_no_init);
return false;
}
@@ -984,13 +967,8 @@
// C++11 [dcl.constexpr]p4:
// - every constructor involved in initializing non-static data members and
// base class sub-objects shall be a constexpr constructor.
- //
- // FIXME: We currently disable this check inside system headers, to work
- // around early STL implementations which contain constexpr functions which
- // can't produce constant expressions.
llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
- if (!Context.getSourceManager().isInSystemHeader(Dcl->getLocation()) &&
- !IsInstantiation && !Expr::isPotentialConstantExpr(Dcl, Diags)) {
+ if (!Expr::isPotentialConstantExpr(Dcl, Diags)) {
Diag(Dcl->getLocation(), diag::err_constexpr_function_never_constant_expr)
<< isa<CXXConstructorDecl>(Dcl);
for (size_t I = 0, N = Diags.size(); I != N; ++I)
@@ -1753,7 +1731,7 @@
Expr *InitList,
SourceLocation EllipsisLoc) {
return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy,
- DS, IdLoc, MultiInitializer(InitList),
+ DS, IdLoc, InitList,
EllipsisLoc);
}
@@ -1770,10 +1748,10 @@
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc,
SourceLocation EllipsisLoc) {
+ Expr *List = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+ RParenLoc);
return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy,
- DS, IdLoc, MultiInitializer(LParenLoc, Args,
- NumArgs, RParenLoc),
- EllipsisLoc);
+ DS, IdLoc, List, EllipsisLoc);
}
namespace {
@@ -1810,7 +1788,7 @@
ParsedType TemplateTypeTy,
const DeclSpec &DS,
SourceLocation IdLoc,
- const MultiInitializer &Args,
+ Expr *Init,
SourceLocation EllipsisLoc) {
if (!ConstructorD)
return true;
@@ -1849,9 +1827,10 @@
(Member = dyn_cast<IndirectFieldDecl>(*Result.first))) {
if (EllipsisLoc.isValid())
Diag(EllipsisLoc, diag::err_pack_expansion_member_init)
- << MemberOrBase << SourceRange(IdLoc, Args.getEndLoc());
+ << MemberOrBase
+ << SourceRange(IdLoc, Init->getSourceRange().getEnd());
- return BuildMemberInitializer(Member, Args, IdLoc);
+ return BuildMemberInitializer(Member, Init, IdLoc);
}
}
}
@@ -1912,7 +1891,7 @@
Diag(Member->getLocation(), diag::note_previous_decl)
<< CorrectedQuotedStr;
- return BuildMemberInitializer(Member, Args, IdLoc);
+ return BuildMemberInitializer(Member, Init, IdLoc);
} else if (TypeDecl *Type = Corr.getCorrectionDeclAs<TypeDecl>()) {
const CXXBaseSpecifier *DirectBaseSpec;
const CXXBaseSpecifier *VirtualBaseSpec;
@@ -1940,7 +1919,7 @@
if (!TyD && BaseType.isNull()) {
Diag(IdLoc, diag::err_mem_init_not_member_or_class)
- << MemberOrBase << SourceRange(IdLoc, Args.getEndLoc());
+ << MemberOrBase << SourceRange(IdLoc,Init->getSourceRange().getEnd());
return true;
}
}
@@ -1960,7 +1939,7 @@
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(BaseType, IdLoc);
- return BuildBaseInitializer(BaseType, TInfo, Args, ClassDecl, EllipsisLoc);
+ return BuildBaseInitializer(BaseType, TInfo, Init, ClassDecl, EllipsisLoc);
}
/// Checks a member initializer expression for cases where reference (or
@@ -2087,15 +2066,14 @@
}
MemInitResult
-Sema::BuildMemberInitializer(ValueDecl *Member,
- const MultiInitializer &Args,
+Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
SourceLocation IdLoc) {
FieldDecl *DirectMember = dyn_cast<FieldDecl>(Member);
IndirectFieldDecl *IndirectMember = dyn_cast<IndirectFieldDecl>(Member);
assert((DirectMember || IndirectMember) &&
"Member must be a FieldDecl or IndirectFieldDecl");
- if (Args.DiagnoseUnexpandedParameterPack(*this))
+ if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer))
return true;
if (Member->isInvalidDecl())
@@ -2105,13 +2083,19 @@
// foo(foo)
// where foo is not also a parameter to the constructor.
// TODO: implement -Wuninitialized and fold this into that framework.
- for (MultiInitializer::iterator I = Args.begin(), E = Args.end();
- I != E; ++I) {
+ Expr **Args;
+ unsigned NumArgs;
+ if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+ Args = ParenList->getExprs();
+ NumArgs = ParenList->getNumExprs();
+ } else {
+ InitListExpr *InitList = cast<InitListExpr>(Init);
+ Args = InitList->getInits();
+ NumArgs = InitList->getNumInits();
+ }
+ for (unsigned i = 0; i < NumArgs; ++i) {
SourceLocation L;
- Expr *Arg = *I;
- if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Arg))
- Arg = DIE->getInit();
- if (InitExprContainsUninitializedFields(Arg, Member, &L)) {
+ if (InitExprContainsUninitializedFields(Args[i], Member, &L)) {
// FIXME: Return true in the case when other fields are used before being
// uninitialized. For example, let this field be the i'th field. When
// initializing the i'th field, throw a warning if any of the >= i'th
@@ -2122,29 +2106,38 @@
}
}
- bool HasDependentArg = Args.isTypeDependent();
+ SourceRange InitRange = Init->getSourceRange();
- Expr *Init;
- if (Member->getType()->isDependentType() || HasDependentArg) {
+ if (Member->getType()->isDependentType() || Init->isTypeDependent()) {
// Can't check initialization for a member of dependent type or when
// any of the arguments are type-dependent expressions.
- Init = Args.CreateInitExpr(Context,Member->getType().getNonReferenceType());
-
DiscardCleanupsInEvaluationContext();
} else {
+ bool InitList = false;
+ if (isa<InitListExpr>(Init)) {
+ InitList = true;
+ Args = &Init;
+ NumArgs = 1;
+ }
+
// Initialize the member.
InitializedEntity MemberEntity =
DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
: InitializedEntity::InitializeMember(IndirectMember, 0);
InitializationKind Kind =
- InitializationKind::CreateDirect(IdLoc, Args.getStartLoc(),
- Args.getEndLoc());
-
- ExprResult MemberInit = Args.PerformInit(*this, MemberEntity, Kind);
+ InitList ? InitializationKind::CreateDirectList(IdLoc)
+ : InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
+ InitRange.getEnd());
+
+ InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
+ ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind,
+ MultiExprArg(*this, Args, NumArgs),
+ 0);
if (MemberInit.isInvalid())
return true;
- CheckImplicitConversions(MemberInit.get(), Args.getStartLoc());
+ CheckImplicitConversions(MemberInit.get(),
+ InitRange.getBegin());
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
@@ -2155,14 +2148,13 @@
// If we are in a dependent context, template instantiation will
// perform this type-checking again. Just save the arguments that we
- // received in a ParenListExpr.
+ // received.
// FIXME: This isn't quite ideal, since our ASTs don't capture all
// of the information that we have about the member
// initializer. However, deconstructing the ASTs is a dicey process,
// and this approach is far more likely to get the corner cases right.
if (CurContext->isDependentContext()) {
- Init = Args.CreateInitExpr(Context,
- Member->getType().getNonReferenceType());
+ // The existing Init will do fine.
} else {
Init = MemberInit.get();
CheckForDanglingReferenceOrPointer(*this, Member, Init, IdLoc);
@@ -2170,19 +2162,18 @@
}
if (DirectMember) {
- return new (Context) CXXCtorInitializer(Context, DirectMember,
- IdLoc, Args.getStartLoc(),
- Init, Args.getEndLoc());
+ return new (Context) CXXCtorInitializer(Context, DirectMember, IdLoc,
+ InitRange.getBegin(), Init,
+ InitRange.getEnd());
} else {
- return new (Context) CXXCtorInitializer(Context, IndirectMember,
- IdLoc, Args.getStartLoc(),
- Init, Args.getEndLoc());
+ return new (Context) CXXCtorInitializer(Context, IndirectMember, IdLoc,
+ InitRange.getBegin(), Init,
+ InitRange.getEnd());
}
}
MemInitResult
-Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo,
- const MultiInitializer &Args,
+Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
CXXRecordDecl *ClassDecl) {
SourceLocation NameLoc = TInfo->getTypeLoc().getLocalSourceRange().getBegin();
if (!LangOpts.CPlusPlus0x)
@@ -2190,21 +2181,34 @@
<< TInfo->getTypeLoc().getLocalSourceRange();
Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
+ bool InitList = true;
+ Expr **Args = &Init;
+ unsigned NumArgs = 1;
+ if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+ InitList = false;
+ Args = ParenList->getExprs();
+ NumArgs = ParenList->getNumExprs();
+ }
+
+ SourceRange InitRange = Init->getSourceRange();
// Initialize the object.
InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
QualType(ClassDecl->getTypeForDecl(), 0));
InitializationKind Kind =
- InitializationKind::CreateDirect(NameLoc, Args.getStartLoc(),
- Args.getEndLoc());
-
- ExprResult DelegationInit = Args.PerformInit(*this, DelegationEntity, Kind);
+ InitList ? InitializationKind::CreateDirectList(NameLoc)
+ : InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
+ InitRange.getEnd());
+ InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args, NumArgs);
+ ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
+ MultiExprArg(*this, Args,NumArgs),
+ 0);
if (DelegationInit.isInvalid())
return true;
assert(cast<CXXConstructExpr>(DelegationInit.get())->getConstructor() &&
"Delegating constructor with no target?");
- CheckImplicitConversions(DelegationInit.get(), Args.getStartLoc());
+ CheckImplicitConversions(DelegationInit.get(), InitRange.getBegin());
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
@@ -2213,18 +2217,15 @@
if (DelegationInit.isInvalid())
return true;
- return new (Context) CXXCtorInitializer(Context, TInfo, Args.getStartLoc(),
+ return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(),
DelegationInit.takeAs<Expr>(),
- Args.getEndLoc());
+ InitRange.getEnd());
}
MemInitResult
Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
- const MultiInitializer &Args,
- CXXRecordDecl *ClassDecl,
+ Expr *Init, CXXRecordDecl *ClassDecl,
SourceLocation EllipsisLoc) {
- bool HasDependentArg = Args.isTypeDependent();
-
SourceLocation BaseLoc
= BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin();
@@ -2238,13 +2239,14 @@
// of that class, the mem-initializer is ill-formed. A
// mem-initializer-list can initialize a base class using any
// name that denotes that base class type.
- bool Dependent = BaseType->isDependentType() || HasDependentArg;
+ bool Dependent = BaseType->isDependentType() || Init->isTypeDependent();
+ SourceRange InitRange = Init->getSourceRange();
if (EllipsisLoc.isValid()) {
// This is a pack expansion.
if (!BaseType->containsUnexpandedParameterPack()) {
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
- << SourceRange(BaseLoc, Args.getEndLoc());
+ << SourceRange(BaseLoc, InitRange.getEnd());
EllipsisLoc = SourceLocation();
}
@@ -2253,7 +2255,7 @@
if (DiagnoseUnexpandedParameterPack(BaseLoc, BaseTInfo, UPPC_Initializer))
return true;
- if (Args.DiagnoseUnexpandedParameterPack(*this))
+ if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer))
return true;
}
@@ -2263,7 +2265,7 @@
if (!Dependent) {
if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0),
BaseType))
- return BuildDelegatingInitializer(BaseTInfo, Args, ClassDecl);
+ return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl);
FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
VirtualBaseSpec);
@@ -2288,16 +2290,12 @@
}
if (Dependent) {
- // Can't check initialization for a base of dependent type or when
- // any of the arguments are type-dependent expressions.
- Expr *BaseInit = Args.CreateInitExpr(Context, BaseType);
-
DiscardCleanupsInEvaluationContext();
return new (Context) CXXCtorInitializer(Context, BaseTInfo,
/*IsVirtual=*/false,
- Args.getStartLoc(), BaseInit,
- Args.getEndLoc(), EllipsisLoc);
+ InitRange.getBegin(), Init,
+ InitRange.getEnd(), EllipsisLoc);
}
// C++ [base.class.init]p2:
@@ -2308,23 +2306,34 @@
return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
<< BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
- CXXBaseSpecifier *BaseSpec
- = const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
+ CXXBaseSpecifier *BaseSpec = const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
if (!BaseSpec)
BaseSpec = const_cast<CXXBaseSpecifier *>(VirtualBaseSpec);
// Initialize the base.
+ bool InitList = true;
+ Expr **Args = &Init;
+ unsigned NumArgs = 1;
+ if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+ InitList = false;
+ Args = ParenList->getExprs();
+ NumArgs = ParenList->getNumExprs();
+ }
+
InitializedEntity BaseEntity =
InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
- InitializationKind Kind =
- InitializationKind::CreateDirect(BaseLoc, Args.getStartLoc(),
- Args.getEndLoc());
-
- ExprResult BaseInit = Args.PerformInit(*this, BaseEntity, Kind);
+ InitializationKind Kind =
+ InitList ? InitializationKind::CreateDirectList(BaseLoc)
+ : InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
+ InitRange.getEnd());
+ InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
+ ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind,
+ MultiExprArg(*this, Args, NumArgs),
+ 0);
if (BaseInit.isInvalid())
return true;
- CheckImplicitConversions(BaseInit.get(), Args.getStartLoc());
+ CheckImplicitConversions(BaseInit.get(), InitRange.getBegin());
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
@@ -2341,13 +2350,13 @@
// initializer. However, deconstructing the ASTs is a dicey process,
// and this approach is far more likely to get the corner cases right.
if (CurContext->isDependentContext())
- BaseInit = Owned(Args.CreateInitExpr(Context, BaseType));
+ BaseInit = Owned(Init);
return new (Context) CXXCtorInitializer(Context, BaseTInfo,
BaseSpec->isVirtual(),
- Args.getStartLoc(),
+ InitRange.getBegin(),
BaseInit.takeAs<Expr>(),
- Args.getEndLoc(), EllipsisLoc);
+ InitRange.getEnd(), EllipsisLoc);
}
// Create a static_cast\<T&&>(expr).
@@ -3637,7 +3646,8 @@
// complain about any non-static data members of reference or const scalar
// type, since they will never get initializers.
if (!Record->isInvalidDecl() && !Record->isDependentType() &&
- !Record->isAggregate() && !Record->hasUserDeclaredConstructor()) {
+ !Record->isAggregate() && !Record->hasUserDeclaredConstructor() &&
+ !Record->isLambda()) {
bool Complained = false;
for (RecordDecl::field_iterator F = Record->field_begin(),
FEnd = Record->field_end();
@@ -3708,9 +3718,6 @@
// const. [...] The class of which that function is a member shall be
// a literal type.
//
- // It's fine to diagnose constructors here too: such constructors cannot
- // produce a constant expression, so are ill-formed (no diagnostic required).
- //
// If the class has virtual bases, any constexpr members will already have
// been diagnosed by the checks performed on the member declaration, so
// suppress this (less useful) diagnostic.
@@ -3719,16 +3726,14 @@
for (CXXRecordDecl::method_iterator M = Record->method_begin(),
MEnd = Record->method_end();
M != MEnd; ++M) {
- if (M->isConstexpr() && M->isInstance()) {
+ if (M->isConstexpr() && M->isInstance() && !isa<CXXConstructorDecl>(*M)) {
switch (Record->getTemplateSpecializationKind()) {
case TSK_ImplicitInstantiation:
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
// If a template instantiates to a non-literal type, but its members
// instantiate to constexpr functions, the template is technically
- // ill-formed, but we allow it for sanity. Such members are treated as
- // non-constexpr.
- (*M)->setConstexpr(false);
+ // ill-formed, but we allow it for sanity.
continue;
case TSK_Undeclared:
@@ -3827,7 +3832,10 @@
// C++11 [dcl.fct.def.default]p2:
// An explicitly-defaulted function may be declared constexpr only if it
// would have been implicitly declared as constexpr,
- if (CD->isConstexpr()) {
+ // Do not apply this rule to templates, since core issue 1358 makes such
+ // functions always instantiate to constexpr functions.
+ if (CD->isConstexpr() &&
+ CD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) {
if (!CD->getParent()->defaultedDefaultConstructorIsConstexpr()) {
Diag(CD->getLocStart(), diag::err_incorrect_defaulted_constexpr)
<< CXXDefaultConstructor;
@@ -3915,7 +3923,10 @@
// C++11 [dcl.fct.def.default]p2:
// An explicitly-defaulted function may be declared constexpr only if it
// would have been implicitly declared as constexpr,
- if (CD->isConstexpr()) {
+ // Do not apply this rule to templates, since core issue 1358 makes such
+ // functions always instantiate to constexpr functions.
+ if (CD->isConstexpr() &&
+ CD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) {
if (!CD->getParent()->defaultedCopyConstructorIsConstexpr()) {
Diag(CD->getLocStart(), diag::err_incorrect_defaulted_constexpr)
<< CXXCopyConstructor;
@@ -4092,7 +4103,10 @@
// C++11 [dcl.fct.def.default]p2:
// An explicitly-defaulted function may be declared constexpr only if it
// would have been implicitly declared as constexpr,
- if (CD->isConstexpr()) {
+ // Do not apply this rule to templates, since core issue 1358 makes such
+ // functions always instantiate to constexpr functions.
+ if (CD->isConstexpr() &&
+ CD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) {
if (!CD->getParent()->defaultedMoveConstructorIsConstexpr()) {
Diag(CD->getLocStart(), diag::err_incorrect_defaulted_constexpr)
<< CXXMoveConstructor;
@@ -4293,6 +4307,13 @@
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;
+
break;
case CXXCopyConstructor:
IsConstructor = true;
@@ -4574,6 +4595,12 @@
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
@@ -9048,7 +9075,8 @@
MarkFunctionReferenced(ConstructLoc, Constructor);
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
Constructor, Elidable, Exprs, NumExprs,
- HadMultipleCandidates, RequiresZeroInit,
+ HadMultipleCandidates, /*FIXME*/false,
+ RequiresZeroInit,
static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
ParenRange));
}
@@ -9100,184 +9128,6 @@
Diag(VD->getLocation(), diag::warn_global_destructor);
}
-/// AddCXXDirectInitializerToDecl - This action is called immediately after
-/// ActOnDeclarator, when a C++ direct initializer is present.
-/// e.g: "int x(1);"
-void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
- SourceLocation LParenLoc,
- MultiExprArg Exprs,
- SourceLocation RParenLoc,
- bool TypeMayContainAuto) {
- // If there is no declaration, there was an error parsing it. Just ignore
- // the initializer.
- if (RealDecl == 0)
- return;
-
- VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
- if (!VDecl) {
- Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
- RealDecl->setInvalidDecl();
- return;
- }
-
- // C++0x [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
- if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
- if (Exprs.size() == 0) {
- // It isn't possible to write this directly, but it is possible to
- // end up in this situation with "auto x(some_pack...);"
- Diag(LParenLoc, diag::err_auto_var_init_no_expression)
- << VDecl->getDeclName() << VDecl->getType()
- << VDecl->getSourceRange();
- RealDecl->setInvalidDecl();
- return;
- }
-
- if (Exprs.size() > 1) {
- Diag(Exprs.get()[1]->getSourceRange().getBegin(),
- diag::err_auto_var_init_multiple_expressions)
- << VDecl->getDeclName() << VDecl->getType()
- << VDecl->getSourceRange();
- RealDecl->setInvalidDecl();
- return;
- }
-
- Expr *Init = Exprs.get()[0];
- TypeSourceInfo *DeducedType = 0;
- if (DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType) ==
- DAR_Failed)
- DiagnoseAutoDeductionFailure(VDecl, Init);
- if (!DeducedType) {
- RealDecl->setInvalidDecl();
- return;
- }
- VDecl->setTypeSourceInfo(DeducedType);
- VDecl->setType(DeducedType->getType());
-
- // In ARC, infer lifetime.
- if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
- VDecl->setInvalidDecl();
-
- // If this is a redeclaration, check that the type we just deduced matches
- // the previously declared type.
- if (VarDecl *Old = VDecl->getPreviousDecl())
- MergeVarDeclTypes(VDecl, Old);
- }
-
- // We will represent direct-initialization similarly to copy-initialization:
- // int x(1); -as-> int x = 1;
- // ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
- //
- // Clients that want to distinguish between the two forms, can check for
- // direct initializer using VarDecl::hasCXXDirectInitializer().
- // A major benefit is that clients that don't particularly care about which
- // exactly form was it (like the CodeGen) can handle both cases without
- // special case code.
-
- // C++ 8.5p11:
- // The form of initialization (using parentheses or '=') is generally
- // insignificant, but does matter when the entity being initialized has a
- // class type.
-
- if (!VDecl->getType()->isDependentType() &&
- !VDecl->getType()->isIncompleteArrayType() &&
- RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
- diag::err_typecheck_decl_incomplete_type)) {
- VDecl->setInvalidDecl();
- return;
- }
-
- // The variable can not have an abstract class type.
- if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
- diag::err_abstract_type_in_decl,
- AbstractVariableType))
- VDecl->setInvalidDecl();
-
- const VarDecl *Def;
- if ((Def = VDecl->getDefinition()) && Def != VDecl) {
- Diag(VDecl->getLocation(), diag::err_redefinition)
- << VDecl->getDeclName();
- Diag(Def->getLocation(), diag::note_previous_definition);
- VDecl->setInvalidDecl();
- return;
- }
-
- // C++ [class.static.data]p4
- // If a static data member is of const integral or const
- // enumeration type, its declaration in the class definition can
- // specify a constant-initializer which shall be an integral
- // constant expression (5.19). In that case, the member can appear
- // in integral constant expressions. The member shall still be
- // defined in a namespace scope if it is used in the program and the
- // namespace scope definition shall not contain an initializer.
- //
- // We already performed a redefinition check above, but for static
- // data members we also need to check whether there was an in-class
- // declaration with an initializer.
- const VarDecl* PrevInit = 0;
- if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
- Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
- Diag(PrevInit->getLocation(), diag::note_previous_definition);
- return;
- }
-
- bool IsDependent = false;
- for (unsigned I = 0, N = Exprs.size(); I != N; ++I) {
- if (DiagnoseUnexpandedParameterPack(Exprs.get()[I], UPPC_Expression)) {
- VDecl->setInvalidDecl();
- return;
- }
-
- if (Exprs.get()[I]->isTypeDependent())
- IsDependent = true;
- }
-
- // If either the declaration has a dependent type or if any of the
- // expressions is type-dependent, we represent the initialization
- // via a ParenListExpr for later use during template instantiation.
- if (VDecl->getType()->isDependentType() || IsDependent) {
- // Let clients know that initialization was done with a direct initializer.
- VDecl->setCXXDirectInitializer(true);
-
- // Store the initialization expressions as a ParenListExpr.
- unsigned NumExprs = Exprs.size();
- VDecl->setInit(new (Context) ParenListExpr(
- Context, LParenLoc, (Expr **)Exprs.release(), NumExprs, RParenLoc,
- VDecl->getType().getNonReferenceType()));
- return;
- }
-
- // Capture the variable that is being initialized and the style of
- // initialization.
- InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
-
- // FIXME: Poor source location information.
- InitializationKind Kind
- = InitializationKind::CreateDirect(VDecl->getLocation(),
- LParenLoc, RParenLoc);
-
- QualType T = VDecl->getType();
- InitializationSequence InitSeq(*this, Entity, Kind,
- Exprs.get(), Exprs.size());
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs), &T);
- if (Result.isInvalid()) {
- VDecl->setInvalidDecl();
- return;
- } else if (T != VDecl->getType()) {
- VDecl->setType(T);
- Result.get()->setType(T);
- }
-
-
- Expr *Init = Result.get();
- CheckImplicitConversions(Init, LParenLoc);
-
- Init = MaybeCreateExprWithCleanups(Init);
- VDecl->setInit(Init);
- VDecl->setCXXDirectInitializer(true);
-
- CheckCompleteVariableDeclaration(VDecl);
-}
-
/// \brief Given a constructor and the set of arguments provided for the
/// constructor, convert the arguments and add any required default arguments
/// to form a proper call to this constructor.
Modified: cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp Tue Feb 14 03:11:10 2012
@@ -1465,11 +1465,9 @@
const llvm::DenseSet<Selector> &InsMap,
const llvm::DenseSet<Selector> &ClsMap,
ObjCContainerDecl *CDecl) {
- ObjCInterfaceDecl *IDecl;
- if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl))
- IDecl = C->getClassInterface();
- else
- IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
+ ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
+ ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
+ : dyn_cast<ObjCInterfaceDecl>(CDecl);
assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
ObjCInterfaceDecl *Super = IDecl->getSuperClass();
@@ -1504,20 +1502,27 @@
!method->isSynthesized() && !InsMap.count(method->getSelector()) &&
(!Super ||
!Super->lookupInstanceMethod(method->getSelector()))) {
+ // If a method is not implemented in the category implementation but
+ // has been declared in its primary class, superclass,
+ // or in one of their protocols, no need to issue the warning.
+ // This is because method will be implemented in the primary class
+ // or one of its super class implementation.
+
// Ugly, but necessary. Method declared in protcol might have
// have been synthesized due to a property declared in the class which
// uses the protocol.
- ObjCMethodDecl *MethodInClass =
- IDecl->lookupInstanceMethod(method->getSelector());
- if (!MethodInClass || !MethodInClass->isSynthesized()) {
- unsigned DIAG = diag::warn_unimplemented_protocol_method;
- if (Diags.getDiagnosticLevel(DIAG, ImpLoc)
- != DiagnosticsEngine::Ignored) {
- WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
- Diag(method->getLocation(), diag::note_method_declared_at);
- Diag(CDecl->getLocation(), diag::note_required_for_protocol_at)
- << PDecl->getDeclName();
- }
+ if (ObjCMethodDecl *MethodInClass =
+ IDecl->lookupInstanceMethod(method->getSelector(),
+ true /*noCategoryLookup*/))
+ if (C || MethodInClass->isSynthesized())
+ continue;
+ unsigned DIAG = diag::warn_unimplemented_protocol_method;
+ if (Diags.getDiagnosticLevel(DIAG, ImpLoc)
+ != DiagnosticsEngine::Ignored) {
+ WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
+ Diag(method->getLocation(), diag::note_method_declared_at);
+ Diag(CDecl->getLocation(), diag::note_required_for_protocol_at)
+ << PDecl->getDeclName();
}
}
}
@@ -1529,6 +1534,10 @@
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!ClsMap.count(method->getSelector()) &&
(!Super || !Super->lookupClassMethod(method->getSelector()))) {
+ // See above comment for instance method lookups.
+ if (C && IDecl->lookupClassMethod(method->getSelector(),
+ true /*noCategoryLookup*/))
+ continue;
unsigned DIAG = diag::warn_unimplemented_protocol_method;
if (Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
DiagnosticsEngine::Ignored) {
@@ -1542,7 +1551,7 @@
// Check on this protocols's referenced protocols, recursively.
for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
E = PDecl->protocol_end(); PI != E; ++PI)
- CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
+ CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, CDecl);
}
/// MatchAllMethodDeclarations - Check methods declared in interface
@@ -1556,7 +1565,7 @@
ObjCContainerDecl* CDecl,
bool &IncompleteImpl,
bool ImmediateClass,
- bool WarnExactMatch) {
+ bool WarnCategoryMethodImpl) {
// Check and see if instance methods in class interface have been
// implemented in the implementation class. If so, their types match.
for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
@@ -1578,12 +1587,12 @@
ObjCMethodDecl *MethodDecl = *I;
// ImpMethodDecl may be null as in a @dynamic property.
if (ImpMethodDecl) {
- if (!WarnExactMatch)
+ if (!WarnCategoryMethodImpl)
WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
isa<ObjCProtocolDecl>(CDecl));
else if (!MethodDecl->isSynthesized())
WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
- isa<ObjCProtocolDecl>(CDecl));
+ isa<ObjCProtocolDecl>(CDecl));
}
}
}
@@ -1605,12 +1614,12 @@
assert(CDecl->getClassMethod((*I)->getSelector()) &&
"Expected to find the method through lookup as well");
ObjCMethodDecl *MethodDecl = *I;
- if (!WarnExactMatch)
+ if (!WarnCategoryMethodImpl)
WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
isa<ObjCProtocolDecl>(CDecl));
else
WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
- isa<ObjCProtocolDecl>(CDecl));
+ isa<ObjCProtocolDecl>(CDecl));
}
}
@@ -1621,7 +1630,8 @@
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
IMPDecl,
const_cast<ObjCCategoryDecl *>(ClsExtDecl),
- IncompleteImpl, false, WarnExactMatch);
+ IncompleteImpl, false,
+ WarnCategoryMethodImpl);
// Check for any implementation of a methods declared in protocol.
for (ObjCInterfaceDecl::all_protocol_iterator
@@ -1629,11 +1639,12 @@
E = I->all_referenced_protocol_end(); PI != E; ++PI)
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
IMPDecl,
- (*PI), IncompleteImpl, false, WarnExactMatch);
+ (*PI), IncompleteImpl, false,
+ WarnCategoryMethodImpl);
// FIXME. For now, we are not checking for extact match of methods
// in category implementation and its primary class's super class.
- if (!WarnExactMatch && I->getSuperClass())
+ if (!WarnCategoryMethodImpl && I->getSuperClass())
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
IMPDecl,
I->getSuperClass(), IncompleteImpl, false);
@@ -1670,7 +1681,8 @@
bool IncompleteImpl = false;
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
CatIMPDecl, IDecl,
- IncompleteImpl, false, true /*WarnExactMatch*/);
+ IncompleteImpl, false,
+ true /*WarnCategoryMethodImpl*/);
}
void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
Modified: cfe/branches/tooling/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExpr.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExpr.cpp Tue Feb 14 03:11:10 2012
@@ -18,6 +18,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
@@ -65,8 +66,7 @@
return true;
}
-AvailabilityResult
-Sema::DiagnoseAvailabilityOfDecl(
+static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
NamedDecl *D, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass) {
// See if this declaration is unavailable or deprecated.
@@ -85,22 +85,22 @@
break;
case AR_Deprecated:
- EmitDeprecationWarning(D, Message, Loc, UnknownObjCClass);
+ S.EmitDeprecationWarning(D, Message, Loc, UnknownObjCClass);
break;
case AR_Unavailable:
- if (getCurContextAvailability() != AR_Unavailable) {
+ if (S.getCurContextAvailability() != AR_Unavailable) {
if (Message.empty()) {
if (!UnknownObjCClass)
- Diag(Loc, diag::err_unavailable) << D->getDeclName();
+ S.Diag(Loc, diag::err_unavailable) << D->getDeclName();
else
- Diag(Loc, diag::warn_unavailable_fwdclass_message)
+ S.Diag(Loc, diag::warn_unavailable_fwdclass_message)
<< D->getDeclName();
}
else
- Diag(Loc, diag::err_unavailable_message)
+ S.Diag(Loc, diag::err_unavailable_message)
<< D->getDeclName() << Message;
- Diag(D->getLocation(), diag::note_unavailable_here)
+ S.Diag(D->getLocation(), diag::note_unavailable_here)
<< isa<FunctionDecl>(D) << false;
}
break;
@@ -155,7 +155,7 @@
return true;
}
}
- DiagnoseAvailabilityOfDecl(D, Loc, UnknownObjCClass);
+ DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass);
// Warn if this is used but marked unused.
if (D->hasAttr<UnusedAttr>())
@@ -2094,6 +2094,15 @@
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)
@@ -2117,7 +2126,8 @@
// 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;
+ S.ExprEvalContexts.back().Context != Sema::Unevaluated &&
+ willCaptureByCopy(LSI, var);
}
static ExprResult BuildBlockDeclRefExpr(Sema &S, ValueDecl *VD,
@@ -2910,6 +2920,11 @@
case tok::minusminus: Opc = UO_PostDec; break;
}
+ // Since this might is a postfix expression, get rid of ParenListExprs.
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input);
+ if (Result.isInvalid()) return ExprError();
+ Input = Result.take();
+
return BuildUnaryOp(S, OpLoc, Opc, Input);
}
@@ -3794,7 +3809,8 @@
= InitializedEntity::InitializeTemporary(literalType);
InitializationKind Kind
= InitializationKind::CreateCStyleCast(LParenLoc,
- SourceRange(LParenLoc, RParenLoc));
+ SourceRange(LParenLoc, RParenLoc),
+ /*InitList=*/true);
InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
MultiExprArg(*this, &LiteralExpr, 1),
@@ -4241,8 +4257,8 @@
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE);
}
-/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
-/// of comma binary operators.
+/// This is not an AltiVec-style cast or or C++ direct-initialization, so turn
+/// the ParenListExpr into a sequence of comma binary operators.
ExprResult
Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr);
@@ -4260,18 +4276,13 @@
return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
}
-ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
- SourceLocation R,
- MultiExprArg Val) {
+ExprResult Sema::ActOnParenListExpr(SourceLocation L,
+ SourceLocation R,
+ MultiExprArg Val) {
unsigned nexprs = Val.size();
Expr **exprs = reinterpret_cast<Expr**>(Val.release());
assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
- Expr *expr;
- if (nexprs == 1)
- expr = new (Context) ParenExpr(L, R, exprs[0]);
- else
- expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R,
- exprs[nexprs-1]->getType());
+ Expr *expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R);
return Owned(expr);
}
@@ -4982,9 +4993,9 @@
// It's okay to add or remove GC or lifetime qualifiers when converting to
// and from void*.
- else if (lhq.withoutObjCGCAttr().withoutObjCGLifetime()
+ else if (lhq.withoutObjCGCAttr().withoutObjCLifetime()
.compatiblyIncludes(
- rhq.withoutObjCGCAttr().withoutObjCGLifetime())
+ rhq.withoutObjCGCAttr().withoutObjCLifetime())
&& (lhptee->isVoidType() || rhptee->isVoidType()))
; // keep old
@@ -9272,6 +9283,10 @@
return BaseTransform::TransformUnaryOperator(E);
}
+ ExprResult TransformLambdaExpr(LambdaExpr *E) {
+ // Lambdas never need to be transformed.
+ return E;
+ }
};
}
@@ -9297,6 +9312,29 @@
void Sema::PopExpressionEvaluationContext() {
ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
+ if (!Rec.Lambdas.empty()) {
+ if (Rec.Context == Unevaluated) {
+ // C++11 [expr.prim.lambda]p2:
+ // A lambda-expression shall not appear in an unevaluated operand
+ // (Clause 5).
+ for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I)
+ Diag(Rec.Lambdas[I]->getLocStart(),
+ diag::err_lambda_unevaluated_operand);
+ } else {
+ // Mark the capture expressions odr-used. This was deferred
+ // during lambda expression creation.
+ for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) {
+ LambdaExpr *Lambda = Rec.Lambdas[I];
+ for (LambdaExpr::capture_init_iterator
+ C = Lambda->capture_init_begin(),
+ CEnd = Lambda->capture_init_end();
+ C != CEnd; ++C) {
+ MarkDeclarationsReferencedInExpr(*C);
+ }
+ }
+ }
+ }
+
// When are coming out of an unevaluated context, clear out any
// temporaries that we may have created as part of the evaluation of
// the expression in that context: they aren't relevant because they
@@ -9307,7 +9345,6 @@
ExprNeedsCleanups = Rec.ParentNeedsCleanups;
CleanupVarDeclMarking();
std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs);
-
// Otherwise, merge the contexts together.
} else {
ExprNeedsCleanups |= Rec.ParentNeedsCleanups;
@@ -9446,8 +9483,11 @@
// expression evaluator needing to call back into Sema if it sees a
// call to such a function.
InstantiateFunctionDefinition(Loc, Func);
- else
+ else {
PendingInstantiations.push_back(std::make_pair(Func, Loc));
+ // Notify the consumer that a function was implicitly instantiated.
+ Consumer.HandleCXXImplicitFunctionInstantiation(Func);
+ }
}
} else {
// Walk redefinitions, as some of them may be instantiable.
@@ -9524,20 +9564,172 @@
return false;
}
-// Check if the variable needs to be captured; if so, try to perform
-// the capture.
-// FIXME: Add support for explicit captures.
-void Sema::TryCaptureVar(VarDecl *var, SourceLocation loc,
- TryCaptureKind Kind) {
+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) {
+ CXXRecordDecl *Lambda = LSI->Lambda;
+ QualType FieldType = S.getLambdaCaptureFieldType(Type, ByRef);
+
+ // Build the non-static data member.
+ FieldDecl *Field
+ = FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType,
+ S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
+ 0, false, false);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ Lambda->addDecl(Field);
+
+ // C++11 [expr.prim.lambda]p21:
+ // When the lambda-expression is evaluated, the entities that
+ // are captured by copy are used to direct-initialize each
+ // corresponding non-static data member of the resulting closure
+ // object. (For array members, the array elements are
+ // 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
+ // to be re-"exported" from the lambda expression itself.
+ S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+
+ // 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);
+ Var->setUsed(true);
+
+ // When the field has array type, create index variables for each
+ // dimension of the array. We use these index variables to subscript
+ // 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;
+ {
+ SmallString<8> Str;
+ llvm::raw_svector_ostream OS(Str);
+ OS << "__i" << IndexVariables.size();
+ IterationVarName = &S.Context.Idents.get(OS.str());
+ }
+ VarDecl *IterationVar
+ = VarDecl::Create(S.Context, S.CurContext, Loc, Loc,
+ IterationVarName, SizeType,
+ S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
+ SC_None, SC_None);
+ IndexVariables.push_back(IterationVar);
+ LSI->ArrayIndexVars.push_back(IterationVar);
+
+ // Create a reference to the iteration variable.
+ ExprResult IterationVarRef
+ = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
+ assert(!IterationVarRef.isInvalid() &&
+ "Reference to invented variable cannot fail!");
+ IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take());
+ assert(!IterationVarRef.isInvalid() &&
+ "Conversion of invented variable cannot fail!");
+
+ // Subscript the array with this iteration variable.
+ ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(
+ Ref, Loc, IterationVarRef.take(), Loc);
+ if (Subscript.isInvalid()) {
+ S.CleanupVarDeclMarking();
+ S.DiscardCleanupsInEvaluationContext();
+ S.PopExpressionEvaluationContext();
+ return ExprError();
+ }
+
+ Ref = Subscript.take();
+ BaseType = Array->getElementType();
+ }
+
+ // Construct the entity that we will be initializing. For an array, this
+ // will be first element in the array, which may require several levels
+ // of array-subscript entities.
+ SmallVector<InitializedEntity, 4> Entities;
+ Entities.reserve(1 + IndexVariables.size());
+ Entities.push_back(InitializedEntity::InitializeMember(Field));
+ for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
+ Entities.push_back(InitializedEntity::InitializeElement(S.Context,
+ 0,
+ Entities.back()));
+
+ InitializationKind InitKind
+ = InitializationKind::CreateDirect(Loc, Loc, Loc);
+ InitializationSequence Init(S, Entities.back(), InitKind, &Ref, 1);
+ ExprResult Result(true);
+ if (!Init.Diagnose(S, Entities.back(), InitKind, &Ref, 1))
+ Result = Init.Perform(S, Entities.back(), InitKind,
+ MultiExprArg(S, &Ref, 1));
+
+ // If this initialization requires any cleanups (e.g., due to a
+ // default argument to a copy constructor), note that for the
+ // lambda.
+ if (S.ExprNeedsCleanups)
+ LSI->ExprNeedsCleanups = true;
+
+ // Exit the expression evaluation context used for the capture.
+ S.CleanupVarDeclMarking();
+ S.DiscardCleanupsInEvaluationContext();
+ S.PopExpressionEvaluationContext();
+ 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;
+
DeclContext *DC = CurContext;
- if (var->getDeclContext() == DC) return;
- if (!var->hasLocalStorage()) return;
+ if (Var->getDeclContext() == DC) return false;
+ if (!Var->hasLocalStorage()) return false;
- // Actually try to capture it.
- QualType type = var->getType();
- bool Nested = false;
+ bool HasBlocksAttr = Var->hasAttr<BlocksAttr>();
- unsigned functionScopesIndex = FunctionScopes.size() - 1;
+ // Figure out whether we can capture the variable.
do {
// Only block literals and lambda expressions can capture; other
// scopes don't work.
@@ -9545,84 +9737,125 @@
if (isa<BlockDecl>(DC))
ParentDC = DC->getParent();
else if (isa<CXXMethodDecl>(DC) &&
+ cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
cast<CXXRecordDecl>(DC->getParent())->isLambda())
ParentDC = DC->getParent()->getParent();
- else
- return diagnoseUncapturableValueReference(*this, loc, var, DC);
+ else {
+ if (Diagnose)
+ diagnoseUncapturableValueReference(*this, Loc, Var, DC);
+ return false;
+ }
CapturingScopeInfo *CSI =
- cast<CapturingScopeInfo>(FunctionScopes[functionScopesIndex]);
+ cast<CapturingScopeInfo>(FunctionScopes[FunctionScopesIndex]);
// Check whether we've already captured it.
- if (CSI->CaptureMap.count(var)) {
+ if (CSI->CaptureMap.count(Var)) {
// If we found a capture, any subcaptures are nested
Nested = true;
- if (shouldAddConstForScope(CSI, var))
- type.addConst();
+ if (shouldAddConstForScope(CSI, Var))
+ Type.addConst();
break;
}
- functionScopesIndex--;
- DC = ParentDC;
- } while (var->getDeclContext() != DC);
-
- bool hasBlocksAttr = var->hasAttr<BlocksAttr>();
-
- for (unsigned i = functionScopesIndex + 1,
- e = FunctionScopes.size(); i != e; ++i) {
- CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[i]);
- bool isBlock = isa<BlockScopeInfo>(CSI);
- bool isLambda = isa<LambdaScopeInfo>(CSI);
+ bool IsBlock = isa<BlockScopeInfo>(CSI);
+ bool IsLambda = isa<LambdaScopeInfo>(CSI);
// 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()) {
- Diag(loc, diag::err_lambda_capture_anonymous_var);
- Diag(var->getLocation(), diag::note_declared_at);
- return;
+ if (IsLambda && !Var->getDeclName()) {
+ if (Diagnose) {
+ Diag(Loc, diag::err_lambda_capture_anonymous_var);
+ Diag(Var->getLocation(), diag::note_declared_at);
+ }
+ return false;
}
// Prohibit variably-modified types; they're difficult to deal with.
- if (type->isVariablyModifiedType()) {
- if (isBlock)
- Diag(loc, diag::err_ref_vm_type);
- else
- Diag(loc, diag::err_lambda_capture_vm_type) << var->getDeclName();
- Diag(var->getLocation(), diag::note_previous_decl) << var->getDeclName();
- return;
+ if (Type->isVariablyModifiedType()) {
+ if (Diagnose) {
+ if (IsBlock)
+ Diag(Loc, diag::err_ref_vm_type);
+ else
+ Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName();
+ Diag(Var->getLocation(), diag::note_previous_decl)
+ << Var->getDeclName();
+ }
+ return false;
}
// Blocks are not allowed to capture arrays.
- if (isBlock && type->isArrayType()) {
- Diag(loc, diag::err_ref_array_type);
- Diag(var->getLocation(), diag::note_previous_decl) << var->getDeclName();
- return;
+ if (IsBlock && Type->isArrayType()) {
+ if (Diagnose) {
+ Diag(Loc, diag::err_ref_array_type);
+ Diag(Var->getLocation(), diag::note_previous_decl)
+ << Var->getDeclName();
+ }
+ return false;
}
// Lambdas are not allowed to capture __block variables; they don't
// support the expected semantics.
- if (isLambda && hasBlocksAttr) {
- Diag(loc, diag::err_lambda_capture_block) << var->getDeclName();
- Diag(var->getLocation(), diag::note_previous_decl) << var->getDeclName();
- return;
+ if (IsLambda && HasBlocksAttr) {
+ if (Diagnose) {
+ Diag(Loc, diag::err_lambda_capture_block)
+ << Var->getDeclName();
+ Diag(Var->getLocation(), diag::note_previous_decl)
+ << Var->getDeclName();
+ }
+ return false;
+ }
+
+ if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
+ // No capture-default
+ if (Diagnose) {
+ 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;
}
+ FunctionScopesIndex--;
+ DC = ParentDC;
+ Explicit = false;
+ } while (!Var->getDeclContext()->Equals(DC));
+
+ ++FunctionScopesIndex;
+ return !Type->isVariablyModifiedType();
+}
+
+// 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_None) {
- // No capture-default
- 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;
} else if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval) {
// capture-default '='
byRef = false;
@@ -9642,71 +9875,10 @@
Expr *copyExpr = 0;
const RecordType *rtype;
if (isLambda) {
- CXXRecordDecl *Lambda = cast<LambdaScopeInfo>(CSI)->Lambda;
- QualType FieldType;
- 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.
- FieldType = Context.getLValueReferenceType(type.getNonReferenceType());
- } 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
- = type->getAs<ReferenceType>()) {
- if (!RefType->getPointeeType()->isFunctionType())
- FieldType = RefType->getPointeeType();
- else
- FieldType = type;
- } else {
- FieldType = type;
- }
- }
-
- // Build the non-static data member.
- FieldDecl *Field
- = FieldDecl::Create(Context, Lambda, loc, loc, 0, FieldType,
- Context.getTrivialTypeSourceInfo(FieldType, loc),
- 0, false, false);
- Field->setImplicit(true);
- Field->setAccess(AS_private);
-
- // C++11 [expr.prim.lambda]p21:
- // When the lambda-expression is evaluated, the entities that
- // are captured by copy are used to direct-initialize each
- // corresponding non-static data member of the resulting closure
- // object. (For array members, the array elements are
- // 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.
- // FIXME: Totally broken for arrays.
- Expr *Ref = new (Context) DeclRefExpr(var, type.getNonReferenceType(),
- VK_LValue, loc);
- InitializedEntity InitEntity
- = InitializedEntity::InitializeMember(Field, /*Parent=*/0);
- InitializationKind InitKind
- = InitializationKind::CreateDirect(loc, loc, loc);
- InitializationSequence Init(*this, InitEntity, InitKind, &Ref, 1);
- if (!Init.Diagnose(*this, InitEntity, InitKind, &Ref, 1)) {
- ExprResult Result = Init.Perform(*this, InitEntity, InitKind,
- MultiExprArg(*this, &Ref, 1));
- if (!Result.isInvalid())
- copyExpr = Result.take();
- }
+ 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.
@@ -9722,8 +9894,6 @@
// of the copy/move done to move a __block variable to the heap.
type.addConst();
- // FIXME: Add an initialized entity for lambda capture.
- // FIXME: Won't work for arrays, although we do need this behavior.
Expr *declRef = new (Context) DeclRefExpr(var, type, VK_LValue, loc);
ExprResult result =
PerformCopyInitialization(
@@ -9877,7 +10047,7 @@
MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E);
}
-/// \brief Perform marking for a reference to an aribitrary declaration. It
+/// \brief Perform marking for a reference to an arbitrary declaration. It
/// marks the declaration referenced, and performs odr-use checking for functions
/// and variables. This method should not be used when building an normal
/// expression which refers to a variable.
Modified: cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp Tue Feb 14 03:11:10 2012
@@ -686,11 +686,10 @@
}
if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref ||
+ CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval ||
CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block ||
Explicit) {
// This closure can capture 'this'; continue looking upwards.
- // FIXME: Is this check correct? The rules in the standard are a bit
- // unclear.
NumClosures++;
Explicit = false;
continue;
@@ -708,8 +707,22 @@
for (unsigned idx = FunctionScopes.size() - 1;
NumClosures; --idx, --NumClosures) {
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
+ Expr *ThisExpr = 0;
+ 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,
+ Context.getTrivialTypeSourceInfo(ThisTy, Loc),
+ 0, false, false);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ Lambda->addDecl(Field);
+ ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true);
+ }
bool isNested = NumClosures > 1;
- CSI->AddThisCapture(isNested, Loc);
+ CSI->AddThisCapture(isNested, Loc, ThisExpr);
}
}
@@ -754,7 +767,6 @@
unsigned NumExprs = exprs.size();
Expr **Exprs = (Expr**)exprs.get();
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
- SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
if (Ty->isDependentType() ||
CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) {
@@ -766,6 +778,12 @@
RParenLoc));
}
+ bool ListInitialization = LParenLoc.isInvalid();
+ assert((!ListInitialization || (NumExprs == 1 && isa<InitListExpr>(Exprs[0])))
+ && "List initialization must have initializer list as expression.");
+ SourceRange FullRange = SourceRange(TyBeginLoc,
+ ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc);
+
if (Ty->isArrayType())
return ExprError(Diag(TyBeginLoc,
diag::err_value_init_for_array_type) << FullRange);
@@ -784,7 +802,7 @@
// If the expression list is a single expression, the type conversion
// expression is equivalent (in definedness, and if defined in meaning) to the
// corresponding cast expression.
- if (NumExprs == 1) {
+ if (NumExprs == 1 && !ListInitialization) {
Expr *Arg = Exprs[0];
exprs.release();
return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc);
@@ -792,13 +810,28 @@
InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo);
InitializationKind Kind
- = NumExprs ? InitializationKind::CreateDirect(TyBeginLoc,
- LParenLoc, RParenLoc)
+ = NumExprs ? ListInitialization
+ ? InitializationKind::CreateDirectList(TyBeginLoc)
+ : InitializationKind::CreateDirect(TyBeginLoc,
+ LParenLoc, RParenLoc)
: InitializationKind::CreateValue(TyBeginLoc,
LParenLoc, RParenLoc);
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs));
+ if (!Result.isInvalid() && ListInitialization &&
+ isa<InitListExpr>(Result.get())) {
+ // If the list-initialization doesn't involve a constructor call, we'll get
+ // the initializer-list (with corrected type) back, but that's not what we
+ // want, since it will be treated as an initializer list in further
+ // processing. Explicitly insert a cast here.
+ InitListExpr *List = cast<InitListExpr>(Result.take());
+ Result = Owned(CXXFunctionalCastExpr::Create(Context, List->getType(),
+ Expr::getValueKindForType(TInfo->getType()),
+ TInfo, TyBeginLoc, CK_NoOp,
+ List, /*Path=*/0, RParenLoc));
+ }
+
// FIXME: Improve AST representation?
return move(Result);
}
@@ -859,11 +892,24 @@
return (del->getNumParams() == 2);
}
-/// ActOnCXXNew - Parsed a C++ 'new' expression (C++ 5.3.4), as in e.g.:
+/// \brief Parsed a C++ 'new' expression (C++ 5.3.4).
+
+/// E.g.:
/// @code new (memory) int[size][4] @endcode
/// or
/// @code ::new Foo(23, "hello") @endcode
-/// For the interpretation of this heap of arguments, consult the base version.
+///
+/// \param StartLoc The first location of the expression.
+/// \param UseGlobal True if 'new' was prefixed with '::'.
+/// \param PlacementLParen Opening paren of the placement arguments.
+/// \param PlacementArgs Placement new arguments.
+/// \param PlacementRParen Closing paren of the placement arguments.
+/// \param TypeIdParens If the type is in parens, the source range.
+/// \param D The type to be allocated, as well as array dimensions.
+/// \param ConstructorLParen Opening paren of the constructor args, empty if
+/// initializer-list syntax is used.
+/// \param ConstructorArgs Constructor/initialization arguments.
+/// \param ConstructorRParen Closing paren of the constructor args.
ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
@@ -955,21 +1001,25 @@
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);
+ }
TypeSourceInfo *DeducedType = 0;
- if (DeduceAutoType(AllocTypeInfo, ConstructorArgs.get()[0], DeducedType) ==
+ if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) ==
DAR_Failed)
return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
- << AllocType
- << ConstructorArgs.get()[0]->getType()
- << TypeRange
- << ConstructorArgs.get()[0]->getSourceRange());
+ << AllocType << Deduce->getType()
+ << TypeRange << Deduce->getSourceRange());
if (!DeducedType)
return ExprError();
AllocTypeInfo = DeducedType;
AllocType = AllocTypeInfo->getType();
}
-
+
// Per C++0x [expr.new]p5, the type being constructed may be a
// typedef of an array type.
if (!ArraySize) {
@@ -985,6 +1035,17 @@
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)) {
+ Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
+ diag::warn_dangling_std_initializer_list)
+ << /*at end of FE*/0 << ConstructorArgs.get()[0]->getSourceRange();
+ }
+
// In ARC, infer 'retaining' for the allocated
if (getLangOptions().ObjCAutoRefCount &&
AllocType.getObjCLifetime() == Qualifiers::OCL_None &&
@@ -1140,7 +1201,7 @@
}
}
- bool Init = ConstructorLParen.isValid();
+ bool Init = ConstructorLParen.isValid() || ConstructorArgs.size() > 0;
// --- Choosing a constructor ---
CXXConstructorDecl *Constructor = 0;
bool HadMultipleCandidates = false;
@@ -1159,7 +1220,7 @@
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
- // C++0x [expr.new]p15:
+ // C++11 [expr.new]p15:
// A new-expression that creates an object of type T initializes that
// object as follows:
InitializationKind Kind
@@ -1169,9 +1230,12 @@
= !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
// - Otherwise, the new-initializer is interpreted according to the
// initialization rules of 8.5 for direct-initialization.
- : InitializationKind::CreateDirect(TypeRange.getBegin(),
- ConstructorLParen,
- ConstructorRParen);
+ : ListInitialization ? InitializationKind::CreateDirectList(
+ TypeRange.getBegin())
+ : InitializationKind::CreateDirect(
+ TypeRange.getBegin(),
+ ConstructorLParen,
+ ConstructorRParen);
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, AllocType);
@@ -4870,327 +4934,3 @@
return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo);
}
-
-//===----------------------------------------------------------------------===//
-// Lambdas.
-//===----------------------------------------------------------------------===//
-
-void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
- Declarator &ParamInfo,
- Scope *CurScope) {
- DeclContext *DC = CurContext;
- while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
- DC = DC->getParent();
-
- // Start constructing the lambda class.
- CXXRecordDecl *Class = CXXRecordDecl::Create(Context, TTK_Class, DC,
- Intro.Range.getBegin(),
- /*IdLoc=*/SourceLocation(),
- /*Id=*/0);
- Class->startDefinition();
- Class->setLambda(true);
- CurContext->addDecl(Class);
-
- // Build the call operator; we don't really have all the relevant information
- // at this point, but we need something to attach child declarations to.
- QualType MethodTy;
- TypeSourceInfo *MethodTyInfo;
- bool ExplicitParams = true;
- if (ParamInfo.getNumTypeObjects() == 0) {
- // C++11 [expr.prim.lambda]p4:
- // If a lambda-expression does not include a lambda-declarator, it is as
- // if the lambda-declarator were ().
- FunctionProtoType::ExtProtoInfo EPI;
- EPI.TypeQuals |= DeclSpec::TQ_const;
- MethodTy = Context.getFunctionType(Context.DependentTy,
- /*Args=*/0, /*NumArgs=*/0, EPI);
- MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
- ExplicitParams = false;
- } else {
- assert(ParamInfo.isFunctionDeclarator() &&
- "lambda-declarator is a function");
- DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getFunctionTypeInfo();
-
- // C++11 [expr.prim.lambda]p5:
- // 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. It is neither virtual nor declared volatile. [...]
- 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");
- MethodTy = MethodTyInfo->getType();
- assert(!MethodTy.isNull() && "no type from lambda declarator");
- }
-
- // 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
- // the lambda-expression’s parameter-declaration-clause and
- // trailing-return-type respectively.
- DeclarationName MethodName
- = Context.DeclarationNames.getCXXOperatorName(OO_Call);
- CXXMethodDecl *Method
- = CXXMethodDecl::Create(Context,
- Class,
- ParamInfo.getSourceRange().getEnd(),
- DeclarationNameInfo(MethodName,
- /*NameLoc=*/SourceLocation()),
- MethodTy,
- MethodTyInfo,
- /*isStatic=*/false,
- SC_None,
- /*isInline=*/true,
- /*isConstExpr=*/false,
- ParamInfo.getSourceRange().getEnd());
- Method->setAccess(AS_public);
- Class->addDecl(Method);
- Method->setLexicalDeclContext(DC); // FIXME: Minor hack.
-
- ProcessDeclAttributes(CurScope, Method, ParamInfo);
-
- // Enter a new evaluation context to insulate the block from any
- // cleanups from the enclosing full-expression.
- PushExpressionEvaluationContext(PotentiallyEvaluated);
-
- PushDeclContext(CurScope, Method);
-
- // Introduce the lambda scope.
- PushLambdaScope(Class);
- LambdaScopeInfo *LSI = getCurLambda();
- if (Intro.Default == LCD_ByCopy)
- LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
- else if (Intro.Default == LCD_ByRef)
- LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
- LSI->IntroducerRange = Intro.Range;
- LSI->ExplicitParams = ExplicitParams;
- LSI->Mutable = (Method->getTypeQualifiers() & Qualifiers::Const) == 0;
-
- // Handle explicit captures.
- for (llvm::SmallVector<LambdaCapture, 4>::const_iterator
- C = Intro.Captures.begin(),
- E = Intro.Captures.end();
- C != E; ++C) {
- if (C->Kind == LCK_This) {
- // C++11 [expr.prim.lambda]p8:
- // An identifier or this shall not appear more than once in a
- // lambda-capture.
- if (LSI->isCXXThisCaptured()) {
- Diag(C->Loc, diag::err_capture_more_than_once)
- << "'this'"
- << SourceRange(LSI->getCXXThisCapture().getLocation());
- continue;
- }
-
- // C++11 [expr.prim.lambda]p8:
- // If a lambda-capture includes a capture-default that is =, the
- // lambda-capture shall not contain this [...].
- if (Intro.Default == LCD_ByCopy) {
- Diag(C->Loc, diag::err_this_capture_with_copy_default);
- continue;
- }
-
- // C++11 [expr.prim.lambda]p12:
- // If this is captured by a local lambda expression, its nearest
- // enclosing function shall be a non-static member function.
- QualType ThisCaptureType = getCurrentThisType();
- if (ThisCaptureType.isNull()) {
- Diag(C->Loc, diag::err_this_capture) << true;
- continue;
- }
-
- CheckCXXThisCapture(C->Loc, /*Explicit=*/true);
- continue;
- }
-
- assert(C->Id && "missing identifier for capture");
-
- // C++11 [expr.prim.lambda]p8:
- // If a lambda-capture includes a capture-default that is &, the
- // identifiers in the lambda-capture shall not be preceded by &.
- // If a lambda-capture includes a capture-default that is =, [...]
- // each identifier it contains shall be preceded by &.
- if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) {
- Diag(C->Loc, diag::err_reference_capture_with_reference_default);
- continue;
- } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) {
- Diag(C->Loc, diag::err_copy_capture_with_copy_default);
- continue;
- }
-
- DeclarationNameInfo Name(C->Id, C->Loc);
- LookupResult R(*this, Name, LookupOrdinaryName);
- LookupName(R, CurScope);
- if (R.isAmbiguous())
- continue;
- if (R.empty()) {
- // FIXME: Disable corrections that would add qualification?
- CXXScopeSpec ScopeSpec;
- DeclFilterCCC<VarDecl> Validator;
- if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator))
- continue;
- }
-
- // C++11 [expr.prim.lambda]p10:
- // The identifiers in a capture-list are looked up using the usual rules
- // 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.
- VarDecl *Var = R.getAsSingle<VarDecl>();
- if (!Var) {
- Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id;
- continue;
- }
-
- if (!Var->hasLocalStorage()) {
- Diag(C->Loc, diag::err_capture_non_automatic_variable) << C->Id;
- Diag(Var->getLocation(), diag::note_previous_decl) << C->Id;
- continue;
- }
-
- // C++11 [expr.prim.lambda]p8:
- // An identifier or this shall not appear more than once in a
- // lambda-capture.
- if (LSI->isCaptured(Var)) {
- Diag(C->Loc, diag::err_capture_more_than_once)
- << C->Id
- << SourceRange(LSI->getCapture(Var).getLocation());
- continue;
- }
-
- TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
- TryCapture_ExplicitByVal;
- TryCaptureVar(Var, C->Loc, Kind);
- }
- LSI->finishedExplicitCaptures();
-
- // Set the parameters on the decl, if specified.
- if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
- FunctionProtoTypeLoc Proto =
- cast<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc());
- Method->setParams(Proto.getParams());
- CheckParmsForFunctionDef(Method->param_begin(),
- Method->param_end(),
- /*CheckParameterNames=*/false);
-
- // Introduce our parameters into the function scope
- for (unsigned p = 0, NumParams = Method->getNumParams(); p < NumParams; ++p) {
- ParmVarDecl *Param = Method->getParamDecl(p);
- Param->setOwningFunction(Method);
-
- // If this has an identifier, add it to the scope stack.
- if (Param->getIdentifier()) {
- CheckShadow(CurScope, Param);
-
- PushOnScopeChains(Param, CurScope);
- }
- }
- }
-
- const FunctionType *Fn = MethodTy->getAs<FunctionType>();
- QualType RetTy = Fn->getResultType();
- if (RetTy != Context.DependentTy) {
- LSI->ReturnType = RetTy;
- } else {
- LSI->HasImplicitReturnType = true;
- }
-
- // FIXME: Check return type is complete, !isObjCObjectType
-
-}
-
-void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
- // Leave the expression-evaluation context.
- DiscardCleanupsInEvaluationContext();
- PopExpressionEvaluationContext();
-
- // Leave the context of the lambda.
- PopDeclContext();
- PopFunctionScopeInfo();
-}
-
-ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,
- Stmt *Body, Scope *CurScope) {
- // Leave the expression-evaluation context.
- DiscardCleanupsInEvaluationContext();
- PopExpressionEvaluationContext();
-
- // Leave the context of the lambda.
- PopDeclContext();
-
- // FIXME: End-of-lambda checking
-
- // Collect information from the lambda scope.
- llvm::SmallVector<LambdaExpr::Capture, 4> Captures;
- llvm::SmallVector<Expr *, 4> CaptureInits;
- LambdaCaptureDefault CaptureDefault;
- CXXRecordDecl *Class;
- SourceRange IntroducerRange;
- bool ExplicitParams;
- {
- LambdaScopeInfo *LSI = getCurLambda();
- Class = LSI->Lambda;
- IntroducerRange = LSI->IntroducerRange;
- ExplicitParams = LSI->ExplicitParams;
-
- // Translate captures.
- for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
- LambdaScopeInfo::Capture From = LSI->Captures[I];
- assert(!From.isBlockCapture() && "Cannot capture __block variables");
- bool IsImplicit = I >= LSI->NumExplicitCaptures;
-
- // Handle 'this' capture.
- if (From.isThisCapture()) {
- Captures.push_back(LambdaExpr::Capture(From.getLocation(),
- IsImplicit,
- LCK_This));
- CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(),
- getCurrentThisType(),
- /*isImplicit=*/true));
- continue;
- }
-
- 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));
- CaptureInits.push_back(From.getCopyExpr());
- }
-
- switch (LSI->ImpCaptureStyle) {
- case CapturingScopeInfo::ImpCap_None:
- CaptureDefault = LCD_None;
- break;
-
- case CapturingScopeInfo::ImpCap_LambdaByval:
- CaptureDefault = LCD_ByCopy;
- break;
-
- case CapturingScopeInfo::ImpCap_LambdaByref:
- CaptureDefault = LCD_ByRef;
- break;
-
- case CapturingScopeInfo::ImpCap_Block:
- llvm_unreachable("block capture in lambda");
- break;
- }
-
- PopFunctionScopeInfo();
- }
-
- Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
- CaptureDefault, Captures, ExplicitParams,
- CaptureInits, Body->getLocEnd());
- (void)Lambda;
- Diag(StartLoc, diag::err_lambda_unsupported);
- return ExprError();
-}
Modified: cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp Tue Feb 14 03:11:10 2012
@@ -1279,9 +1279,6 @@
Method = LookupFactoryMethodInGlobalPool(Sel,
SourceRange(LBracLoc, RBracLoc),
receiverIsId);
- if (Method)
- DiagnoseAvailabilityOfDecl(Method, Loc, 0);
-
} else if (ReceiverType->isObjCClassType() ||
ReceiverType->isObjCQualifiedClassType()) {
// Handle messages to Class.
Modified: cfe/branches/tooling/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaInit.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaInit.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaInit.cpp Tue Feb 14 03:11:10 2012
@@ -1511,7 +1511,8 @@
IdentifierInfo *FieldName) {
assert(AnonField->isAnonymousStructOrUnion());
Decl *NextDecl = AnonField->getNextDeclInContext();
- while (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(NextDecl)) {
+ while (IndirectFieldDecl *IF =
+ dyn_cast_or_null<IndirectFieldDecl>(NextDecl)) {
if (FieldName && FieldName == IF->getAnonField()->getIdentifier())
return IF;
NextDecl = NextDecl->getNextDeclInContext();
@@ -2859,9 +2860,7 @@
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
- bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct ||
- Kind.getKind() == InitializationKind::IK_Value ||
- Kind.getKind() == InitializationKind::IK_Default);
+ bool AllowExplicit = Kind.AllowExplicit();
bool CopyInitialization = Kind.getKind() == InitializationKind::IK_Copy;
// - Otherwise, if T is a class type, constructors are considered. The
@@ -3064,8 +3063,10 @@
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, /*InitListSyntax=*/true);
+ Sequence, Kind.getKind() != InitializationKind::IK_Direct);
} else
Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
return;
@@ -3073,7 +3074,7 @@
InitListChecker CheckInitList(S, Entity, InitList,
DestType, /*VerifyOnly=*/true,
- Kind.getKind() != InitializationKind::IK_Direct ||
+ Kind.getKind() != InitializationKind::IK_DirectList ||
!S.getLangOptions().CPlusPlus0x);
if (CheckInitList.HadError()) {
Sequence.SetFailed(InitializationSequence::FK_ListInitializationFailed);
@@ -3117,7 +3118,7 @@
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
- bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
+ bool AllowExplicit = Kind.AllowExplicit();
const RecordType *T1RecordType = 0;
if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) &&
@@ -3479,7 +3480,7 @@
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
- bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct);
+ bool AllowExplicit = Kind.AllowExplicit();
InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1);
@@ -3642,7 +3643,7 @@
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
- bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
+ bool AllowExplicit = Kind.AllowExplicit();
if (const RecordType *DestRecordType = DestType->getAs<RecordType>()) {
// The type we're converting to is a class type. Enumerate its constructors
@@ -3742,8 +3743,10 @@
if (isa<CXXConstructorDecl>(Function)) {
// Add the user-defined conversion step. Any cv-qualification conversion is
- // subsumed by the initialization.
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType,
+ // subsumed by the initialization. Per DR5, the created temporary is of the
+ // cv-unqualified type of the destination.
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl,
+ DestType.getUnqualifiedType(),
HadMultipleCandidates);
return;
}
@@ -3751,7 +3754,7 @@
// Add the user-defined conversion step that calls the conversion function.
QualType ConvType = Function->getCallResultType();
if (ConvType->getAs<RecordType>()) {
- // If we're converting to a class type, there may be an copy if
+ // If we're converting to a class type, there may be an copy of
// the resulting temporary object (possible to create an object of
// a base class type). That copy is not a separate conversion, so
// we just make a note of the actual destination type (possibly a
@@ -3967,11 +3970,13 @@
SourceType = Initializer->getType();
}
- // - If the initializer is a braced-init-list, the object is
- // list-initialized (8.5.4).
- if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
- TryListInitialization(S, Entity, Kind, InitList, *this);
- return;
+ // - If the initializer is a (non-parenthesized) braced-init-list, the
+ // object is list-initialized (8.5.4).
+ if (Kind.getKind() != InitializationKind::IK_Direct) {
+ if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
+ TryListInitialization(S, Entity, Kind, InitList, *this);
+ return;
+ }
}
// - If the destination type is a reference type, see 8.5.3.
@@ -4705,6 +4710,13 @@
}
}
+ if (Kind.getKind() == InitializationKind::IK_Direct &&
+ !Kind.isExplicitCast()) {
+ // Rebuild the ParenListExpr.
+ SourceRange ParenRange = Kind.getParenRange();
+ return S.ActOnParenListExpr(ParenRange.getBegin(), ParenRange.getEnd(),
+ move(Args));
+ }
assert(Kind.getKind() == InitializationKind::IK_Copy ||
Kind.isExplicitCast());
return ExprResult(Args.release()[0]);
@@ -4898,7 +4910,7 @@
Loc, ConstructorArgs))
return ExprError();
- // Build the an expression that constructs a temporary.
+ // Build an expression that constructs a temporary.
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
move_arg(ConstructorArgs),
HadMultipleCandidates,
@@ -5018,7 +5030,7 @@
InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(Ty);
InitListChecker PerformInitList(S, IsTemporary ? TempEntity : Entity,
InitList, Ty, /*VerifyOnly=*/false,
- Kind.getKind() != InitializationKind::IK_Direct ||
+ Kind.getKind() != InitializationKind::IK_DirectList ||
!S.getLangOptions().CPlusPlus0x);
if (PerformInitList.HadError())
return ExprError();
@@ -5040,10 +5052,19 @@
}
case SK_ListConstructorCall: {
+ // 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?
+ InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
+ Entity.getType().getNonReferenceType());
+ bool UseTemporary = Entity.getType()->isReferenceType();
InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
MultiExprArg Arg(InitList->getInits(), InitList->getNumInits());
- CurInit = PerformConstructorInitialization(S, Entity, Kind,
- move(Arg), *Step,
+ CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity :
+ Entity,
+ Kind, move(Arg), *Step,
ConstructorInitRequiresZeroInit);
break;
}
@@ -5539,7 +5560,7 @@
QualType DestType = Entity.getType();
InitListChecker DiagnoseInitList(S, Entity, InitList,
DestType, /*VerifyOnly=*/false,
- Kind.getKind() != InitializationKind::IK_Direct ||
+ Kind.getKind() != InitializationKind::IK_DirectList ||
!S.getLangOptions().CPlusPlus0x);
assert(DiagnoseInitList.HadError() &&
"Inconsistent init list check result.");
Modified: cfe/branches/tooling/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaOverload.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaOverload.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaOverload.cpp Tue Feb 14 03:11:10 2012
@@ -2211,7 +2211,7 @@
Qualifiers ToQuals = ToPointee.getQualifiers();
if (!ToPointee->isObjCLifetimeType() ||
ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing ||
- !ToQuals.withoutObjCGLifetime().empty())
+ !ToQuals.withoutObjCLifetime().empty())
return false;
// Argument must be a pointer to __strong to __weak.
@@ -2750,6 +2750,76 @@
return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
}
+static OverloadingResult
+IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
+ CXXRecordDecl *To,
+ UserDefinedConversionSequence &User,
+ OverloadCandidateSet &CandidateSet,
+ bool AllowExplicit) {
+ DeclContext::lookup_iterator Con, ConEnd;
+ for (llvm::tie(Con, ConEnd) = S.LookupConstructors(To);
+ Con != ConEnd; ++Con) {
+ NamedDecl *D = *Con;
+ DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
+ // Find the constructor (which may be a template).
+ CXXConstructorDecl *Constructor = 0;
+ FunctionTemplateDecl *ConstructorTmpl
+ = dyn_cast<FunctionTemplateDecl>(D);
+ if (ConstructorTmpl)
+ Constructor
+ = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
+ else
+ Constructor = cast<CXXConstructorDecl>(D);
+
+ bool Usable = !Constructor->isInvalidDecl() &&
+ S.isInitListConstructor(Constructor) &&
+ (AllowExplicit || !Constructor->isExplicit());
+ if (Usable) {
+ if (ConstructorTmpl)
+ S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+ /*ExplicitArgs*/ 0,
+ &From, 1, CandidateSet,
+ /*SuppressUserConversions=*/true);
+ else
+ S.AddOverloadCandidate(Constructor, FoundDecl,
+ &From, 1, CandidateSet,
+ /*SuppressUserConversions=*/true);
+ }
+ }
+
+ bool HadMultipleCandidates = (CandidateSet.size() > 1);
+
+ OverloadCandidateSet::iterator Best;
+ switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
+ case OR_Success: {
+ // Record the standard conversion we used and the conversion function.
+ CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
+ S.MarkFunctionReferenced(From->getLocStart(), Constructor);
+
+ QualType ThisType = Constructor->getThisType(S.Context);
+ // Initializer lists don't have conversions as such.
+ User.Before.setAsIdentityConversion();
+ User.HadMultipleCandidates = HadMultipleCandidates;
+ User.ConversionFunction = Constructor;
+ User.FoundConversionFunction = Best->FoundDecl;
+ User.After.setAsIdentityConversion();
+ User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
+ User.After.setAllToTypes(ToType);
+ return OR_Success;
+ }
+
+ case OR_No_Viable_Function:
+ return OR_No_Viable_Function;
+ case OR_Deleted:
+ return OR_Deleted;
+ case OR_Ambiguous:
+ return OR_Ambiguous;
+ }
+
+ llvm_unreachable("Invalid OverloadResult!");
+}
+
/// Determines whether there is a user-defined conversion sequence
/// (C++ [over.ics.user]) that converts expression From to the type
/// ToType. If such a conversion exists, User will contain the
@@ -2762,8 +2832,8 @@
/// functions (C++0x [class.conv.fct]p2).
static OverloadingResult
IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
- UserDefinedConversionSequence& User,
- OverloadCandidateSet& CandidateSet,
+ UserDefinedConversionSequence &User,
+ OverloadCandidateSet &CandidateSet,
bool AllowExplicit) {
// Whether we will only visit constructors.
bool ConstructorsOnly = false;
@@ -2796,9 +2866,17 @@
Expr **Args = &From;
unsigned NumArgs = 1;
bool ListInitializing = false;
- // If we're list-initializing, we pass the individual elements as
- // arguments, not the entire list.
if (InitListExpr *InitList = dyn_cast<InitListExpr>(From)) {
+ // But first, see if there is an init-list-contructor that will work.
+ OverloadingResult Result = IsInitializerListConstructorConversion(
+ S, From, ToType, ToRecordDecl, User, CandidateSet, AllowExplicit);
+ if (Result != OR_No_Viable_Function)
+ return Result;
+ // Never mind.
+ CandidateSet.clear();
+
+ // If we're list-initializing, we pass the individual elements as
+ // arguments, not the entire list.
Args = InitList->getInits();
NumArgs = InitList->getNumInits();
ListInitializing = true;
@@ -7583,9 +7661,11 @@
if (Meth->isMoveAssignmentOperator())
return oc_implicit_move_assignment;
- assert(Meth->isCopyAssignmentOperator()
- && "implicit method is not copy assignment operator?");
- return oc_implicit_copy_assignment;
+ if (Meth->isCopyAssignmentOperator())
+ return oc_implicit_copy_assignment;
+
+ assert(isa<CXXConversionDecl>(Meth) && "expected conversion");
+ return oc_method;
}
return isTemplate ? oc_function_template : oc_function;
@@ -9585,7 +9665,7 @@
// Build the actual expression node.
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
- HadMultipleCandidates);
+ HadMultipleCandidates, OpLoc);
if (FnExpr.isInvalid())
return ExprError();
@@ -10011,12 +10091,12 @@
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
- DeclarationNameLoc LocInfo;
- LocInfo.CXXOperatorName.BeginOpNameLoc = LLoc.getRawEncoding();
- LocInfo.CXXOperatorName.EndOpNameLoc = RLoc.getRawEncoding();
+ DeclarationNameInfo OpLocInfo(OpName, LLoc);
+ OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
HadMultipleCandidates,
- LLoc, LocInfo);
+ OpLocInfo.getLoc(),
+ OpLocInfo.getInfo());
if (FnExpr.isInvalid())
return ExprError();
@@ -10521,8 +10601,13 @@
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
MethodArgs[ArgIdx + 1] = Args[ArgIdx];
+ DeclarationNameInfo OpLocInfo(
+ Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc);
+ OpLocInfo.setCXXOperatorNameRange(SourceRange(LParenLoc, RParenLoc));
ExprResult NewFn = CreateFunctionRefExpr(*this, Method,
- HadMultipleCandidates);
+ HadMultipleCandidates,
+ OpLocInfo.getLoc(),
+ OpLocInfo.getInfo());
if (NewFn.isInvalid())
return true;
@@ -10698,7 +10783,7 @@
// Build the operator call.
ExprResult FnExpr = CreateFunctionRefExpr(*this, Method,
- HadMultipleCandidates);
+ HadMultipleCandidates, OpLoc);
if (FnExpr.isInvalid())
return ExprError();
Modified: cfe/branches/tooling/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaStmt.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaStmt.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaStmt.cpp Tue Feb 14 03:11:10 2012
@@ -1798,7 +1798,7 @@
CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
if (CurCap->HasImplicitReturnType) {
QualType ReturnT;
- if (RetValExp) {
+ if (RetValExp && !isa<InitListExpr>(RetValExp)) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
@@ -1808,7 +1808,15 @@
ReturnT = RetValExp->getType();
else
ReturnT = Context.DependentTy;
- } else {
+ } else {
+ if (RetValExp) {
+ // C++11 [expr.lambda.prim]p4 bans inferring the result from an
+ // initializer list, because it is not an expression (even
+ // though we represent it as one). We still deduce 'void'.
+ Diag(ReturnLoc, diag::err_lambda_return_init_list)
+ << RetValExp->getSourceRange();
+ }
+
ReturnT = Context.VoidTy;
}
// We require the return types to strictly match here.
Modified: cfe/branches/tooling/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplate.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplate.cpp Tue Feb 14 03:11:10 2012
@@ -1023,6 +1023,11 @@
NumOuterTemplateParamLists,
OuterTemplateParamLists);
+ // Add alignment attributes if necessary; these attributes are checked when
+ // the ASTContext lays out the structure.
+ AddAlignmentAttributesForRecord(NewClass);
+ AddMsStructLayoutForRecord(NewClass);
+
ClassTemplateDecl *NewTemplate
= ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
DeclarationName(Name), TemplateParams,
@@ -6837,6 +6842,11 @@
this->Loc = Loc;
this->Entity = Entity;
}
+
+ ExprResult TransformLambdaExpr(LambdaExpr *E) {
+ // Lambdas never need to be transformed.
+ return E;
+ }
};
}
Modified: cfe/branches/tooling/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplateDeduction.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplateDeduction.cpp Tue Feb 14 03:11:10 2012
@@ -2019,7 +2019,8 @@
const TemplateArgumentList &TemplateArgs,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
TemplateDeductionInfo &Info) {
- // Trap errors.
+ // Unevaluated SFINAE context.
+ EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
Sema::SFINAETrap Trap(S);
Sema::ContextRAII SavedContext(S, Partial);
@@ -2145,7 +2146,11 @@
// argument list if the template arguments of the partial
// specialization can be deduced from the actual template argument
// list (14.8.2).
+
+ // Unevaluated SFINAE context.
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
+
SmallVector<DeducedTemplateArgument, 4> Deduced;
Deduced.resize(Partial->getTemplateParameters()->size());
if (TemplateDeductionResult Result
@@ -2226,8 +2231,8 @@
return TDK_Success;
}
- // Substitution of the explicit template arguments into a function template
- /// is a SFINAE context. Trap any errors that might occur.
+ // Unevaluated SFINAE context.
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
// C++ [temp.arg.explicit]p3:
@@ -2286,33 +2291,45 @@
}
}
+ const FunctionProtoType *Proto
+ = Function->getType()->getAs<FunctionProtoType>();
+ assert(Proto && "Function template does not have a prototype?");
+
// Instantiate the types of each of the function parameters given the
- // explicitly-specified template arguments.
- if (SubstParmTypes(Function->getLocation(),
+ // explicitly-specified template arguments. If the function has a trailing
+ // return type, substitute it after the arguments to ensure we substitute
+ // in lexical order.
+ if (Proto->hasTrailingReturn() &&
+ SubstParmTypes(Function->getLocation(),
Function->param_begin(), Function->getNumParams(),
MultiLevelTemplateArgumentList(*ExplicitArgumentList),
ParamTypes))
return TDK_SubstitutionFailure;
- // If the caller wants a full function type back, instantiate the return
- // type and form that function type.
- if (FunctionType) {
- // FIXME: exception-specifications?
- const FunctionProtoType *Proto
- = Function->getType()->getAs<FunctionProtoType>();
- assert(Proto && "Function template does not have a prototype?");
+ // Instantiate the return type.
+ // FIXME: exception-specifications?
+ QualType ResultType
+ = SubstType(Proto->getResultType(),
+ MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+ Function->getTypeSpecStartLoc(),
+ Function->getDeclName());
+ if (ResultType.isNull() || Trap.hasErrorOccurred())
+ return TDK_SubstitutionFailure;
- QualType ResultType
- = SubstType(Proto->getResultType(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
- Function->getTypeSpecStartLoc(),
- Function->getDeclName());
- if (ResultType.isNull() || Trap.hasErrorOccurred())
- return TDK_SubstitutionFailure;
+ // Instantiate the types of each of the function parameters given the
+ // explicitly-specified template arguments if we didn't do so earlier.
+ if (!Proto->hasTrailingReturn() &&
+ SubstParmTypes(Function->getLocation(),
+ Function->param_begin(), Function->getNumParams(),
+ MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+ ParamTypes))
+ return TDK_SubstitutionFailure;
+ if (FunctionType) {
*FunctionType = BuildFunctionType(ResultType,
ParamTypes.data(), ParamTypes.size(),
Proto->isVariadic(),
+ Proto->hasTrailingReturn(),
Proto->getTypeQuals(),
Proto->getRefQualifier(),
Function->getLocation(),
@@ -2449,8 +2466,8 @@
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
- // Template argument deduction for function templates in a SFINAE context.
- // Trap any errors that might occur.
+ // Unevaluated SFINAE context.
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
// Enter a new template instantiation context while we instantiate the
@@ -3172,8 +3189,8 @@
NumExplicitlySpecified = Deduced.size();
}
- // Template argument deduction for function templates in a SFINAE context.
- // Trap any errors that might occur.
+ // Unevaluated SFINAE context.
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
Deduced.resize(TemplateParams->size());
@@ -3257,8 +3274,8 @@
A = A.getUnqualifiedType();
}
- // Template argument deduction for function templates in a SFINAE context.
- // Trap any errors that might occur.
+ // Unevaluated SFINAE context.
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
// C++ [temp.deduct.conv]p1:
@@ -3362,6 +3379,11 @@
return Result;
}
}
+
+ ExprResult TransformLambdaExpr(LambdaExpr *E) {
+ // Lambdas never need to be transformed.
+ return E;
+ }
};
}
Modified: cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp Tue Feb 14 03:11:10 2012
@@ -732,6 +732,14 @@
/// this declaration.
Decl *TransformDecl(SourceLocation Loc, Decl *D);
+ void transformAttrs(Decl *Old, Decl *New) {
+ SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
+ }
+
+ void transformedLocalDecl(Decl *Old, Decl *New) {
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
+ }
+
/// \brief Transform the definition of the given declaration by
/// instantiating it.
Decl *TransformDefinition(SourceLocation Loc, Decl *D);
@@ -1833,14 +1841,16 @@
FieldDecl *NewField = FieldsWithMemberInitializers[I].second;
Expr *OldInit = OldField->getInClassInitializer();
- SourceLocation LParenLoc, RParenLoc;
- ASTOwningVector<Expr*> NewArgs(*this);
- if (InstantiateInitializer(OldInit, TemplateArgs, LParenLoc, NewArgs,
- RParenLoc))
+ ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
+ /*CXXDirectInit=*/false);
+ if (NewInit.isInvalid())
NewField->setInvalidDecl();
else {
- assert(NewArgs.size() == 1 && "wrong number of in-class initializers");
- ActOnCXXInClassMemberInitializer(NewField, LParenLoc, NewArgs[0]);
+ Expr *Init = NewInit.take();
+ assert(Init && "no-argument initializer in class");
+ assert(!isa<ParenListExpr>(Init) && "call-style init in class");
+ ActOnCXXInClassMemberInitializer(NewField,
+ Init->getSourceRange().getBegin(), Init);
}
}
@@ -1863,6 +1873,7 @@
ActOnFinishDelayedMemberInitializers(Instantiation);
if (TSK == TSK_ImplicitInstantiation) {
+ Instantiation->setLocation(Pattern->getLocation());
Instantiation->setLocStart(Pattern->getInnerLocStart());
Instantiation->setRBraceLoc(Pattern->getRBraceLoc());
}
Modified: cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Feb 14 03:11:10 2012
@@ -252,66 +252,6 @@
return Inst;
}
-/// \brief Instantiate an initializer, breaking it into separate
-/// initialization arguments.
-///
-/// \param Init The initializer to instantiate.
-///
-/// \param TemplateArgs Template arguments to be substituted into the
-/// initializer.
-///
-/// \param NewArgs Will be filled in with the instantiation arguments.
-///
-/// \returns true if an error occurred, false otherwise
-bool Sema::InstantiateInitializer(Expr *Init,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation &LParenLoc,
- ASTOwningVector<Expr*> &NewArgs,
- SourceLocation &RParenLoc) {
- NewArgs.clear();
- LParenLoc = SourceLocation();
- RParenLoc = SourceLocation();
-
- if (!Init)
- return false;
-
- if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
- Init = ExprTemp->getSubExpr();
-
- while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
- Init = Binder->getSubExpr();
-
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
- Init = ICE->getSubExprAsWritten();
-
- if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
- LParenLoc = ParenList->getLParenLoc();
- RParenLoc = ParenList->getRParenLoc();
- return SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(),
- true, TemplateArgs, NewArgs);
- }
-
- if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {
- if (!isa<CXXTemporaryObjectExpr>(Construct)) {
- if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true,
- TemplateArgs, NewArgs))
- return true;
-
- // FIXME: Fake locations!
- LParenLoc = PP.getLocForEndOfToken(Init->getLocStart());
- RParenLoc = LParenLoc;
- return false;
- }
- }
-
- ExprResult Result = SubstExpr(Init, TemplateArgs);
- if (Result.isInvalid())
- return true;
-
- NewArgs.push_back(Result.takeAs<Expr>());
- return false;
-}
-
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
// If this is the variable for an anonymous struct or union,
// instantiate the anonymous struct/union type first.
@@ -342,7 +282,7 @@
D->getStorageClass(),
D->getStorageClassAsWritten());
Var->setThreadSpecified(D->isThreadSpecified());
- Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
+ Var->setInitStyle(D->getInitStyle());
Var->setCXXForRangeDecl(D->isCXXForRangeDecl());
Var->setConstexpr(D->isConstexpr());
@@ -403,25 +343,16 @@
SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
// Instantiate the initializer.
- SourceLocation LParenLoc, RParenLoc;
- ASTOwningVector<Expr*> InitArgs(SemaRef);
- if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc,
- InitArgs, RParenLoc)) {
+ ExprResult Init = SemaRef.SubstInitializer(D->getInit(), TemplateArgs,
+ D->getInitStyle() == VarDecl::CallInit);
+ if (!Init.isInvalid()) {
bool TypeMayContainAuto = true;
- if (D->hasCXXDirectInitializer()) {
- // Add the direct initializer to the declaration.
- SemaRef.AddCXXDirectInitializerToDecl(Var,
- LParenLoc,
- move_arg(InitArgs),
- RParenLoc,
- TypeMayContainAuto);
- } else if (InitArgs.size() == 0) {
+ if (Init.get()) {
+ bool DirectInit = D->isDirectInit();
+ SemaRef.AddInitializerToDecl(Var, Init.take(), DirectInit,
+ TypeMayContainAuto);
+ } else
SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto);
- } else {
- assert(InitArgs.size() == 1);
- Expr *Init = InitArgs.take()[0];
- SemaRef.AddInitializerToDecl(Var, Init, false, TypeMayContainAuto);
- }
} else {
// FIXME: Not too happy about invalidating the declaration
// because of a bogus initializer.
@@ -1103,7 +1034,7 @@
D->getLocation(), D->getDeclName(), T, TInfo,
D->getStorageClass(), D->getStorageClassAsWritten(),
D->isInlineSpecified(), D->hasWrittenPrototype(),
- /*isConstexpr*/ false);
+ D->isConstexpr());
if (QualifierLoc)
Function->setQualifierInfo(QualifierLoc);
@@ -1448,7 +1379,7 @@
StartLoc, NameInfo, T, TInfo,
Constructor->isExplicit(),
Constructor->isInlineSpecified(),
- false, /*isConstexpr*/ false);
+ false, Constructor->isConstexpr());
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
@@ -1459,7 +1390,7 @@
StartLoc, NameInfo, T, TInfo,
Conversion->isInlineSpecified(),
Conversion->isExplicit(),
- /*isConstexpr*/ false,
+ Conversion->isConstexpr(),
Conversion->getLocEnd());
} else {
Method = CXXMethodDecl::Create(SemaRef.Context, Record,
@@ -1467,7 +1398,7 @@
D->isStatic(),
D->getStorageClassAsWritten(),
D->isInlineSpecified(),
- /*isConstexpr*/ false, D->getLocEnd());
+ D->isConstexpr(), D->getLocEnd());
}
if (QualifierLoc)
@@ -2374,13 +2305,6 @@
EPI));
}
- // C++0x [dcl.constexpr]p6: If the instantiated template specialization of
- // a constexpr function template satisfies the requirements for a constexpr
- // function, then it is a constexpr function.
- if (Tmpl->isConstexpr() &&
- SemaRef.CheckConstexprFunctionDecl(New, Sema::CCK_Instantiation))
- New->setConstexpr(true);
-
const FunctionDecl* Definition = Tmpl;
// Get the definition. Leaves the variable unchanged if undefined.
@@ -2743,18 +2667,6 @@
}
}
-static MultiInitializer CreateMultiInitializer(SmallVectorImpl<Expr*> &Args,
- const CXXCtorInitializer *Init) {
- // FIXME: This is a hack that will do slightly the wrong thing for an
- // initializer of the form foo({...}).
- // The right thing to do would be to modify InstantiateInitializer to create
- // the MultiInitializer.
- if (Args.size() == 1 && isa<InitListExpr>(Args[0]))
- return MultiInitializer(Args[0]);
- return MultiInitializer(Init->getLParenLoc(), Args.data(),
- Args.size(), Init->getRParenLoc());
-}
-
void
Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
const CXXConstructorDecl *Tmpl,
@@ -2774,9 +2686,6 @@
if (!Init->isWritten())
continue;
- SourceLocation LParenLoc, RParenLoc;
- ASTOwningVector<Expr*> NewArgs(*this);
-
SourceLocation EllipsisLoc;
if (Init->isPackExpansion()) {
@@ -2804,8 +2713,9 @@
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
// Instantiate the initializer.
- if (InstantiateInitializer(Init->getInit(), TemplateArgs,
- LParenLoc, NewArgs, RParenLoc)) {
+ ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs,
+ /*CXXDirectInit=*/true);
+ if (TempInit.isInvalid()) {
AnyErrors = true;
break;
}
@@ -2821,9 +2731,8 @@
}
// Build the initializer.
- MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),
- BaseTInfo, MultiInit,
+ BaseTInfo, TempInit.take(),
New->getParent(),
SourceLocation());
if (NewInit.isInvalid()) {
@@ -2832,15 +2741,15 @@
}
NewInits.push_back(NewInit.get());
- NewArgs.clear();
}
continue;
}
// Instantiate the initializer.
- if (InstantiateInitializer(Init->getInit(), TemplateArgs,
- LParenLoc, NewArgs, RParenLoc)) {
+ ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs,
+ /*CXXDirectInit=*/true);
+ if (TempInit.isInvalid()) {
AnyErrors = true;
continue;
}
@@ -2857,13 +2766,11 @@
continue;
}
- MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
-
if (Init->isBaseInitializer())
- NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, MultiInit,
+ NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.take(),
New->getParent(), EllipsisLoc);
else
- NewInit = BuildDelegatingInitializer(TInfo, MultiInit,
+ NewInit = BuildDelegatingInitializer(TInfo, TempInit.take(),
cast<CXXRecordDecl>(CurContext->getParent()));
} else if (Init->isMemberInitializer()) {
FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
@@ -2876,8 +2783,7 @@
continue;
}
- MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
- NewInit = BuildMemberInitializer(Member, MultiInit,
+ NewInit = BuildMemberInitializer(Member, TempInit.take(),
Init->getSourceLocation());
} else if (Init->isIndirectMemberInitializer()) {
IndirectFieldDecl *IndirectMember =
@@ -2891,8 +2797,7 @@
continue;
}
- MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
- NewInit = BuildMemberInitializer(IndirectMember, MultiInit,
+ NewInit = BuildMemberInitializer(IndirectMember, TempInit.take(),
Init->getSourceLocation());
}
@@ -2900,9 +2805,6 @@
AnyErrors = true;
New->setInvalidDecl();
} else {
- // FIXME: It would be nice if ASTOwningVector had a release function.
- NewArgs.take();
-
NewInits.push_back(NewInit.get());
}
}
@@ -2915,6 +2817,45 @@
AnyErrors);
}
+ExprResult Sema::SubstInitializer(Expr *Init,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ bool CXXDirectInit) {
+ // Initializers are instantiated like expressions, except that various outer
+ // layers are stripped.
+ if (!Init)
+ return Owned(Init);
+
+ if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
+ Init = ExprTemp->getSubExpr();
+
+ while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
+ Init = Binder->getSubExpr();
+
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
+ Init = ICE->getSubExprAsWritten();
+
+ // If this is a direct-initializer, we take apart CXXConstructExprs.
+ // Everything else is passed through.
+ CXXConstructExpr *Construct;
+ if (!CXXDirectInit || !(Construct = dyn_cast<CXXConstructExpr>(Init)) ||
+ isa<CXXTemporaryObjectExpr>(Construct))
+ return SubstExpr(Init, TemplateArgs);
+
+ ASTOwningVector<Expr*> NewArgs(*this);
+ if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true,
+ TemplateArgs, NewArgs))
+ return ExprError();
+
+ // Treat an empty initializer like none.
+ if (NewArgs.empty())
+ return Owned((Expr*)0);
+
+ // Build a ParenListExpr to represent anything else.
+ // FIXME: Fake locations!
+ SourceLocation Loc = PP.getLocForEndOfToken(Init->getLocStart());
+ return ActOnParenListExpr(Loc, Loc, move_arg(NewArgs));
+}
+
// TODO: this could be templated if the various decl types used the
// same method name.
static bool isInstantiationOf(ClassTemplateDecl *Pattern,
Modified: cfe/branches/tooling/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaType.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaType.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaType.cpp Tue Feb 14 03:11:10 2012
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "clang/Basic/OpenCL.h"
@@ -1434,6 +1435,8 @@
///
/// \param Variadic Whether this is a variadic function type.
///
+/// \param HasTrailingReturn Whether this function has a trailing return type.
+///
/// \param Quals The cvr-qualifiers to be applied to the function type.
///
/// \param Loc The location of the entity whose type involves this
@@ -1448,7 +1451,8 @@
QualType Sema::BuildFunctionType(QualType T,
QualType *ParamTypes,
unsigned NumParamTypes,
- bool Variadic, unsigned Quals,
+ bool Variadic, bool HasTrailingReturn,
+ unsigned Quals,
RefQualifierKind RefQualifier,
SourceLocation Loc, DeclarationName Entity,
FunctionType::ExtInfo Info) {
@@ -1487,6 +1491,7 @@
FunctionProtoType::ExtProtoInfo EPI;
EPI.Variadic = Variadic;
+ EPI.HasTrailingReturn = HasTrailingReturn;
EPI.TypeQuals = Quals;
EPI.RefQualifier = RefQualifier;
EPI.ExtInfo = Info;
@@ -1498,7 +1503,6 @@
///
/// \param T the type to which the member pointer refers.
/// \param Class the class type into which the member pointer points.
-/// \param CVR Qualifiers applied to the member pointer type
/// \param Loc the location where this type begins
/// \param Entity the name of the entity that will have this member pointer type
///
@@ -1786,8 +1790,8 @@
if (D.getAttributes())
distributeTypeAttrsFromDeclarator(state, T);
- // C++0x [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
- // In C++0x, a function declarator using 'auto' must have a trailing return
+ // C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
+ // In C++11, a function declarator using 'auto' must have a trailing return
// type (this is checked later) and we can skip this. In other languages
// using auto, we need to check regardless.
if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
@@ -1849,7 +1853,7 @@
if (D.isFunctionDeclarator())
Error = 10;
- // C++0x [dcl.spec.auto]p2: 'auto' is always fine if the declarator
+ // C++11 [dcl.spec.auto]p2: 'auto' is always fine if the declarator
// contains a trailing return type. That is only legal at the outermost
// level. Check all declarator chunks (outermost first) anyway, to give
// better diagnostics.
@@ -1890,7 +1894,7 @@
case Declarator::ForContext:
case Declarator::BlockLiteralContext:
case Declarator::LambdaExprContext:
- // C++0x [dcl.type]p3:
+ // C++11 [dcl.type]p3:
// A type-specifier-seq shall not define a class or enumeration unless
// it appears in the type-id of an alias-declaration (7.1.3) that is not
// the declaration of a template-declaration.
@@ -1934,6 +1938,66 @@
return T;
}
+std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy) {
+ std::string Quals =
+ Qualifiers::fromCVRMask(FnTy->getTypeQuals()).getAsString();
+
+ switch (FnTy->getRefQualifier()) {
+ case RQ_None:
+ break;
+
+ case RQ_LValue:
+ if (!Quals.empty())
+ Quals += ' ';
+ Quals += '&';
+ break;
+
+ case RQ_RValue:
+ if (!Quals.empty())
+ Quals += ' ';
+ Quals += "&&";
+ break;
+ }
+
+ return Quals;
+}
+
+/// Check that the function type T, which has a cv-qualifier or a ref-qualifier,
+/// can be contained within the declarator chunk DeclType, and produce an
+/// appropriate diagnostic if not.
+static void checkQualifiedFunction(Sema &S, QualType T,
+ DeclaratorChunk &DeclType) {
+ // C++98 [dcl.fct]p4 / C++11 [dcl.fct]p6: a function type with a
+ // cv-qualifier or a ref-qualifier can only appear at the topmost level
+ // of a type.
+ int DiagKind = -1;
+ switch (DeclType.Kind) {
+ case DeclaratorChunk::Paren:
+ case DeclaratorChunk::MemberPointer:
+ // These cases are permitted.
+ return;
+ case DeclaratorChunk::Array:
+ case DeclaratorChunk::Function:
+ // These cases don't allow function types at all; no need to diagnose the
+ // qualifiers separately.
+ return;
+ case DeclaratorChunk::BlockPointer:
+ DiagKind = 0;
+ break;
+ case DeclaratorChunk::Pointer:
+ DiagKind = 1;
+ break;
+ case DeclaratorChunk::Reference:
+ DiagKind = 2;
+ break;
+ }
+
+ assert(DiagKind != -1);
+ S.Diag(DeclType.Loc, diag::err_compound_qualified_function_type)
+ << DiagKind << isa<FunctionType>(T.IgnoreParens()) << T
+ << getFunctionQualifiersAsString(T->castAs<FunctionProtoType>());
+}
+
static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
QualType declSpecType,
TypeSourceInfo *TInfo) {
@@ -1965,6 +2029,11 @@
D.getContext() == Declarator::AliasDeclContext ||
D.getContext() == Declarator::AliasTemplateContext;
+ // Does T refer to a function type with a cv-qualifier or a ref-qualifier?
+ bool IsQualifiedFunction = T->isFunctionProtoType() &&
+ (T->castAs<FunctionProtoType>()->getTypeQuals() != 0 ||
+ T->castAs<FunctionProtoType>()->getRefQualifier() != RQ_None);
+
// Walk the DeclTypeInfo, building the recursive type as we go.
// DeclTypeInfos are ordered from the identifier out, which is
// opposite of what we want :).
@@ -1972,6 +2041,10 @@
unsigned chunkIndex = e - i - 1;
state.setCurrentChunkIndex(chunkIndex);
DeclaratorChunk &DeclType = D.getTypeObject(chunkIndex);
+ if (IsQualifiedFunction) {
+ checkQualifiedFunction(S, T, DeclType);
+ IsQualifiedFunction = DeclType.Kind == DeclaratorChunk::Paren;
+ }
switch (DeclType.Kind) {
case DeclaratorChunk::Paren:
T = S.BuildParenType(T);
@@ -2053,6 +2126,7 @@
// does not have a K&R-style identifier list), then the arguments are part
// of the type, otherwise the argument list is ().
const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
+ IsQualifiedFunction = FTI.TypeQuals || FTI.hasRefQualifier();
// Check for auto functions and trailing return type and adjust the
// return type accordingly.
@@ -2185,6 +2259,7 @@
FunctionProtoType::ExtProtoInfo EPI;
EPI.Variadic = FTI.isVariadic;
+ EPI.HasTrailingReturn = FTI.TrailingReturnType;
EPI.TypeQuals = FTI.TypeQuals;
EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None
: FTI.RefQualifierIsLValueRef? RQ_LValue
@@ -2403,113 +2478,57 @@
FnTy->getNumArgs(), EPI);
}
- // C++0x [dcl.fct]p6:
- // A ref-qualifier shall only be part of the function type for a
- // non-static member function, the function type to which a pointer to
- // member refers, or the top-level function type of a function typedef
- // declaration.
- if ((FnTy->getTypeQuals() != 0 || FnTy->getRefQualifier()) &&
- !(D.getContext() == Declarator::TemplateTypeArgContext &&
- !D.isFunctionDeclarator()) && !IsTypedefName &&
- (FreeFunction ||
- D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
- if (D.getContext() == Declarator::TemplateTypeArgContext) {
- // Accept qualified function types as template type arguments as a GNU
- // extension. This is also the subject of C++ core issue 547.
- std::string Quals;
- if (FnTy->getTypeQuals() != 0)
- Quals = Qualifiers::fromCVRMask(FnTy->getTypeQuals()).getAsString();
-
- switch (FnTy->getRefQualifier()) {
- case RQ_None:
- break;
-
- case RQ_LValue:
- if (!Quals.empty())
- Quals += ' ';
- Quals += '&';
- break;
-
- case RQ_RValue:
- if (!Quals.empty())
- Quals += ' ';
- Quals += "&&";
- break;
- }
-
- S.Diag(D.getIdentifierLoc(),
- diag::ext_qualified_function_type_template_arg)
- << Quals;
- } else {
- if (FnTy->getTypeQuals() != 0) {
- if (D.isFunctionDeclarator()) {
- SourceRange Range = D.getIdentifierLoc();
- for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
- const DeclaratorChunk &Chunk = D.getTypeObject(N-I-1);
- if (Chunk.Kind == DeclaratorChunk::Function &&
- Chunk.Fun.TypeQuals != 0) {
- switch (Chunk.Fun.TypeQuals) {
- case Qualifiers::Const:
- Range = Chunk.Fun.getConstQualifierLoc();
- break;
- case Qualifiers::Volatile:
- Range = Chunk.Fun.getVolatileQualifierLoc();
- break;
- case Qualifiers::Const | Qualifiers::Volatile: {
- SourceLocation CLoc = Chunk.Fun.getConstQualifierLoc();
- SourceLocation VLoc = Chunk.Fun.getVolatileQualifierLoc();
- if (S.getSourceManager()
- .isBeforeInTranslationUnit(CLoc, VLoc)) {
- Range = SourceRange(CLoc, VLoc);
- } else {
- Range = SourceRange(VLoc, CLoc);
- }
- }
- break;
- }
- break;
- }
- }
- S.Diag(Range.getBegin(), diag::err_invalid_qualified_function_type)
- << FixItHint::CreateRemoval(Range);
- } else
- S.Diag(D.getIdentifierLoc(),
- diag::err_invalid_qualified_typedef_function_type_use)
- << FreeFunction;
- }
-
- if (FnTy->getRefQualifier()) {
- if (D.isFunctionDeclarator()) {
- SourceLocation Loc = D.getIdentifierLoc();
- for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
- const DeclaratorChunk &Chunk = D.getTypeObject(N-I-1);
- if (Chunk.Kind == DeclaratorChunk::Function &&
- Chunk.Fun.hasRefQualifier()) {
- Loc = Chunk.Fun.getRefQualifierLoc();
- break;
- }
- }
-
- S.Diag(Loc, diag::err_invalid_ref_qualifier_function_type)
- << (FnTy->getRefQualifier() == RQ_LValue)
- << FixItHint::CreateRemoval(Loc);
- } else {
- S.Diag(D.getIdentifierLoc(),
- diag::err_invalid_ref_qualifier_typedef_function_type_use)
- << FreeFunction
- << (FnTy->getRefQualifier() == RQ_LValue);
- }
+ // C++11 [dcl.fct]p6 (w/DR1417):
+ // An attempt to specify a function type with a cv-qualifier-seq or a
+ // ref-qualifier (including by typedef-name) is ill-formed unless it is:
+ // - the function type for a non-static member function,
+ // - the function type to which a pointer to member refers,
+ // - the top-level function type of a function typedef declaration or
+ // alias-declaration,
+ // - the type-id in the default argument of a type-parameter, or
+ // - the type-id of a template-argument for a type-parameter
+ if (IsQualifiedFunction &&
+ !(!FreeFunction &&
+ D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) &&
+ !IsTypedefName &&
+ D.getContext() != Declarator::TemplateTypeArgContext) {
+ SourceLocation Loc = D.getSourceRange().getBegin();
+ SourceRange RemovalRange;
+ unsigned I;
+ if (D.isFunctionDeclarator(I)) {
+ SmallVector<SourceLocation, 4> RemovalLocs;
+ const DeclaratorChunk &Chunk = D.getTypeObject(I);
+ assert(Chunk.Kind == DeclaratorChunk::Function);
+ if (Chunk.Fun.hasRefQualifier())
+ RemovalLocs.push_back(Chunk.Fun.getRefQualifierLoc());
+ if (Chunk.Fun.TypeQuals & Qualifiers::Const)
+ RemovalLocs.push_back(Chunk.Fun.getConstQualifierLoc());
+ if (Chunk.Fun.TypeQuals & Qualifiers::Volatile)
+ RemovalLocs.push_back(Chunk.Fun.getVolatileQualifierLoc());
+ // FIXME: We do not track the location of the __restrict qualifier.
+ //if (Chunk.Fun.TypeQuals & Qualifiers::Restrict)
+ // RemovalLocs.push_back(Chunk.Fun.getRestrictQualifierLoc());
+ if (!RemovalLocs.empty()) {
+ std::sort(RemovalLocs.begin(), RemovalLocs.end(),
+ SourceManager::LocBeforeThanCompare(S.getSourceManager()));
+ RemovalRange = SourceRange(RemovalLocs.front(), RemovalLocs.back());
+ Loc = RemovalLocs.front();
}
-
- // Strip the cv-qualifiers and ref-qualifiers from the type.
- FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo();
- EPI.TypeQuals = 0;
- EPI.RefQualifier = RQ_None;
-
- T = Context.getFunctionType(FnTy->getResultType(),
- FnTy->arg_type_begin(),
- FnTy->getNumArgs(), EPI);
}
+
+ S.Diag(Loc, diag::err_invalid_qualified_function_type)
+ << FreeFunction << D.isFunctionDeclarator() << T
+ << getFunctionQualifiersAsString(FnTy)
+ << FixItHint::CreateRemoval(RemovalRange);
+
+ // Strip the cv-qualifiers and ref-qualifiers from the type.
+ FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo();
+ EPI.TypeQuals = 0;
+ EPI.RefQualifier = RQ_None;
+
+ T = Context.getFunctionType(FnTy->getResultType(),
+ FnTy->arg_type_begin(),
+ FnTy->getNumArgs(), EPI);
}
}
@@ -3236,6 +3255,36 @@
Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
}
+/// Does this type have a "direct" ownership qualifier? That is,
+/// is it written like "__strong id", as opposed to something like
+/// "typeof(foo)", where that happens to be strong?
+static bool hasDirectOwnershipQualifier(QualType type) {
+ // Fast path: no qualifier at all.
+ assert(type.getQualifiers().hasObjCLifetime());
+
+ while (true) {
+ // __strong id
+ if (const AttributedType *attr = dyn_cast<AttributedType>(type)) {
+ if (attr->getAttrKind() == AttributedType::attr_objc_ownership)
+ return true;
+
+ type = attr->getModifiedType();
+
+ // X *__strong (...)
+ } else if (const ParenType *paren = dyn_cast<ParenType>(type)) {
+ type = paren->getInnerType();
+
+ // That's it for things we want to complain about. In particular,
+ // we do not want to look through typedefs, typeof(expr),
+ // typeof(type), or any other way that the type is somehow
+ // abstracted.
+ } else {
+
+ return false;
+ }
+ }
+}
+
/// handleObjCOwnershipTypeAttr - Process an objc_ownership
/// attribute on the specified type.
///
@@ -3264,12 +3313,6 @@
if (AttrLoc.isMacroID())
AttrLoc = S.getSourceManager().getImmediateExpansionRange(AttrLoc).first;
- if (type.getQualifiers().getObjCLifetime()) {
- S.Diag(AttrLoc, diag::err_attr_objc_ownership_redundant)
- << type;
- return true;
- }
-
if (!attr.getParameterName()) {
S.Diag(AttrLoc, diag::err_attribute_argument_n_not_string)
<< "objc_ownership" << 1;
@@ -3277,6 +3320,11 @@
return true;
}
+ // Consume lifetime attributes without further comment outside of
+ // ARC mode.
+ if (!S.getLangOptions().ObjCAutoRefCount)
+ return true;
+
Qualifiers::ObjCLifetime lifetime;
if (attr.getParameterName()->isStr("none"))
lifetime = Qualifiers::OCL_ExplicitNone;
@@ -3293,10 +3341,31 @@
return true;
}
- // Consume lifetime attributes without further comment outside of
- // ARC mode.
- if (!S.getLangOptions().ObjCAutoRefCount)
- return true;
+ SplitQualType underlyingType = type.split();
+
+ // Check for redundant/conflicting ownership qualifiers.
+ if (Qualifiers::ObjCLifetime previousLifetime
+ = type.getQualifiers().getObjCLifetime()) {
+ // If it's written directly, that's an error.
+ if (hasDirectOwnershipQualifier(type)) {
+ S.Diag(AttrLoc, diag::err_attr_objc_ownership_redundant)
+ << type;
+ return true;
+ }
+
+ // Otherwise, if the qualifiers actually conflict, pull sugar off
+ // until we reach a type that is directly qualified.
+ if (previousLifetime != lifetime) {
+ // This should always terminate: the canonical type is
+ // qualified, so some bit of sugar must be hiding it.
+ while (!underlyingType.Quals.hasObjCLifetime()) {
+ underlyingType = underlyingType.getSingleStepDesugaredType();
+ }
+ underlyingType.Quals.removeObjCLifetime();
+ }
+ }
+
+ underlyingType.Quals.addObjCLifetime(lifetime);
if (NonObjCPointer) {
StringRef name = attr.getName()->getName();
@@ -3312,11 +3381,9 @@
<< name << type;
}
- Qualifiers qs;
- qs.setObjCLifetime(lifetime);
QualType origType = type;
if (!NonObjCPointer)
- type = S.Context.getQualifiedType(type, qs);
+ type = S.Context.getQualifiedType(underlyingType);
// If we have a valid source location for the attribute, use an
// AttributedType instead.
@@ -3497,9 +3564,9 @@
SplitQualType SplitOld = Old.split();
// As a special case, tail-recurse if there are no qualifiers.
- if (SplitOld.second.empty())
- return wrap(C, SplitOld.first, I);
- return C.getQualifiedType(wrap(C, SplitOld.first, I), SplitOld.second);
+ if (SplitOld.Quals.empty())
+ return wrap(C, SplitOld.Ty, I);
+ return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals);
}
QualType wrap(ASTContext &C, const Type *Old, unsigned I) {
@@ -4176,19 +4243,14 @@
/// @param PD The partial diagnostic that will be printed out if T is not a
/// literal type.
///
-/// @param AllowIncompleteType If true, an incomplete type will be considered
-/// acceptable.
-///
/// @returns @c true if @p T is not a literal type and a diagnostic was emitted,
/// @c false otherwise.
bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
- const PartialDiagnostic &PD,
- bool AllowIncompleteType) {
+ const PartialDiagnostic &PD) {
assert(!T->isDependentType() && "type should not be dependent");
- bool Incomplete = RequireCompleteType(Loc, T, 0);
- if (T->isLiteralType() ||
- (AllowIncompleteType && Incomplete && !T->isVoidType()))
+ RequireCompleteType(Loc, T, 0);
+ if (T->isLiteralType())
return false;
if (PD.getDiagID() == 0)
@@ -4206,8 +4268,9 @@
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
// If the class has virtual base classes, then it's not an aggregate, and
- // cannot have any constexpr constructors, so is non-literal. This is better
- // to diagnose than the resulting absence of constexpr constructors.
+ // cannot have any constexpr constructors or a trivial default constructor,
+ // so is non-literal. This is better to diagnose than the resulting absence
+ // of constexpr constructors.
if (RD->getNumVBases()) {
Diag(RD->getLocation(), diag::note_non_literal_virtual_base)
<< RD->isStruct() << RD->getNumVBases();
@@ -4215,29 +4278,9 @@
E = RD->vbases_end(); I != E; ++I)
Diag(I->getSourceRange().getBegin(),
diag::note_constexpr_virtual_base_here) << I->getSourceRange();
- } else if (!RD->isAggregate() && !RD->hasConstexprNonCopyMoveConstructor()) {
+ } else if (!RD->isAggregate() && !RD->hasConstexprNonCopyMoveConstructor() &&
+ !RD->hasTrivialDefaultConstructor()) {
Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors) << RD;
-
- switch (RD->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
- break;
-
- case TSK_ImplicitInstantiation:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- // If the base template had constexpr constructors which were
- // instantiated as non-constexpr constructors, explain why.
- for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(),
- E = RD->ctor_end(); I != E; ++I) {
- if ((*I)->isCopyConstructor() || (*I)->isMoveConstructor())
- continue;
-
- FunctionDecl *Base = (*I)->getInstantiatedFromMemberFunction();
- if (Base && Base->isConstexpr())
- CheckConstexprFunctionDecl(*I, CCK_NoteNonConstexprInstantiation);
- }
- }
} else if (RD->hasNonLiteralTypeFieldsOrBases()) {
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
E = RD->bases_end(); I != E; ++I) {
@@ -4250,12 +4293,11 @@
}
for (CXXRecordDecl::field_iterator I = RD->field_begin(),
E = RD->field_end(); I != E; ++I) {
- if (!(*I)->getType()->isLiteralType()) {
+ if (!(*I)->getType()->isLiteralType() ||
+ (*I)->getType().isVolatileQualified()) {
Diag((*I)->getLocation(), diag::note_non_literal_field)
- << RD << (*I) << (*I)->getType();
- return true;
- } else if ((*I)->isMutable()) {
- Diag((*I)->getLocation(), diag::note_non_literal_mutable_field) << RD;
+ << RD << (*I) << (*I)->getType()
+ << (*I)->getType().isVolatileQualified();
return true;
}
}
@@ -4305,12 +4347,106 @@
return Context.getTypeOfExprType(E);
}
+/// getDecltypeForExpr - Given an expr, will return the decltype for
+/// that expression, according to the rules in C++11
+/// [dcl.type.simple]p4 and C++11 [expr.lambda.prim]p18.
+static QualType getDecltypeForExpr(Sema &S, Expr *E) {
+ if (E->isTypeDependent())
+ return S.Context.DependentTy;
+
+ // C++11 [dcl.type.simple]p4:
+ // The type denoted by decltype(e) is defined as follows:
+ //
+ // - if e is an unparenthesized id-expression or an unparenthesized class
+ // member access (5.2.5), decltype(e) is the type of the entity named
+ // by e. If there is no such entity, or if e names a set of overloaded
+ // functions, the program is ill-formed;
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
+ return VD->getType();
+ }
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
+ return FD->getType();
+ }
+
+ // C++11 [expr.lambda.prim]p18:
+ // Every occurrence of decltype((x)) where x is a possibly
+ // parenthesized id-expression that names an entity of automatic
+ // storage duration is treated as if x were transformed into an
+ // access to a corresponding data member of the closure type that
+ // would have been declared if x were an odr-use of the denoted
+ // entity.
+ using namespace sema;
+ if (S.getCurLambda()) {
+ 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;
+ }
+ }
+ }
+ }
+ }
+
+
+ // C++11 [dcl.type.simple]p4:
+ // [...]
+ QualType T = E->getType();
+ switch (E->getValueKind()) {
+ // - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the
+ // type of e;
+ case VK_XValue: T = S.Context.getRValueReferenceType(T); break;
+ // - otherwise, if e is an lvalue, decltype(e) is T&, where T is the
+ // type of e;
+ case VK_LValue: T = S.Context.getLValueReferenceType(T); break;
+ // - otherwise, decltype(e) is the type of e.
+ case VK_RValue: break;
+ }
+
+ return T;
+}
+
QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) {
ExprResult ER = CheckPlaceholderExpr(E);
if (ER.isInvalid()) return QualType();
E = ER.take();
- return Context.getDecltypeType(E);
+ return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
}
QualType Sema::BuildUnaryTransformType(QualType BaseType,
@@ -4339,12 +4475,14 @@
QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
if (!T->isDependentType()) {
+ // FIXME: It isn't entirely clear whether incomplete atomic types
+ // are allowed or not; for simplicity, ban them for the moment.
+ if (RequireCompleteType(Loc, T,
+ PDiag(diag::err_atomic_specifier_bad_type) << 0))
+ return QualType();
+
int DisallowedKind = -1;
- if (T->isIncompleteType())
- // FIXME: It isn't entirely clear whether incomplete atomic types
- // are allowed or not; for simplicity, ban them for the moment.
- DisallowedKind = 0;
- else if (T->isArrayType())
+ if (T->isArrayType())
DisallowedKind = 1;
else if (T->isFunctionType())
DisallowedKind = 2;
Modified: cfe/branches/tooling/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/TreeTransform.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/TreeTransform.h (original)
+++ cfe/branches/tooling/lib/Sema/TreeTransform.h Tue Feb 14 03:11:10 2012
@@ -112,6 +112,11 @@
protected:
Sema &SemaRef;
+ /// \brief The set of local declarations that have been transformed, for
+ /// cases where we are forced to build new declarations within the transformer
+ /// rather than in the subclass (e.g., lambda closure types).
+ llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
+
public:
/// \brief Initializes a new tree transformer.
TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
@@ -351,10 +356,36 @@
/// \brief Transform the given declaration, which is referenced from a type
/// or expression.
///
- /// By default, acts as the identity function on declarations. Subclasses
+ /// By default, acts as the identity function on declarations, unless the
+ /// transformer has had to transform the declaration itself. Subclasses
/// may override this function to provide alternate behavior.
- Decl *TransformDecl(SourceLocation Loc, Decl *D) { return D; }
-
+ Decl *TransformDecl(SourceLocation Loc, Decl *D) {
+ llvm::DenseMap<Decl *, Decl *>::iterator Known
+ = TransformedLocalDecls.find(D);
+ if (Known != TransformedLocalDecls.end())
+ return Known->second;
+
+ return D;
+ }
+
+ /// \brief Transform the attributes associated with the given declaration and
+ /// place them on the new declaration.
+ ///
+ /// By default, this operation does nothing. Subclasses may override this
+ /// behavior to transform attributes.
+ void transformAttrs(Decl *Old, Decl *New) { }
+
+ /// \brief Note that a local declaration has been transformed by this
+ /// transformer.
+ ///
+ /// Local declarations are typically transformed via a call to
+ /// TransformDefinition. However, in some cases (e.g., lambda expressions),
+ /// the transformer itself has to transform the declarations. This routine
+ /// can be overridden by a subclass that keeps track of such mappings.
+ void transformedLocalDecl(Decl *Old, Decl *New) {
+ TransformedLocalDecls[Old] = New;
+ }
+
/// \brief Transform the definition of the given declaration.
///
/// By default, invokes TransformDecl() to transform the declaration.
@@ -666,7 +697,8 @@
QualType RebuildFunctionProtoType(QualType T,
QualType *ParamTypes,
unsigned NumParamTypes,
- bool Variadic, unsigned Quals,
+ bool Variadic, bool HasTrailingReturn,
+ unsigned Quals,
RefQualifierKind RefQualifier,
const FunctionType::ExtInfo &Info);
@@ -1645,10 +1677,9 @@
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
- MultiExprArg SubExprs,
- SourceLocation RParenLoc) {
- return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc,
- move(SubExprs));
+ MultiExprArg SubExprs,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
}
/// \brief Build a new address-of-label expression.
@@ -4137,6 +4168,7 @@
ParamTypes.data(),
ParamTypes.size(),
T->isVariadic(),
+ T->hasTrailingReturn(),
T->getTypeQuals(),
T->getRefQualifier(),
T->getExtInfo());
@@ -7621,8 +7653,111 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
- assert(false && "Lambda expressions cannot be instantiated (yet)");
- return ExprError();
+ // Create the local class that will describe the lambda.
+ CXXRecordDecl *Class
+ = getSema().createLambdaClosureType(E->getIntroducerRange());
+ getDerived().transformedLocalDecl(E->getLambdaClass(), Class);
+
+ // Transform the type of the lambda parameters and start the definition of
+ // the lambda itself.
+ TypeSourceInfo *MethodTy
+ = TransformType(E->getCallOperator()->getTypeSourceInfo());
+ if (!MethodTy)
+ return ExprError();
+
+ // Build the call operator.
+ CXXMethodDecl *CallOperator
+ = getSema().startLambdaDefinition(Class, E->getIntroducerRange(),
+ MethodTy,
+ E->getCallOperator()->getLocEnd());
+ getDerived().transformAttrs(E->getCallOperator(), CallOperator);
+
+ // FIXME: Instantiation-specific.
+ CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(),
+ TSK_ImplicitInstantiation);
+
+ // Introduce the context of the call operator.
+ Sema::ContextRAII SavedContext(getSema(), CallOperator);
+
+ // Enter the scope of the lambda.
+ sema::LambdaScopeInfo *LSI
+ = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(),
+ E->getCaptureDefault(),
+ E->hasExplicitParameters(),
+ E->hasExplicitResultType(),
+ E->isMutable());
+
+ // Transform captures.
+ bool Invalid = false;
+ bool FinishedExplicitCaptures = false;
+ for (LambdaExpr::capture_iterator C = E->capture_begin(),
+ CEnd = E->capture_end();
+ C != CEnd; ++C) {
+ // When we hit the first implicit capture, tell Sema that we've finished
+ // the list of explicit captures.
+ if (!FinishedExplicitCaptures && C->isImplicit()) {
+ getSema().finishLambdaExplicitCaptures(LSI);
+ FinishedExplicitCaptures = true;
+ }
+
+ // Capturing 'this' is trivial.
+ if (C->capturesThis()) {
+ getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit());
+ continue;
+ }
+
+ // Transform the captured variable.
+ VarDecl *CapturedVar
+ = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
+ C->getCapturedVar()));
+ if (!CapturedVar) {
+ 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);
+ }
+ 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.
+ getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+
+ if (Invalid) {
+ getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
+ /*IsInstantiation=*/true);
+ return ExprError();
+ }
+
+ // Instantiate the body of the lambda expression.
+ StmtResult Body = getDerived().TransformStmt(E->getBody());
+ if (Body.isInvalid()) {
+ getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
+ /*IsInstantiation=*/true);
+ return ExprError();
+ }
+
+ return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
+ /*CurScope=*/0,
+ /*IsInstantiation=*/true);
}
template<typename Derived>
@@ -8209,7 +8344,7 @@
paramTypes.data(),
paramTypes.size(),
oldBlock->isVariadic(),
- 0, RQ_None,
+ false, 0, RQ_None,
exprFunctionType->getExtInfo());
blockScope->FunctionType = functionType;
@@ -8452,11 +8587,12 @@
QualType *ParamTypes,
unsigned NumParamTypes,
bool Variadic,
+ bool HasTrailingReturn,
unsigned Quals,
RefQualifierKind RefQualifier,
const FunctionType::ExtInfo &Info) {
return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
- Quals, RefQualifier,
+ HasTrailingReturn, Quals, RefQualifier,
getDerived().getBaseLocation(),
getDerived().getBaseEntity(),
Info);
Modified: cfe/branches/tooling/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReader.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReader.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReader.cpp Tue Feb 14 03:11:10 2012
@@ -27,6 +27,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Analysis/Support/SaveAndRestore.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
@@ -3877,6 +3878,7 @@
ParamTypes.push_back(readType(*Loc.F, Record, Idx));
EPI.Variadic = Record[Idx++];
+ EPI.HasTrailingReturn = Record[Idx++];
EPI.TypeQuals = Record[Idx++];
EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);
ExceptionSpecificationType EST =
@@ -3926,8 +3928,10 @@
return Context.getTypeOfType(UnderlyingType);
}
- case TYPE_DECLTYPE:
- return Context.getDecltypeType(ReadExpr(*Loc.F));
+ case TYPE_DECLTYPE: {
+ QualType UnderlyingType = readType(*Loc.F, Record, Idx);
+ return Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType);
+ }
case TYPE_UNARY_TRANSFORM: {
QualType BaseType = readType(*Loc.F, Record, Idx);
@@ -6246,33 +6250,27 @@
assert(NumCurrentElementsDeserializing &&
"FinishedDeserializing not paired with StartedDeserializing");
if (NumCurrentElementsDeserializing == 1) {
+ // We decrease NumCurrentElementsDeserializing only after pending actions
+ // are finished, to avoid recursively re-calling finishPendingActions().
+ finishPendingActions();
+ }
+ --NumCurrentElementsDeserializing;
- while (Consumer && !InterestingDecls.empty()) {
- finishPendingActions();
+ if (NumCurrentElementsDeserializing == 0 &&
+ Consumer && !PassingDeclsToConsumer) {
+ // Guard variable to avoid recursively redoing the process of passing
+ // decls to consumer.
+ SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
+ true);
+ while (!InterestingDecls.empty()) {
// We are not in recursive loading, so it's safe to pass the "interesting"
// decls to the consumer.
Decl *D = InterestingDecls.front();
InterestingDecls.pop_front();
-
- // Fully load the interesting decls, including deserializing their
- // bodies, so that any other declarations that get referenced in the
- // body will be fully deserialized by the time we pass them to the
- // consumer.
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (FD->doesThisDeclarationHaveABody()) {
- FD->getBody();
- finishPendingActions();
- }
- }
-
PassInterestingDeclToConsumer(D);
}
-
- finishPendingActions();
- PendingDeclChainsKnown.clear();
}
- --NumCurrentElementsDeserializing;
}
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
@@ -6293,6 +6291,7 @@
NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
+ PassingDeclsToConsumer(false),
NumCXXBaseSpecifiersLoaded(0)
{
SourceMgr.setExternalSLocEntrySource(this);
Modified: cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp Tue Feb 14 03:11:10 2012
@@ -324,12 +324,11 @@
} else if (D->isTemplateParameter()) {
// If we have a fully initialized template parameter, we can now
// set its DeclContext.
- D->setDeclContext(
- cast_or_null<DeclContext>(
- Reader.GetDecl(DeclContextIDForTemplateParmDecl)));
- D->setLexicalDeclContext(
- cast_or_null<DeclContext>(
- Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl)));
+ DeclContext *SemaDC = cast<DeclContext>(
+ Reader.GetDecl(DeclContextIDForTemplateParmDecl));
+ DeclContext *LexicalDC = cast<DeclContext>(
+ Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl));
+ D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
}
}
@@ -343,15 +342,20 @@
LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
} else {
- D->setDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
- D->setLexicalDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
+ DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
+ DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx);
+ // Avoid calling setLexicalDeclContext() directly because it uses
+ // Decl::getASTContext() internally which is unsafe during derialization.
+ D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
}
D->setLocation(Reader.ReadSourceLocation(F, RawLocation));
D->setInvalidDecl(Record[Idx++]);
if (Record[Idx++]) { // hasAttrs
AttrVec Attrs;
Reader.ReadAttributes(F, Attrs, Record, Idx);
- D->setAttrs(Attrs);
+ // Avoid calling setAttrs() directly because it uses Decl::getASTContext()
+ // internally which is unsafe during derialization.
+ D->setAttrsImpl(Attrs, Reader.getContext());
}
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
@@ -873,7 +877,7 @@
VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++];
VD->VarDeclBits.ThreadSpecified = Record[Idx++];
- VD->VarDeclBits.HasCXXDirectInit = Record[Idx++];
+ VD->VarDeclBits.InitStyle = Record[Idx++];
VD->VarDeclBits.ExceptionVar = Record[Idx++];
VD->VarDeclBits.NRVOVariable = Record[Idx++];
VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];
@@ -2018,6 +2022,10 @@
assert(D && "Unknown declaration reading AST file");
LoadedDecl(Index, D);
+ // Set the DeclContext before doing any deserialization, to make sure internal
+ // calls to Decl::getASTContext() by Decl's methods will find the
+ // TranslationUnitDecl without crashing.
+ D->setDeclContext(Context.getTranslationUnitDecl());
Reader.Visit(D);
// If this declaration is also a declaration context, get the
Modified: cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriter.cpp Tue Feb 14 03:11:10 2012
@@ -29,7 +29,6 @@
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemStatCache.h"
#include "clang/Basic/OnDiskHashTable.h"
@@ -186,6 +185,7 @@
for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
Writer.AddTypeRef(T->getArgType(I), Record);
Record.push_back(T->isVariadic());
+ Record.push_back(T->hasTrailingReturn());
Record.push_back(T->getTypeQuals());
Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
Record.push_back(T->getExceptionSpecType());
@@ -222,6 +222,7 @@
}
void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) {
+ Writer.AddTypeRef(T->getUnderlyingType(), Record);
Writer.AddStmt(T->getUnderlyingExpr());
Code = TYPE_DECLTYPE;
}
@@ -4501,4 +4502,3 @@
RewriteDecl(D);
}
-
Modified: cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp Tue Feb 14 03:11:10 2012
@@ -656,7 +656,7 @@
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isThreadSpecified());
- Record.push_back(D->hasCXXDirectInitializer());
+ Record.push_back(D->getInitStyle());
Record.push_back(D->isExceptionVariable());
Record.push_back(D->isNRVOVariable());
Record.push_back(D->isCXXForRangeDecl());
@@ -688,7 +688,7 @@
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
!D->hasExtInfo() &&
D->getFirstDeclaration() == D->getMostRecentDecl() &&
- !D->hasCXXDirectInitializer() &&
+ D->getInitStyle() == VarDecl::CInit &&
D->getInit() == 0 &&
!isa<ParmVarDecl>(D) &&
!SpecInfo)
@@ -728,7 +728,7 @@
D->getAccess() == AS_none &&
!D->isModulePrivate() &&
D->getStorageClass() == 0 &&
- !D->hasCXXDirectInitializer() && // Can params have this ever?
+ D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
D->getFunctionScopeDepth() == 0 &&
D->getObjCDeclQualifier() == 0 &&
!D->isKNRPromoted() &&
Modified: cfe/branches/tooling/lib/Serialization/GeneratePCH.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/GeneratePCH.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/GeneratePCH.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/GeneratePCH.cpp Tue Feb 14 03:11:10 2012
@@ -17,7 +17,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemStatCache.h"
#include "llvm/Bitcode/BitstreamWriter.h"
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp Tue Feb 14 03:11:10 2012
@@ -17,7 +17,6 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CMakeLists.txt Tue Feb 14 03:11:10 2012
@@ -12,6 +12,7 @@
ArrayBoundCheckerV2.cpp
AttrNonNullChecker.cpp
BasicObjCFoundationChecks.cpp
+ BoolAssignmentChecker.cpp
BuiltinFunctionChecker.cpp
CStringChecker.cpp
CStringSyntaxChecker.cpp
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/Checkers.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/Checkers.td?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/Checkers.td Tue Feb 14 03:11:10 2012
@@ -87,6 +87,10 @@
let ParentPackage = CoreExperimental in {
+def BoolAssignmentChecker : Checker<"BoolAssignment">,
+ HelpText<"Warn about assigning non-{0,1} values to Boolean variables">,
+ DescFile<"BoolAssignmentChecker.cpp">;
+
def CastSizeChecker : Checker<"CastSize">,
HelpText<"Check when casting a malloc'ed type T, whether the size is a multiple of the size of T">,
DescFile<"CastSizeChecker.cpp">;
@@ -282,8 +286,12 @@
HelpText<"Check improper use of chroot">,
DescFile<"ChrootChecker.cpp">;
-def MallocChecker : Checker<"Malloc">,
- HelpText<"Check for potential memory leaks, double free, and use-after-free problems">,
+def MallocOptimistic : Checker<"MallocWithAnnotations">,
+ HelpText<"Check for memory leaks, double free, and use-after-free problems. Assumes that all user-defined functions which might free a pointer are annotated.">,
+ DescFile<"MallocChecker.cpp">;
+
+def MallocPessimistic : Checker<"Malloc">,
+ HelpText<"Check for memory leaks, double free, and use-after-free problems.">,
DescFile<"MallocChecker.cpp">;
def MallocSizeofChecker : Checker<"MallocSizeof">,
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp Tue Feb 14 03:11:10 2012
@@ -17,7 +17,6 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Feb 14 03:11:10 2012
@@ -20,6 +20,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
@@ -41,6 +42,7 @@
bool isReleased() const { return K == Released; }
//bool isEscaped() const { return K == Escaped; }
//bool isRelinquished() const { return K == Relinquished; }
+ const Stmt *getStmt() const { return S; }
bool operator==(const RefState &X) const {
return K == X.K && S == X.S;
@@ -64,15 +66,14 @@
}
};
-class RegionState {};
-
-class MallocChecker : public Checker<eval::Call,
- check::DeadSymbols,
+class MallocChecker : public Checker<check::DeadSymbols,
check::EndPath,
check::PreStmt<ReturnStmt>,
+ check::PostStmt<CallExpr>,
check::Location,
check::Bind,
- eval::Assume>
+ eval::Assume,
+ check::RegionChanges>
{
mutable OwningPtr<BuiltinBug> BT_DoubleFree;
mutable OwningPtr<BuiltinBug> BT_Leak;
@@ -84,7 +85,18 @@
public:
MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
- bool evalCall(const CallExpr *CE, CheckerContext &C) const;
+ /// In pessimistic mode, the checker assumes that it does not know which
+ /// functions might free the memory.
+ struct ChecksFilter {
+ DefaultBool CMallocPessimistic;
+ DefaultBool CMallocOptimistic;
+ };
+
+ ChecksFilter Filter;
+
+ void initIdentifierInfo(CheckerContext &C) const;
+
+ void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
void checkEndPath(CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -94,6 +106,14 @@
CheckerContext &C) const;
void checkBind(SVal location, SVal val, const Stmt*S,
CheckerContext &C) const;
+ ProgramStateRef
+ checkRegionChanges(ProgramStateRef state,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions) const;
+ bool wantsRegionChangeUpdate(ProgramStateRef state) const {
+ return true;
+ }
private:
static void MallocMem(CheckerContext &C, const CallExpr *CE);
@@ -120,14 +140,56 @@
void ReallocMem(CheckerContext &C, const CallExpr *CE) 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;
+
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;
+
+ void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
+
+ /// The bug visitor which allows us to print extra diagnostics along the
+ /// BugReport path. For example, showing the allocation site of the leaked
+ /// region.
+ class MallocBugVisitor : public BugReporterVisitor {
+ protected:
+ // The allocated region symbol tracked by the main analysis.
+ SymbolRef Sym;
+
+ public:
+ MallocBugVisitor(SymbolRef S) : Sym(S) {}
+ virtual ~MallocBugVisitor() {}
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ static int X = 0;
+ ID.AddPointer(&X);
+ ID.AddPointer(Sym);
+ }
+
+ inline bool isAllocated(const RefState *S, const RefState *SPrev) {
+ // Did not track -> allocated. Other state (released) -> allocated.
+ return ((S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
+ }
+
+ inline bool isReleased(const RefState *S, const RefState *SPrev) {
+ // Did not track -> released. Other state (allocated) -> released.
+ return ((S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
+ }
+
+ PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR);
+ };
};
} // end anonymous namespace
typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
-
+typedef llvm::ImmutableMap<SymbolRef, SymbolRef> SymRefToSymRefTy;
+class RegionState {};
+class ReallocPairs {};
namespace clang {
namespace ento {
template <>
@@ -135,14 +197,30 @@
: public ProgramStatePartialTrait<RegionStateTy> {
static void *GDMIndex() { static int x; return &x; }
};
+
+ template <>
+ struct ProgramStateTrait<ReallocPairs>
+ : public ProgramStatePartialTrait<SymRefToSymRefTy> {
+ static void *GDMIndex() { static int x; return &x; }
+ };
}
}
-bool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
- const FunctionDecl *FD = C.getCalleeDecl(CE);
- if (!FD)
- return false;
+namespace {
+class StopTrackingCallback : public SymbolVisitor {
+ ProgramStateRef state;
+public:
+ StopTrackingCallback(ProgramStateRef st) : state(st) {}
+ ProgramStateRef getState() const { return state; }
+
+ bool VisitSymbol(SymbolRef sym) {
+ state = state->remove<RegionState>(sym);
+ return true;
+ }
+};
+} // end anonymous namespace
+void MallocChecker::initIdentifierInfo(CheckerContext &C) const {
ASTContext &Ctx = C.getASTContext();
if (!II_malloc)
II_malloc = &Ctx.Idents.get("malloc");
@@ -152,30 +230,36 @@
II_realloc = &Ctx.Idents.get("realloc");
if (!II_calloc)
II_calloc = &Ctx.Idents.get("calloc");
+}
+
+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) {
MallocMem(C, CE);
- return true;
- }
-
- if (FD->getIdentifier() == II_free) {
- FreeMem(C, CE);
- return true;
+ return;
}
-
if (FD->getIdentifier() == II_realloc) {
ReallocMem(C, CE);
- return true;
+ return;
}
if (FD->getIdentifier() == II_calloc) {
CallocMem(C, CE);
- return true;
+ return;
}
+ if (FD->getIdentifier() == II_free) {
+ FreeMem(C, CE);
+ return;
+ }
+
+ if (Filter.CMallocOptimistic)
// Check all the attributes, if there are any.
// There can be multiple of these attributes.
- bool rv = false;
if (FD->hasAttrs()) {
for (specific_attr_iterator<OwnershipAttr>
i = FD->specific_attr_begin<OwnershipAttr>(),
@@ -184,19 +268,52 @@
switch ((*i)->getOwnKind()) {
case OwnershipAttr::Returns: {
MallocMemReturnsAttr(C, CE, *i);
- rv = true;
- break;
+ return;
}
case OwnershipAttr::Takes:
case OwnershipAttr::Holds: {
FreeMemAttr(C, CE, *i);
- rv = true;
- break;
+ 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;
+ }
+ }
+
+ // 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);
}
}
}
- return rv;
}
void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
@@ -222,23 +339,24 @@
C.addTransition(state);
}
-ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
+ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
const CallExpr *CE,
SVal Size, SVal Init,
ProgramStateRef state) {
- unsigned Count = C.getCurrentBlockCount();
SValBuilder &svalBuilder = C.getSValBuilder();
- // Set the return value.
- SVal retVal = svalBuilder.getConjuredSymbolVal(NULL, CE,
- CE->getType(), Count);
- state = state->BindExpr(CE, C.getLocationContext(), retVal);
+ // Get the return value.
+ SVal retVal = state->getSVal(CE, C.getLocationContext());
// Fill the region with the initialization value.
state = state->bindDefault(retVal, Init);
// Set the region's extent equal to the Size parameter.
- const SymbolicRegion *R = cast<SymbolicRegion>(retVal.getAsRegion());
+ const SymbolicRegion *R =
+ dyn_cast_or_null<SymbolicRegion>(retVal.getAsRegion());
+ if (!R || !isa<DefinedOrUnknownSVal>(Size))
+ return 0;
+
DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
DefinedOrUnknownSVal extentMatchesSize =
@@ -277,34 +395,30 @@
}
ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
- const CallExpr *CE,
- ProgramStateRef state,
- unsigned Num,
- bool Hold) const {
+ const CallExpr *CE,
+ ProgramStateRef state,
+ unsigned Num,
+ bool Hold) const {
const Expr *ArgExpr = CE->getArg(Num);
SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
-
+ if (!isa<DefinedOrUnknownSVal>(ArgVal))
+ return 0;
DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
// Check for null dereferences.
if (!isa<Loc>(location))
- return state;
+ return 0;
- // FIXME: Technically using 'Assume' here can result in a path
- // bifurcation. In such cases we need to return two states, not just one.
+ // The explicit NULL case, no operation is performed.
ProgramStateRef notNullState, nullState;
llvm::tie(notNullState, nullState) = state->assume(location);
-
- // The explicit NULL case, no operation is performed.
if (nullState && !notNullState)
- return nullState;
-
- assert(notNullState);
+ return 0;
// Unknown values could easily be okay
// Undefined values are handled elsewhere
if (ArgVal.isUnknownOrUndef())
- return notNullState;
+ return 0;
const MemRegion *R = ArgVal.getAsRegion();
@@ -312,7 +426,7 @@
// Non-region locations (labels and fixed addresses) also shouldn't be freed.
if (!R) {
ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
- return NULL;
+ return 0;
}
R = R->StripCasts();
@@ -320,7 +434,7 @@
// Blocks might show up as heap data, but should not be free()d
if (isa<BlockDataRegion>(R)) {
ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
- return NULL;
+ return 0;
}
const MemSpaceRegion *MS = R->getMemorySpace();
@@ -336,14 +450,14 @@
// False negatives are better than false positives.
ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
- return NULL;
+ return 0;
}
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
// Various cases could lead to non-symbol values here.
// For now, ignore them.
if (!SR)
- return notNullState;
+ return 0;
SymbolRef Sym = SR->getSymbol();
const RefState *RS = state->get<RegionState>(Sym);
@@ -352,7 +466,7 @@
// called on a pointer that does not get its pointee directly from malloc().
// Full support of this requires inter-procedural analysis.
if (!RS)
- return notNullState;
+ return 0;
// Check double free.
if (RS->isReleased()) {
@@ -361,18 +475,18 @@
BT_DoubleFree.reset(
new BuiltinBug("Double free",
"Try to free a memory block that has been released"));
- // FIXME: should find where it's freed last time.
BugReport *R = new BugReport(*BT_DoubleFree,
BT_DoubleFree->getDescription(), N);
+ R->addVisitor(new MallocBugVisitor(Sym));
C.EmitReport(R);
}
- return NULL;
+ return 0;
}
// Normal free.
if (Hold)
- return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
- return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
+ return state->set<RegionState>(Sym, RefState::getRelinquished(CE));
+ return state->set<RegionState>(Sym, RefState::getReleased(CE));
}
bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
@@ -504,8 +618,10 @@
ProgramStateRef state = C.getState();
const Expr *arg0Expr = CE->getArg(0);
const LocationContext *LCtx = C.getLocationContext();
- DefinedOrUnknownSVal arg0Val
- = cast<DefinedOrUnknownSVal>(state->getSVal(arg0Expr, LCtx));
+ SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
+ if (!isa<DefinedOrUnknownSVal>(Arg0Val))
+ return;
+ DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val);
SValBuilder &svalBuilder = C.getSValBuilder();
@@ -518,51 +634,68 @@
return;
// Get the value of the size argument.
- DefinedOrUnknownSVal Arg1Val =
- cast<DefinedOrUnknownSVal>(state->getSVal(Arg1, LCtx));
+ SVal Arg1ValG = state->getSVal(Arg1, LCtx);
+ if (!isa<DefinedOrUnknownSVal>(Arg1ValG))
+ return;
+ DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG);
// Compare the size argument to 0.
DefinedOrUnknownSVal SizeZero =
svalBuilder.evalEQ(state, Arg1Val,
svalBuilder.makeIntValWithPtrWidth(0, false));
+ ProgramStateRef StatePtrIsNull, StatePtrNotNull;
+ llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
+ ProgramStateRef StateSizeIsZero, StateSizeNotZero;
+ llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
+ // We only assume exceptional states if they are definitely true; if the
+ // state is under-constrained, assume regular realloc behavior.
+ bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
+ bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
+
// If the ptr is NULL and the size is not 0, the call is equivalent to
// malloc(size).
- ProgramStateRef stateEqual = state->assume(PtrEQ, true);
- if (stateEqual && state->assume(SizeZero, false)) {
- // Hack: set the NULL symbolic region to released to suppress false warning.
- // In the future we should add more states for allocated regions, e.g.,
- // CheckedNull, CheckedNonNull.
-
- SymbolRef Sym = arg0Val.getAsLocSymbol();
- if (Sym)
- stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
-
+ if ( PrtIsNull && !SizeIsZero) {
ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
- UndefinedVal(), stateEqual);
+ UndefinedVal(), StatePtrIsNull);
C.addTransition(stateMalloc);
+ return;
}
- if (ProgramStateRef stateNotEqual = state->assume(PtrEQ, false)) {
- // If the size is 0, free the memory.
- if (ProgramStateRef stateSizeZero =
- stateNotEqual->assume(SizeZero, true))
- if (ProgramStateRef stateFree =
- FreeMemAux(C, CE, stateSizeZero, 0, false)) {
-
- // Bind the return value to NULL because it is now free.
- C.addTransition(stateFree->BindExpr(CE, LCtx,
- svalBuilder.makeNull(), true));
- }
- if (ProgramStateRef stateSizeNotZero =
- stateNotEqual->assume(SizeZero,false))
- if (ProgramStateRef stateFree = FreeMemAux(C, CE, stateSizeNotZero,
- 0, false)) {
- // FIXME: We should copy the content of the original buffer.
- ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
- UnknownVal(), stateFree);
- C.addTransition(stateRealloc);
- }
+ if (PrtIsNull && SizeIsZero)
+ return;
+
+ // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
+ assert(!PrtIsNull);
+ SymbolRef FromPtr = arg0Val.getAsSymbol();
+ SVal RetVal = state->getSVal(CE, LCtx);
+ SymbolRef ToPtr = RetVal.getAsSymbol();
+ if (!FromPtr || !ToPtr)
+ return;
+
+ // If the size is 0, free the memory.
+ if (SizeIsZero)
+ if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){
+ // 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);
+ C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
+ C.addTransition(stateFree);
+ return;
+ }
+
+ // Default behavior.
+ if (ProgramStateRef stateFree = FreeMemAux(C, CE, state, 0, false)) {
+ // FIXME: We should copy the content of the original buffer.
+ ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
+ UnknownVal(), stateFree);
+ if (!stateRealloc)
+ return;
+ stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, FromPtr);
+ C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
+ C.addTransition(stateRealloc);
+ return;
}
}
@@ -579,6 +712,25 @@
C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state));
}
+void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
+ CheckerContext &C) const {
+ assert(N);
+ if (!BT_Leak) {
+ BT_Leak.reset(new BuiltinBug("Memory leak",
+ "Allocated memory never released. Potential memory leak."));
+ // 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
+ // with __noreturn functions such as assert() or exit(). We choose not
+ // to report leaks on such paths.
+ BT_Leak->setSuppressOnSink(true);
+ }
+
+ BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
+ R->addVisitor(new MallocBugVisitor(Sym));
+ C.EmitReport(R);
+}
+
void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
CheckerContext &C) const
{
@@ -590,169 +742,260 @@
RegionStateTy::Factory &F = state->get_context<RegionState>();
bool generateReport = false;
-
+ llvm::SmallVector<SymbolRef, 2> Errors;
for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
if (SymReaper.isDead(I->first)) {
- if (I->second.isAllocated())
+ if (I->second.isAllocated()) {
generateReport = true;
-
+ Errors.push_back(I->first);
+ }
// Remove the dead symbol from the map.
RS = F.remove(RS, I->first);
}
}
+ // 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)) {
+ state = state->remove<ReallocPairs>(I->first);
+ }
+ }
+
ExplodedNode *N = C.addTransition(state->set<RegionState>(RS));
- // FIXME: This does not handle when we have multiple leaks at a single
- // place.
if (N && generateReport) {
- if (!BT_Leak)
- BT_Leak.reset(new BuiltinBug("Memory leak",
- "Allocated memory never released. Potential memory leak."));
- // FIXME: where it is allocated.
- BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
- C.EmitReport(R);
+ for (llvm::SmallVector<SymbolRef, 2>::iterator
+ I = Errors.begin(), E = Errors.end(); I != E; ++I) {
+ reportLeak(*I, N, C);
+ }
}
}
-void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
- ProgramStateRef state = Ctx.getState();
+void MallocChecker::checkEndPath(CheckerContext &C) const {
+ ProgramStateRef state = C.getState();
RegionStateTy M = state->get<RegionState>();
for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
RefState RS = I->second;
if (RS.isAllocated()) {
- ExplodedNode *N = Ctx.addTransition(state);
- if (N) {
- if (!BT_Leak)
- BT_Leak.reset(new BuiltinBug("Memory leak",
- "Allocated memory never released. Potential memory leak."));
- BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
- Ctx.EmitReport(R);
- }
+ ExplodedNode *N = C.addTransition(state);
+ if (N)
+ reportLeak(I->first, N, C);
}
}
}
+bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S,
+ CheckerContext &C) const {
+ ProgramStateRef state = C.getState();
+ const RefState *RS = state->get<RegionState>(Sym);
+ if (!RS)
+ return false;
+
+ if (RS->isAllocated()) {
+ state = state->set<RegionState>(Sym, RefState::getEscaped(S));
+ C.addTransition(state);
+ return true;
+ }
+ return false;
+}
+
void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
- const Expr *retExpr = S->getRetValue();
- if (!retExpr)
+ const Expr *E = S->getRetValue();
+ if (!E)
return;
- ProgramStateRef state = C.getState();
-
- SymbolRef Sym = state->getSVal(retExpr, C.getLocationContext()).getAsSymbol();
+ // Check if we are returning a symbol.
+ SymbolRef Sym = C.getState()->getSVal(E, C.getLocationContext()).getAsSymbol();
if (!Sym)
return;
- const RefState *RS = state->get<RegionState>(Sym);
- if (!RS)
+ // Check if we are returning freed memory.
+ if (checkUseAfterFree(Sym, C, S))
return;
- // FIXME: check other cases.
- if (RS->isAllocated())
- state = state->set<RegionState>(Sym, RefState::getEscaped(S));
+ // Check if the symbol is escaping.
+ checkEscape(Sym, S, C);
+}
+bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
+ const Stmt *S) const {
+ assert(Sym);
+ const RefState *RS = C.getState()->get<RegionState>(Sym);
+ 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."));
+
+ BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),N);
+ if (S)
+ R->addRange(S->getSourceRange());
+ R->addVisitor(new MallocBugVisitor(Sym));
+ C.EmitReport(R);
+ return true;
+ }
+ }
+ return false;
+}
+
+// Check if the location is a freed symbolic region.
+void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
+ CheckerContext &C) const {
+ SymbolRef Sym = l.getLocSymbolInBase();
+ if (Sym)
+ checkUseAfterFree(Sym, C);
+}
+
+//===----------------------------------------------------------------------===//
+// Check various ways a symbol can be invalidated.
+// TODO: This logic (the next 3 functions) is copied/similar to the
+// RetainRelease checker. We might want to factor this out.
+//===----------------------------------------------------------------------===//
+
+// Stop tracking symbols when a value escapes as a result of checkBind.
+// A value escapes in three possible cases:
+// (1) we are binding to something that is not a memory region.
+// (2) we are binding to a memregion that does not have stack storage
+// (3) we are binding to a memregion with stack storage that the store
+// does not understand.
+void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S,
+ CheckerContext &C) const {
+ // Are we storing to something that causes the value to "escape"?
+ bool escapes = true;
+ ProgramStateRef state = C.getState();
+
+ if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
+ escapes = !regionLoc->getRegion()->hasStackStorage();
+
+ if (!escapes) {
+ // To test (3), generate a new state with the binding added. If it is
+ // the same state, then it escapes (since the store cannot represent
+ // the binding).
+ escapes = (state == (state->bindLoc(*regionLoc, val)));
+ }
+ }
+
+ // If our store can represent the binding and we aren't storing to something
+ // that doesn't have local storage then just return and have the simulation
+ // state continue as is.
+ if (!escapes)
+ return;
+
+ // Otherwise, find all symbols referenced by 'val' that we are tracking
+ // and stop tracking them.
+ state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
C.addTransition(state);
}
+// If a symbolic region is assumed to NULL (or another constant), stop tracking
+// it - assuming that allocation failed on this path.
ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
- SVal Cond,
+ SVal Cond,
bool Assumption) const {
- // If a symblic region is assumed to NULL, set its state to AllocateFailed.
- // FIXME: should also check symbols assumed to non-null.
-
RegionStateTy RS = state->get<RegionState>();
-
for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
- // If the symbol is assumed to NULL, this will return an APSInt*.
+ // If the symbol is assumed to NULL or another constant, this will
+ // return an APSInt*.
if (state->getSymVal(I.getKey()))
- state = state->set<RegionState>(I.getKey(),RefState::getAllocateFailed());
+ state = state->remove<RegionState>(I.getKey());
}
- return state;
-}
-
-// Check if the location is a freed symbolic region.
-void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
- CheckerContext &C) const {
- SymbolRef Sym = l.getLocSymbolInBase();
- if (Sym) {
- const RefState *RS = C.getState()->get<RegionState>(Sym);
- if (RS && RS->isReleased()) {
- if (ExplodedNode *N = C.addTransition()) {
- if (!BT_UseFree)
- BT_UseFree.reset(new BuiltinBug("Use dynamically allocated memory "
- "after it is freed."));
-
- BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
- N);
- C.EmitReport(R);
+ // 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) {
+ // 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());
+ if (RS) {
+ if (RS->isReleased())
+ state = state->set<RegionState>(I.getData(),
+ RefState::getAllocateUnchecked(RS->getStmt()));
+ else if (RS->isAllocated())
+ state = state->set<RegionState>(I.getData(),
+ RefState::getReleased(RS->getStmt()));
}
+ state = state->remove<ReallocPairs>(I.getKey());
}
}
+
+ return state;
}
-void MallocChecker::checkBind(SVal location, SVal val,
- const Stmt *BindS, CheckerContext &C) const {
- // The PreVisitBind implements the same algorithm as already used by the
- // Objective C ownership checker: if the pointer escaped from this scope by
- // assignment, let it go. However, assigning to fields of a stack-storage
- // structure does not transfer ownership.
+// 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,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions) const {
+ if (!invalidated)
+ return state;
- ProgramStateRef state = C.getState();
- DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
+ 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());
+ }
- // Check for null dereferences.
- if (!isa<Loc>(l))
- return;
+ for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
+ E = invalidated->end(); I!=E; ++I) {
+ SymbolRef sym = *I;
+ if (WhitelistedSymbols.count(sym))
+ continue;
+ // Don't track the symbol.
+ state = state->remove<RegionState>(sym);
+ }
+ return state;
+}
- // Before checking if the state is null, check if 'val' has a RefState.
- // Only then should we check for null and bifurcate the state.
- SymbolRef Sym = val.getLocSymbolInBase();
- if (Sym) {
- if (const RefState *RS = state->get<RegionState>(Sym)) {
- // If ptr is NULL, no operation is performed.
- ProgramStateRef notNullState, nullState;
- llvm::tie(notNullState, nullState) = state->assume(l);
-
- // Generate a transition for 'nullState' to record the assumption
- // that the state was null.
- if (nullState)
- C.addTransition(nullState);
+PathDiagnosticPiece *
+MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) {
+ const RefState *RS = N->getState()->get<RegionState>(Sym);
+ const RefState *RSPrev = PrevN->getState()->get<RegionState>(Sym);
+ 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)
+ 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 (!Msg)
+ return 0;
+
+ // Generate the extra diagnostic.
+ PathDiagnosticLocation Pos(CE, BRC.getSourceManager(),
+ N->getLocationContext());
+ return new PathDiagnosticEventPiece(Pos, Msg);
+}
- if (!notNullState)
- return;
- if (RS->isAllocated()) {
- // Something we presently own is being assigned somewhere.
- const MemRegion *AR = location.getAsRegion();
- if (!AR)
- return;
- AR = AR->StripCasts()->getBaseRegion();
- do {
- // If it is on the stack, we still own it.
- if (AR->hasStackNonParametersStorage())
- break;
-
- // If the state can't represent this binding, we still own it.
- if (notNullState == (notNullState->bindLoc(cast<Loc>(location),
- UnknownVal())))
- break;
-
- // We no longer own this pointer.
- notNullState =
- notNullState->set<RegionState>(Sym,
- RefState::getRelinquished(BindS));
- }
- while (false);
- }
- C.addTransition(notNullState);
- }
- }
+#define REGISTER_CHECKER(name) \
+void ento::register##name(CheckerManager &mgr) {\
+ mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
}
-void ento::registerMallocChecker(CheckerManager &mgr) {
- mgr.registerChecker<MallocChecker>();
-}
+REGISTER_CHECKER(MallocPessimistic)
+REGISTER_CHECKER(MallocOptimistic)
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp Tue Feb 14 03:11:10 2012
@@ -20,7 +20,6 @@
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Checkers/DereferenceChecker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp Tue Feb 14 03:11:10 2012
@@ -19,7 +19,6 @@
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StreamChecker.cpp Tue Feb 14 03:11:10 2012
@@ -20,7 +20,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/AnalysisManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/AnalysisManager.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/AnalysisManager.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/AnalysisManager.cpp Tue Feb 14 03:11:10 2012
@@ -10,7 +10,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/Index/Entity.h"
#include "clang/Index/Indexer.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp Tue Feb 14 03:11:10 2012
@@ -21,7 +21,6 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/StmtObjC.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
@@ -30,6 +29,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include <queue>
using namespace clang;
@@ -447,7 +447,7 @@
PathDiagnosticLocation L =
PathDiagnosticLocation::createBegin(S, BR.getSourceManager(),
Pred->getLocationContext());
- PD.push_front(new PathDiagnosticEventPiece(L, os.str()));
+ PD.path.push_front(new PathDiagnosticEventPiece(L, os.str()));
}
return true;
@@ -559,8 +559,8 @@
os << "Control jumps to line "
<< End.asLocation().getExpansionLineNumber();
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
- os.str()));
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ os.str()));
break;
}
@@ -611,13 +611,13 @@
break;
}
}
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
os << "'Default' branch taken. ";
const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
@@ -629,7 +629,7 @@
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
break;
}
@@ -651,7 +651,7 @@
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
break;
}
@@ -674,14 +674,14 @@
PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
PathDiagnosticLocation Start =
PathDiagnosticLocation::createOperatorLoc(B, SMgr);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
os << "true";
PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
}
@@ -693,7 +693,7 @@
os << "false";
PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
@@ -701,7 +701,7 @@
PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
PathDiagnosticLocation Start =
PathDiagnosticLocation::createOperatorLoc(B, SMgr);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
}
@@ -720,7 +720,7 @@
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
@@ -729,7 +729,7 @@
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Loop condition is false. Exiting loop"));
}
@@ -747,7 +747,7 @@
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
@@ -755,7 +755,7 @@
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Loop condition is true. Entering loop body"));
}
@@ -769,10 +769,10 @@
End = PDB.getEnclosingStmtLocation(S);
if (*(Src->succ_begin()+1) == Dst)
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Taking false branch"));
else
- PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Taking true branch"));
break;
@@ -786,7 +786,7 @@
for (BugReport::visitor_iterator I = R->visitor_begin(),
E = R->visitor_end(); I!=E; ++I) {
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R))
- PD.push_front(p);
+ PD.path.push_front(p);
}
}
@@ -907,8 +907,8 @@
// If the PathDiagnostic already has pieces, add the enclosing statement
// of the first piece as a context as well.
- if (!PD.empty()) {
- PrevLoc = PD.begin()->getLocation();
+ if (!PD.path.empty()) {
+ PrevLoc = (*PD.path.begin())->getLocation();
if (const Stmt *S = PrevLoc.asStmt())
addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
@@ -1019,7 +1019,7 @@
PrevLocClean.asLocation().getExpansionLoc())
return;
- PD.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
+ PD.path.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
PrevLoc = NewLoc;
}
@@ -1179,7 +1179,7 @@
"Looping back to the head of the loop");
EB.addEdge(p->getLocation(), true);
- PD.push_front(p);
+ PD.path.push_front(p);
if (CS) {
PathDiagnosticLocation BL =
@@ -1221,7 +1221,7 @@
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
const PathDiagnosticLocation &Loc = p->getLocation();
EB.addEdge(Loc, true);
- PD.push_front(p);
+ PD.path.push_front(p);
if (const Stmt *S = Loc.asStmt())
EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
}
@@ -1550,18 +1550,18 @@
/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
/// and collapses PathDiagosticPieces that are expanded by macros.
static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
- typedef std::vector<std::pair<PathDiagnosticMacroPiece*, SourceLocation> >
+ typedef std::vector<std::pair<llvm::IntrusiveRefCntPtr<PathDiagnosticMacroPiece>, SourceLocation> >
MacroStackTy;
- typedef std::vector<PathDiagnosticPiece*>
+ typedef std::vector<llvm::IntrusiveRefCntPtr<PathDiagnosticPiece> >
PiecesTy;
MacroStackTy MacroStack;
PiecesTy Pieces;
- for (PathDiagnostic::iterator I = PD.begin(), E = PD.end(); I!=E; ++I) {
+ for (PathPieces::iterator I = PD.path.begin(), E = PD.path.end(); I!=E; ++I) {
// Get the location of the PathDiagnosticPiece.
- const FullSourceLoc Loc = I->getLocation().asLocation();
+ const FullSourceLoc Loc = (*I)->getLocation().asLocation();
// Determine the instantiation location, which is the location we group
// related PathDiagnosticPieces.
@@ -1571,7 +1571,7 @@
if (Loc.isFileID()) {
MacroStack.clear();
- Pieces.push_back(&*I);
+ Pieces.push_back(*I);
continue;
}
@@ -1579,13 +1579,13 @@
// Is the PathDiagnosticPiece within the same macro group?
if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
- MacroStack.back().first->push_back(&*I);
+ MacroStack.back().first->subPieces.push_back(*I);
continue;
}
// We aren't in the same group. Are we descending into a new macro
// or are part of an old one?
- PathDiagnosticMacroPiece *MacroGroup = 0;
+ llvm::IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
SM.getExpansionLoc(Loc) :
@@ -1610,10 +1610,10 @@
// Create a new macro group and add it to the stack.
PathDiagnosticMacroPiece *NewGroup =
new PathDiagnosticMacroPiece(
- PathDiagnosticLocation::createSingleLocation(I->getLocation()));
+ PathDiagnosticLocation::createSingleLocation((*I)->getLocation()));
if (MacroGroup)
- MacroGroup->push_back(NewGroup);
+ MacroGroup->subPieces.push_back(NewGroup);
else {
assert(InstantiationLoc.isFileID());
Pieces.push_back(NewGroup);
@@ -1624,20 +1624,17 @@
}
// Finally, add the PathDiagnosticPiece to the group.
- MacroGroup->push_back(&*I);
+ MacroGroup->subPieces.push_back(*I);
}
// Now take the pieces and construct a new PathDiagnostic.
- PD.resetPath(false);
+ PD.path.clear();
for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I) {
- if (PathDiagnosticMacroPiece *MP=dyn_cast<PathDiagnosticMacroPiece>(*I))
- if (!MP->containsEvent()) {
- delete MP;
+ if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
+ if (!MP->containsEvent())
continue;
- }
-
- PD.push_back(*I);
+ PD.path.push_back(*I);
}
}
@@ -1693,7 +1690,7 @@
if (!LastPiece)
LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
if (LastPiece)
- PD.push_back(LastPiece);
+ PD.path.push_back(LastPiece);
else
return;
@@ -1952,13 +1949,13 @@
if (!PD)
return;
- if (D->empty()) {
+ if (D->path.empty()) {
PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
exampleReport->getLocation(getSourceManager()),
exampleReport->getDescription());
for ( ; Beg != End; ++Beg) piece->addRange(*Beg);
- D->push_back(piece);
+ D->path.push_back(piece);
}
PD->HandlePathDiagnostic(D.take());
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerRegistry.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerRegistry.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerRegistry.cpp Tue Feb 14 03:11:10 2012
@@ -10,7 +10,6 @@
#include "clang/StaticAnalyzer/Core/CheckerRegistry.h"
#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace ento;
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Feb 14 03:11:10 2012
@@ -309,6 +309,30 @@
}
+// For now, skip inlining variadic functions.
+// We also don't inline blocks.
+static bool shouldInlineCall(const CallExpr *CE, ExprEngine &Eng) {
+ if (!Eng.getAnalysisManager().shouldInlineCall())
+ return false;
+ QualType callee = CE->getCallee()->getType();
+ const FunctionProtoType *FT = 0;
+ if (const PointerType *PT = callee->getAs<PointerType>())
+ FT = dyn_cast<FunctionProtoType>(PT->getPointeeType());
+ else if (const BlockPointerType *BT = callee->getAs<BlockPointerType>()) {
+ // FIXME: inline blocks.
+ // FT = dyn_cast<FunctionProtoType>(BT->getPointeeType());
+ (void) BT;
+ return false;
+ }
+
+ // If we have no prototype, assume the function is okay.
+ if (!FT)
+ return true;
+
+ // Skip inlining of variadic functions.
+ return !FT->isVariadic();
+}
+
void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
ExplodedNodeSet &dst) {
// Perform the previsit of the CallExpr.
@@ -325,7 +349,7 @@
: Eng(eng), CE(ce) {}
virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) {
// Should we inline the call?
- if (Eng.getAnalysisManager().shouldInlineCall() &&
+ if (shouldInlineCall(CE, Eng) &&
Eng.InlineCall(Dst, CE, Pred)) {
return;
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp Tue Feb 14 03:11:10 2012
@@ -119,12 +119,13 @@
if (noDir)
return;
- const SourceManager &SMgr = D.begin()->getLocation().getManager();
+ const SourceManager &SMgr = (*D.path.begin())->getLocation().getManager();
FileID FID;
// Verify that the entire path is from the same FileID.
- for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
- FullSourceLoc L = I->getLocation().asLocation().getExpansionLoc();
+ for (PathPieces::const_iterator I = D.path.begin(), E = D.path.end();
+ I != E; ++I) {
+ FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
if (FID.isInvalid()) {
FID = SMgr.getFileID(L);
@@ -132,16 +133,13 @@
return; // FIXME: Emit a warning?
// Check the source ranges.
- for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
- RE=I->ranges_end(); RI!=RE; ++RI) {
-
+ for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
+ RE = (*I)->ranges_end();
+ RI != RE; ++RI) {
SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
-
if (!L.isFileID() || SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
-
L = SMgr.getExpansionLoc(RI->getEnd());
-
if (!L.isFileID() || SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
}
@@ -154,12 +152,12 @@
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
// Process the path.
- unsigned n = D.size();
+ unsigned n = D.path.size();
unsigned max = n;
- for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
- I!=E; ++I, --n)
- HandlePiece(R, FID, *I, n, max);
+ for (PathPieces::const_reverse_iterator I = D.path.rbegin(), E=D.path.rend();
+ I != E; ++I, --n)
+ HandlePiece(R, FID, **I, n, max);
// Add line numbers, header, footer, etc.
@@ -202,9 +200,9 @@
<< html::EscapeText(Entry->getName())
<< "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
"<a href=\"#EndPath\">line "
- << (*D.rbegin()).getLocation().asLocation().getExpansionLineNumber()
+ << (*D.path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
<< ", column "
- << (*D.rbegin()).getLocation().asLocation().getExpansionColumnNumber()
+ << (*D.path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
<< "</a></td></tr>\n"
"<tr><td class=\"rowname\">Description:</td><td>"
<< D.getDescription() << "</td></tr>\n";
@@ -242,10 +240,10 @@
os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
os << "\n<!-- BUGLINE "
- << D.back()->getLocation().asLocation().getExpansionLineNumber()
+ << D.path.back()->getLocation().asLocation().getExpansionLineNumber()
<< " -->\n";
- os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
+ os << "\n<!-- BUGPATHLENGTH " << D.path.size() << " -->\n";
// Mark the end of the tags.
os << "\n<!-- BUGMETAEND -->\n";
@@ -501,7 +499,7 @@
const PathDiagnosticMacroPiece& P,
unsigned num) {
- for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+ for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
I!=E; ++I) {
if (const PathDiagnosticMacroPiece *MP =
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Tue Feb 14 03:11:10 2012
@@ -24,15 +24,14 @@
using namespace ento;
bool PathDiagnosticMacroPiece::containsEvent() const {
- for (const_iterator I = begin(), E = end(); I!=E; ++I) {
+ for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
+ I!=E; ++I) {
if (isa<PathDiagnosticEventPiece>(*I))
return true;
-
if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
if (MP->containsEvent())
return true;
}
-
return false;
}
@@ -55,32 +54,14 @@
PathDiagnosticCallEnterPiece::~PathDiagnosticCallEnterPiece() {}
PathDiagnosticCallExitPiece::~PathDiagnosticCallExitPiece() {}
PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {}
-
-PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {
- for (iterator I = begin(), E = end(); I != E; ++I) delete *I;
-}
-
-PathDiagnostic::PathDiagnostic() : Size(0) {}
-
-PathDiagnostic::~PathDiagnostic() {
- for (iterator I = begin(), E = end(); I != E; ++I) delete &*I;
-}
-
-void PathDiagnostic::resetPath(bool deletePieces) {
- Size = 0;
-
- if (deletePieces)
- for (iterator I=begin(), E=end(); I!=E; ++I)
- delete &*I;
-
- path.clear();
-}
-
+PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {}
+PathDiagnostic::PathDiagnostic() {}
+PathPieces::~PathPieces() {}
+PathDiagnostic::~PathDiagnostic() {}
PathDiagnostic::PathDiagnostic(StringRef bugtype, StringRef desc,
StringRef category)
- : Size(0),
- BugType(StripTrailingDots(bugtype)),
+ : BugType(StripTrailingDots(bugtype)),
Desc(StripTrailingDots(desc)),
Category(StripTrailingDots(category)) {}
@@ -98,7 +79,7 @@
if (!D)
return;
- if (D->empty()) {
+ if (D->path.empty()) {
delete D;
return;
}
@@ -115,9 +96,9 @@
if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
// Keep the PathDiagnostic with the shorter path.
- if (orig->size() <= D->size()) {
+ if (orig->path.size() <= D->path.size()) {
bool shouldKeepOriginal = true;
- if (orig->size() == D->size()) {
+ if (orig->path.size() == D->path.size()) {
// Here we break ties in a fairly arbitrary, but deterministic, way.
llvm::FoldingSetNodeID fullProfile, fullProfileOrig;
D->FullProfile(fullProfile);
@@ -474,12 +455,13 @@
void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
PathDiagnosticSpotPiece::Profile(ID);
- for (const_iterator I = begin(), E = end(); I != E; ++I)
+ for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
+ I != E; ++I)
ID.Add(**I);
}
void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
- if (Size)
+ if (!path.empty())
getLocation().Profile(ID);
ID.AddString(BugType);
ID.AddString(Desc);
@@ -488,8 +470,8 @@
void PathDiagnostic::FullProfile(llvm::FoldingSetNodeID &ID) const {
Profile(ID);
- for (const_iterator I = begin(), E = end(); I != E; ++I)
- ID.Add(*I);
+ for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; ++I)
+ ID.Add(**I);
for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
ID.AddString(*I);
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Tue Feb 14 03:11:10 2012
@@ -246,7 +246,7 @@
const LangOptions &LangOpts,
unsigned indent) {
- for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+ for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
I!=E; ++I) {
switch ((*I)->getKind()) {
@@ -298,18 +298,19 @@
const SourceManager* SM = 0;
if (!Diags.empty())
- SM = &(*Diags.begin())->begin()->getLocation().getManager();
+ SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager();
for (std::vector<const PathDiagnostic*>::iterator DI = Diags.begin(),
DE = Diags.end(); DI != DE; ++DI) {
const PathDiagnostic *D = *DI;
- for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I!=E; ++I) {
- AddFID(FM, Fids, SM, I->getLocation().asLocation());
+ for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
+ I!=E; ++I) {
+ AddFID(FM, Fids, SM, (*I)->getLocation().asLocation());
- for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
- RE=I->ranges_end(); RI!=RE; ++RI) {
+ for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
+ RE= (*I)->ranges_end(); RI != RE; ++RI) {
AddFID(FM, Fids, SM, RI->getBegin());
AddFID(FM, Fids, SM, RI->getEnd());
}
@@ -357,8 +358,9 @@
o << " <array>\n";
- for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I)
- ReportDiag(o, *I, FM, *SM, LangOpts);
+ for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
+ I != E; ++I)
+ ReportDiag(o, **I, FM, *SM, LangOpts);
o << " </array>\n";
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp Tue Feb 14 03:11:10 2012
@@ -13,7 +13,6 @@
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -59,11 +58,12 @@
for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(),
et = Diags.end(); it != et; ++it) {
const PathDiagnostic *D = *it;
- for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) {
+ for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
+ I != E; ++I) {
unsigned diagID =
Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
- I->getString());
- Diag.Report(I->getLocation().asLocation(), diagID);
+ (*I)->getString());
+ Diag.Report((*I)->getLocation().asLocation(), diagID);
}
}
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Tue Feb 14 03:11:10 2012
@@ -27,7 +27,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/AnalyzerOptions.h"
Modified: cfe/branches/tooling/test/ARCMT/checking.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/ARCMT/checking.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/ARCMT/checking.m (original)
+++ cfe/branches/tooling/test/ARCMT/checking.m Tue Feb 14 03:11:10 2012
@@ -15,9 +15,9 @@
typedef unsigned NSUInteger;
@protocol NSObject
-- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{unavailable here}}
+- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
-- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note 4 {{unavailable here}}
+- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
@end
@@ -75,20 +75,16 @@
void test1(A *a, BOOL b, struct UnsafeS *unsafeS) {
[[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \
- // expected-error {{ARC forbids explicit message send}} \
- // expected-error {{unavailable}}
+ // expected-error {{ARC forbids explicit message send}}
[a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \
- // expected-error {{ARC forbids explicit message send}} \
- // expected-error {{unavailable}}
+ // expected-error {{ARC forbids explicit message send}}
[unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \
// expected-error {{ARC forbids explicit message send}}
id foo = [unsafeS->unsafeObj retain]; // no warning.
[global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \
- // expected-error {{ARC forbids explicit message send}} \
- // expected-error {{unavailable}}
+ // expected-error {{ARC forbids explicit message send}}
[global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \
- // expected-error {{ARC forbids explicit message send}} \
- // expected-error {{unavailable}}
+ // expected-error {{ARC forbids explicit message send}}
[a dealloc];
[a retain];
[a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}}
@@ -302,8 +298,7 @@
// rdar://9504750
void rdar9504750(id p) {
- RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} \
- // expected-error {{unavailable}}
+ RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}}
}
// rdar://8939557
Modified: cfe/branches/tooling/test/Analysis/free.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/free.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/free.c (original)
+++ cfe/branches/tooling/test/Analysis/free.c Tue Feb 14 03:11:10 2012
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,experimental.unix.Malloc -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,experimental.unix.MallocWithAnnotations -fblocks -verify %s
void free(void *);
void t1 () {
Modified: cfe/branches/tooling/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/malloc.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/malloc.c (original)
+++ cfe/branches/tooling/test/Analysis/malloc.c Tue Feb 14 03:11:10 2012
@@ -1,26 +1,14 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,experimental.unix.Malloc -analyzer-store=region -verify %s
+#include "system-header-simulator.h"
+
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
void free(void *);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
-void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
-void __attribute((ownership_takes(malloc, 1))) my_free(void *);
-void __attribute((ownership_returns(malloc, 1))) *my_malloc2(size_t);
-void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
-
-// Duplicate attributes are silly, but not an error.
-// Duplicate attribute has no extra effect.
-// If two are of different kinds, that is an error and reported as such.
-void __attribute((ownership_holds(malloc, 1)))
-__attribute((ownership_holds(malloc, 1)))
-__attribute((ownership_holds(malloc, 3))) my_hold2(void *, void *, void *);
-void *my_malloc3(size_t);
-void *myglobalpointer;
-struct stuff {
- void *somefield;
-};
-struct stuff myglobalstuff;
+
+void myfoo(int *p);
+void myfooint(int p);
void f1() {
int *p = malloc(12);
@@ -44,107 +32,124 @@
int *q = realloc(p,0); // no-warning
}
-// ownership attributes tests
-void naf1() {
- int *p = my_malloc3(12);
- return; // no-warning
+void reallocNotNullPtr(unsigned sizeIn) {
+ unsigned size = 12;
+ char *p = (char*)malloc(size);
+ if (p) {
+ char *q = (char*)realloc(p, sizeIn);
+ char x = *q; // expected-warning {{Allocated memory never released.}}
+ }
}
-void n2af1() {
- int *p = my_malloc2(12);
- return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
-}
-
-void af1() {
- int *p = my_malloc(12);
- return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
+int *realloctest1() {
+ int *q = malloc(12);
+ q = realloc(q, 20);
+ return q; // no warning - returning the allocated value
}
-void af1_b() {
- int *p = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+// p should be freed if realloc fails.
+void reallocFails() {
+ char *p = malloc(12);
+ char *r = realloc(p, 12+1);
+ if (!r) {
+ free(p);
+ } else {
+ free(r);
+ }
}
-void af1_c() {
- myglobalpointer = my_malloc(12); // no-warning
+void reallocSizeZero1() {
+ char *p = malloc(12);
+ char *r = realloc(p, 0);
+ if (!r) {
+ free(p);
+ } else {
+ free(r);
+ }
}
-void af1_d() {
- struct stuff mystuff;
- mystuff.somefield = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
+void reallocSizeZero2() {
+ char *p = malloc(12);
+ char *r = realloc(p, 0);
+ if (!r) {
+ free(p);
+ } else {
+ free(r);
+ }
+ free(p); // expected-warning {{Try to free a memory block that has been released}}
}
-// Test that we can pass out allocated memory via pointer-to-pointer.
-void af1_e(void **pp) {
- *pp = my_malloc(42); // no-warning
+void reallocSizeZero3() {
+ char *p = malloc(12);
+ char *r = realloc(p, 0);
+ free(r);
}
-void af1_f(struct stuff *somestuff) {
- somestuff->somefield = my_malloc(12); // no-warning
+void reallocSizeZero4() {
+ char *r = realloc(0, 0);
+ free(r);
}
-// Allocating memory for a field via multiple indirections to our arguments is OK.
-void af1_g(struct stuff **pps) {
- *pps = my_malloc(sizeof(struct stuff)); // no-warning
- (*pps)->somefield = my_malloc(42); // no-warning
+void reallocSizeZero5() {
+ char *r = realloc(0, 0);
}
-void af2() {
- int *p = my_malloc(12);
- my_free(p);
- free(p); // expected-warning{{Try to free a memory block that has been released}}
+void reallocPtrZero1() {
+ char *r = realloc(0, 12); // expected-warning {{Allocated memory never released.}}
}
-void af2b() {
- int *p = my_malloc(12);
- free(p);
- my_free(p); // expected-warning{{Try to free a memory block that has been released}}
+void reallocPtrZero2() {
+ char *r = realloc(0, 12);
+ if (r)
+ free(r);
}
-void af2c() {
- int *p = my_malloc(12);
- free(p);
- my_hold(p); // expected-warning{{Try to free a memory block that has been released}}
+void reallocPtrZero3() {
+ char *r = realloc(0, 12);
+ free(r);
}
-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}}
+void reallocRadar6337483_1() {
+ char *buf = malloc(100);
+ buf = (char*)realloc(buf, 0x1000000);
+ if (!buf) {
+ return;// expected-warning {{Allocated memory never released.}}
+ }
+ free(buf);
}
-// No leak if malloc returns null.
-void af2e() {
- int *p = my_malloc(12);
- if (!p)
- return; // no-warning
- free(p); // no-warning
+void reallocRadar6337483_2() {
+ char *buf = malloc(100);
+ char *buf2 = (char*)realloc(buf, 0x1000000);
+ if (!buf2) { // expected-warning {{Allocated memory never released.}}
+ ;
+ } else {
+ free(buf2);
+ }
}
-// This case would inflict a double-free elsewhere.
-// However, this case is considered an analyzer bug since it causes false-positives.
-void af3() {
- int *p = my_malloc(12);
- my_hold(p);
- free(p); // no-warning
-}
-
-// This case would inflict a double-free elsewhere.
-// However, this case is considered an analyzer bug since it causes false-positives.
-int * af4() {
- int *p = my_malloc(12);
- my_free(p);
- return p; // no-warning
+void reallocRadar6337483_3() {
+ char * buf = malloc(100);
+ char * tmp;
+ tmp = (char*)realloc(buf, 0x1000000);
+ if (!tmp) {
+ free(buf);
+ return;
+ }
+ buf = tmp;
+ free(buf);
}
-// This case is (possibly) ok, be conservative
-int * af5() {
- int *p = my_malloc(12);
- my_hold(p);
- return p; // no-warning
+void reallocRadar6337483_4() {
+ char *buf = malloc(100);
+ char *buf2 = (char*)realloc(buf, 0x1000000);
+ if (!buf2) {
+ return; // expected-warning {{Allocated memory never released.}}
+ } else {
+ free(buf2);
+ }
}
-
-
// 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.
@@ -199,13 +204,13 @@
void f7() {
char *x = (char*) malloc(4);
free(x);
- x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}}
+ x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
}
void f7_realloc() {
char *x = (char*) malloc(4);
realloc(x,0);
- x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}}
+ x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
}
void PR6123() {
@@ -261,3 +266,276 @@
}
return result; // expected-warning{{never released}}
}
+
+void nullFree() {
+ int *p = 0;
+ free(p); // no warning - a nop
+}
+
+void paramFree(int *p) {
+ myfoo(p);
+ free(p); // no warning
+ myfoo(p); // TODO: This should be a warning.
+}
+
+int* mallocEscapeRet() {
+ int *p = malloc(12);
+ return p; // no warning
+}
+
+void mallocEscapeFoo() {
+ int *p = malloc(12);
+ myfoo(p);
+ return; // no warning
+}
+
+void mallocEscapeFree() {
+ int *p = malloc(12);
+ myfoo(p);
+ free(p);
+}
+
+void mallocEscapeFreeFree() {
+ int *p = malloc(12);
+ myfoo(p);
+ free(p);
+ free(p); // expected-warning{{Try to free a memory block that has been released}}
+}
+
+void mallocEscapeFreeUse() {
+ int *p = malloc(12);
+ myfoo(p);
+ free(p);
+ myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
+}
+
+int *myalloc();
+void myalloc2(int **p);
+
+void mallocEscapeFreeCustomAlloc() {
+ int *p = malloc(12);
+ myfoo(p);
+ free(p);
+ p = myalloc();
+ free(p); // no warning
+}
+
+void mallocEscapeFreeCustomAlloc2() {
+ int *p = malloc(12);
+ myfoo(p);
+ free(p);
+ myalloc2(&p);
+ free(p); // no warning
+}
+
+void mallocBindFreeUse() {
+ int *x = malloc(12);
+ int *y = x;
+ free(y);
+ myfoo(x); // expected-warning{{Use of dynamically allocated 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.}}
+}
+
+void mallocMalloc() {
+ int *p = malloc(12);
+ p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}}
+}
+
+void mallocFreeMalloc() {
+ int *p = malloc(12);
+ free(p);
+ p = malloc(12);
+ free(p);
+}
+
+void mallocFreeUse_params() {
+ int *p = malloc(12);
+ free(p);
+ myfoo(p); //expected-warning{{Use of dynamically allocated 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}}
+}
+
+void mallocFailedOrNot() {
+ int *p = malloc(12);
+ if (!p)
+ free(p);
+ else
+ free(p);
+}
+
+struct StructWithInt {
+ int g;
+};
+
+int *mallocReturnFreed() {
+ int *p = malloc(12);
+ free(p);
+ return p; // expected-warning {{Use of dynamically allocated}}
+}
+
+int useAfterFreeStruct() {
+ struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
+ px->g = 5;
+ free(px);
+ return px->g; // expected-warning {{Use of dynamically allocated}}
+}
+
+void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
+
+void mallocEscapeFooNonSymbolArg() {
+ struct StructWithInt *p = malloc(sizeof(struct StructWithInt));
+ nonSymbolAsFirstArg(&p->g, p);
+ return; // no warning
+}
+
+void mallocFailedOrNotLeak() {
+ int *p = malloc(12);
+ if (p == 0)
+ return; // no warning
+ else
+ return; // expected-warning {{Allocated memory never released. Potential memory leak.}}
+}
+
+int *Gl;
+struct GlStTy {
+ int *x;
+};
+
+struct GlStTy GlS = {0};
+
+void GlobalFree() {
+ free(Gl);
+}
+
+void GlobalMalloc() {
+ Gl = malloc(12);
+}
+
+void GlobalStructMalloc() {
+ int *a = malloc(12);
+ GlS.x = a;
+}
+
+void GlobalStructMallocFree() {
+ int *a = malloc(12);
+ GlS.x = a;
+ free(GlS.x);
+}
+
+// Region escape testing.
+
+unsigned takePtrToPtr(int **p);
+void PassTheAddrOfAllocatedData(int f) {
+ int *p = malloc(12);
+ // We don't know what happens after the call. Should stop tracking here.
+ if (takePtrToPtr(&p))
+ f++;
+ free(p); // no warning
+}
+
+struct X {
+ int *p;
+};
+unsigned takePtrToStruct(struct X *s);
+int ** foo2(int *g, int f) {
+ int *p = malloc(12);
+ struct X *px= malloc(sizeof(struct X));
+ px->p = p;
+ // We don't know what happens after this call. Should not track px nor p.
+ if (takePtrToStruct(px))
+ f++;
+ free(p);
+ return 0;
+}
+
+struct X* RegInvalidationDetect1(struct X *s2) {
+ struct X *px= malloc(sizeof(struct X));
+ px->p = 0;
+ px = s2;
+ return px; // expected-warning {{Allocated memory never released. Potential memory leak.}}
+}
+
+struct X* RegInvalidationGiveUp1() {
+ int *p = malloc(12);
+ struct X *px= malloc(sizeof(struct X));
+ px->p = p;
+ return px;
+}
+
+int **RegInvalidationDetect2(int **pp) {
+ int *p = malloc(12);
+ pp = &p;
+ pp++;
+ return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}}
+}
+
+extern void exit(int) __attribute__ ((__noreturn__));
+void mallocExit(int *g) {
+ struct xx *p = malloc(12);
+ if (g != 0)
+ exit(1);
+ free(p);
+ return;
+}
+
+extern void __assert_fail (__const char *__assertion, __const char *__file,
+ unsigned int __line, __const char *__function)
+ __attribute__ ((__noreturn__));
+#define assert(expr) \
+ ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__))
+void mallocAssert(int *g) {
+ struct xx *p = malloc(12);
+
+ assert(g != 0);
+ free(p);
+ return;
+}
+
+void doNotInvalidateWhenPassedToSystemCalls(char *s) {
+ char *p = malloc(12);
+ strlen(p);
+ strcpy(p, s); // expected-warning {{leak}}
+}
+
+// Below are the known false positives.
+
+// TODO: There should be no warning here. This one might be difficult to get rid of.
+void dependsOnValueOfPtr(int *g, unsigned f) {
+ int *p;
+
+ if (f) {
+ p = g;
+ } else {
+ p = malloc(12);
+ }
+
+ if (p != g)
+ free(p);
+ else
+ return; // expected-warning{{Allocated memory never released. Potential memory leak}}
+ return;
+}
+
+// TODO: Should this be a warning?
+// Here we are returning a pointer one past the allocated value. An idiom which
+// can be used for implementing special malloc. The correct uses of this might
+// be rare enough so that we could keep this as a warning.
+static void *specialMalloc(int n){
+ int *p;
+ p = malloc( n+8 );
+ if( p ){
+ p[0] = n;
+ p++;
+ }
+ return p;// expected-warning {{Allocated memory never released. Potential memory leak.}}
+}
Modified: cfe/branches/tooling/test/Analysis/system-header-simulator.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/system-header-simulator.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/system-header-simulator.h (original)
+++ cfe/branches/tooling/test/Analysis/system-header-simulator.h Tue Feb 14 03:11:10 2012
@@ -8,3 +8,6 @@
extern int errno;
unsigned long strlen(const char *);
+
+char *strcpy(char *restrict s1, const char *restrict s2);
+
Modified: cfe/branches/tooling/test/CXX/basic/basic.types/p10.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/basic/basic.types/p10.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/basic/basic.types/p10.cpp (original)
+++ cfe/branches/tooling/test/CXX/basic/basic.types/p10.cpp Tue Feb 14 03:11:10 2012
@@ -5,22 +5,23 @@
// A type is a literal type if it is:
// - a scalar type
-constexpr int f1(double);
+constexpr int f1(double) { return 0; }
// - a reference type
struct S { S(); };
-constexpr int f2(S &);
+constexpr int f2(S &) { return 0; }
// - a class type that has all of the following properties:
// - it has a trivial destructor
struct UserProvDtor {
- constexpr UserProvDtor(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
+ constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
~UserProvDtor(); // expected-note {{has a user-provided destructor}}
};
struct NonTrivDtor {
- constexpr NonTrivDtor(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
+ constexpr NonTrivDtor();
+ constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}}
};
struct NonTrivDtorBase {
@@ -30,16 +31,16 @@
struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}}
constexpr DerivedFromNonTrivDtor();
};
-constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}}
+constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>) { return 0; } // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}}
struct TrivDtor {
constexpr TrivDtor();
};
-constexpr int f(TrivDtor);
+constexpr int f(TrivDtor) { return 0; }
struct TrivDefaultedDtor {
constexpr TrivDefaultedDtor();
~TrivDefaultedDtor() = default;
};
-constexpr int f(TrivDefaultedDtor);
+constexpr int f(TrivDefaultedDtor) { return 0; }
// - it is an aggregate type or has at least one constexpr constructor or
// constexpr constructor template that is not a copy or move constructor
@@ -52,36 +53,41 @@
template<typename T> constexpr CtorTemplate(T);
};
struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
- constexpr CopyCtorOnly(CopyCtorOnly&); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
+ constexpr CopyCtorOnly(CopyCtorOnly&);
+ constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
};
struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}}
- constexpr MoveCtorOnly(MoveCtorOnly&&); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
+ constexpr MoveCtorOnly(MoveCtorOnly&&);
+ constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
};
template<typename T>
-struct CtorArg { // expected-note {{no constexpr constructors other than copy or move constructors}}
- constexpr CtorArg(T); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}}
+struct CtorArg {
+ constexpr CtorArg(T);
};
-constexpr int f(CtorArg<int>);
-constexpr int f(CtorArg<NonLiteral>); // expected-error {{not a literal type}}
+constexpr int f(CtorArg<int>) { return 0; } // ok
+constexpr int f(CtorArg<NonLiteral>) { return 0; } // ok, ctor is still constexpr
// We have a special-case diagnostic for classes with virtual base classes.
struct VBase {};
struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}}
struct Derived : HasVBase {
- constexpr Derived(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
+ constexpr Derived() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
};
template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}}
constexpr DerivedFromVBase();
};
-constexpr int f(DerivedFromVBase<HasVBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
+constexpr int f(DerivedFromVBase<HasVBase>) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
+template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {}
+constexpr int nVBase = (DerivedFromVBase<HasVBase>(), 0); // expected-error {{constant expression}} expected-note {{cannot construct object of type 'DerivedFromVBase<HasVBase>' with virtual base class in a constant expression}}
// - it has all non-static data members and base classes of literal types
struct NonLitMember {
S s; // expected-note {{has data member 's' of non-literal type 'S'}}
};
-constexpr int f(NonLitMember); // expected-error {{1st parameter type 'NonLitMember' is not a literal type}}
+constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitMember' is not a literal type}}
struct NonLitBase :
S { // expected-note {{base class 'S' of non-literal type}}
- constexpr NonLitBase(); // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
+ constexpr NonLitBase();
+ constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
};
struct LitMemBase : Agg {
Agg agg;
@@ -91,8 +97,8 @@
T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}}
constexpr MemberType();
};
-constexpr int f(MemberType<int>);
-constexpr int f(MemberType<NonLiteral>); // expected-error {{not a literal type}}
+constexpr int f(MemberType<int>) { return 0; }
+constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}}
// - an array of literal type
struct ArrGood {
@@ -101,27 +107,9 @@
TrivDtor td[3];
TrivDefaultedDtor tdd[3];
};
-constexpr int f(ArrGood);
+constexpr int f(ArrGood) { return 0; }
struct ArrBad {
S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}}
};
-constexpr int f(ArrBad); // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
-
-
-// As a non-conforming tweak to the standard, we do not allow a literal type to
-// have any mutable data members.
-namespace MutableMembers {
- struct MM {
- mutable int n; // expected-note {{'MM' is not literal because it has a mutable data member}}
- };
- constexpr int f(MM); // expected-error {{not a literal type}}
-
- // Here's one reason why allowing this would be a disaster...
- template<int n> struct Id { int k = n; };
- int f() {
- constexpr MM m = { 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type 'const MutableMembers::MM' cannot be used in a constant expression}} expected-note {{here}}
- ++m.n;
- return Id<m.n>().k; // expected-error {{not a constant expression}} expected-note {{initializer of 'm' is not a constant expression}}
- }
-}
+constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
Modified: cfe/branches/tooling/test/CXX/class/class.friend/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/class/class.friend/p1.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/class/class.friend/p1.cpp (original)
+++ cfe/branches/tooling/test/CXX/class/class.friend/p1.cpp Tue Feb 14 03:11:10 2012
@@ -58,7 +58,7 @@
friend A operator|(const A& r); // expected-error {{overloaded 'operator|' must be a binary operator (has 1 parameter)}}
friend operator bool() const; // expected-error {{must use a qualified name when declaring a conversion operator as a friend}} \
- // expected-error{{type qualifier is not allowed on this function}}
+ // expected-error{{non-member function cannot have 'const' qualifier}}
typedef void ftypedef();
friend ftypedef typedeffed_function; // okay (because it's not declared as a member)
Modified: cfe/branches/tooling/test/CXX/class/class.local/p1-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/class/class.local/p1-0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/class/class.local/p1-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/class/class.local/p1-0x.cpp Tue Feb 14 03:11:10 2012
@@ -7,12 +7,12 @@
int& x2 = x; // expected-error{{reference to local variable 'x' declared in enclosing function 'f'}}
int cc = c;
};
- []() mutable { // expected-error {{not supported yet}}
+ (void)[]() mutable {
int x = 3; // expected-note{{'x' declared here}}
struct C {
int& x2 = x; // expected-error{{reference to local variable 'x' declared in enclosing lambda expression}}
};
- }
+ };
C();
}
Modified: cfe/branches/tooling/test/CXX/class/class.static/class.static.data/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/class/class.static/class.static.data/p3.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/class/class.static/class.static.data/p3.cpp (original)
+++ cfe/branches/tooling/test/CXX/class/class.static/class.static.data/p3.cpp Tue Feb 14 03:11:10 2012
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-struct NonLit {
+struct NonLit { // expected-note 3{{no constexpr constructors}}
NonLit();
};
@@ -29,15 +29,14 @@
struct U {
static constexpr int a = 0;
static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}}
- // FIXME: It'd be nice to error on this at template definition time.
- static constexpr NonLit h = NonLit(); // expected-error 2{{must be initialized by a constant expression}} expected-note 2{{non-literal type}}
- static constexpr T c = T(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type}}
+ static constexpr NonLit h = NonLit(); // expected-error {{cannot have non-literal type 'const NonLit'}}
+ static constexpr T c = T(); // expected-error {{cannot have non-literal type}}
static const T d;
};
-template<typename T> constexpr T U<T>::d = T(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type 'const NonLit'}}
+template<typename T> constexpr T U<T>::d = T(); // expected-error {{non-literal type 'const NonLit'}}
-U<int> u1; // expected-note {{here}}
+U<int> u1;
U<NonLit> u2; // expected-note {{here}}
static_assert(U<int>::a == 0, "");
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp Tue Feb 14 03:11:10 2012
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-struct notlit {
+struct notlit { // expected-note {{not literal because}}
notlit() {}
};
struct notlit2 {
@@ -20,7 +20,7 @@
// not a definition of an object
constexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}}
// not a literal type
-constexpr notlit nl1; // expected-error {{constexpr variable 'nl1' must be initialized by a constant expression}} expected-note {{non-literal type 'const notlit' cannot be used in a constant expression}}
+constexpr notlit nl1; // expected-error {{constexpr variable cannot have non-literal type 'const notlit'}}
// function parameters
void f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}}
// non-static member
@@ -77,11 +77,11 @@
// explicit specialization can differ in constepxr
// FIXME: When checking the explicit specialization, we implicitly instantiate
// the primary template then claim a constexpr mismatch.
-template <> notlit ft(notlit nl) { return nl; }
+template <> notlit ft(notlit nl) { return nl; } // unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
template <> char ft(char c) { return c; } // desired-note {{previous}} unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
template <> constexpr char ft(char nl); // desired-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
template <> constexpr int gt(int nl) { return nl; } // unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}}
-template <> notlit S::f() const { return notlit(); }
+template <> notlit S::f() const { return notlit(); } // unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
template <> constexpr int S::g() { return 0; } // desired-note {{previous}} unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}}
template <> int S::g() const; // desired-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
// specializations can drop the 'constexpr' but not the implied 'const'.
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp Tue Feb 14 03:11:10 2012
@@ -8,7 +8,7 @@
typedef double D;
}
-struct NonLiteral { // expected-note 4{{no constexpr constructors}}
+struct NonLiteral { // expected-note 2{{no constexpr constructors}}
NonLiteral() {}
NonLiteral(int) {}
};
@@ -24,31 +24,28 @@
int ImplicitlyVirtual() const;
};
-// Note, the wording applies constraints to the definition of constexpr
-// functions, but we intentionally apply all that we can to the declaration
-// instead. See DR1360.
-
// The definition of a constexpr function shall satisfy the following
// constraints:
struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
- constexpr T(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
+ constexpr T();
+ constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
// - it shall not be virtual;
- virtual constexpr int ExplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}}
+ virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
- constexpr int ImplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}}
+ constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
// - its return type shall be a literal type;
- constexpr NonLiteral NonLiteralReturn(); // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
- constexpr void VoidReturn(); // expected-error {{constexpr function's return type 'void' is not a literal type}}
+ constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
+ constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}}
constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
typedef NonLiteral F();
- constexpr F NonLiteralReturn2; // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
+ constexpr F NonLiteralReturn2; // ok until definition
// - each of its parameter types shall be a literal type;
- constexpr int NonLiteralParam(NonLiteral); // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
+ constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
typedef int G(NonLiteral);
- constexpr G NonLiteralParam2; // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
+ constexpr G NonLiteralParam2; // ok until definition
// - its function-body shall be = delete, = default,
constexpr int Deleted() = delete;
@@ -65,7 +62,7 @@
};
struct V : virtual U { // expected-note {{here}}
- constexpr int F(); // expected-error {{constexpr member function not allowed in struct with virtual base class}}
+ constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
};
// or a compound-statememt that contains only
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp Tue Feb 14 03:11:10 2012
@@ -18,16 +18,12 @@
operator int() const { return 0; }
};
-// Note, the wording applies constraints to the definition of constexpr
-// constructors, but we intentionally apply all that we can to the declaration
-// instead. See DR1360.
-
// In the definition of a constexpr constructor, each of the parameter types
// shall be a literal type.
struct S {
- constexpr S(int, N::C);
- constexpr S(int, NonLiteral, N::C); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
- constexpr S(int, NonLiteral = 42); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
+ constexpr S(int, N::C) {}
+ constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
+ constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
// In addition, either its function-body shall be = delete or = default
constexpr S() = default;
@@ -38,14 +34,14 @@
// - the class shall not have any virtual base classes;
struct T : virtual S { // expected-note {{here}}
- constexpr T(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
+ constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
};
namespace IndirectVBase {
struct A {};
struct B : virtual A {}; // expected-note {{here}}
class C : public B {
public:
- constexpr C(); // expected-error {{constexpr constructor not allowed in class with virtual base class}}
+ constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}}
};
}
@@ -151,6 +147,16 @@
constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}}
};
+union Empty {
+ constexpr Empty() {} // ok
+} constexpr empty1;
+
+struct EmptyVariant {
+ union {};
+ struct {};
+ constexpr EmptyVariant() {} // ok
+} constexpr empty2;
+
template<typename T> using Int = int;
template<typename T>
struct TemplateInit {
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp Tue Feb 14 03:11:10 2012
@@ -10,7 +10,7 @@
struct NonLiteral {
NonLiteral() {}
- NonLiteral(int) {}
+ NonLiteral(int) {} // expected-note 2{{here}}
operator int() const { return 0; }
};
struct Literal {
@@ -19,7 +19,7 @@
};
struct S {
- virtual int ImplicitlyVirtual();
+ virtual int ImplicitlyVirtual() const;
};
struct T {};
@@ -27,48 +27,42 @@
constexpr int ImplicitlyVirtual() { return 0; }
};
-// FIXME: Can't test this until we have function invocation substitution
-#if 0
-constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // desired-error {{not a constant expression}}
+constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}}
constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // ok
-#endif
+constexpr int c = ImplicitVirtualFromDependentBase<S>().ImplicitVirtualFromDependentBase<S>::ImplicitlyVirtual();
template<typename R> struct ConstexprMember {
constexpr R F() { return 0; }
};
-// FIXME: Can't test this until we have function invocation substitution
-#if 0
-constexpr int c = ConstexprMember<int>().F(); // ok
-constexpr int d = ConstexprMember<NonLiteral>().F(); // desired-error {{not a constant expression}}
-#endif
-
-template<typename ...P> struct ConstexprCtor { // expected-note 2{{no constexpr constructors}}
- constexpr ConstexprCtor(P...); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}} \
- expected-note {{constructor template instantiation is not constexpr because 2nd parameter type 'NonLiteral' is not a literal type}}
-};
-constexpr ConstexprCtor<> f1(); // ok
-constexpr ConstexprCtor<int> f2(); // ok
-constexpr ConstexprCtor<NonLiteral> f3(); // expected-error {{not a literal type}}
-constexpr ConstexprCtor<int, NonLiteral> f4(); // expected-error {{not a literal type}}
+constexpr int d = ConstexprMember<int>().F(); // ok
+constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}}
+
+template<typename ...P> struct ConstexprCtor {
+ constexpr ConstexprCtor(P...) {}
+};
+constexpr ConstexprCtor<> f1() { return {}; } // ok
+constexpr ConstexprCtor<int> f2() { return 0; } // ok
+constexpr ConstexprCtor<NonLiteral> f3() { return { 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}}
+constexpr ConstexprCtor<int, NonLiteral> f4() { return { 0, 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}}
struct VirtBase : virtual S {}; // expected-note {{here}}
namespace TemplateVBase {
template<typename T> struct T1 : virtual Literal { // expected-note {{here}}
- constexpr T1(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
+ constexpr T1() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
};
- template<typename T> struct T2 : virtual T { // expected-note {{struct with virtual base class is not a literal type}} expected-note {{here}}
+ template<typename T> struct T2 : virtual T {
// FIXME: This is ill-formed (no diagnostic required).
// We should diagnose it now rather than waiting until instantiation.
- constexpr T2(); // desired-error {{constexpr constructor not allowed in class with virtual base classes}}
+ constexpr T2() {}
};
- constexpr T2<Literal> g2(); // expected-error {{not a literal type}}
+ constexpr T2<Literal> g2() { return {}; }
template<typename T> class T3 : public T { // expected-note {{class with virtual base class is not a literal type}}
public:
constexpr T3() {}
};
- constexpr T3<Literal> g3(); // ok
- constexpr T3<VirtBase> g4(); // expected-error {{not a literal type}}
+ constexpr T3<Literal> g3() { return {}; } // ok
+ constexpr T3<VirtBase> g4() { return {}; } // expected-error {{not a literal type}}
}
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp Tue Feb 14 03:11:10 2012
@@ -18,15 +18,15 @@
// A variable declaration which uses the constexpr specifier shall have an
// initializer and shall be initialized by a constant expression.
constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}}
-constexpr struct C { C(); } ni2; // expected-error {{constexpr variable 'ni2' must be initialized by a constant expression}} expected-note {{non-literal type 'const struct C' cannot be used in a constant expression}}
+constexpr struct C { C(); } ni2; // expected-error {{cannot have non-literal type 'const struct C'}} expected-note 3{{has no constexpr constructors}}
constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}}
constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
-constexpr C nc2 = C(); // expected-error {{constexpr variable 'nc2' must be initialized by a constant expression}} expected-note {{non-literal type}}
+constexpr C nc2 = C(); // expected-error {{cannot have non-literal type 'const C'}}
int &f(); // expected-note {{declared here}}
constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}}
constexpr int nc4(i); // expected-error {{constexpr variable 'nc4' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}
-constexpr C nc5((C())); // expected-error {{constexpr variable 'nc5' must be initialized by a constant expression}} expected-note {{non-literal type 'const C'}}
+constexpr C nc5((C())); // expected-error {{cannot have non-literal type 'const C'}}
int &f(); // expected-note {{here}}
constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}}
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp Tue Feb 14 03:11:10 2012
@@ -60,7 +60,7 @@
template <const auto (*a)[3] = &ints> class D { }; // expected-error{{'auto' not allowed in template parameter}}
enum E : auto {}; // expected-error{{'auto' not allowed here}}
struct F : auto {}; // expected-error{{expected class name}}
-template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed here}}
+template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed in template argument}}
using A = auto; // expected-error{{'auto' not allowed in type alias}}
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp Tue Feb 14 03:11:10 2012
@@ -19,3 +19,9 @@
static_assert(is_same<decltype(i), int>::value, "");
static_assert(is_same<decltype(a->x), double>::value, "");
static_assert(is_same<decltype((a->x)), const double&>::value, "");
+static_assert(is_same<decltype(static_cast<int&&>(i)), int&&>::value, "");
+
+int f0(int); // expected-note{{possible target}}
+float f0(float); // expected-note{{possible target}}
+
+decltype(f0) f0_a; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
Modified: cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp Tue Feb 14 03:11:10 2012
@@ -15,8 +15,7 @@
using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
- // FIXME: this is illegal; we incorrectly accept it for typedefs too.
- using F = void(*)(int n) &&; // expected-err
+ using F = void(*)(int n) &&; // expected-error {{pointer to function type cannot have '&&' qualifier}}
using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}
using H = void(int n); // ok
Modified: cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp Tue Feb 14 03:11:10 2012
@@ -1,20 +1,45 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-void f0() &; // expected-error{{ref-qualifier '&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
-void f1() &&; // expected-error{{ref-qualifier '&&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+void f0() &; // expected-error {{non-member function cannot have '&' qualifier}}
+void f1() &&; // expected-error {{non-member function cannot have '&&' qualifier}}
+void f2() const volatile &&; // expected-error {{non-member function cannot have 'const volatile &&' qualifier}}
struct X {
- void f0() &;
+ void f0() &;
void f1() &&;
- static void f2() &; // expected-error{{ref-qualifier '&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
- static void f3() &&; // expected-error{{ref-qualifier '&&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+ static void f2() &; // expected-error{{static member function cannot have '&' qualifier}}
+ static void f3() &&; // expected-error{{static member function cannot have '&&' qualifier}}
};
typedef void func_type_lvalue() &;
typedef void func_type_rvalue() &&;
-func_type_lvalue f2; // expected-error{{nonmember function cannot have a ref-qualifier '&'}}
-func_type_rvalue f3; // expected-error{{nonmember function cannot have a ref-qualifier '&&'}}
+typedef func_type_lvalue *func_type_lvalue_ptr; // expected-error{{pointer to function type 'func_type_lvalue' (aka 'void () &') cannot have '&' qualifier}}
+typedef func_type_rvalue *func_type_rvalue_ptr; // expected-error{{pointer to function type 'func_type_rvalue' (aka 'void () &&') cannot have '&&' qualifier}}
+
+typedef func_type_lvalue &func_type_lvalue_ref; // expected-error{{reference to function type 'func_type_lvalue' (aka 'void () &') cannot have '&' qualifier}}
+typedef func_type_rvalue &func_type_rvalue_ref; // expected-error{{reference to function type 'func_type_rvalue' (aka 'void () &&') cannot have '&&' qualifier}}
+
+template<typename T = func_type_lvalue> struct wrap {
+ typedef T val;
+ typedef T *ptr;
+ typedef T &ref;
+};
+
+using func_type_lvalue = wrap<>::val;
+using func_type_lvalue = wrap<func_type_lvalue>::val;
+using func_type_rvalue = wrap<func_type_rvalue>::val;
+
+using func_type_lvalue_ptr = wrap<>::ptr;
+using func_type_lvalue_ptr = wrap<func_type_lvalue>::ptr;
+using func_type_rvalue_ptr = wrap<func_type_rvalue>::ptr;
+
+using func_type_lvalue_ref = wrap<>::ref;
+using func_type_lvalue_ref = wrap<func_type_lvalue>::ref;
+using func_type_rvalue_ref = wrap<func_type_rvalue>::ref;
+
+func_type_lvalue f2; // expected-error{{non-member function of type 'func_type_lvalue' (aka 'void () &') cannot have '&' qualifier}}
+func_type_rvalue f3; // expected-error{{non-member function of type 'func_type_rvalue' (aka 'void () &&') cannot have '&&' qualifier}}
struct Y {
func_type_lvalue f0;
@@ -25,4 +50,4 @@
void (X::*mpf2)() && = &X::f1;
-void (f() &&); // expected-error{{ref-qualifier '&&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+void (f() &&); // expected-error{{non-member function cannot have '&&' qualifier}}
Modified: cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp Tue Feb 14 03:11:10 2012
@@ -1,14 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-void f() const; // expected-error{{type qualifier is not allowed on this function}}
+typedef void F() const;
+
+void f() const; // expected-error {{non-member function cannot have 'const' qualifier}}
+F g; // expected-error {{non-member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}}
struct X {
void f() const;
- friend void g() const; // expected-error{{type qualifier is not allowed on this function}}
- static void h() const; // expected-error{{type qualifier is not allowed on this function}}
+ friend void g() const; // expected-error {{non-member function cannot have 'const' qualifier}}
+ static void h() const; // expected-error {{static member function cannot have 'const' qualifier}}
+ F i; // ok
+ friend F j; // expected-error {{non-member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}}
+ static F k; // expected-error {{static member function of type 'F' (aka 'void () const') cannot have 'const' qualifier}}
};
struct Y {
friend void X::f() const;
- friend void ::f() const; // expected-error{{type qualifier is not allowed on this function}}
+ friend void ::f() const; // expected-error {{non-member function cannot have 'const' qualifier}}
};
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=150465&r1=150464&r2=150465&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 Tue Feb 14 03:11:10 2012
@@ -109,6 +109,23 @@
};
}
+// DR1458: taking the address of an object of incomplete class type
+namespace IncompleteClassTypeAddr {
+ struct S;
+ extern S s;
+ constexpr S *p = &s; // ok
+ static_assert(p, "");
+
+ extern S sArr[];
+ constexpr S (*p2)[] = &sArr; // ok
+
+ struct S {
+ constexpr S *operator&() { return nullptr; }
+ };
+ constexpr S *q = &s; // ok
+ static_assert(!q, "");
+}
+
// - an operation that would have undefined behavior [Note: including, for
// example, signed integer overflow (Clause 5 [expr]), certain pointer
// arithmetic (5.7 [expr.add]), division by zero (5.6 [expr.mul]), or certain
@@ -144,8 +161,11 @@
constexpr int shl_unsigned_overflow = 1024u << 31; // ok
constexpr int shl_signed_negative = (-3) << 1; // expected-error {{constant expression}} expected-note {{left shift of negative value -3}}
constexpr int shl_signed_ok = 1 << 30; // ok
- constexpr int shl_signed_into_sign = 1 << 31; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
- constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{value 2199023255552 is outside the range}} expected-warning {{requires 43 bits to represent}}
+ constexpr int shl_signed_into_sign = 1 << 31; // ok (DR1457)
+ constexpr int shl_signed_into_sign_2 = 0x7fffffff << 1; // ok (DR1457)
+ constexpr int shl_signed_off_end = 2 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{signed shift result (0x100000000) requires 34 bits to represent, but 'int' only has 32 bits}}
+ constexpr int shl_signed_off_end_2 = 0x7fffffff << 2; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{signed shift result (0x1FFFFFFFC) requires 34 bits to represent, but 'int' only has 32 bits}}
+ constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{requires 43 bits to represent}}
constexpr int shl_signed_ok2 = 1024 << 20; // ok
constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}}
@@ -268,7 +288,7 @@
// non-volatile const object with a preceding initialization, initialized
// with a constant expression [Note: a string literal (2.14.5 [lex.string])
// corresponds to an array of such objects. -end note], or
- volatile const int vi = 1; // expected-note {{here}}
+ volatile const int vi = 1; // expected-note 2{{here}}
const int ci = 1;
volatile const int &vrci = ci;
static_assert(vi, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
@@ -278,18 +298,23 @@
// - a non-volatile glvalue of literal type that refers to a non-volatile
// object defined with constexpr, or that refers to a sub-object of such an
// object, or
+ struct V {
+ constexpr V() : v(1) {}
+ volatile int v; // expected-note {{not literal because}}
+ };
+ constexpr V v; // expected-error {{non-literal type}}
struct S {
- constexpr S(int=0) : i(1), v(1) {}
- constexpr S(const S &s) : i(2), v(2) {}
+ constexpr S(int=0) : i(1), v(const_cast<volatile int&>(vi)) {}
+ constexpr S(const S &s) : i(2), v(const_cast<volatile int&>(vi)) {}
int i;
- volatile int v; // expected-note {{here}}
+ volatile int &v;
};
- constexpr S s;
+ constexpr S s; // ok
constexpr volatile S vs; // expected-note {{here}}
- constexpr const volatile S &vrs = s;
+ constexpr const volatile S &vrs = s; // ok
static_assert(s.i, "");
static_assert(s.v, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
- static_assert(const_cast<int&>(s.v), ""); // expected-error {{constant expression}} expected-note {{read of volatile member 'v'}}
+ static_assert(const_cast<int&>(s.v), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vi'}}
static_assert(vs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
static_assert(const_cast<int&>(vs.i), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vs'}}
static_assert(vrs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
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=150465&r1=150464&r2=150465&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 Tue Feb 14 03:11:10 2012
@@ -2,9 +2,7 @@
void block_capture_errors() {
__block int var; // expected-note 2{{'var' declared here}}
- (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} \
- // expected-error{{lambda expressions are not supported yet}}
+ (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
- (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} \
- // expected-error{{lambda expressions are not supported yet}}
+ (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
}
Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p10.cpp Tue Feb 14 03:11:10 2012
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c++11 %s -verify
-int GlobalVar; // expected-note 2{{declared here}}
+int GlobalVar; // expected-note {{declared here}}
namespace N {
int AmbiguousVar; // expected-note {{candidate}}
@@ -16,9 +16,25 @@
virtual X0& Overload(float);
void explicit_capture() {
- [&Overload] () {}; // expected-error {{does not name a variable}} expected-error {{not supported yet}}
- [&GlobalVar] () {}; // expected-error {{does not have automatic storage duration}} expected-error {{not supported yet}}
- [&AmbiguousVar] () {} // expected-error {{reference to 'AmbiguousVar' is ambiguous}} expected-error {{not supported yet}}
- [&Globalvar] () {}; // expected-error {{use of undeclared identifier 'Globalvar'; did you mean 'GlobalVar}}
+ int variable; // expected-note {{declared here}}
+ (void)[&Overload] () {}; // expected-error {{does not name a variable}}
+ (void)[&GlobalVar] () {}; // expected-error {{does not have automatic storage duration}}
+ (void)[&AmbiguousVar] () {}; // expected-error {{reference to 'AmbiguousVar' is ambiguous}}
+ (void)[&Variable] () {}; // expected-error {{use of undeclared identifier 'Variable'; did you mean 'variable'}}
}
};
+
+void test_reaching_scope() {
+ int local; // expected-note{{declared here}}
+ static int local_static; // expected-note{{'local_static' declared here}}
+ (void)[=]() {
+ struct InnerLocal {
+ void member() {
+ (void)[local, // expected-error{{reference to local variable 'local' declared in enclosing function 'test_reaching_scope'}}
+ local_static]() { // expected-error{{'local_static' cannot be captured because it does not have automatic storage duration}}
+ return 0;
+ };
+ }
+ };
+ };
+}
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=150465&r1=150464&r2=150465&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 Tue Feb 14 03:11:10 2012
@@ -1,15 +1,65 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+template<typename T> void capture(const T&);
+
class NonCopyable {
NonCopyable(const NonCopyable&); // expected-note 2 {{implicitly declared private here}}
};
void capture_by_copy(NonCopyable nc, NonCopyable &ncr) {
// FIXME: error messages should talk about capture
- [nc] { }; // expected-error{{field of type 'NonCopyable' has private copy constructor}} \
- // expected-error{{lambda expressions are not supported yet}}
- [ncr] { }; // expected-error{{field of type 'NonCopyable' has private copy constructor}} \
- // expected-error{{lambda expressions are not supported yet}}
+ (void)[nc] { }; // expected-error{{field of type 'NonCopyable' has private copy constructor}}
+ (void)[ncr] { }; // expected-error{{field of type 'NonCopyable' has private copy constructor}}
+}
+
+struct NonTrivial {
+ NonTrivial();
+ NonTrivial(const NonTrivial &);
+ ~NonTrivial();
+};
+
+struct CopyCtorDefault {
+ CopyCtorDefault();
+ CopyCtorDefault(const CopyCtorDefault&, NonTrivial nt = NonTrivial());
+
+ void foo() const;
+};
+
+void capture_with_default_args(CopyCtorDefault cct) {
+ (void)[=] () -> void { cct.foo(); };
+}
+
+struct ExpectedArrayLayout {
+ CopyCtorDefault array[3];
+};
+
+void capture_array() {
+ CopyCtorDefault array[3];
+ auto x = [=]() -> void {
+ capture(array[0]);
+ };
+ static_assert(sizeof(x) == sizeof(ExpectedArrayLayout), "layout mismatch");
}
-// FIXME: arrays!
+// Check for the expected non-static data members.
+
+struct ExpectedLayout {
+ char a;
+ short b;
+};
+
+void test_layout(char a, short b) {
+ auto x = [=] () -> void {
+ capture(a);
+ capture(b);
+ };
+ static_assert(sizeof(x) == sizeof(ExpectedLayout), "Layout mismatch!");
+}
+
+struct ExpectedThisLayout {
+ ExpectedThisLayout* a;
+ void f() {
+ auto x = [this]() -> void {};
+ static_assert(sizeof(x) == sizeof(ExpectedThisLayout), "Layout mismatch!");
+ }
+};
Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p15.cpp Tue Feb 14 03:11:10 2012
@@ -5,6 +5,8 @@
};
void capture_by_ref(NonCopyable nc, NonCopyable &ncr) {
- [&nc] {}; // expected-error{{lambda expressions are not supported yet}}
- [&ncr] {}; // expected-error{{lambda expressions are not supported yet}}
+ int array[3];
+ (void)[&nc] () -> void {};
+ (void)[&ncr] () -> void {};
+ (void)[&array] () -> void {};
}
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=150465&r1=150464&r2=150465&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 Tue Feb 14 03:11:10 2012
@@ -1,7 +1,61 @@
-// RUN: %clang_cc1 -std=c++11 %s -verify
+// RUN: %clang_cc1 -std=c++11 %s -Winvalid-noreturn -verify
+// 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}}
+}
+
+template<typename T>
+struct bogus_override_if_virtual : public T {
+ bogus_override_if_virtual() : T(*(T*)0) { }
+ int operator()() const;
+};
+
+void test_quals() {
+ // 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.
+ auto l = [=](){}; // expected-note{{method is not marked volatile}}
+ const decltype(l) lc = l;
+ l();
+ lc();
+
+ auto ml = [=]() mutable{}; // expected-note{{method is not marked const}} \
+ // expected-note{{method is not marked volatile}}
+ const decltype(ml) mlc = ml;
+ ml();
+ mlc(); // expected-error{{no matching function for call to object of type}}
+
+ // It is neither virtual nor declared volatile.
+ volatile decltype(l) lv = l;
+ volatile decltype(ml) mlv = ml;
+ lv(); // expected-error{{no matching function for call to object of type}}
+ mlv(); // expected-error{{no matching function for call to object of type}}
+
+ bogus_override_if_virtual<decltype(l)> bogus;
+}
+
+// Default arguments (8.3.6) shall not be specified in the
+// parameter-declaration-clause of a lambda- declarator.
int test_default_args() {
- [](int i = 5, // expected-error{{default arguments can only be specified for parameters in a function declaration}} \
- // expected-error{{lambda expressions are not supported yet}}
- int j = 17) {}; // expected-error{{default arguments can only be specified for parameters in a function declaration}}
+ 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}}
+}
+
+// Any exception-specification specified on a lambda-expression
+// applies to the corresponding function call operator.
+void test_exception_spec() {
+ auto tl1 = []() throw(int) {};
+ auto tl2 = []() {};
+ static_assert(!noexcept(tl1()), "lambda can throw");
+ static_assert(!noexcept(tl2()), "lambda can throw");
+
+ auto ntl1 = []() throw() {};
+ auto ntl2 = []() noexcept(true) {};
+ auto ntl3 = []() noexcept {};
+ static_assert(noexcept(ntl1()), "lambda cannot throw");
+ static_assert(noexcept(ntl2()), "lambda cannot throw");
+ static_assert(noexcept(ntl3()), "lambda cannot throw");
}
+
Modified: cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp Tue Feb 14 03:11:10 2012
@@ -4,13 +4,26 @@
void explicit_capture() {
int foo;
- [foo, foo] () {}; // expected-error {{'foo' can appear only once}} expected-error {{not supported yet}}
- [this, this] () {}; // expected-error {{'this' can appear only once}} expected-error {{not supported yet}}
- [=, foo] () {}; // expected-error {{'&' must precede a capture when}} expected-error {{not supported yet}}
- [=, &foo] () {}; // expected-error {{not supported yet}}
- [=, this] () {}; // expected-error {{'this' cannot appear}} expected-error {{not supported yet}}
- [&, foo] () {}; // expected-error {{not supported yet}}
- [&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}} expected-error {{not supported yet}}
- [&, this] () {}; // expected-error {{not supported yet}}
+ (void)[foo, foo] () {}; // expected-error {{'foo' can appear only once}}
+ (void)[this, this] () {}; // expected-error {{'this' can appear only once}}
+ (void)[=, foo] () {}; // expected-error {{'&' must precede a capture when}}
+ (void)[=, &foo] () {};
+ (void)[=, this] () {}; // expected-error {{'this' cannot be explicitly captured}}
+ (void)[&, foo] () {};
+ (void)[&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}}
+ (void)[&, this] () {};
}
};
+
+struct S2 {
+ void f(int i);
+ void g(int i);
+};
+
+void S2::f(int i) {
+ (void)[&, i]{ };
+ (void)[&, &i]{ }; // expected-error{{'&' cannot precede a capture when the capture default is '&'}}
+ (void)[=, this]{ }; // expected-error{{'this' cannot be explicitly captured}}
+ (void)[=]{ this->g(i); };
+ (void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
+}
Modified: cfe/branches/tooling/test/CXX/special/class.ctor/p6-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.ctor/p6-0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.ctor/p6-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.ctor/p6-0x.cpp Tue Feb 14 03:11:10 2012
@@ -11,7 +11,7 @@
struct NonConstexpr2a : NonConstexpr1 { };
constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor
constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor
-constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonConstexpr2a'}}
+constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor
constexpr int nc2_a = NonConstexpr2().nl.a; // ok
constexpr int nc2a_a = NonConstexpr2a().a; // ok
struct Helper {
@@ -21,8 +21,8 @@
struct Constexpr1 {};
constexpr Constexpr1 c1 = Constexpr1(); // ok
-struct NonConstexpr3 : virtual Constexpr1 {};
-constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonConstexpr3'}}
+struct NonConstexpr3 : virtual Constexpr1 {}; // expected-note {{struct with virtual base}} expected-note {{declared here}}
+constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{non-literal type 'const NonConstexpr3'}}
struct Constexpr2 {
int a = 0;
Modified: cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (original)
+++ cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Tue Feb 14 03:11:10 2012
@@ -185,7 +185,7 @@
void test_initializers() {
T copy_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
- T direct_init(0, static_cast<Types>(0)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ T direct_init(0, static_cast<Types>(0)); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
}
Modified: cfe/branches/tooling/test/CodeGen/arm-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/arm-arguments.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/arm-arguments.c (original)
+++ cfe/branches/tooling/test/CodeGen/arm-arguments.c Tue Feb 14 03:11:10 2012
@@ -153,3 +153,15 @@
// AAPCS: define arm_aapcscc void @f30({{.*}} noalias sret
struct s30 { _Complex int f0; };
struct s30 f30() {}
+
+// PR11905
+struct s31 { char x; };
+void f31(struct s31 s) { }
+// AAPCS: @f31([1 x i32] %s.coerce)
+// AAPCS: %s = alloca %struct.s31, align 4
+// AAPCS: alloca [1 x i32]
+// AAPCS: store [1 x i32] %s.coerce, [1 x i32]*
+// APCS-GNU: @f31([1 x i32] %s.coerce)
+// APCS-GNU: %s = alloca %struct.s31, align 4
+// APCS-GNU: alloca [1 x i32]
+// APCS-GNU: store [1 x i32] %s.coerce, [1 x i32]*
Modified: cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c (original)
+++ cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c Tue Feb 14 03:11:10 2012
@@ -14,3 +14,45 @@
// CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 8, i32 11, i32 7, i32 6, i32 12, i32 15>
return _mm256_shuffle_ps(a, b, 203);
}
+
+__m128d test_mm_permute_pd(__m128d a) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 1, i32 0>
+ return _mm_permute_pd(a, 1);
+}
+
+__m256d test_mm256_permute_pd(__m256d a) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 1, i32 0, i32 3, i32 2>
+ return _mm256_permute_pd(a, 5);
+}
+
+__m128 test_mm_permute_ps(__m128 a) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0>
+ return _mm_permute_ps(a, 0x1b);
+}
+
+__m256 test_mm256_permute_ps(__m256 a) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
+ return _mm256_permute_ps(a, 0x1b);
+}
+
+__m256d test_mm256_permute2f128_pd(__m256d a, __m256d b) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 2, i32 3, i32 6, i32 7>
+ return _mm256_permute2f128_pd(a, b, 0x31);
+}
+
+__m256 test_mm256_permute2f128_ps(__m256 a, __m256 b) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 12, i32 13, i32 14, i32 15, i32 4, i32 5, i32 6, i32 7>
+ return _mm256_permute2f128_ps(a, b, 0x13);
+}
+
+__m256i test_mm256_permute2f128_si256(__m256i a, __m256i b) {
+ // Check if the mask is correct
+ // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
+ return _mm256_permute2f128_si256(a, b, 0x20);
+}
Modified: cfe/branches/tooling/test/CodeGen/avx2-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/avx2-builtins.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/avx2-builtins.c (original)
+++ cfe/branches/tooling/test/CodeGen/avx2-builtins.c Tue Feb 14 03:11:10 2012
@@ -677,8 +677,8 @@
}
__m256i test_mm256_permute2x128_si256(__m256i a, __m256i b) {
- // CHECK: @llvm.x86.avx2.vperm2i128
- return _mm256_permute2x128_si256(a, b, 94);
+ // CHECK: shufflevector{{.*}}<i32 2, i32 3, i32 6, i32 7>
+ return _mm256_permute2x128_si256(a, b, 0x31);
}
__m128i test_mm256_extracti128_si256(__m256i a) {
Modified: cfe/branches/tooling/test/CodeGen/builtins-x86.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/builtins-x86.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/builtins-x86.c (original)
+++ cfe/branches/tooling/test/CodeGen/builtins-x86.c Tue Feb 14 03:11:10 2012
@@ -414,13 +414,6 @@
tmp_V4i = __builtin_ia32_cvttpd2dq256(tmp_V4d);
tmp_V4i = __builtin_ia32_cvtpd2dq256(tmp_V4d);
tmp_V8i = __builtin_ia32_cvttps2dq256(tmp_V8f);
- tmp_V4d = __builtin_ia32_vperm2f128_pd256(tmp_V4d, tmp_V4d, 0x7);
- tmp_V8f = __builtin_ia32_vperm2f128_ps256(tmp_V8f, tmp_V8f, 0x7);
- tmp_V8i = __builtin_ia32_vperm2f128_si256(tmp_V8i, tmp_V8i, 0x7);
- tmp_V2d = __builtin_ia32_vpermilpd(tmp_V2d, 0x7);
- tmp_V4f = __builtin_ia32_vpermilps(tmp_V4f, 0x7);
- tmp_V4d = __builtin_ia32_vpermilpd256(tmp_V4d, 0x7);
- tmp_V8f = __builtin_ia32_vpermilps256(tmp_V8f, 0x7);
tmp_V4d = __builtin_ia32_vinsertf128_pd256(tmp_V4d, tmp_V2d, 0x7);
tmp_V8f = __builtin_ia32_vinsertf128_ps256(tmp_V8f, tmp_V4f, 0x7);
tmp_V8i = __builtin_ia32_vinsertf128_si256(tmp_V8i, tmp_V4i, 0x7);
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp Tue Feb 14 03:11:10 2012
@@ -185,9 +185,93 @@
extern constexpr void (B2::*b2m)() = (void(B2::*)())&D::m;
}
+namespace LiteralReference {
+ struct Lit {
+ constexpr Lit() : n(5) {}
+ int n;
+ };
+ // FIXME: This should have static initialization, but we do not implement
+ // that yet. For now, just check that we don't set the (pointer) value of
+ // the reference to 5!
+ //
+ // CHECK: @_ZN16LiteralReference3litE = global {{.*}} null
+ const Lit &lit = Lit();
+}
+
+namespace NonLiteralConstexpr {
+ constexpr int factorial(int n) {
+ return n ? factorial(n-1) * n : 1;
+ }
+ extern void f(int *p);
+
+ struct NonTrivialDtor {
+ constexpr NonTrivialDtor() : n(factorial(5)), p(&n) {}
+ ~NonTrivialDtor() {
+ f(p);
+ }
+
+ int n;
+ int *p;
+ };
+ static_assert(!__is_literal(NonTrivialDtor), "");
+ // CHECK: @_ZN19NonLiteralConstexpr3ntdE = global {{.*}} { i32 120, i32* getelementptr
+ NonTrivialDtor ntd;
+
+ struct VolatileMember {
+ constexpr VolatileMember() : n(5) {}
+ volatile int n;
+ };
+ static_assert(!__is_literal(VolatileMember), "");
+ // CHECK: @_ZN19NonLiteralConstexpr2vmE = global {{.*}} { i32 5 }
+ VolatileMember vm;
+
+ struct Both {
+ constexpr Both() : n(10) {}
+ ~Both();
+ volatile int n;
+ };
+ // CHECK: @_ZN19NonLiteralConstexpr1bE = global {{.*}} { i32 10 }
+ Both b;
+
+ void StaticVars() {
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE3ntd = {{.*}} { i32 120, i32* getelementptr {{.*}}
+ // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE3ntd =
+ static NonTrivialDtor ntd;
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE2vm = {{.*}} { i32 5 }
+ // CHECK-NOT: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE2vm =
+ static VolatileMember vm;
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE1b = {{.*}} { i32 10 }
+ // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE1b =
+ static Both b;
+ }
+}
+
// Constant initialization tests go before this point,
// dynamic initialization tests go after.
+// We must emit a constant initializer for NonLiteralConstexpr::ntd, but also
+// emit an initializer to register its destructor.
+// CHECK: define {{.*}}cxx_global_var_init{{.*}}
+// CHECK-NOT: NonLiteralConstexpr
+// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev {{.*}} @_ZN19NonLiteralConstexpr3ntdE
+// CHECK-NEXT: ret void
+
+// We don't need to emit any dynamic initialization for NonLiteralConstexpr::vm.
+// CHECK-NOT: NonLiteralConstexpr2vm
+
+// We must emit a constant initializer for NonLiteralConstexpr::b, but also
+// emit an initializer to register its destructor.
+// CHECK: define {{.*}}cxx_global_var_init{{.*}}
+// CHECK-NOT: NonLiteralConstexpr
+// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr4BothD1Ev {{.*}} @_ZN19NonLiteralConstexpr1bE
+// CHECK-NEXT: ret void
+
+// CHECK: define {{.*}}NonLiteralConstexpr10StaticVars
+// CHECK-NOT: }
+// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev
+// CHECK-NOT: }
+// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr4BothD1Ev
+
namespace CrossFuncLabelDiff {
// Make sure we refuse to constant-fold the variable b.
constexpr long a(bool x) { return x ? 0 : (long)&&lbl + (0 && ({lbl: 0;})); }
Modified: cfe/branches/tooling/test/CodeGenCXX/debug-info-limit-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/debug-info-limit-type.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/debug-info-limit-type.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/debug-info-limit-type.cpp Tue Feb 14 03:11:10 2012
@@ -1,4 +1,5 @@
// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
+// XFAIL: *
class B {
public:
@@ -19,5 +20,5 @@
A a;
}
-// B should only be emitted as a forward reference.
-// CHECK: metadata !"B", metadata !6, i32 3, i64 0, i64 0, i32 0, i32 4, null, null, i32 0, null, null} ; [ DW_TAG_class_type
+// B should only be emitted as a forward reference (i32 4).
+// CHECK: metadata !"B", metadata !6, i32 3, i32 0, i32 0, i32 0, i32 4} ; [ DW_TAG_class_type ]
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp Tue Feb 14 03:11:10 2012
@@ -46,3 +46,15 @@
friend enum class E; // expected-error {{must use 'enum' not 'enum class'}}
};
}
+
+struct S2 {
+ void f(int i);
+ void g(int i);
+};
+
+void S2::f(int i) {
+ (void)[&, &i, &i]{}; // expected-error 2{{'&' cannot precede a capture when the capture default is '&'}}
+ (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}}
+}
Modified: cfe/branches/tooling/test/FixIt/fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/FixIt/fixit.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/FixIt/fixit.cpp (original)
+++ cfe/branches/tooling/test/FixIt/fixit.cpp Tue Feb 14 03:11:10 2012
@@ -162,9 +162,9 @@
aPtr = br; // expected-error {{assigning to 'AD *' from incompatible type 'BD'; take the address with &}}
}
-void foo1() const {} // expected-error {{type qualifier is not allowed on this function}}
-void foo2() volatile {} // expected-error {{type qualifier is not allowed on this function}}
-void foo3() const volatile {} // expected-error {{type qualifier is not allowed on this function}}
+void foo1() const {} // expected-error {{non-member function cannot have 'const' qualifier}}
+void foo2() volatile {} // expected-error {{non-member function cannot have 'volatile' qualifier}}
+void foo3() const volatile {} // expected-error {{non-member function cannot have 'const volatile' qualifier}}
struct S { void f(int, char); };
int itsAComma,
Modified: cfe/branches/tooling/test/Index/annotate-tokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/annotate-tokens.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/annotate-tokens.cpp (original)
+++ cfe/branches/tooling/test/Index/annotate-tokens.cpp Tue Feb 14 03:11:10 2012
@@ -34,7 +34,7 @@
// CHECK: Punctuation: ")" [2:17 - 2:18] FunctionDecl=test:2:6 (Definition)
// CHECK: Punctuation: "{" [2:19 - 2:20] CompoundStmt=
// CHECK: Identifier: "X" [3:5 - 3:6] DeclRefExpr=X:2:16
-// CHECK: Punctuation: "=" [3:7 - 3:8] CallExpr=operator=:1:8
+// CHECK: Punctuation: "=" [3:7 - 3:8] DeclRefExpr=operator=:1:8
// CHECK: Identifier: "X" [3:9 - 3:10] DeclRefExpr=X:2:16
// CHECK: Punctuation: ";" [3:10 - 3:11] CompoundStmt=
// CHECK: Keyword: "__is_base_of" [4:5 - 4:17] UnexposedExpr=
@@ -78,7 +78,7 @@
// CHECK: Punctuation: "(" [13:3 - 13:4] ParenExpr=
// CHECK: Identifier: "x" [13:4 - 13:5] DeclRefExpr=x:11:14
// CHECK: Punctuation: ")" [13:5 - 13:6] ParenExpr=
-// CHECK: Punctuation: "++" [13:6 - 13:8] CallExpr=operator++:9:5
+// CHECK: Punctuation: "++" [13:6 - 13:8] DeclRefExpr=operator++:9:5
// CHECK: Punctuation: ";" [13:8 - 13:9] CompoundStmt=
// CHECK: Punctuation: "}" [14:1 - 14:2] CompoundStmt=
// CHECK: Keyword: "struct" [16:1 - 16:7] StructDecl=S1:16:8 (Definition)
@@ -111,7 +111,7 @@
// CHECK: Punctuation: ")" [18:17 - 18:18] FunctionDecl=test3:18:6 (Definition)
// CHECK: Punctuation: "{" [18:19 - 18:20] CompoundStmt=
// CHECK: Identifier: "s2" [19:3 - 19:5] DeclRefExpr=s2:18:15
-// CHECK: Punctuation: "->" [19:5 - 19:7] MemberRefExpr=f:16:18
+// CHECK: Punctuation: "->" [19:5 - 19:7] DeclRefExpr=operator->:17:17
// CHECK: Identifier: "f" [19:7 - 19:8] MemberRefExpr=f:16:18
// CHECK: Punctuation: "(" [19:8 - 19:9] CallExpr=f:16:18
// CHECK: Punctuation: ")" [19:9 - 19:10] CallExpr=f:16:18
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/index-refs.cpp (original)
+++ cfe/branches/tooling/test/Index/index-refs.cpp Tue Feb 14 03:11:10 2012
@@ -18,6 +18,43 @@
SecondVal = EnumVal
};
+struct S {
+ S& operator++();
+ int operator*();
+ S& operator=(int x);
+ S& operator!=(int x);
+ S& operator()(int x);
+};
+
+void foo2(S &s) {
+ (void)++s;
+ (void)*s;
+ s = 3;
+ (void)(s != 3);
+ s(3);
+}
+
+namespace NS {
+ namespace Inn {}
+ typedef int Foo;
+}
+
+using namespace NS;
+using namespace NS::Inn;
+using NS::Foo;
+
+template <typename T1, typename T2>
+struct TS { };
+
+template <typename T>
+struct TS<T, int> {
+ typedef int MyInt;
+};
+
+void foo3() {
+ TS<int, int> s;
+}
+
// RUN: c-index-test -index-file %s | FileCheck %s
// CHECK: [indexDeclaration]: kind: namespace | name: NS
// CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx
@@ -35,3 +72,24 @@
// CHECK-NEXT: [indexDeclaration]: kind: enum
// CHECK-NEXT: [indexDeclaration]: kind: enumerator | name: SecondVal
// CHECK-NEXT: [indexEntityReference]: kind: enumerator | name: EnumVal
+
+// CHECK: [indexDeclaration]: kind: function | name: foo2
+// CHECK: [indexEntityReference]: kind: c++-instance-method | name: operator++
+// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator*
+// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator=
+// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator!=
+// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator()
+
+// CHECK: [indexEntityReference]: kind: namespace | name: NS | {{.*}} | loc: 42:17
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS | {{.*}} | loc: 43:17
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: Inn | {{.*}} | loc: 43:21
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS | {{.*}} | loc: 44:7
+// CHECK-NEXT: [indexEntityReference]: kind: typedef | name: Foo | {{.*}} | loc: 44:11
+
+// 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]
+// 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
Modified: cfe/branches/tooling/test/Index/recursive-cxx-member-calls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/recursive-cxx-member-calls.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/recursive-cxx-member-calls.cpp (original)
+++ cfe/branches/tooling/test/Index/recursive-cxx-member-calls.cpp Tue Feb 14 03:11:10 2012
@@ -933,7 +933,7 @@
// CHECK-tokens: Punctuation: ")" [102:58 - 102:59] CallExpr=endswith:56:8
// CHECK-tokens: Punctuation: ")" [102:59 - 102:60] IfStmt=
// CHECK-tokens: Identifier: "AttrName" [103:5 - 103:13] DeclRefExpr=AttrName:101:19
-// CHECK-tokens: Punctuation: "=" [103:14 - 103:15] CallExpr=operator=:38:7
+// CHECK-tokens: Punctuation: "=" [103:14 - 103:15] DeclRefExpr=operator=:38:7
// CHECK-tokens: Identifier: "AttrName" [103:16 - 103:24] DeclRefExpr=AttrName:101:19
// CHECK-tokens: Punctuation: "." [103:24 - 103:25] MemberRefExpr=substr:60:13
// CHECK-tokens: Identifier: "substr" [103:25 - 103:31] MemberRefExpr=substr:60:13
Modified: cfe/branches/tooling/test/Lexer/char-literal-encoding-error.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Lexer/char-literal-encoding-error.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Lexer/char-literal-encoding-error.c (original)
+++ cfe/branches/tooling/test/Lexer/char-literal-encoding-error.c Tue Feb 14 03:11:10 2012
@@ -3,8 +3,13 @@
// This file is encoded using ISO-8859-1
int main() {
- 'é'; // expected-error {{illegal character encoding in character literal}}
- u'é'; // expected-error {{illegal character encoding in character literal}}
- U'é'; // expected-error {{illegal character encoding in character literal}}
- L'é'; // expected-error {{illegal character encoding in character literal}}
+ (void)'é'; // expected-warning {{illegal character encoding in character literal}}
+ (void)u'é'; // expected-error {{illegal character encoding in character literal}}
+ (void)U'é'; // expected-error {{illegal character encoding in character literal}}
+ (void)L'é'; // expected-error {{illegal character encoding in character literal}}
+
+ // For narrow character literals, since there is no error, make sure the
+ // encoding is correct
+ static_assert((unsigned char)'é' == 0xE9, ""); // expected-warning {{illegal character encoding in character literal}}
+ static_assert('éé' == 0xE9E9, ""); // expected-warning {{illegal character encoding in character literal}} expected-warning {{multi-character character constant}}
}
Modified: cfe/branches/tooling/test/Lexer/hexfloat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Lexer/hexfloat.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Lexer/hexfloat.cpp (original)
+++ cfe/branches/tooling/test/Lexer/hexfloat.cpp Tue Feb 14 03:11:10 2012
@@ -1,4 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
float f = 0x1p+1; // expected-warning{{hexadecimal floating constants are a C99 feature}}
-
+double e = 0x.p0; //expected-error{{hexadecimal floating constants require a significand}}
+double d = 0x.2p2; // expected-warning{{hexadecimal floating constants are a C99 feature}}
+float g = 0x1.2p2; // expected-warning{{hexadecimal floating constants are a C99 feature}}
+double h = 0x1.p2; // expected-warning{{hexadecimal floating constants are a C99 feature}}
Modified: cfe/branches/tooling/test/Lexer/string-literal-encoding.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Lexer/string-literal-encoding.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Lexer/string-literal-encoding.c (original)
+++ cfe/branches/tooling/test/Lexer/string-literal-encoding.c Tue Feb 14 03:11:10 2012
@@ -12,4 +12,7 @@
wchar_t const *d = LR"(Àéîõü)"; // expected-error {{illegal character encoding in string literal}}
char16_t const *e = uR"(Àéîõü)"; // expected-error {{illegal character encoding in string literal}}
char32_t const *f = UR"(Àéîõü)"; // expected-error {{illegal character encoding in string literal}}
+
+ char const *g = "Àéîõü"; // expected-warning {{illegal character encoding in string literal}}
+ char const *h = u8"Àéîõü"; // expected-error {{illegal character encoding in string literal}}
}
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Misc/warning-flags.c (original)
+++ cfe/branches/tooling/test/Misc/warning-flags.c Tue Feb 14 03:11:10 2012
@@ -17,8 +17,7 @@
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (266):
-CHECK-NEXT: ext_anon_param_requires_type_specifier
+CHECK: Warnings without flags (258):
CHECK-NEXT: ext_anonymous_struct_union_qualified
CHECK-NEXT: ext_array_init_copy
CHECK-NEXT: ext_binary_literal
@@ -145,16 +144,13 @@
CHECK-NEXT: warn_double_const_requires_fp64
CHECK-NEXT: warn_drv_assuming_mfloat_abi_is
CHECK-NEXT: warn_drv_clang_unsupported
-CHECK-NEXT: warn_drv_conflicting_deployment_targets
CHECK-NEXT: warn_drv_input_file_unused
CHECK-NEXT: warn_drv_not_using_clang_arch
CHECK-NEXT: warn_drv_not_using_clang_cpp
CHECK-NEXT: warn_drv_not_using_clang_cxx
CHECK-NEXT: warn_drv_objc_gc_unsupported
CHECK-NEXT: warn_drv_pch_not_first_include
-CHECK-NEXT: warn_drv_pipe_ignored_with_save_temps
CHECK-NEXT: warn_drv_preprocessed_input_file_unused
-CHECK-NEXT: warn_drv_unsupported_option_argument
CHECK-NEXT: warn_dup_category_def
CHECK-NEXT: warn_duplicate_protocol_def
CHECK-NEXT: warn_enum_too_large
@@ -185,7 +181,6 @@
CHECK-NEXT: warn_integer_too_large
CHECK-NEXT: warn_integer_too_large_for_signed
CHECK-NEXT: warn_invalid_asm_cast_lvalue
-CHECK-NEXT: warn_label_attribute_not_unused
CHECK-NEXT: warn_many_braces_around_scalar_init
CHECK-NEXT: warn_maynot_respond
CHECK-NEXT: warn_member_extra_qualification
@@ -231,7 +226,6 @@
CHECK-NEXT: warn_pragma_options_expected_align
CHECK-NEXT: warn_pragma_pack_invalid_action
CHECK-NEXT: warn_pragma_pack_invalid_alignment
-CHECK-NEXT: warn_pragma_pack_invalid_constant
CHECK-NEXT: warn_pragma_pack_malformed
CHECK-NEXT: warn_pragma_pack_pop_failed
CHECK-NEXT: warn_pragma_pack_pop_identifer_and_alignment
@@ -269,14 +263,12 @@
CHECK-NEXT: warn_transparent_union_attribute_floating
CHECK-NEXT: warn_transparent_union_attribute_not_definition
CHECK-NEXT: warn_transparent_union_attribute_zero_fields
-CHECK-NEXT: warn_transparent_union_nonpointer
CHECK-NEXT: warn_typecheck_function_qualifiers
CHECK-NEXT: warn_unavailable_fwdclass_message
CHECK-NEXT: warn_undef_interface
CHECK-NEXT: warn_undef_interface_suggest
CHECK-NEXT: warn_undef_protocolref
CHECK-NEXT: warn_undefined_internal
-CHECK-NEXT: warn_uninit_val
CHECK-NEXT: warn_unknown_analyzer_checker
CHECK-NEXT: warn_unknown_method_family
CHECK-NEXT: warn_unterminated_char
Modified: cfe/branches/tooling/test/Parser/cxx-default-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/cxx-default-delete.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/cxx-default-delete.cpp (original)
+++ cfe/branches/tooling/test/Parser/cxx-default-delete.cpp Tue Feb 14 03:11:10 2012
@@ -3,8 +3,12 @@
int i = delete; // expected-error{{only functions}}
int j = default; // expected-error{{special member functions}}
-int f() = delete, g; // expected-error{{standalone}}
-int o, p() = delete; // expected-error{{standalone}}
+int f() = delete, g; // expected-error{{'= delete' is a function definition}}
+int o, p() = delete; // expected-error{{'= delete' is a function definition}}
+
+int q() = default, r; // expected-error{{only special member functions}} \
+ // expected-error{{'= default' is a function definition}}
+int s, t() = default; // expected-error{{'= default' is a function definition}}
struct foo {
foo() = default;
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp (original)
+++ cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 %s
class C {
@@ -12,13 +12,13 @@
[&this] {}; // expected-error {{'this' cannot be captured by reference}}
[&,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[=,] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
- [] {}; // expected-error {{lambda expressions are not supported yet}}
- [=] (int i) {}; // expected-error {{lambda expressions are not supported yet}}
- [&] (int) mutable -> void {}; // expected-error {{lambda expressions are not supported yet}}
- [foo,bar] () { return 3; }; // expected-error {{lambda expressions are not supported yet}}
- [=,&foo] () {}; // expected-error {{lambda expressions are not supported yet}}
- [&,foo] () {}; // expected-error {{lambda expressions are not supported yet}}
- [this] () {}; // expected-error {{lambda expressions are not supported yet}}
+ [] {};
+ [=] (int i) {};
+ [&] (int) mutable -> void {};
+ [foo,bar] () { return 3; };
+ [=,&foo] () {};
+ [&,foo] () {};
+ [this] () {};
return 1;
}
Modified: cfe/branches/tooling/test/Parser/objcxx-lambda-expressions-neg.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/objcxx-lambda-expressions-neg.mm?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/objcxx-lambda-expressions-neg.mm (original)
+++ cfe/branches/tooling/test/Parser/objcxx-lambda-expressions-neg.mm Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify %s
int main() {
[]{}; // expected-error {{expected expression}}
Modified: cfe/branches/tooling/test/Parser/objcxx0x-lambda-expressions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/objcxx0x-lambda-expressions.mm?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/objcxx0x-lambda-expressions.mm (original)
+++ cfe/branches/tooling/test/Parser/objcxx0x-lambda-expressions.mm Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++11 %s
class C {
@@ -11,12 +11,12 @@
[]; // expected-error {{expected body of lambda expression}}
[=,foo+] {}; // expected-error {{expected ',' or ']' in lambda capture list}}
[&this] {}; // expected-error {{address expression must be an lvalue}}
- [] {}; // expected-error {{lambda expressions are not supported yet}}
- [=] (int i) {}; // expected-error {{lambda expressions are not supported yet}}
- [&] (int) mutable -> void {}; // expected-error {{lambda expressions are not supported yet}}
- [foo,bar] () { return 3; }; // expected-error {{lambda expressions are not supported yet}}
- [=,&foo] () {}; // expected-error {{lambda expressions are not supported yet}}
- [this] () {}; // expected-error {{lambda expressions are not supported yet}}
+ [] {};
+ [=] (int i) {};
+ [&] (int) mutable -> void {};
+ [foo,bar] () { return 3; };
+ [=,&foo] () {};
+ [this] () {};
}
};
Modified: cfe/branches/tooling/test/Sema/atomic-type.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/atomic-type.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/atomic-type.c (original)
+++ cfe/branches/tooling/test/Sema/atomic-type.c Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
extern _Atomic(int (*)(int(*)[10], int(*)[10])) mergetest;
_Atomic(int()) error1; // expected-error {{_Atomic cannot be applied to function type}}
-_Atomic(struct ErrorS) error2; // expected-error {{_Atomic cannot be applied to incomplete type}}
+_Atomic(struct ErrorS) error2; // expected-error {{_Atomic cannot be applied to incomplete type}} expected-note {{forward declaration}}
_Atomic(int[10]) error3; // expected-error {{_Atomic cannot be applied to array type}}
_Atomic(const int) error4; // expected-error {{_Atomic cannot be applied to qualified type}}
_Atomic(_Atomic(int)) error5; // expected-error {{_Atomic cannot be applied to atomic type}}
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/format-strings.c (original)
+++ cfe/branches/tooling/test/Sema/format-strings.c Tue Feb 14 03:11:10 2012
@@ -471,6 +471,8 @@
const char kFormat17[] = "%hu"; // expected-note{{format string is defined here}}}
printf(kFormat17, (int[]){0}); // expected-warning{{format specifies type 'unsigned short' but the argument}}
+
+ printf("%a", (long double)0); // expected-warning{{format specifies type 'double' but the argument has type 'long double'}}
}
// PR 9466: clang: doesn't know about %Lu, %Ld, and %Lx
@@ -491,6 +493,7 @@
void test_other_formats() {
char *str = "";
monformat("", 1); // expected-warning{{format string is empty}}
+ monformat(str); // expected-warning{{format string is not a string literal (potentially insecure)}}
dateformat(""); // expected-warning{{format string is empty}}
- dateformat(str); // expected-warning{{format string is not a string literal (potentially insecure)}}
+ dateformat(str); // no-warning (using strftime non literal is not unsafe)
}
Modified: cfe/branches/tooling/test/Sema/init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/init.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/init.c (original)
+++ cfe/branches/tooling/test/Sema/init.c Tue Feb 14 03:11:10 2012
@@ -18,10 +18,19 @@
void *g = &x;
int *h = &x;
+struct union_crash
+{
+ union
+ {
+ };
+};
+
int test() {
-int a[10];
-int b[10] = a; // expected-error {{array initializer must be an initializer list}}
-int +; // expected-error {{expected identifier or '('}}
+ int a[10];
+ int b[10] = a; // expected-error {{array initializer must be an initializer list}}
+ int +; // expected-error {{expected identifier or '('}}
+
+ struct union_crash u = { .d = 1 }; // expected-error {{field designator 'd' does not refer to any field in type 'struct union_crash'}}
}
Removed: cfe/branches/tooling/test/Sema/paren-list-expr-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/paren-list-expr-type.cpp?rev=150464&view=auto
==============================================================================
--- cfe/branches/tooling/test/Sema/paren-list-expr-type.cpp (original)
+++ cfe/branches/tooling/test/Sema/paren-list-expr-type.cpp (removed)
@@ -1,17 +0,0 @@
-// RUN: %clang -cc1 -ast-dump %s | not grep NULL
-// Makes sure that we don't introduce null types when handling
-// ParenListExpr.
-
-template<typename T> class X { void f() { X x(*this); } };
-
-template<typename T> class Y { Y() : t(1) {} T t; };
-
-template<typename T> class Z { Z() : b(true) {} const bool b; };
-
-template<typename T> class A : public Z<T> { A() : Z<T>() {} };
-
-class C {};
-template<typename T> class D : public C { D(): C() {} };
-
-void f() { (int)(1, 2); }
-
Modified: cfe/branches/tooling/test/Sema/switch.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/switch.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/switch.c (original)
+++ cfe/branches/tooling/test/Sema/switch.c Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-enum %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-enum -Wcovered-switch-default %s
void f (int z) {
while (z) {
default: z--; // expected-error {{statement not in switch}}
Modified: cfe/branches/tooling/test/SemaCXX/alias-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/alias-template.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/alias-template.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/alias-template.cpp Tue Feb 14 03:11:10 2012
@@ -12,8 +12,7 @@
template<typename U> using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
template<typename U> using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
template<typename U> using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
- // FIXME: this is illegal; we incorrectly accept it for typedefs too.
- template<typename U> using F = void(*)(int n) &&; // expected-err
+ template<typename U> using F = void(*)(int n) &&; // expected-error {{pointer to function type cannot have '&&' qualifier}}
template<typename U> using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}
template<typename U> using H = void(int n); // ok
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp Tue Feb 14 03:11:10 2012
@@ -299,6 +299,7 @@
constexpr S* sptr = &s;
constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr); // expected-error {{constant expression}} expected-note {{dynamic_cast}}
+struct U {};
struct Str {
int a : dynamic_cast<S*>(sptr) == dynamic_cast<S*>(sptr); // \
expected-warning {{not an integral constant expression}} \
@@ -315,7 +316,7 @@
int e : (Str*)(sptr) == (Str*)(sptr); // \
expected-warning {{not an integral constant expression}} \
expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
- int f : &(Str&)(*sptr) == &(Str&)(*sptr); // \
+ int f : &(U&)(*sptr) == &(U&)(*sptr); // \
expected-warning {{not an integral constant expression}} \
expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
int g : (S*)(void*)(sptr) == sptr; // \
@@ -1120,6 +1121,30 @@
static_assert(s2.f == 7, "");
}
+// DR1405: don't allow reading mutable members in constant expressions.
+namespace MutableMembers {
+ struct MM {
+ mutable int n; // expected-note 3{{declared here}}
+ } constexpr mm = { 4 };
+ constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
+ int x = (mm.n = 1, 3);
+ constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
+
+ // Here's one reason why allowing this would be a disaster...
+ template<int n> struct Id { int k = n; };
+ int f() {
+ constexpr MM m = { 0 };
+ ++m.n;
+ return Id<m.n>().k; // expected-error {{not a constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
+ }
+
+ struct A { int n; };
+ struct B { mutable A a; }; // expected-note {{here}}
+ struct C { B b; };
+ constexpr C c[3] = {};
+ constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}}
+}
+
namespace Fold {
// This macro forces its argument to be constant-folded, even if it's not
Modified: cfe/branches/tooling/test/SemaCXX/constexpr-nqueens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/constexpr-nqueens.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constexpr-nqueens.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constexpr-nqueens.cpp Tue Feb 14 03:11:10 2012
@@ -62,7 +62,7 @@
*p == 0 ? true :
false;
}
-constexpr bool check = q8.check(
+static_assert(q8.check(
"o-------\n"
"------o-\n"
"----o---\n"
@@ -70,7 +70,4 @@
"-o------\n"
"---o----\n"
"-----o--\n"
- "--o-----\n");
-
-typedef int check_it[1];
-typedef int check_it[check];
+ "--o-----\n"), "");
Removed: cfe/branches/tooling/test/SemaCXX/constexpr-sysheaders.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/constexpr-sysheaders.cpp?rev=150464&view=auto
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constexpr-sysheaders.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constexpr-sysheaders.cpp (removed)
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -include %s %s
-
-// libstdc++4.6 has a broken numeric_limits with a non-constant min() for signed
-// integral types. Disable the 'never produces a constant expression' error in
-// system headers to work around it. We still won't treat the function as
-// producing a constant expression, though.
-
-#ifndef INCLUDED_HEADER
-#define INCLUDED_HEADER
-
-#pragma GCC system_header
-
-// An approximation of libstdc++4.6's broken definition of numeric_limits.
-// FIXME: In the -include case, the line numbers are off by one for some reason!
-struct numeric_limits { // expected-note {{value 2147483648 is outside the range}}
- static constexpr int min() throw() { return (int)1 << (sizeof(int) * 8 - 1); } // no-error
- // expected-note {{in call to 'min()'}}
- static constexpr int lowest() throw() { return min(); }
-};
-
-#else
-
-constexpr int k = numeric_limits::lowest(); // expected-error {{constant expression}} expected-note {{in call to 'lowest()'}}
-
-#endif
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constexpr-value-init.cpp Tue Feb 14 03:11:10 2012
@@ -26,6 +26,6 @@
constexpr C c1; // expected-error {{requires a user-provided default constructor}}
constexpr C c2 = C(); // ok
constexpr D d1; // expected-error {{requires a user-provided default constructor}}
-constexpr D d2 = D(); // expected-error {{constant expression}} expected-note {{non-literal type 'const D'}}
+constexpr D d2 = D(); // ok with DR1452
static_assert(D().c == 0, "");
static_assert(D().d == 0, "");
Modified: cfe/branches/tooling/test/SemaCXX/copy-initialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/copy-initialization.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/copy-initialization.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/copy-initialization.cpp Tue Feb 14 03:11:10 2012
@@ -42,3 +42,26 @@
f(foo);
}
}
+
+namespace DR5 {
+ // Core issue 5: if a temporary is created in copy-initialization, it is of
+ // the cv-unqualified version of the destination type.
+ namespace Ex1 {
+ struct C { };
+ C c;
+ struct A {
+ A(const A&);
+ A(const C&);
+ };
+ const volatile A a = c; // ok
+ }
+
+ namespace Ex2 {
+ struct S {
+ S(S&&); // expected-warning {{C++11}}
+ S(int);
+ };
+ const S a(0);
+ const S b = 0;
+ }
+}
Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-defaulted-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-defaulted-functions.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-defaulted-functions.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-defaulted-functions.cpp Tue Feb 14 03:11:10 2012
@@ -28,7 +28,7 @@
bar& bar::operator = (bar&) = default;
bar::~bar() = default;
-// FIXME: static_assert(__is_trivial(foo), "foo should be trivial");
+static_assert(__is_trivial(foo), "foo should be trivial");
static_assert(!__has_trivial_destructor(bar), "bar's destructor isn't trivial");
static_assert(!__has_trivial_constructor(bar),
@@ -43,3 +43,11 @@
b = c;
}
+template<typename T> struct S : T {
+ constexpr S() = default;
+ constexpr S(const S&) = default;
+ constexpr S(S&&) = default;
+};
+struct lit { constexpr lit() {} };
+S<lit> s_lit; // ok
+S<bar> s_bar; // ok
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-aggregates.cpp Tue Feb 14 03:11:10 2012
@@ -27,6 +27,20 @@
S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
}
+ void bracing_new() {
+ new S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
+ new S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
+ new S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
+ new S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
+ }
+
+ void bracing_construct() {
+ (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
+ (void) S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
+ (void) S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
+ (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
+ }
+
struct String {
String(const char*);
};
@@ -56,4 +70,6 @@
// String is not default-constructible
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}}
}
Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp Tue Feb 14 03:11:10 2012
@@ -3,6 +3,38 @@
struct one { char c[1]; };
struct two { char c[2]; };
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ // libc++'s implementation
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+
+ initializer_list(const _E* __b, size_t __s)
+ : __begin_(__b),
+ __size_(__s)
+ {}
+
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ initializer_list() : __begin_(nullptr), __size_(0) {}
+
+ size_t size() const {return __size_;}
+ const _E* begin() const {return __begin_;}
+ const _E* end() const {return __begin_ + __size_;}
+ };
+}
+
namespace objects {
struct X1 { X1(int); };
@@ -15,6 +47,19 @@
};
template <int N>
+ struct F {
+ F() { static_assert(N == 0, ""); }
+ F(int, double) { static_assert(N == 1, ""); }
+ F(std::initializer_list<int>) { static_assert(N == 3, ""); }
+ };
+
+ template <int N>
+ struct D {
+ D(std::initializer_list<int>) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}}
+ D(std::initializer_list<double>) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}}
+ };
+
+ template <int N>
struct E {
E(int, int) { static_assert(N == 0, ""); }
E(X1, int) { static_assert(N == 1, ""); }
@@ -26,6 +71,22 @@
{ A<1> a{1, 1.0}; }
{ A<1> a = {1, 1.0}; }
+ { F<0> f{}; }
+ { F<0> f = {}; }
+ // Narrowing conversions don't affect viability. The next two choose
+ // the initializer_list constructor.
+ // FIXME: Emit narrowing conversion errors.
+ { F<3> f{1, 1.0}; } // xpected-error {{narrowing conversion}}
+ { F<3> f = {1, 1.0}; } // xpected-error {{narrowing conversion}}
+ { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
+ { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; }
+ { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
+ { F<3> f{1, 2}; }
+
+ { D<0> d{1, 2, 3}; }
+ { D<1> d{1.0, 2.0, 3.0}; }
+ { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}}
+
{ E<0> e{1, 2}; }
}
@@ -57,6 +118,8 @@
void inline_init() {
(void) C{1, 1.0};
(void) new C{1, 1.0};
+ (void) A<1>{1, 1.0};
+ (void) new A<1>{1, 1.0};
}
struct B { // expected-note 2 {{candidate constructor}}
@@ -77,5 +140,50 @@
static_assert(sizeof(ov1({{1, 1.0}, 2, {3, 4}})) == sizeof(one), "bad overload");
ov1({1}); // expected-error {{no matching function}}
+
+ one ov2(int);
+ two ov2(F<3>);
+ static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity
+ static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable
+ }
+
+ struct G { // expected-note 6 {{not viable}}
+ // This is not an initializer-list constructor.
+ template<typename ...T>
+ G(std::initializer_list<int>, T ...); // expected-note 3 {{not viable}}
+ };
+
+ struct H { // expected-note 6 {{not viable}}
+ explicit H(int, int); // expected-note 3 {{not viable}}
+ H(int, void*); // expected-note 3 {{not viable}}
+ };
+
+ void edge_cases() {
+ // invalid (the first phase only considers init-list ctors)
+ // (for the second phase, no constructor is viable)
+ G g1{1, 2, 3}; // expected-error {{no matching constructor}}
+ (void) new G{1, 2, 3}; // expected-error {{no matching constructor}}
+ (void) G{1, 2, 3} // expected-error {{no matching constructor}}
+
+ // valid (T deduced to <>).
+ G g2({1, 2, 3});
+ (void) new G({1, 2, 3});
+ (void) G({1, 2, 3});
+
+ // invalid
+ H h1({1, 2}); // expected-error {{no matching constructor}}
+ (void) new H({1, 2}); // expected-error {{no matching constructor}}
+ // FIXME: Bad diagnostic, mentions void type instead of init list.
+ (void) H({1, 2}); // expected-error {{no matching conversion}}
+
+ // valid (by copy constructor).
+ H h2({1, nullptr});
+ (void) new H({1, nullptr});
+ (void) H({1, nullptr});
+
+ // valid
+ H h3{1, 2};
+ (void) new H{1, 2};
+ (void) H{1, 2};
}
}
Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-references.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-references.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-references.cpp Tue Feb 14 03:11:10 2012
@@ -71,4 +71,9 @@
static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload resolution");
}
+ void edge_cases() {
+ // FIXME: very poor error message
+ int const &b({0}); // expected-error {{could not bind}}
+ }
+
}
Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-scalars.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-scalars.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-scalars.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-scalars.cpp Tue Feb 14 03:11:10 2012
@@ -25,7 +25,7 @@
}
void inline_init() {
- (void) int{1};
+ auto v = int{1};
(void) new int{1};
}
@@ -55,4 +55,11 @@
emptylist({});
emptylist({}, {}, {});
}
+
+ void edge_cases() {
+ // FIXME: very poor error message
+ int a({0}); // expected-error {{cannot initialize}}
+ (void) int({0}); // expected-error {{functional-style cast}}
+ new int({0}); // expected-error {{cannot initialize}}
+ }
}
Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Tue Feb 14 03:11:10 2012
@@ -122,3 +122,8 @@
for (int i : {1, 2, 3, 4}) {}
}
+
+void dangle() {
+ new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}}
+ new std::initializer_list<int>{1, 2, 3}; // expected-warning {{at the end of the full-expression}}
+}
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=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp Tue Feb 14 03:11:10 2012
@@ -39,8 +39,10 @@
}
int InitList() {
- (void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
- (void)int{}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
+ (void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \
+ // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
+ (void)int{}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \
+ // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
int x { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
}
Modified: cfe/branches/tooling/test/SemaCXX/destructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/destructor.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/destructor.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/destructor.cpp Tue Feb 14 03:11:10 2012
@@ -16,7 +16,7 @@
struct D {
static void ~D(int, ...) const { } // \
- // expected-error{{type qualifier is not allowed on this function}} \
+ // expected-error{{static member function cannot have 'const' qualifier}} \
// expected-error{{destructor cannot be declared 'static'}} \
// expected-error{{destructor cannot have any parameters}} \
// expected-error{{destructor cannot be variadic}} \
Modified: cfe/branches/tooling/test/SemaCXX/format-strings-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/format-strings-0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/format-strings-0x.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/format-strings-0x.cpp Tue Feb 14 03:11:10 2012
@@ -10,4 +10,6 @@
printf("%a", 1.0);
scanf("%afoobar", fp);
+ printf(nullptr);
+ printf(*sp); // expected-warning {{not a string literal}}
}
Modified: cfe/branches/tooling/test/SemaCXX/format-strings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/format-strings.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/format-strings.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/format-strings.cpp Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic %s
extern "C" {
extern int scanf(const char *restrict, ...);
@@ -17,3 +17,38 @@
void g() {
printf("%ls", "foo"); // expected-warning{{format specifies type 'wchar_t *' but the argument has type 'const char *'}}
}
+
+// Test that we properly handle format_idx on C++ members.
+class Foo {
+public:
+ const char *gettext(const char *fmt) __attribute__((format_arg(2)));
+
+ int scanf(const char *restrict, ...) __attribute__((format(scanf, 2, 3)));
+ int printf(const char *restrict, ...) __attribute__((format(printf, 2, 3)));
+
+ static const char *gettext_static(const char *fmt) __attribute__((format_arg(1)));
+ static int printf_static(const char *restrict, ...) __attribute__((format(printf, 1, 2)));
+};
+
+void h(int *i) {
+ Foo foo;
+ foo.scanf("%d"); // expected-warning{{more '%' conversions than data arguments}}
+ foo.printf("%d", i); // expected-warning{{format specifies type 'int' but the argument has type 'int *'}}
+ Foo::printf_static("%d", i); // expected-warning{{format specifies type 'int' but the argument has type 'int *'}}
+
+ printf(foo.gettext("%d"), i); // expected-warning{{format specifies type 'int' but the argument has type 'int *'}}
+ printf(Foo::gettext_static("%d"), i); // expected-warning{{format specifies type 'int' but the argument has type 'int *'}}
+}
+
+// Test handling __null for format string literal checking.
+extern "C" {
+ int test_null_format(const char *format, ...) __attribute__((__format__ (__printf__, 1, 2)));
+}
+
+void rdar8269537(const char *f)
+{
+ test_null_format(false); // expected-warning {{null from a constant boolean}}
+ test_null_format(0); // no-warning
+ test_null_format(__null); // no-warning
+ test_null_format(f); // expected-warning {{not a string literal}}
+}
Modified: cfe/branches/tooling/test/SemaCXX/function-type-qual.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/function-type-qual.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/function-type-qual.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/function-type-qual.cpp Tue Feb 14 03:11:10 2012
@@ -1,17 +1,17 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-void f() const; // expected-error {{type qualifier is not allowed on this function}}
-void (*pf)() const; // expected-error {{type qualifier is not allowed on this function pointer}}
-void (&rf)() const = f; // expected-error {{type qualifier is not allowed on this function reference}}
+void f() const; // expected-error {{non-member function cannot have 'const' qualifier}}
+void (*pf)() const; // expected-error {{pointer to function type cannot have 'const' qualifier}}
+extern void (&rf)() const; // expected-error {{reference to function type cannot have 'const' qualifier}}
-typedef void cfn() const;
-cfn f2; // expected-error {{a qualified function type cannot be used to declare a nonmember function}}
+typedef void cfn() const;
+cfn f2; // expected-error {{non-member function of type 'cfn' (aka 'void () const') cannot have 'const' qualifier}}
class C {
void f() const;
cfn f2;
- static void f3() const; // expected-error {{type qualifier is not allowed on this function}}
- static cfn f4; // expected-error {{a qualified function type cannot be used to declare a static member function}}
+ static void f3() const; // expected-error {{static member function cannot have 'const' qualifier}}
+ static cfn f4; // expected-error {{static member function of type 'cfn' (aka 'void () const') cannot have 'const' qualifier}}
void m1() {
x = 0;
Removed: cfe/branches/tooling/test/SemaCXX/generalized-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/generalized-initializers.cpp?rev=150464&view=auto
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/generalized-initializers.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/generalized-initializers.cpp (removed)
@@ -1,158 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// XFAIL: *
-
-template <typename T, typename U>
-struct same_type { static const bool value = false; };
-template <typename T>
-struct same_type<T, T> { static const bool value = true; };
-
-namespace std {
- typedef decltype(sizeof(int)) size_t;
-
- // libc++'s implementation
- template <class _E>
- class initializer_list
- {
- const _E* __begin_;
- size_t __size_;
-
- initializer_list(const _E* __b, size_t __s)
- : __begin_(__b),
- __size_(__s)
- {}
-
- public:
- typedef _E value_type;
- typedef const _E& reference;
- typedef const _E& const_reference;
- typedef size_t size_type;
-
- typedef const _E* iterator;
- typedef const _E* const_iterator;
-
- initializer_list() : __begin_(nullptr), __size_(0) {}
-
- size_t size() const {return __size_;}
- const _E* begin() const {return __begin_;}
- const _E* end() const {return __begin_ + __size_;}
- };
-}
-
-namespace objects {
-
- struct X1 { X1(int); };
- struct X2 { explicit X2(int); };
-
- template <int N>
- struct A {
- A() { static_assert(N == 0, ""); }
- A(int, double) { static_assert(N == 1, ""); }
- A(std::initializer_list<int>) { static_assert(N == 3, ""); }
- };
-
- template <int N>
- struct D {
- D(std::initializer_list<int>) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}}
- D(std::initializer_list<double>) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}}
- };
-
- template <int N>
- struct E {
- E(int, int) { static_assert(N == 0, ""); }
- E(X1, int) { static_assert(N == 1, ""); }
- };
-
- void overload_resolution() {
- { A<0> a{}; }
- { A<0> a = {}; }
- // Narrowing conversions don't affect viability. The next two choose
- // the initializer_list constructor.
- { A<3> a{1, 1.0}; } // expected-error {{narrowing conversion}}
- { A<3> a = {1, 1.0}; } // expected-error {{narrowing conversion}}
- { A<3> a{1, 2, 3, 4, 5, 6, 7, 8}; }
- { A<3> a = {1, 2, 3, 4, 5, 6, 7, 8}; }
- { A<3> a{1, 2, 3, 4, 5, 6, 7, 8}; }
- { A<3> a{1, 2}; }
-
- { D<0> d{1, 2, 3}; }
- { D<1> d{1.0, 2.0, 3.0}; }
- { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}}
-
- { E<0> e{1, 2}; }
- }
-
- void explicit_implicit() {
- { X1 x{0}; }
- { X1 x = {0}; }
- { X2 x{0}; }
- { X2 x = {0}; } // expected-error {{explicit}}
- }
-
- struct C {
- C();
- C(int, double);
- C(int, int);
- C(std::initializer_list<int>);
-
- int operator[](C);
- };
-
- C function_call() {
- void takes_C(C);
- takes_C({1, 1.0});
-
- C c;
- c[{1, 1.0}];
-
- return {1, 1.0};
- }
-
- void inline_init() {
- (void) A<1>{1, 1.0};
- (void) new A<1>{1, 1.0};
- }
-
- struct B {
- B(C, int, C);
- };
-
- void nested_init() {
- B b{{1, 1.0}, 2, {3, 4, 5, 6, 7}};
- }
-}
-
-namespace litb {
-
- // invalid
- struct A { int a[2]; A():a({1, 2}) { } }; // expected-error {{}}
-
- // invalid
- int a({0}); // expected-error {{}}
-
- // invalid
- int const &b({0}); // expected-error {{}}
-
- struct C { explicit C(int, int); C(int, long); };
-
- // invalid
- C c({1, 2}); // expected-error {{}}
-
- // valid (by copy constructor).
- C d({1, 2L});
-
- // valid
- C e{1, 2};
-
- struct B {
- template<typename ...T>
- B(std::initializer_list<int>, T ...);
- };
-
- // invalid (the first phase only considers init-list ctors)
- // (for the second phase, no constructor is viable)
- B f{1, 2, 3};
-
- // valid (T deduced to <>).
- B g({1, 2, 3});
-
-}
Modified: cfe/branches/tooling/test/SemaCXX/goto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/goto.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/goto.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/goto.cpp Tue Feb 14 03:11:10 2012
@@ -103,3 +103,15 @@
exit:
return;
}
+
+namespace PR10620 {
+ struct S {
+ ~S() {}
+ };
+ void g(const S& s) {
+ goto done; // expected-error {{goto into protected scope}}
+ const S s2(s); // expected-note {{jump bypasses variable initialization}}
+ done:
+ ;
+ }
+}
Modified: cfe/branches/tooling/test/SemaCXX/issue547.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/issue547.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/issue547.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/issue547.cpp Tue Feb 14 03:11:10 2012
@@ -11,17 +11,17 @@
};
template<typename R, typename ...Args>
-struct classify_function<R(Args...) const> { // expected-warning{{template argument of 'const' qualified function type is a GNU extension}}
+struct classify_function<R(Args...) const> {
static const unsigned value = 2;
};
template<typename R, typename ...Args>
-struct classify_function<R(Args...) volatile> { // expected-warning{{template argument of 'volatile' qualified function type is a GNU extension}}
+struct classify_function<R(Args...) volatile> {
static const unsigned value = 3;
};
template<typename R, typename ...Args>
-struct classify_function<R(Args...) const volatile> { // expected-warning{{template argument of 'const volatile' qualified function type is a GNU extension}}
+struct classify_function<R(Args...) const volatile> {
static const unsigned value = 4;
};
@@ -31,27 +31,27 @@
};
template<typename R, typename ...Args>
-struct classify_function<R(Args......) const> { // expected-warning{{template argument of 'const' qualified function type is a GNU extension}}
+struct classify_function<R(Args......) const> {
static const unsigned value = 6;
};
template<typename R, typename ...Args>
-struct classify_function<R(Args......) volatile> { // expected-warning{{template argument of 'volatile' qualified function type is a GNU extension}}
+struct classify_function<R(Args......) volatile> {
static const unsigned value = 7;
};
template<typename R, typename ...Args>
-struct classify_function<R(Args......) const volatile> { // expected-warning{{template argument of 'const volatile' qualified function type is a GNU extension}}
+struct classify_function<R(Args......) const volatile> {
static const unsigned value = 8;
};
template<typename R, typename ...Args>
-struct classify_function<R(Args......) &&> { // expected-warning{{template argument of '&&' qualified function type is a GNU extension}}
+struct classify_function<R(Args......) &&> {
static const unsigned value = 9;
};
template<typename R, typename ...Args>
-struct classify_function<R(Args......) const &> { // expected-warning{{template argument of 'const &' qualified function type is a GNU extension}}
+struct classify_function<R(Args......) const &> {
static const unsigned value = 10;
};
Modified: cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp Tue Feb 14 03:11:10 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify -fblocks %s
+// RUN: %clang_cc1 -std=c++0x -Wno-unused-value -fsyntax-only -verify -fblocks %s
namespace std { class type_info; };
@@ -11,76 +11,79 @@
virtual C& Overload(float);
void ImplicitThisCapture() {
- [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}} expected-error {{not supported yet}}
- [&](){(void)Member;}; // expected-error {{not supported yet}}
- // 'this' captures below don't actually work yet
- [this](){(void)Member;}; // expected-error{{lambda expressions are not supported yet}}
- [this]{[this]{};}; // expected-error 2{{lambda expressions are not supported yet}}
- []{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}} expected-error 2 {{not supported yet}}
- []{Overload(3);}; // expected-error {{not supported yet}}
- []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}} expected-error {{not supported yet}}
- []{(void)typeid(Overload());};// expected-error {{not supported yet}}
- []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}} expected-error {{not supported yet}}
+ [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}}
+ [&](){(void)Member;};
+
+ [this](){(void)Member;};
+ [this]{[this]{};};
+ []{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}}
+ []{Overload(3);};
+ []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}}
+ []{(void)typeid(Overload());};
+ []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}}
}
};
void f() {
- [this] () {}; // expected-error {{'this' cannot be captured in this context}} expected-error {{not supported yet}}
+ [this] () {}; // expected-error {{'this' cannot be captured in this context}}
}
}
namespace ReturnDeduction {
void test() {
- [](){ return 1; }; // expected-error {{not supported yet}}
- [](){ return 1; }; // expected-error {{not supported yet}}
- [](){ return ({return 1; 1;}); }; // expected-error {{not supported yet}}
- [](){ return ({return 'c'; 1;}); }; // expected-error {{not supported yet}} expected-error {{must match previous return type}}
- []()->int{ return 'c'; return 1; }; // expected-error {{not supported yet}}
- [](){ return 'c'; return 1; }; // expected-error {{not supported yet}} expected-error {{must match previous return type}}
- []() { return; return (void)0; }; // expected-error {{not supported yet}}
- // FIXME: Need to check structure of lambda body
- [](){ return 1; return 1; }; // expected-error {{not supported yet}}
+ [](){ return 1; };
+ [](){ return 1; };
+ [](){ return ({return 1; 1;}); };
+ [](){ return ({return 'c'; 1;}); }; // expected-error {{must match previous return type}} \
+ // expected-warning{{omitted result type}}
+ []()->int{ return 'c'; return 1; };
+ [](){ return 'c'; return 1; }; // expected-error {{must match previous return type}}
+ []() { return; return (void)0; };
+ [](){ return 1; return 1; }; // expected-warning{{omitted result type}}
}
}
namespace ImplicitCapture {
void test() {
int a = 0; // expected-note 5 {{declared}}
- []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}} expected-error {{not supported yet}}
- [&]() { return a; }; // expected-error {{not supported yet}}
- [=]() { return a; }; // expected-error {{not supported yet}}
- [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}} expected-error {{not supported yet}}
- [=]() { return [&]() { return a; }; }; // expected-error 2 {{not supported yet}}
- []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-error 2 {{not supported yet}}
- []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-error {{not supported yet}}
- []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}} expected-error 2 {{not supported yet}}
- [=]() { return [&a] { return a; }; }; // expected-error 2 {{not supported yet}}
+ []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}}
+ [&]() { return a; };
+ [=]() { return a; };
+ [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}}
+ [=]() { return [&]() { return a; }; };
+ []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
+ []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
+ []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}}
+ [=]() { return [&a] { return a; }; }; //
const int b = 2;
- []() { return b; }; // expected-error {{not supported yet}}
+ []() { return b; };
union { // expected-note {{declared}}
int c;
float d;
};
d = 3;
- [=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}} expected-error {{not supported yet}}
+ [=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}}
__block int e; // expected-note 3 {{declared}}
- [&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}} expected-error {{not supported yet}}
- [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}} expected-error {{not supported yet}}
+ [&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}}
+ [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}}
int f[10]; // expected-note {{declared}}
- [&]() { return f[2]; }; // expected-error {{not supported yet}}
- (void) ^{ return []() { return f[2]; }; }; // expected-error {{cannot refer to declaration with an array type inside block}} expected-error {{not supported yet}}
+ [&]() { return f[2]; };
+ (void) ^{ return []() { return f[2]; }; }; // expected-error {{variable 'f' cannot be implicitly captured in a lambda with no capture-default specified}} \
+ // expected-note{{lambda expression begins here}}
struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}}
G g;
- [=]() { const G* gg = &g; return gg->a; }; // expected-error {{not supported yet}}
- [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'const ImplicitCapture::G'}} expected-error 2 {{not supported yet}}
- (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const ImplicitCapture::G'}} expected-error {{not supported yet}}
+ [=]() { const G* gg = &g; return gg->a; }; // expected-warning{{omitted result type}}
+ [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'const ImplicitCapture::G'}} \
+ // expected-warning{{omitted result type}}
+ (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const ImplicitCapture::G'}} \
+ // expected-warning{{omitted result type}}
const int h = a; // expected-note {{declared}}
- []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} expected-error {{not supported yet}}
+ []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
}
}
Modified: cfe/branches/tooling/test/SemaCXX/literal-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/literal-type.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/literal-type.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/literal-type.cpp Tue Feb 14 03:11:10 2012
@@ -23,6 +23,8 @@
// a constant expression,
// -- it is an aggregate type or has at least one constexpr constructor
// or constructor template that is not a copy or move constructor, and
+// [DR1452 adds class types with trivial default constructors to
+// this list]
// -- it has all non-static data members and base classes of literal
// types
struct Empty {};
@@ -36,25 +38,26 @@
struct HasDtor { ~HasDtor(); };
class NonAggregate { int x; };
-struct HasNonLiteralBase : NonAggregate {};
+struct NonLiteral { NonLiteral(); };
+struct HasNonLiteralBase : NonLiteral {};
struct HasNonLiteralMember { HasDtor x; };
static_assert(__is_literal(Empty), "fail");
static_assert(__is_literal(LiteralType), "fail");
+static_assert(__is_literal(NonAggregate), "fail");
+static_assert(!__is_literal(NonLiteral), "fail");
static_assert(!__is_literal(HasDtor), "fail");
-static_assert(!__is_literal(NonAggregate), "fail");
static_assert(!__is_literal(HasNonLiteralBase), "fail");
static_assert(!__is_literal(HasNonLiteralMember), "fail");
-// FIXME: Test constexpr constructors and non-static members with initializers
-// when Clang supports them:
-#if 0
-extern int f();
+// DR1361 removes the brace-or-equal-initializer bullet so that we can allow:
+extern int f(); // expected-note {{here}}
struct HasNonConstExprMemInit {
- int x = f();
- constexpr HasNonConstExprMemInit(int y) {}
+ int x = f(); // expected-note {{non-constexpr function}}
+ constexpr HasNonConstExprMemInit() {} // expected-error {{never produces a constant expression}}
+ constexpr HasNonConstExprMemInit(int y) : x(y) {} // ok
};
-static_assert(!__is_literal(HasNonConstExprMemInit), "fail");
+static_assert(__is_literal(HasNonConstExprMemInit), "fail");
class HasConstExprCtor {
int x;
@@ -66,6 +69,9 @@
public:
template <typename U> constexpr HasConstExprCtorTemplate(U y) : x(y) {}
};
+template <typename T> class HasConstExprCtorT {
+ constexpr HasConstExprCtorT(T) {}
+};
static_assert(__is_literal(HasConstExprCtor), "fail");
-static_assert(__is_literal(HasConstExprCtorTemplate), "fail");
-#endif
+static_assert(__is_literal(HasConstExprCtorTemplate<int>), "fail");
+static_assert(__is_literal(HasConstExprCtorT<NonLiteral>), "fail");
Modified: cfe/branches/tooling/test/SemaCXX/trailing-return-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/trailing-return-0x.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/trailing-return-0x.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/trailing-return-0x.cpp Tue Feb 14 03:11:10 2012
@@ -21,6 +21,16 @@
int h() -> int; // expected-error{{trailing return type must specify return type 'auto', not 'int'}}
+int i();
+auto i() -> int;
+int i() {}
+
+using T = auto (int) -> auto (*)(char) -> void; // expected-note {{previous}}
+using T = void; // expected-error {{type alias redefinition with different types ('void' vs 'auto (int) -> auto (*)(char) -> void')}}
+
+using U = auto (int) -> auto (*)(char) -> void;
+using U = void (*(int))(char); // ok
+
int x;
template <class T>
Modified: cfe/branches/tooling/test/SemaCXX/undefined-internal.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/undefined-internal.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/undefined-internal.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/undefined-internal.cpp Tue Feb 14 03:11:10 2012
@@ -170,3 +170,14 @@
b();
}
}
+
+
+namespace OverloadUse {
+ namespace {
+ void f();
+ void f(int); // expected-warning {{function 'OverloadUse::<anonymous namespace>::f' has internal linkage but is not defined}}
+ }
+ template<void x()> void t(int*) { x(); }
+ template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}}
+ void g() { long a; t<f>(&a); }
+}
Propchange: cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Feb 14 03:11:10 2012
@@ -1,2 +1,2 @@
/cfe/branches/type-system-rewrite/test/SemaCXX/warn-unreachable.cpp:134693-134817
-/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,146581-149982
+/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,146581-150463
Modified: cfe/branches/tooling/test/SemaObjC/arc-objc-lifetime.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/arc-objc-lifetime.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/arc-objc-lifetime.m (original)
+++ cfe/branches/tooling/test/SemaObjC/arc-objc-lifetime.m Tue Feb 14 03:11:10 2012
@@ -32,3 +32,11 @@
__autoreleasing id *stuff = (__autoreleasing id *)addr;
}
@end
+
+// rdar://problem/10711456
+__strong I *__strong test1; // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}}
+__strong I *(__strong test2); // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}}
+__strong I *(__strong (test3)); // expected-error {{the type 'I *__strong' is already explicitly ownership-qualified}}
+__unsafe_unretained __typeof__(test3) test4;
+typedef __strong I *strong_I;
+__unsafe_unretained strong_I test5;
Modified: cfe/branches/tooling/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/arc.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/arc.m (original)
+++ cfe/branches/tooling/test/SemaObjC/arc.m Tue Feb 14 03:11:10 2012
@@ -39,8 +39,6 @@
}
@end
-__weak __strong id x; // expected-error {{the type '__strong id' already has retainment attributes}}
-
// rdar://8843638
@interface I
Modified: cfe/branches/tooling/test/SemaObjC/attr-deprecated.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/attr-deprecated.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/attr-deprecated.m (original)
+++ cfe/branches/tooling/test/SemaObjC/attr-deprecated.m Tue Feb 14 03:11:10 2012
@@ -53,7 +53,7 @@
void t2(id a)
{
- [a f]; // expected-warning {{'f' is deprecated}}
+ [a f];
}
void t3(A<P>* a)
@@ -121,20 +121,3 @@
__attribute__((deprecated))
@interface A(Blah) // expected-error{{attributes may not be specified on a category}}
@end
-
-// rdar://10459930
-
- at class NSString;
- at interface NSDocumentController
-{
- id iv;
-}
-- (void)fileExtensionsFromType:(NSString *)typeName __attribute__((deprecated));
- at end
-
- at implementation NSDocumentController
-- (void) Meth {
- [iv fileExtensionsFromType:@"public.text"]; // expected-warning {{'fileExtensionsFromType:' is deprecated}}
-}
-- (void)fileExtensionsFromType:(NSString *)typeName {}
- at end
Modified: cfe/branches/tooling/test/SemaObjC/invalid-code.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/invalid-code.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/invalid-code.m (original)
+++ cfe/branches/tooling/test/SemaObjC/invalid-code.m Tue Feb 14 03:11:10 2012
@@ -27,3 +27,17 @@
return self;
}
@end
+
+ at interface I
+ at end
+ at interface I2
+ at end
+
+ at implementation I // expected-note {{started here}}
+-(void) foo {}
+
+ at implementation I2 // expected-error {{missing '@end'}}
+-(void) foo2 {}
+ at end
+
+ at end // expected-error {{'@end' must appear in an Objective-C context}}
Modified: cfe/branches/tooling/test/SemaObjC/method-undef-category-warn-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/method-undef-category-warn-1.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/method-undef-category-warn-1.m (original)
+++ cfe/branches/tooling/test/SemaObjC/method-undef-category-warn-1.m Tue Feb 14 03:11:10 2012
@@ -28,3 +28,26 @@
@implementation MyClass1(CAT1)
@end
+
+// rdar://10823023
+ at class NSString;
+
+ at protocol NSObject
+- (NSString *)meth_inprotocol;
+ at end
+
+ at interface NSObject <NSObject>
+- (NSString *)description;
++ (NSString *) cls_description;
+ at end
+
+ at protocol Foo
+- (NSString *)description;
++ (NSString *) cls_description;
+ at end
+
+ at interface NSObject (FooConformance) <Foo>
+ at end
+
+ at implementation NSObject (FooConformance)
+ at end
Modified: cfe/branches/tooling/test/SemaObjC/missing-atend-metadata.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/missing-atend-metadata.m?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/missing-atend-metadata.m (original)
+++ cfe/branches/tooling/test/SemaObjC/missing-atend-metadata.m Tue Feb 14 03:11:10 2012
@@ -10,7 +10,7 @@
@end
@implementation I1 // expected-note {{implementation started here}}
--(void) im0 { self = [super init]; }
+-(void) im0 { self = [super init]; } // expected-warning {{not found}}
@interface I2 : I0 // expected-error {{missing '@end'}}
- I2meth;
Modified: cfe/branches/tooling/test/SemaObjCXX/arc-templates.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjCXX/arc-templates.mm?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjCXX/arc-templates.mm (original)
+++ cfe/branches/tooling/test/SemaObjCXX/arc-templates.mm Tue Feb 14 03:11:10 2012
@@ -97,8 +97,8 @@
template<typename T>
struct make_weak_fail {
typedef T T_type;
- typedef __weak T_type type; // expected-error{{the type 'T_type' (aka '__weak id') already has retainment attributes set on it}} \
- // expected-error{{the type 'T_type' (aka '__strong id') already has retainment attributes set on it}}
+ typedef __weak T_type type; // expected-error{{the type 'T_type' (aka '__weak id') is already explicitly ownership-qualified}} \
+ // expected-error{{the type 'T_type' (aka '__strong id') is already explicitly ownership-qualified}}
};
int check_make_weak_fail0[is_same<make_weak_fail<__weak id>::type, __weak id>::value? 1 : -1]; // expected-note{{in instantiation of template class 'make_weak_fail<__weak id>' requested here}}
Modified: cfe/branches/tooling/test/SemaTemplate/instantiate-complete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaTemplate/instantiate-complete.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaTemplate/instantiate-complete.cpp (original)
+++ cfe/branches/tooling/test/SemaTemplate/instantiate-complete.cpp Tue Feb 14 03:11:10 2012
@@ -28,7 +28,6 @@
void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
X<char(char)> *ptr3, X<short(short)> *ptr4) {
(void)(ptr1 + 5);
- // FIXME: if I drop the ')' after void, below, it still parses (!)
(void)(5 + ptr2);
(void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
(void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
@@ -145,4 +144,3 @@
BaseT<int> bt(ft);
}
}
-
Modified: cfe/branches/tooling/test/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/lit.cfg?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/test/lit.cfg (original)
+++ cfe/branches/tooling/test/lit.cfg Tue Feb 14 03:11:10 2012
@@ -32,7 +32,7 @@
config.test_format = lit.formats.ShTest(execute_external)
# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl']
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s']
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
Modified: cfe/branches/tooling/tools/arcmt-test/arcmt-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/arcmt-test/arcmt-test.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/arcmt-test/arcmt-test.cpp (original)
+++ cfe/branches/tooling/tools/arcmt-test/arcmt-test.cpp Tue Feb 14 03:11:10 2012
@@ -177,7 +177,7 @@
origCI.getMigratorOpts().NoFinalizeRemoval);
assert(!transforms.empty());
- llvm::OwningPtr<PrintTransforms> transformPrinter;
+ OwningPtr<PrintTransforms> transformPrinter;
if (OutputTransformations)
transformPrinter.reset(new PrintTransforms(llvm::outs()));
@@ -353,7 +353,7 @@
if (StringRef(argv[optargc]) == "--args")
break;
}
- llvm::cl::ParseCommandLineOptions(optargc, const_cast<char **>(argv), "arcmt-test");
+ llvm::cl::ParseCommandLineOptions(optargc, argv, "arcmt-test");
if (VerifyTransformedFiles) {
if (ResultFiles.empty()) {
Modified: cfe/branches/tooling/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/c-index-test/c-index-test.c?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/c-index-test/c-index-test.c (original)
+++ cfe/branches/tooling/tools/c-index-test/c-index-test.c Tue Feb 14 03:11:10 2012
@@ -418,13 +418,21 @@
}
}
-void PrintDiagnostics(CXTranslationUnit TU) {
- int i, n = clang_getNumDiagnostics(TU);
- for (i = 0; i != n; ++i) {
- CXDiagnostic Diag = clang_getDiagnostic(TU, i);
+void PrintDiagnosticSet(CXDiagnosticSet Set) {
+ int i = 0, n = clang_getNumDiagnosticsInSet(Set);
+ for ( ; i != n ; ++i) {
+ CXDiagnostic Diag = clang_getDiagnosticInSet(Set, i);
+ CXDiagnosticSet ChildDiags = clang_getChildDiagnostics(Diag);
PrintDiagnostic(Diag);
- clang_disposeDiagnostic(Diag);
- }
+ if (ChildDiags)
+ PrintDiagnosticSet(ChildDiags);
+ }
+}
+
+void PrintDiagnostics(CXTranslationUnit TU) {
+ CXDiagnosticSet TUSet = clang_getDiagnosticSetFromTU(TU);
+ PrintDiagnosticSet(TUSet);
+ clang_disposeDiagnosticSet(TUSet);
}
void PrintMemoryUsage(CXTranslationUnit TU) {
Modified: cfe/branches/tooling/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/driver/CMakeLists.txt?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/driver/CMakeLists.txt (original)
+++ cfe/branches/tooling/tools/driver/CMakeLists.txt Tue Feb 14 03:11:10 2012
@@ -40,16 +40,17 @@
if(UNIX)
set(CLANGXX_LINK_OR_COPY create_symlink)
+# Create a relative symlink
+ set(clang_binary "clang${CMAKE_EXECUTABLE_SUFFIX}")
else()
set(CLANGXX_LINK_OR_COPY copy)
+ set(clang_binary "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
endif()
# Create the clang++ symlink in the build directory.
set(clang_pp "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}")
add_custom_command(TARGET clang POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY}
- "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}"
- "${clang_pp}")
+ COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_pp}")
set_property(DIRECTORY APPEND
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_pp})
Modified: cfe/branches/tooling/tools/driver/cc1_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/driver/cc1_main.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/driver/cc1_main.cpp (original)
+++ cfe/branches/tooling/tools/driver/cc1_main.cpp Tue Feb 14 03:11:10 2012
@@ -117,7 +117,7 @@
int cc1_main(const char **ArgBegin, const char **ArgEnd,
const char *Argv0, void *MainAddr) {
- llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+ OwningPtr<CompilerInstance> Clang(new CompilerInstance());
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
// Run clang -cc1 test.
Modified: cfe/branches/tooling/tools/driver/cc1as_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/driver/cc1as_main.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/driver/cc1as_main.cpp (original)
+++ cfe/branches/tooling/tools/driver/cc1as_main.cpp Tue Feb 14 03:11:10 2012
@@ -63,8 +63,17 @@
/// @name Target Options
/// @{
+ /// The name of the target triple to assemble for.
std::string Triple;
+ /// If given, the name of the target CPU to determine which instructions
+ /// are legal.
+ std::string CPU;
+
+ /// The list of target specific features to enable or disable -- this should
+ /// be a list of strings starting with '+' or '-'.
+ std::vector<std::string> Features;
+
/// @}
/// @name Language Options
/// @{
@@ -158,9 +167,13 @@
// Construct the invocation.
// Target Options
- Opts.Triple = Triple::normalize(Args->getLastArgValue(OPT_triple));
- if (Opts.Triple.empty()) // Use the default target triple if unspecified.
- Opts.Triple = sys::getDefaultTargetTriple();
+ Opts.Triple = llvm::Triple::normalize(Args->getLastArgValue(OPT_triple));
+ Opts.CPU = Args->getLastArgValue(OPT_target_cpu);
+ Opts.Features = Args->getAllArgValues(OPT_target_feature);
+
+ // Use the default target triple if unspecified.
+ if (Opts.Triple.empty())
+ Opts.Triple = llvm::sys::getDefaultTargetTriple();
// Language Options
Opts.IncludePaths = Args->getAllArgValues(OPT_I);
@@ -293,11 +306,19 @@
if (!Opts.DwarfDebugFlags.empty())
Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
+ // Build up the feature string from the target feature list.
+ std::string FS;
+ if (!Opts.Features.empty()) {
+ FS = Opts.Features[0];
+ for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
+ FS += "," + Opts.Features[i];
+ }
+
OwningPtr<MCStreamer> Str;
OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
OwningPtr<MCSubtargetInfo>
- STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", ""));
+ STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
@@ -390,7 +411,7 @@
// Honor -help.
if (Asm.ShowHelp) {
- llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable());
+ OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable());
Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler");
return 0;
}
@@ -413,7 +434,7 @@
for (unsigned i = 0; i != NumArgs; ++i)
Args[i + 1] = Asm.LLVMArgs[i].c_str();
Args[NumArgs + 1] = 0;
- llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args));
+ llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
}
// Execute the invocation, unless there were parsing errors.
Modified: cfe/branches/tooling/tools/driver/driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/driver/driver.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/driver/driver.cpp (original)
+++ cfe/branches/tooling/tools/driver/driver.cpp Tue Feb 14 03:11:10 2012
@@ -186,7 +186,7 @@
SmallVectorImpl<const char*> &ArgVector,
std::set<std::string> &SavedStrings) {
const char *FName = Arg + 1;
- llvm::OwningPtr<llvm::MemoryBuffer> MemBuf;
+ OwningPtr<llvm::MemoryBuffer> MemBuf;
if (llvm::MemoryBuffer::getFile(FName, MemBuf)) {
ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
return;
@@ -388,7 +388,7 @@
// the installed path. We do this manually, because we want to support that
// path being a symlink.
{
- llvm::SmallString<128> InstalledPath(argv[0]);
+ SmallString<128> InstalledPath(argv[0]);
// Do a PATH lookup, if there are no directory components.
if (llvm::sys::path::filename(InstalledPath) == InstalledPath) {
@@ -448,7 +448,7 @@
argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end());
}
- llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
+ OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 0;
const Command *FailingCommand = 0;
if (C.get())
Modified: cfe/branches/tooling/tools/libclang/ARCMigrate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/ARCMigrate.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/ARCMigrate.cpp (original)
+++ cfe/branches/tooling/tools/libclang/ARCMigrate.cpp Tue Feb 14 03:11:10 2012
@@ -56,7 +56,7 @@
}
TextDiagnosticBuffer diagBuffer;
- llvm::OwningPtr<Remap> remap(new Remap());
+ OwningPtr<Remap> remap(new Remap());
bool err = arcmt::getFileRemappings(remap->Vec, migrate_dir_path,&diagBuffer);
Modified: cfe/branches/tooling/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndex.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndex.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndex.cpp Tue Feb 14 03:11:10 2012
@@ -2457,7 +2457,7 @@
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.getPtr());
- llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
+ OwningPtr<std::vector<ASTUnit::RemappedFile> >
RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
// Recover resources if we crash before exiting this function.
@@ -2472,7 +2472,7 @@
Buffer));
}
- llvm::OwningPtr<std::vector<const char *> >
+ OwningPtr<std::vector<const char *> >
Args(new std::vector<const char*>());
// Recover resources if we crash before exiting this method.
@@ -2516,7 +2516,7 @@
}
unsigned NumErrors = Diags->getClient()->getNumErrors();
- llvm::OwningPtr<ASTUnit> Unit(
+ OwningPtr<ASTUnit> Unit(
ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
/* vector::data() not portable */,
Args->size() ? (&(*Args)[0] + Args->size()) :0,
@@ -2658,7 +2658,7 @@
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
- llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
+ OwningPtr<std::vector<ASTUnit::RemappedFile> >
RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
// Recover resources if we crash before exiting this function.
@@ -2898,7 +2898,7 @@
if (isa<UsingDirectiveDecl>(D))
return createCXString("");
- llvm::SmallString<1024> S;
+ SmallString<1024> S;
llvm::raw_svector_ostream os(S);
ND->printName(os);
@@ -3040,7 +3040,7 @@
D = FunTmpl->getTemplatedDecl();
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
- llvm::SmallString<64> Str;
+ SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *Function;
if (Function->getPrimaryTemplate())
@@ -3062,7 +3062,7 @@
}
if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
- llvm::SmallString<64> Str;
+ SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassTemplate;
OS << "<";
@@ -3098,7 +3098,7 @@
if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
return createCXString(TSInfo->getType().getAsString(Policy));
- llvm::SmallString<64> Str;
+ SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassSpec;
OS << TemplateSpecializationType::PrintTemplateArgumentList(
@@ -5448,7 +5448,7 @@
}
ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
- llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
+ OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
ASTContext &astContext = astUnit->getASTContext();
// How much memory is used by AST nodes and types?
Modified: cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp Tue Feb 14 03:11:10 2012
@@ -698,7 +698,7 @@
#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
- llvm::SmallString<256> LogResult;
+ SmallString<256> LogResult;
llvm::raw_svector_ostream os(LogResult);
// Figure out the language and whether or not it uses PCH.
@@ -718,7 +718,7 @@
else if (strcmp(*I, "-include") == 0) {
if (I+1 != E) {
const char *arg = *(++I);
- llvm::SmallString<512> pchName;
+ SmallString<512> pchName;
{
llvm::raw_svector_ostream os(pchName);
os << arg << ".pth";
@@ -883,7 +883,7 @@
/// \param Buffer A buffer that stores the actual, concatenated string. It will
/// be used if the old string is already-non-empty.
static void AppendToString(StringRef &Old, StringRef New,
- llvm::SmallString<256> &Buffer) {
+ SmallString<256> &Buffer) {
if (Old.empty()) {
Old = New;
return;
@@ -903,7 +903,7 @@
///
/// \param Buffer A buffer used for storage of the completed name.
static StringRef GetTypedName(CodeCompletionString *String,
- llvm::SmallString<256> &Buffer) {
+ SmallString<256> &Buffer) {
StringRef Result;
for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
C != CEnd; ++C) {
@@ -923,9 +923,9 @@
CodeCompletionString *Y
= (CodeCompletionString *)YR.CompletionString;
- llvm::SmallString<256> XBuffer;
+ SmallString<256> XBuffer;
StringRef XText = GetTypedName(X, XBuffer);
- llvm::SmallString<256> YBuffer;
+ SmallString<256> YBuffer;
StringRef YText = GetTypedName(Y, YBuffer);
if (XText.empty() || YText.empty())
Modified: cfe/branches/tooling/tools/libclang/CIndexDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndexDiagnostic.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndexDiagnostic.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndexDiagnostic.cpp Tue Feb 14 03:11:10 2012
@@ -18,6 +18,8 @@
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/DiagnosticRenderer.h"
+#include "clang/Frontend/DiagnosticOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -40,6 +42,107 @@
CXDiagnosticImpl::~CXDiagnosticImpl() {}
+namespace {
+class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
+ std::string Message;
+ CXSourceLocation Loc;
+public:
+ CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
+ : CXDiagnosticImpl(CustomNoteDiagnosticKind),
+ Message(Msg), Loc(L) {}
+
+ virtual ~CXDiagnosticCustomNoteImpl() {}
+
+ CXDiagnosticSeverity getSeverity() const {
+ return CXDiagnostic_Note;
+ }
+
+ CXSourceLocation getLocation() const {
+ return Loc;
+ }
+
+ CXString getSpelling() const {
+ return createCXString(StringRef(Message), false);
+ }
+
+ CXString getDiagnosticOption(CXString *Disable) const {
+ if (Disable)
+ *Disable = createCXString("", false);
+ return createCXString("", false);
+ }
+
+ unsigned getCategory() const { return 0; }
+ unsigned getNumRanges() const { return 0; }
+ CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
+ unsigned getNumFixIts() const { return 0; }
+ CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
+ if (ReplacementRange)
+ *ReplacementRange = clang_getNullRange();
+ return createCXString("", false);
+ }
+};
+
+class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
+public:
+ CXDiagnosticRenderer(const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const DiagnosticOptions &DiagOpts,
+ CXDiagnosticSetImpl *mainSet)
+ : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts),
+ CurrentSet(mainSet), MainSet(mainSet) {}
+
+ virtual ~CXDiagnosticRenderer() {}
+
+ virtual void beginDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) {
+
+ const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
+ if (!SD)
+ return;
+
+ if (Level != DiagnosticsEngine::Note)
+ CurrentSet = MainSet;
+
+ CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts);
+ CurrentSet->appendDiagnostic(CD);
+
+ if (Level != DiagnosticsEngine::Note)
+ CurrentSet = &CD->getChildDiagnostics();
+ }
+
+ virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ StringRef Message,
+ ArrayRef<CharSourceRange> Ranges,
+ DiagOrStoredDiag D) {
+ if (!D.isNull())
+ return;
+
+ CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc);
+ CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
+ CurrentSet->appendDiagnostic(CD);
+ }
+
+ virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges) {}
+
+ virtual void emitCodeContext(SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange>& Ranges,
+ ArrayRef<FixItHint> Hints) {};
+
+ virtual void emitNote(SourceLocation Loc, StringRef Message) {
+ CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc);
+ CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message,
+ L));
+ }
+
+ CXDiagnosticSetImpl *CurrentSet;
+ CXDiagnosticSetImpl *MainSet;
+};
+}
+
CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
bool checkIfChanged) {
ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData);
@@ -75,12 +178,14 @@
if (!TU->Diagnostics) {
CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
TU->Diagnostics = Set;
+ DiagnosticOptions DOpts;
+ CXDiagnosticRenderer Renderer(AU->getSourceManager(),
+ AU->getASTContext().getLangOptions(),
+ DOpts, Set);
for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
ei = AU->stored_diag_end(); it != ei; ++it) {
- CXStoredDiagnostic *D =
- new CXStoredDiagnostic(*it, AU->getASTContext().getLangOptions());
- Set->appendDiagnostic(D);
+ Renderer.emitStoredDiagnostic(*it);
}
}
return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
@@ -126,7 +231,7 @@
CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
- llvm::SmallString<256> Str;
+ SmallString<256> Str;
llvm::raw_svector_ostream Out(Str);
if (Options & CXDiagnostic_DisplaySourceLocation) {
Modified: cfe/branches/tooling/tools/libclang/CIndexDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndexDiagnostic.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndexDiagnostic.h (original)
+++ cfe/branches/tooling/tools/libclang/CIndexDiagnostic.h Tue Feb 14 03:11:10 2012
@@ -54,7 +54,8 @@
class CXDiagnosticImpl {
public:
- enum Kind { StoredDiagnosticKind, LoadedDiagnosticKind };
+ enum Kind { StoredDiagnosticKind, LoadedDiagnosticKind,
+ CustomNoteDiagnosticKind };
virtual ~CXDiagnosticImpl();
Modified: cfe/branches/tooling/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndexUSRs.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndexUSRs.cpp Tue Feb 14 03:11:10 2012
@@ -30,7 +30,7 @@
namespace {
class USRGenerator : public DeclVisitor<USRGenerator> {
- llvm::OwningPtr<llvm::SmallString<128> > OwnedBuf;
+ OwningPtr<SmallString<128> > OwnedBuf;
SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
bool IgnoreResults;
@@ -41,7 +41,7 @@
public:
explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
- : OwnedBuf(extBuf ? 0 : new llvm::SmallString<128>()),
+ : OwnedBuf(extBuf ? 0 : new SmallString<128>()),
Buf(extBuf ? *extBuf : *OwnedBuf.get()),
Out(Buf),
IgnoreResults(false),
@@ -197,6 +197,16 @@
if (!Ctx.getLangOptions().CPlusPlus || D->isExternC())
return;
+ if (const TemplateArgumentList *
+ SpecArgs = D->getTemplateSpecializationArgs()) {
+ Out << '<';
+ for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
+ Out << '#';
+ VisitTemplateArgument(SpecArgs->get(I));
+ }
+ Out << '>';
+ }
+
// Mangle in type information for the arguments.
for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
I != E; ++I) {
Modified: cfe/branches/tooling/tools/libclang/CXLoadedDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CXLoadedDiagnostic.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CXLoadedDiagnostic.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CXLoadedDiagnostic.cpp Tue Feb 14 03:11:10 2012
@@ -257,7 +257,7 @@
FileSystemOptions FO;
FileManager FileMgr(FO);
- llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+ OwningPtr<llvm::MemoryBuffer> Buffer;
Buffer.reset(FileMgr.getBufferForFile(file));
if (!Buffer) {
@@ -282,7 +282,7 @@
return 0;
}
- llvm::OwningPtr<CXLoadedDiagnosticSetImpl>
+ OwningPtr<CXLoadedDiagnosticSetImpl>
Diags(new CXLoadedDiagnosticSetImpl());
while (true) {
@@ -543,7 +543,7 @@
return Failure;
}
- llvm::OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
+ OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
RecordData Record;
while (true) {
Modified: cfe/branches/tooling/tools/libclang/CXString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CXString.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CXString.h (original)
+++ cfe/branches/tooling/tools/libclang/CXString.h Tue Feb 14 03:11:10 2012
@@ -23,7 +23,7 @@
namespace cxstring {
struct CXStringBuf {
- llvm::SmallString<128> Data;
+ SmallString<128> Data;
CXTranslationUnit TU;
CXStringBuf(CXTranslationUnit tu) : TU(tu) {}
};
Modified: cfe/branches/tooling/tools/libclang/IndexBody.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexBody.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexBody.cpp (original)
+++ cfe/branches/tooling/tools/libclang/IndexBody.cpp Tue Feb 14 03:11:10 2012
@@ -90,6 +90,12 @@
return true;
}
+ bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ if (E->getOperatorLoc().isInvalid())
+ return true; // implicit.
+ return base::TraverseCXXOperatorCallExpr(E);
+ }
+
bool VisitDeclStmt(DeclStmt *S) {
if (IndexCtx.indexFunctionLocalSymbols())
IndexCtx.indexDeclGroupRef(S->getDeclGroup());
Modified: cfe/branches/tooling/tools/libclang/IndexDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexDecl.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexDecl.cpp (original)
+++ cfe/branches/tooling/tools/libclang/IndexDecl.cpp Tue Feb 14 03:11:10 2012
@@ -213,6 +213,29 @@
return true;
}
+ bool VisitUsingDecl(UsingDecl *D) {
+ // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
+ // we should do better.
+
+ IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
+ for (UsingDecl::shadow_iterator
+ I = D->shadow_begin(), E = D->shadow_end(); I != E; ++I) {
+ IndexCtx.handleReference((*I)->getUnderlyingDecl(), D->getLocation(),
+ D, D->getLexicalDeclContext());
+ }
+ return true;
+ }
+
+ bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
+ // we should do better.
+
+ IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
+ IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
+ D->getLocation(), D, D->getLexicalDeclContext());
+ return true;
+ }
+
bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
IndexCtx.handleClassTemplate(D);
if (D->isThisDeclarationADefinition())
@@ -220,6 +243,15 @@
return true;
}
+ bool VisitClassTemplateSpecializationDecl(
+ ClassTemplateSpecializationDecl *D) {
+ // FIXME: Notify subsequent callbacks that info comes from implicit
+ // instantiation.
+ if (D->isThisDeclarationADefinition())
+ IndexCtx.indexTagDecl(D);
+ return true;
+ }
+
bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
IndexCtx.handleFunctionTemplate(D);
FunctionDecl *FD = D->getTemplatedDecl();
@@ -243,6 +275,9 @@
} // anonymous namespace
void IndexingContext::indexDecl(const Decl *D) {
+ if (D->isImplicit() && shouldIgnoreIfImplicit(D))
+ return;
+
bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
if (!Handled && isa<DeclContext>(D))
indexDeclContext(cast<DeclContext>(D));
Modified: cfe/branches/tooling/tools/libclang/IndexTypeSourceInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexTypeSourceInfo.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexTypeSourceInfo.cpp (original)
+++ cfe/branches/tooling/tools/libclang/IndexTypeSourceInfo.cpp Tue Feb 14 03:11:10 2012
@@ -72,10 +72,11 @@
}
bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
- if (const TemplateSpecializationType *T = TL.getTypePtr())
- if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl())
- IndexCtx.handleReference(D, TL.getTemplateNameLoc(),
+ if (const TemplateSpecializationType *T = TL.getTypePtr()) {
+ if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
+ IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
Parent, ParentDC);
+ }
return true;
}
};
Modified: cfe/branches/tooling/tools/libclang/Indexing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/Indexing.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/Indexing.cpp (original)
+++ cfe/branches/tooling/tools/libclang/Indexing.cpp Tue Feb 14 03:11:10 2012
@@ -135,6 +135,15 @@
/// The default implementation forwards to HandleTopLevelDecl but we don't
/// care about them when indexing, so have an empty definition.
virtual void HandleInterestingDecl(DeclGroupRef D) {}
+
+ virtual void HandleTagDeclDefinition(TagDecl *D) {
+ if (IndexCtx.isTemplateImplicitInstantiation(D))
+ IndexCtx.indexDecl(D);
+ }
+
+ virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
+ IndexCtx.indexDecl(D);
+ }
};
//===----------------------------------------------------------------------===//
@@ -185,7 +194,7 @@
indexDiagnostics(CXTU, IndexCtx);
}
- virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; }
+ virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
virtual bool hasCodeCompletionSupport() const { return false; }
};
@@ -271,7 +280,7 @@
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.getPtr());
- llvm::OwningPtr<std::vector<const char *> >
+ OwningPtr<std::vector<const char *> >
Args(new std::vector<const char*>());
// Recover resources if we crash before exiting this method.
@@ -303,7 +312,7 @@
if (CInvok->getFrontendOpts().Inputs.empty())
return;
- llvm::OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner());
+ OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner());
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner>
@@ -328,13 +337,13 @@
ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
/*CaptureDiagnostics=*/true);
- llvm::OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(Unit)));
+ OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(Unit)));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
CXTUCleanup(CXTU.get());
- llvm::OwningPtr<IndexingFrontendAction> IndexAction;
+ OwningPtr<IndexingFrontendAction> IndexAction;
IndexAction.reset(new IndexingFrontendAction(client_data, CB,
index_options, CXTU->getTU()));
@@ -487,14 +496,14 @@
? index_callbacks_size : sizeof(CB);
memcpy(&CB, client_index_callbacks, ClientCBSize);
- llvm::OwningPtr<IndexingContext> IndexCtx;
+ OwningPtr<IndexingContext> IndexCtx;
IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext>
IndexCtxCleanup(IndexCtx.get());
- llvm::OwningPtr<IndexingConsumer> IndexConsumer;
+ OwningPtr<IndexingConsumer> IndexConsumer;
IndexConsumer.reset(new IndexingConsumer(*IndexCtx));
// Recover resources if we crash before exiting this method.
Modified: cfe/branches/tooling/tools/libclang/IndexingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexingContext.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexingContext.cpp (original)
+++ cfe/branches/tooling/tools/libclang/IndexingContext.cpp Tue Feb 14 03:11:10 2012
@@ -282,9 +282,23 @@
DInfo.numAttributes = AttrList.getNumAttrs();
getContainerInfo(D->getDeclContext(), DInfo.SemanticContainer);
- getContainerInfo(D->getLexicalDeclContext(), DInfo.LexicalContainer);
DInfo.semanticContainer = &DInfo.SemanticContainer;
- DInfo.lexicalContainer = &DInfo.LexicalContainer;
+
+ if (D->getLexicalDeclContext() == D->getDeclContext()) {
+ DInfo.lexicalContainer = &DInfo.SemanticContainer;
+ } else if (isTemplateImplicitInstantiation(D)) {
+ // Implicit instantiations have the lexical context of where they were
+ // instantiated first. We choose instead the semantic context because:
+ // 1) at the time that we see the instantiation we have not seen the
+ // function where it occurred yet.
+ // 2) the lexical context of the first instantiation is not useful
+ // information anyway.
+ DInfo.lexicalContainer = &DInfo.SemanticContainer;
+ } else {
+ getContainerInfo(D->getLexicalDeclContext(), DInfo.LexicalContainer);
+ DInfo.lexicalContainer = &DInfo.LexicalContainer;
+ }
+
if (DInfo.isContainer) {
getContainerInfo(getEntityContainer(D), DInfo.DeclAsContainer);
DInfo.declAsContainer = &DInfo.DeclAsContainer;
@@ -646,6 +660,19 @@
CXXDInfo.CXXClassInfo.bases = BaseList.getBases();
CXXDInfo.CXXClassInfo.numBases = BaseList.getNumBases();
+ if (suppressRefs()) {
+ // Go through bases and mark them as referenced.
+ for (unsigned i = 0, e = BaseList.getNumBases(); i != e; ++i) {
+ const CXIdxBaseClassInfo *baseInfo = BaseList.getBases()[i];
+ if (baseInfo->base) {
+ const NamedDecl *BaseD = BaseList.BaseEntities[i].Dcl;
+ SourceLocation
+ Loc = SourceLocation::getFromRawEncoding(baseInfo->loc.int_data);
+ markEntityOccurrenceInFile(BaseD, Loc);
+ }
+ }
+ }
+
return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), CXXDInfo);
}
@@ -967,7 +994,7 @@
EntityInfo.name = 0; // anonymous tag/field/namespace.
} else {
- llvm::SmallString<256> StrBuf;
+ SmallString<256> StrBuf;
{
llvm::raw_svector_ostream OS(StrBuf);
D->printName(OS);
@@ -976,7 +1003,7 @@
}
{
- llvm::SmallString<512> StrBuf;
+ SmallString<512> StrBuf;
bool Ignore = getDeclCursorUSR(D, StrBuf);
if (Ignore) {
EntityInfo.USR = 0;
@@ -1012,7 +1039,7 @@
return clang_getNullCursor();
}
-bool IndexingContext::shouldIgnoreIfImplicit(const NamedDecl *D) {
+bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
if (isa<ObjCInterfaceDecl>(D))
return false;
if (isa<ObjCCategoryDecl>(D))
@@ -1023,3 +1050,14 @@
return false;
return true;
}
+
+bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
+ if (const ClassTemplateSpecializationDecl *
+ SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ return SD->getSpecializationKind() == TSK_ImplicitInstantiation;
+ }
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ return FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;
+ }
+ return false;
+}
Modified: cfe/branches/tooling/tools/libclang/IndexingContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexingContext.h?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexingContext.h (original)
+++ cfe/branches/tooling/tools/libclang/IndexingContext.h Tue Feb 14 03:11:10 2012
@@ -13,15 +13,14 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclGroup.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
namespace clang {
class FileEntry;
class ObjCPropertyDecl;
class ClassTemplateDecl;
class FunctionTemplateDecl;
- class Preprocessor;
class TypeAliasTemplateDecl;
+ class ClassTemplateSpecializationDecl;
namespace cxindex {
class IndexingContext;
@@ -428,6 +427,8 @@
CXIdxClientEntity getClientEntity(const Decl *D) const;
void setClientEntity(const Decl *D, CXIdxClientEntity client);
+ static bool isTemplateImplicitInstantiation(const Decl *D);
+
private:
bool handleDecl(const NamedDecl *D,
SourceLocation Loc, CXCursor Cursor,
@@ -461,7 +462,7 @@
CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
- static bool shouldIgnoreIfImplicit(const NamedDecl *D);
+ static bool shouldIgnoreIfImplicit(const Decl *D);
};
class ScratchAlloc {
Modified: cfe/branches/tooling/unittests/Basic/SourceManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/unittests/Basic/SourceManagerTest.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/unittests/Basic/SourceManagerTest.cpp (original)
+++ cfe/branches/tooling/unittests/Basic/SourceManagerTest.cpp Tue Feb 14 03:11:10 2012
@@ -97,7 +97,7 @@
ASSERT_TRUE(macroExpStartLoc.isFileID());
ASSERT_TRUE(macroExpEndLoc.isFileID());
- llvm::SmallString<32> str;
+ SmallString<32> str;
ASSERT_EQ("M", PP.getSpelling(macroExpStartLoc, str));
ASSERT_EQ(")", PP.getSpelling(macroExpEndLoc, str));
Modified: cfe/branches/tooling/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/utils/TableGen/ClangAttrEmitter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/branches/tooling/utils/TableGen/ClangAttrEmitter.cpp Tue Feb 14 03:11:10 2012
@@ -90,7 +90,7 @@
virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
virtual void writeCloneArgs(raw_ostream &OS) const = 0;
virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
- virtual void writeTemplateInstantiation(raw_ostream &OS) const {};
+ virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
virtual void writeCtorBody(raw_ostream &OS) const {}
virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
virtual void writeCtorParameters(raw_ostream &OS) const = 0;
Modified: cfe/branches/tooling/utils/TableGen/ClangDiagnosticsEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/utils/TableGen/ClangDiagnosticsEmitter.cpp (original)
+++ cfe/branches/tooling/utils/TableGen/ClangDiagnosticsEmitter.cpp Tue Feb 14 03:11:10 2012
@@ -194,14 +194,6 @@
// Category number.
OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap));
-
- // Brief
- OS << ", \"";
- OS.write_escaped(R.getValueAsString("Brief")) << '"';
-
- // Explanation
- OS << ", \"";
- OS.write_escaped(R.getValueAsString("Explanation")) << '"';
OS << ")\n";
}
}
@@ -213,7 +205,7 @@
static std::string getDiagCategoryEnum(llvm::StringRef name) {
if (name.empty())
return "DiagCat_None";
- llvm::SmallString<256> enumName = llvm::StringRef("DiagCat_");
+ SmallString<256> enumName = llvm::StringRef("DiagCat_");
for (llvm::StringRef::iterator I = name.begin(), E = name.end(); I != E; ++I)
enumName += isalnum(*I) ? *I : '_';
return enumName.str();
Modified: cfe/branches/tooling/www/get_started.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/www/get_started.html?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/www/get_started.html (original)
+++ cfe/branches/tooling/www/get_started.html Tue Feb 14 03:11:10 2012
@@ -59,6 +59,7 @@
</li>
<li>Checkout Compiler-RT:
<ul>
+ <li><tt>cd ../..</tt> (back to where you started)</li>
<li><tt>cd llvm/projects</tt>
<li><tt>svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk
compiler-rt</tt></li>
Modified: cfe/branches/tooling/www/hacking.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/www/hacking.html?rev=150465&r1=150464&r2=150465&view=diff
==============================================================================
--- cfe/branches/tooling/www/hacking.html (original)
+++ cfe/branches/tooling/www/hacking.html Tue Feb 14 03:11:10 2012
@@ -215,34 +215,49 @@
the following:</p>
<pre>
- python (path to llvm)/llvm/utils/lit/lit.py -sv --no-progress-bar
- (path to llvm)/llvm/tools/clang/test
+ python (path to llvm)\llvm\utils\lit\lit.py -sv
+ --param=build_mode=Win32 --param=build_config=Debug
+ --param=clang_site_config=(build dir)\tools\clang\test\lit.site.cfg
+ (path to llvm)\llvm\tools\clang\test
</pre>
<p>For CMake builds e.g. on Windows with Visual Studio, you will need
to specify your build configuration (Debug, Release, etc.) via
- <tt>--param=build_config=(build config)</tt>.</p>
+ <tt>--param=build_config=(build config)</tt>. You may also need to specify
+ the build mode (Win32, etc) via <tt>--param=build_mode=(build mode)</tt>.</p>
+
+ <p>Additionally, you will need to specify the lit site configuration which
+ lives in (build dir)\tools\clang\test, via
+ <tt>--param=clang_site_config=(build dir)\tools\clang\test\lit.site.cfg</tt>.
+ </p>
<p>To run a single test:</p>
<pre>
- python (path to llvm)/llvm/utils/lit/lit.py -sv --no-progress-bar
- (path to llvm)/llvm/tools/clang/test/(dir)/(test)
+ python (path to llvm)\llvm\utils\lit\lit.py -sv
+ --param=build_mode=Win32 --param=build_config=Debug
+ --param=clang_site_config=(build dir)\tools\clang\test\lit.site.cfg
+ (path to llvm)\llvm\tools\clang\test\(dir)\(test)
</pre>
<p>For example:</p>
<pre>
- python C:/Tools/llvm/utils/lit/lit.py -sv --no-progress-bar
- C:/Tools/llvm/tools/clang/test/Sema/wchar.c
+ python C:\Tool\llvm\utils\lit\lit.py -sv
+ --param=build_mode=Win32 --param=build_config=Debug
+ --param=clang_site_config=c:\Tools\build\tools\clang\test\lit.site.cfg
+ C:\Tools\llvm\tools\clang\test\Sema\wchar.c
</pre>
<p>The -sv option above tells the runner to show the test output if
any tests failed, to help you determine the cause of failure.</p>
+ <p>You can also pass in the --no-progress-bar option if you wish to disable
+ progress indications while the tests are running.</p>
+
<p>Your output might look something like this:</p>
- <pre>lit.py: lit.cfg:152: note: using clang: 'C:/Tools/llvm/bin/Release\\clang.EXE'
+ <pre>lit.py: lit.cfg:152: note: using clang: 'C:\Tools\llvm\bin\Release\clang.EXE'
-- Testing: Testing: 2534 tests, 4 threads --
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
Testing Time: 81.52s
More information about the llvm-branch-commits
mailing list