aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
commitb3d5a323a5ca92ea73443499cee2f15db1ff0fb3 (patch)
tree60a1694bec5a44d15456acc880cb2f91619f66aa
parent8f57cb0305232cb53fff00ef151ca716766f3437 (diff)
downloadsrc-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.tar.gz
src-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.zip
Update clang to r89205.
Notes
Notes: svn path=/vendor/clang/dist/; revision=199482
-rw-r--r--CMakeLists.txt5
-rw-r--r--Makefile6
-rw-r--r--NOTES.txt2
-rw-r--r--TODO.txt9
-rw-r--r--clang.xcodeproj/project.pbxproj14
-rw-r--r--docs/UsersManual.html2
-rw-r--r--include/clang-c/Index.h353
-rw-r--r--include/clang/AST/ASTContext.h27
-rw-r--r--include/clang/AST/Attr.h2
-rw-r--r--include/clang/AST/CanonicalType.h17
-rw-r--r--include/clang/AST/Decl.h10
-rw-r--r--include/clang/AST/DeclBase.h11
-rw-r--r--include/clang/AST/DeclCXX.h364
-rw-r--r--include/clang/AST/DeclContextInternals.h3
-rw-r--r--include/clang/AST/DeclNodes.def4
-rw-r--r--include/clang/AST/DeclObjC.h32
-rw-r--r--include/clang/AST/DeclTemplate.h17
-rw-r--r--include/clang/AST/DeclarationName.h3
-rw-r--r--include/clang/AST/Expr.h11
-rw-r--r--include/clang/AST/ExprCXX.h2
-rw-r--r--include/clang/AST/RecordLayout.h2
-rw-r--r--include/clang/AST/Redeclarable.h3
-rw-r--r--include/clang/AST/TemplateBase.h100
-rw-r--r--include/clang/AST/Type.h327
-rw-r--r--include/clang/AST/TypeLoc.h12
-rw-r--r--include/clang/AST/TypeLocBuilder.h1
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h4
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowSolver.h1
-rw-r--r--include/clang/Analysis/LocalCheckers.h4
-rw-r--r--include/clang/Analysis/ManagerRegistry.h53
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h1
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisManager.h5
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h16
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h15
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h101
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.def15
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.h36
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h32
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h122
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h22
-rw-r--r--include/clang/Analysis/PathSensitive/GRWorkList.h7
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h2
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h4
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h6
-rw-r--r--include/clang/Analysis/ProgramPoint.h64
-rw-r--r--include/clang/Analysis/Support/Optional.h3
-rw-r--r--include/clang/Analysis/Support/SaveAndRestore.h3
-rw-r--r--include/clang/Basic/Diagnostic.h15
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td25
-rw-r--r--include/clang/Basic/DiagnosticGroups.td24
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td10
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td97
-rw-r--r--include/clang/Basic/LangOptions.h7
-rw-r--r--include/clang/Basic/Makefile4
-rw-r--r--include/clang/Basic/TargetInfo.h48
-rw-r--r--include/clang/Basic/TargetOptions.h39
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h75
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
-rw-r--r--include/clang/Driver/Driver.h2
-rw-r--r--include/clang/Driver/Options.def4
-rw-r--r--include/clang/Driver/ToolChain.h11
-rw-r--r--include/clang/Driver/Types.h3
-rw-r--r--include/clang/Frontend/ASTConsumers.h10
-rw-r--r--include/clang/Frontend/Analyses.def3
-rw-r--r--include/clang/Frontend/AnalysisConsumer.h41
-rw-r--r--include/clang/Frontend/ChainedDiagnosticClient.h58
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h3
-rw-r--r--include/clang/Frontend/CompilerInstance.h523
-rw-r--r--include/clang/Frontend/CompilerInvocation.h150
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h43
-rw-r--r--include/clang/Frontend/DiagnosticOptions.h30
-rw-r--r--include/clang/Frontend/FrontendAction.h215
-rw-r--r--include/clang/Frontend/FrontendActions.h216
-rw-r--r--include/clang/Frontend/FrontendOptions.h131
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h23
-rw-r--r--include/clang/Frontend/HeaderSearchOptions.h87
-rw-r--r--include/clang/Frontend/PCHReader.h44
-rw-r--r--include/clang/Frontend/PCHWriter.h3
-rw-r--r--include/clang/Frontend/PreprocessorOptions.h57
-rw-r--r--include/clang/Frontend/PreprocessorOutputOptions.h37
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h9
-rw-r--r--include/clang/Frontend/TypeXML.def6
-rw-r--r--include/clang/Frontend/Utils.h58
-rw-r--r--include/clang/Frontend/VerifyDiagnosticsClient.h82
-rw-r--r--include/clang/Lex/PTHManager.h3
-rw-r--r--include/clang/Lex/Preprocessor.h22
-rw-r--r--include/clang/Lex/Token.h63
-rw-r--r--include/clang/Parse/Action.h53
-rw-r--r--include/clang/Parse/AttributeList.h1
-rw-r--r--include/clang/Parse/DeclSpec.h11
-rw-r--r--include/clang/Parse/Ownership.h35
-rw-r--r--include/clang/Parse/Parser.h29
-rw-r--r--include/clang/Parse/Scope.h6
-rw-r--r--include/clang/Parse/Template.h183
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h146
-rw-r--r--include/clang/Sema/ParseAST.h8
-rw-r--r--lib/AST/ASTContext.cpp113
-rw-r--r--lib/AST/CMakeLists.txt1
-rw-r--r--lib/AST/CXXInheritance.cpp29
-rw-r--r--lib/AST/Decl.cpp6
-rw-r--r--lib/AST/DeclBase.cpp32
-rw-r--r--lib/AST/DeclCXX.cpp86
-rw-r--r--lib/AST/DeclObjC.cpp47
-rw-r--r--lib/AST/DeclPrinter.cpp54
-rw-r--r--lib/AST/DeclTemplate.cpp7
-rw-r--r--lib/AST/DeclarationName.cpp5
-rw-r--r--lib/AST/Expr.cpp19
-rw-r--r--lib/AST/ExprCXX.cpp8
-rw-r--r--lib/AST/ExprConstant.cpp29
-rw-r--r--lib/AST/NestedNameSpecifier.cpp2
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp3
-rw-r--r--lib/AST/StmtDumper.cpp7
-rw-r--r--lib/AST/StmtProfile.cpp4
-rw-r--r--lib/AST/TemplateBase.cpp14
-rw-r--r--lib/AST/Type.cpp710
-rw-r--r--lib/AST/TypePrinter.cpp728
-rw-r--r--lib/Analysis/AnalysisManager.cpp35
-rw-r--r--lib/Analysis/ArrayBoundChecker.cpp86
-rw-r--r--lib/Analysis/AttrNonNullChecker.cpp22
-rw-r--r--lib/Analysis/BadCallChecker.cpp25
-rw-r--r--lib/Analysis/BasicObjCFoundationChecks.cpp2
-rw-r--r--lib/Analysis/BasicStore.cpp19
-rw-r--r--lib/Analysis/CFRefCount.cpp585
-rw-r--r--lib/Analysis/CMakeLists.txt17
-rw-r--r--lib/Analysis/CallGraph.cpp2
-rw-r--r--lib/Analysis/CastToStructChecker.cpp77
-rw-r--r--lib/Analysis/CheckSecuritySyntaxOnly.cpp52
-rw-r--r--lib/Analysis/CheckSizeofPointer.cpp72
-rw-r--r--lib/Analysis/DereferenceChecker.cpp161
-rw-r--r--lib/Analysis/DivZeroChecker.cpp21
-rw-r--r--lib/Analysis/ExplodedGraph.cpp2
-rw-r--r--lib/Analysis/FixedAddressChecker.cpp70
-rw-r--r--lib/Analysis/GRCoreEngine.cpp49
-rw-r--r--lib/Analysis/GRExprEngine.cpp448
-rw-r--r--lib/Analysis/GRExprEngineExperimentalChecks.cpp38
-rw-r--r--lib/Analysis/GRExprEngineExperimentalChecks.h26
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp115
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.h39
-rw-r--r--lib/Analysis/GRState.cpp6
-rw-r--r--lib/Analysis/LiveVariables.cpp12
-rw-r--r--lib/Analysis/MallocChecker.cpp218
-rw-r--r--lib/Analysis/ManagerRegistry.cpp (renamed from lib/Frontend/ManagerRegistry.cpp)2
-rw-r--r--lib/Analysis/MemRegion.cpp20
-rw-r--r--lib/Analysis/NSErrorChecker.cpp13
-rw-r--r--lib/Analysis/PointerArithChecker.cpp71
-rw-r--r--lib/Analysis/PointerSubChecker.cpp77
-rw-r--r--lib/Analysis/PthreadLockChecker.cpp141
-rw-r--r--lib/Analysis/RangeConstraintManager.cpp2
-rw-r--r--lib/Analysis/RegionStore.cpp25
-rw-r--r--lib/Analysis/ReturnPointerRangeChecker.cpp97
-rw-r--r--lib/Analysis/ReturnStackAddressChecker.cpp97
-rw-r--r--lib/Analysis/ReturnUndefChecker.cpp68
-rw-r--r--lib/Analysis/SVals.cpp10
-rw-r--r--lib/Analysis/SValuator.cpp3
-rw-r--r--lib/Analysis/Store.cpp22
-rw-r--r--lib/Analysis/UndefinedArgChecker.cpp29
-rw-r--r--lib/Analysis/UndefinedArraySubscriptChecker.cpp56
-rw-r--r--lib/Analysis/UndefinedAssignmentChecker.cpp5
-rw-r--r--lib/Analysis/VLASizeChecker.cpp153
-rw-r--r--lib/Basic/SourceManager.cpp4
-rw-r--r--lib/Basic/TargetInfo.cpp39
-rw-r--r--lib/Basic/Targets.cpp352
-rw-r--r--lib/Basic/Version.cpp4
-rw-r--r--lib/CodeGen/CGBlocks.cpp69
-rw-r--r--lib/CodeGen/CGBlocks.h3
-rw-r--r--lib/CodeGen/CGBuiltin.cpp21
-rw-r--r--lib/CodeGen/CGCXX.cpp631
-rw-r--r--lib/CodeGen/CGCXXClass.cpp3
-rw-r--r--lib/CodeGen/CGCXXExpr.cpp264
-rw-r--r--lib/CodeGen/CGCall.cpp13
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp265
-rw-r--r--lib/CodeGen/CGDebugInfo.h6
-rw-r--r--lib/CodeGen/CGDecl.cpp6
-rw-r--r--lib/CodeGen/CGExpr.cpp205
-rw-r--r--lib/CodeGen/CGExprAgg.cpp1
-rw-r--r--lib/CodeGen/CGExprConstant.cpp28
-rw-r--r--lib/CodeGen/CGExprScalar.cpp121
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp6
-rw-r--r--lib/CodeGen/CGObjCMac.cpp83
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp6
-rw-r--r--lib/CodeGen/CGRtti.cpp396
-rw-r--r--lib/CodeGen/CGStmt.cpp25
-rw-r--r--lib/CodeGen/CGVtable.cpp579
-rw-r--r--lib/CodeGen/CGVtable.h11
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp127
-rw-r--r--lib/CodeGen/CodeGenFunction.h57
-rw-r--r--lib/CodeGen/CodeGenModule.cpp74
-rw-r--r--lib/CodeGen/CodeGenModule.h75
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp2
-rw-r--r--lib/CodeGen/CodeGenTypes.h4
-rw-r--r--lib/CodeGen/GlobalDecl.h110
-rw-r--r--lib/CodeGen/Mangle.cpp70
-rw-r--r--lib/CodeGen/Mangle.h5
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp14
-rw-r--r--lib/CodeGen/TargetABIInfo.cpp39
-rw-r--r--lib/Driver/ToolChains.h13
-rw-r--r--lib/Driver/Tools.cpp132
-rw-r--r--lib/Driver/Types.cpp13
-rw-r--r--lib/Frontend/ASTUnit.cpp16
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp283
-rw-r--r--lib/Frontend/Backend.cpp91
-rw-r--r--lib/Frontend/CMakeLists.txt7
-rw-r--r--lib/Frontend/CompilerInstance.cpp403
-rw-r--r--lib/Frontend/CompilerInvocation.cpp548
-rw-r--r--lib/Frontend/DependencyFile.cpp44
-rw-r--r--lib/Frontend/DocumentXML.cpp4
-rw-r--r--lib/Frontend/FrontendAction.cpp225
-rw-r--r--lib/Frontend/FrontendActions.cpp281
-rw-r--r--lib/Frontend/FrontendOptions.cpp31
-rw-r--r--lib/Frontend/HTMLDiagnostics.cpp2
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp289
-rw-r--r--lib/Frontend/InitPreprocessor.cpp117
-rw-r--r--lib/Frontend/PCHReader.cpp186
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp9
-rw-r--r--lib/Frontend/PCHWriter.cpp22
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp4
-rw-r--r--lib/Frontend/PlistDiagnostics.cpp10
-rw-r--r--lib/Frontend/PrintParserCallbacks.cpp3
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp26
-rw-r--r--lib/Frontend/RewriteObjC.cpp2
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp11
-rw-r--r--lib/Frontend/VerifyDiagnosticsClient.cpp344
-rw-r--r--lib/Frontend/Warnings.cpp18
-rw-r--r--lib/Headers/stdint.h615
-rw-r--r--lib/Index/ResolveLocation.cpp14
-rw-r--r--lib/Lex/Lexer.cpp8
-rw-r--r--lib/Lex/PPCaching.cpp2
-rw-r--r--lib/Lex/PPExpressions.cpp2
-rw-r--r--lib/Lex/PTHLexer.cpp40
-rw-r--r--lib/Lex/Preprocessor.cpp24
-rw-r--r--lib/Parse/AttributeList.cpp1
-rw-r--r--lib/Parse/DeclSpec.cpp10
-rw-r--r--lib/Parse/MinimalAction.cpp7
-rw-r--r--lib/Parse/ParseDecl.cpp1
-rw-r--r--lib/Parse/ParseDeclCXX.cpp17
-rw-r--r--lib/Parse/ParseExprCXX.cpp67
-rw-r--r--lib/Parse/ParseObjc.cpp51
-rw-r--r--lib/Parse/ParseTemplate.cpp163
-rw-r--r--lib/Parse/Parser.cpp1
-rw-r--r--lib/Rewrite/DeltaTree.cpp28
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp491
-rw-r--r--lib/Sema/JumpDiagnostics.cpp2
-rw-r--r--lib/Sema/Lookup.h392
-rw-r--r--lib/Sema/ParseAST.cpp17
-rw-r--r--lib/Sema/Sema.cpp338
-rw-r--r--lib/Sema/Sema.h507
-rw-r--r--lib/Sema/SemaAttr.cpp7
-rw-r--r--lib/Sema/SemaCXXCast.cpp150
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp29
-rw-r--r--lib/Sema/SemaChecking.cpp23
-rw-r--r--lib/Sema/SemaCodeComplete.cpp554
-rw-r--r--lib/Sema/SemaDecl.cpp249
-rw-r--r--lib/Sema/SemaDeclAttr.cpp44
-rw-r--r--lib/Sema/SemaDeclCXX.cpp745
-rw-r--r--lib/Sema/SemaDeclObjC.cpp81
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp4
-rw-r--r--lib/Sema/SemaExpr.cpp374
-rw-r--r--lib/Sema/SemaExprCXX.cpp182
-rw-r--r--lib/Sema/SemaInit.cpp3
-rw-r--r--lib/Sema/SemaLookup.cpp433
-rw-r--r--lib/Sema/SemaOverload.cpp199
-rw-r--r--lib/Sema/SemaOverload.h8
-rw-r--r--lib/Sema/SemaStmt.cpp10
-rw-r--r--lib/Sema/SemaTemplate.cpp961
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp198
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp294
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp199
-rw-r--r--lib/Sema/SemaType.cpp5
-rw-r--r--lib/Sema/TreeTransform.h44
-rw-r--r--test/Analysis/CFDateGC.m10
-rw-r--r--test/Analysis/CFNumber.c8
-rw-r--r--test/Analysis/CFRetainRelease_NSAssertionHandler.m8
-rw-r--r--test/Analysis/CGColorSpace.c8
-rw-r--r--test/Analysis/CheckNSError.m8
-rw-r--r--test/Analysis/MissingDealloc.m2
-rw-r--r--test/Analysis/NSPanel.m8
-rw-r--r--test/Analysis/NSString.m19
-rw-r--r--test/Analysis/NSWindow.m8
-rw-r--r--test/Analysis/NoReturn.m8
-rw-r--r--test/Analysis/ObjCProperties.m8
-rw-r--r--test/Analysis/ObjCRetSigs.m4
-rw-r--r--test/Analysis/PR2599.m8
-rw-r--r--test/Analysis/PR2978.m2
-rw-r--r--test/Analysis/PR3991.m19
-rw-r--r--test/Analysis/array-struct.c12
-rw-r--r--test/Analysis/casts.c2
-rw-r--r--test/Analysis/casts.m4
-rw-r--r--test/Analysis/cfref_PR2519.c8
-rw-r--r--test/Analysis/cfref_rdar6080742.c8
-rw-r--r--test/Analysis/complex.c8
-rw-r--r--test/Analysis/concrete-address.c4
-rw-r--r--test/Analysis/conditional-op-missing-lhs.c2
-rw-r--r--test/Analysis/dead-stores.c10
-rw-r--r--test/Analysis/dead-stores.cpp10
-rw-r--r--test/Analysis/dead-stores.m2
-rw-r--r--test/Analysis/delegates.m4
-rw-r--r--test/Analysis/elementtype.c2
-rw-r--r--test/Analysis/exercise-ps.c4
-rw-r--r--test/Analysis/fields.c4
-rw-r--r--test/Analysis/func.c4
-rw-r--r--test/Analysis/malloc.c37
-rw-r--r--test/Analysis/misc-ps-64.m8
-rw-r--r--test/Analysis/misc-ps-basic-store.m2
-rw-r--r--test/Analysis/misc-ps-eager-assume.m2
-rw-r--r--test/Analysis/misc-ps-ranges.m6
-rw-r--r--test/Analysis/misc-ps-region-store-i386.m2
-rw-r--r--test/Analysis/misc-ps-region-store-x86_64.m2
-rw-r--r--test/Analysis/misc-ps-region-store.m45
-rw-r--r--test/Analysis/misc-ps.m38
-rw-r--r--test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m4
-rw-r--r--test/Analysis/no-exit-cfg.c4
-rw-r--r--test/Analysis/no-outofbounds.c5
-rw-r--r--test/Analysis/null-deref-ps-region.c2
-rw-r--r--test/Analysis/null-deref-ps.c8
-rw-r--r--test/Analysis/outofbound.c5
-rw-r--r--test/Analysis/override-werror.c4
-rw-r--r--test/Analysis/plist-output.m122
-rw-r--r--test/Analysis/pr4209.m14
-rw-r--r--test/Analysis/pr_2542_rdar_6793404.m4
-rw-r--r--test/Analysis/pr_4164.c4
-rw-r--r--test/Analysis/ptr-arith.c33
-rw-r--r--test/Analysis/rdar-6442306-1.m4
-rw-r--r--test/Analysis/rdar-6540084.m2
-rw-r--r--test/Analysis/rdar-6541136-region.c17
-rw-r--r--test/Analysis/rdar-6541136.c2
-rw-r--r--test/Analysis/rdar-6562655.m4
-rw-r--r--test/Analysis/rdar-6582778-basic-store.c2
-rw-r--r--test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m4
-rw-r--r--test/Analysis/rdar-7168531.m4
-rw-r--r--test/Analysis/refcnt_naming.m4
-rw-r--r--test/Analysis/region-1.m5
-rw-r--r--test/Analysis/retain-release-gc-only.m4
-rw-r--r--test/Analysis/retain-release.m2
-rw-r--r--test/Analysis/security-syntax-checks.m7
-rw-r--r--test/Analysis/sizeofpointer.c8
-rw-r--r--test/Analysis/stack-addr-ps.c4
-rw-r--r--test/Analysis/uninit-msg-expr.m2
-rw-r--r--test/Analysis/uninit-ps-rdar6145427.m2
-rw-r--r--test/Analysis/uninit-vals-ps.c2
-rw-r--r--test/Analysis/uninit-vals.m2
-rw-r--r--test/Analysis/unused-ivars.m2
-rw-r--r--test/CMakeLists.txt44
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.udir/p1.cpp35
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp24
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp67
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp141
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp44
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp2
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p3.cpp2
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp4
-rw-r--r--test/CXX/expr/expr.unary/expr.delete/p5.cpp34
-rw-r--r--test/CXX/special/class.free/p1.cpp11
-rw-r--r--test/CXX/special/class.free/p6.cpp11
-rw-r--r--test/CXX/temp/temp.param/p1.cpp2
-rw-r--r--test/CXX/temp/temp.param/p12.cpp4
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp2
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp5
-rw-r--r--test/CodeCompletion/call.cpp5
-rw-r--r--test/CodeCompletion/enum-switch-case-qualified.cpp3
-rw-r--r--test/CodeCompletion/enum-switch-case.c3
-rw-r--r--test/CodeCompletion/enum-switch-case.cpp3
-rw-r--r--test/CodeCompletion/function-templates.cpp3
-rw-r--r--test/CodeCompletion/functions.cpp3
-rw-r--r--test/CodeCompletion/macros.c5
-rw-r--r--test/CodeCompletion/member-access.c3
-rw-r--r--test/CodeCompletion/member-access.cpp3
-rw-r--r--test/CodeCompletion/namespace-alias.cpp3
-rw-r--r--test/CodeCompletion/namespace.cpp3
-rw-r--r--test/CodeCompletion/nested-name-specifier.cpp3
-rw-r--r--test/CodeCompletion/objc-message.m35
-rw-r--r--test/CodeCompletion/operator.cpp3
-rw-r--r--test/CodeCompletion/ordinary-name.c3
-rw-r--r--test/CodeCompletion/property.m2
-rw-r--r--test/CodeCompletion/tag.c3
-rw-r--r--test/CodeCompletion/tag.cpp3
-rw-r--r--test/CodeCompletion/templates.cpp3
-rw-r--r--test/CodeCompletion/truncation.c5
-rw-r--r--test/CodeCompletion/using-namespace.cpp3
-rw-r--r--test/CodeCompletion/using.cpp3
-rw-r--r--test/CodeGen/2008-07-17-no-emit-on-error.c4
-rw-r--r--test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c2
-rw-r--r--test/CodeGen/2008-07-29-override-alias-decl.c18
-rw-r--r--test/CodeGen/2008-07-30-implicit-initialization.c4
-rw-r--r--test/CodeGen/2008-07-31-asm-labels.c14
-rw-r--r--test/CodeGen/2009-10-20-GlobalDebug.c2
-rw-r--r--test/CodeGen/PR2001-bitfield-reload.c4
-rw-r--r--test/CodeGen/PR3589-freestanding-libcalls.c6
-rw-r--r--test/CodeGen/PR3613-static-decl.c2
-rw-r--r--test/CodeGen/PR4611-bitfield-layout.c2
-rw-r--r--test/CodeGen/address-space-field1.c33
-rw-r--r--test/CodeGen/address-space.c8
-rw-r--r--test/CodeGen/alias.c12
-rw-r--r--test/CodeGen/alignof.c2
-rw-r--r--test/CodeGen/always_inline.c8
-rw-r--r--test/CodeGen/arm-arguments.c2
-rw-r--r--test/CodeGen/asm-2.c2
-rw-r--r--test/CodeGen/asm-inout.c2
-rw-r--r--test/CodeGen/asm.c6
-rw-r--r--test/CodeGen/atomic.c22
-rw-r--r--test/CodeGen/attr-nodebug.c2
-rw-r--r--test/CodeGen/attr-noinline.c2
-rw-r--r--test/CodeGen/attr-used.c6
-rw-r--r--test/CodeGen/attributes.c5
-rw-r--r--test/CodeGen/bitfield-assign.c10
-rw-r--r--test/CodeGen/bitfield-promote.c7
-rw-r--r--test/CodeGen/bitfield.c4
-rw-r--r--test/CodeGen/blocks-1.c16
-rw-r--r--test/CodeGen/blocks-2.c6
-rw-r--r--test/CodeGen/blocks-aligned-byref-variable.c2
-rw-r--r--test/CodeGen/blocks-seq.c12
-rw-r--r--test/CodeGen/blocks.c5
-rw-r--r--test/CodeGen/builtin-count-zeros.c2
-rw-r--r--test/CodeGen/builtin-memfns.c8
-rw-r--r--test/CodeGen/builtin-nanf.c2
-rw-r--r--test/CodeGen/builtin-stackaddress.c2
-rw-r--r--test/CodeGen/builtins-ffs_parity_popcount.c2
-rw-r--r--test/CodeGen/builtins-powi.c2
-rw-r--r--test/CodeGen/builtins-x86.c2
-rw-r--r--test/CodeGen/builtins.c4
-rw-r--r--test/CodeGen/c-strings.c8
-rw-r--r--test/CodeGen/cleanup-stack.c2
-rw-r--r--test/CodeGen/compound-type.c4
-rw-r--r--test/CodeGen/conditional.c8
-rw-r--r--test/CodeGen/const-init.c12
-rw-r--r--test/CodeGen/constant-comparison.c2
-rw-r--r--test/CodeGen/constructor-attribute.c10
-rw-r--r--test/CodeGen/darwin-string-literals.c2
-rw-r--r--test/CodeGen/debug-info.c2
-rw-r--r--test/CodeGen/designated-initializers.c4
-rw-r--r--test/CodeGen/dllimport-dllexport.c4
-rw-r--r--test/CodeGen/emit-all-decls.c6
-rw-r--r--test/CodeGen/ext-vector-shuffle.c4
-rw-r--r--test/CodeGen/flexible-array-init.c6
-rw-r--r--test/CodeGen/functions.c8
-rw-r--r--test/CodeGen/global-decls.c13
-rw-r--r--test/CodeGen/init.c4
-rw-r--r--test/CodeGen/inline.c74
-rw-r--r--test/CodeGen/inline2.c2
-rw-r--r--test/CodeGen/libcalls.c10
-rw-r--r--test/CodeGen/lineno-dbginfo.c6
-rw-r--r--test/CodeGen/mandel.c2
-rw-r--r--test/CodeGen/no-common.c6
-rw-r--r--test/CodeGen/object-size.c24
-rw-r--r--test/CodeGen/packed-union.c4
-rw-r--r--test/CodeGen/parameter-passing.c13
-rw-r--r--test/CodeGen/pragma-pack-2.c2
-rw-r--r--test/CodeGen/pragma-pack-3.c2
-rw-r--r--test/CodeGen/predefined-expr.c2
-rw-r--r--test/CodeGen/private-extern.c4
-rw-r--r--test/CodeGen/rdr-6098585-default-after-caserange.c4
-rw-r--r--test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c2
-rw-r--r--test/CodeGen/rdr-6098585-empty-case-range.c4
-rw-r--r--test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c2
-rw-r--r--test/CodeGen/rdr-6098585-unsigned-caserange.c4
-rw-r--r--test/CodeGen/stack-protector.c19
-rw-r--r--test/CodeGen/staticinit.c4
-rw-r--r--test/CodeGen/stdcall-fastcall.c2
-rw-r--r--test/CodeGen/string-init.c6
-rw-r--r--test/CodeGen/struct-passing.c15
-rw-r--r--test/CodeGen/struct-x86-darwin.c18
-rw-r--r--test/CodeGen/target-data.c13
-rw-r--r--test/CodeGen/tentative-decls.c15
-rw-r--r--test/CodeGen/trapv.c2
-rw-r--r--test/CodeGen/unreachable.c2
-rw-r--r--test/CodeGen/unwind-attr.c2
-rw-r--r--test/CodeGen/visibility.c49
-rw-r--r--test/CodeGen/volatile-1.c6
-rw-r--r--test/CodeGen/volatile.c4
-rw-r--r--test/CodeGen/x86.c16
-rw-r--r--test/CodeGen/x86_32-arguments.c111
-rw-r--r--test/CodeGen/x86_64-arguments.c51
-rw-r--r--test/CodeGenCXX/PR5050-constructor-conversion.cpp9
-rw-r--r--test/CodeGenCXX/array-construction.cpp9
-rw-r--r--test/CodeGenCXX/array-operator-delete-call.cpp63
-rw-r--r--test/CodeGenCXX/array-value-initialize.cpp28
-rw-r--r--test/CodeGenCXX/assign-operator.cpp9
-rw-r--r--test/CodeGenCXX/attr.cpp2
-rw-r--r--test/CodeGenCXX/call-arg-zero-temp.cpp9
-rw-r--r--test/CodeGenCXX/cast-conversion.cpp9
-rw-r--r--test/CodeGenCXX/class-layout.cpp2
-rw-r--r--test/CodeGenCXX/constructor-conversion.cpp9
-rw-r--r--test/CodeGenCXX/constructor-default-arg.cpp9
-rw-r--r--test/CodeGenCXX/constructor-for-array-members.cpp9
-rw-r--r--test/CodeGenCXX/constructor-template.cpp9
-rw-r--r--test/CodeGenCXX/conversion-function.cpp9
-rw-r--r--test/CodeGenCXX/convert-to-fptr.cpp9
-rw-r--r--test/CodeGenCXX/copy-assign-synthesis-1.cpp9
-rw-r--r--test/CodeGenCXX/copy-assign-synthesis.cpp2
-rw-r--r--test/CodeGenCXX/copy-constructor-elim.cpp7
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis.cpp11
-rw-r--r--test/CodeGenCXX/debug-info.cpp13
-rw-r--r--test/CodeGenCXX/decl-ref-init.cpp9
-rw-r--r--test/CodeGenCXX/default-arg-temps.cpp6
-rw-r--r--test/CodeGenCXX/default-arguments.cpp13
-rw-r--r--test/CodeGenCXX/default-constructor-default-argument.cpp8
-rw-r--r--test/CodeGenCXX/default-constructor-for-members.cpp9
-rw-r--r--test/CodeGenCXX/default-destructor-synthesis.cpp9
-rw-r--r--test/CodeGenCXX/delete-two-arg.cpp6
-rw-r--r--test/CodeGenCXX/delete.cpp2
-rw-r--r--test/CodeGenCXX/derived-to-base-conv.cpp9
-rw-r--r--test/CodeGenCXX/destructors.cpp14
-rw-r--r--test/CodeGenCXX/dyncast.cpp414
-rw-r--r--test/CodeGenCXX/empty-union.cpp10
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp2
-rw-r--r--test/CodeGenCXX/extern-c.cpp6
-rw-r--r--test/CodeGenCXX/global-array-destruction.cpp33
-rw-r--r--test/CodeGenCXX/implicit-instantiation-1.cpp11
-rw-r--r--test/CodeGenCXX/init-incomplete-type.cpp12
-rw-r--r--test/CodeGenCXX/instantiate-init-list.cpp13
-rw-r--r--test/CodeGenCXX/mangle-subst.cpp8
-rw-r--r--test/CodeGenCXX/mangle-system-header.cpp7
-rw-r--r--test/CodeGenCXX/mangle.cpp6
-rw-r--r--test/CodeGenCXX/member-expressions.cpp19
-rw-r--r--test/CodeGenCXX/member-function-pointers.cpp6
-rw-r--r--test/CodeGenCXX/member-functions.cpp20
-rw-r--r--test/CodeGenCXX/member-init-struct.cpp18
-rw-r--r--test/CodeGenCXX/member-init-union.cpp10
-rw-r--r--test/CodeGenCXX/member-pointers-zero-init.cpp16
-rw-r--r--test/CodeGenCXX/new-operator-phi.cpp11
-rw-r--r--test/CodeGenCXX/new.cpp3
-rw-r--r--test/CodeGenCXX/ptr-to-member-function.cpp9
-rw-r--r--test/CodeGenCXX/reinterpret-cast.cpp5
-rw-r--r--test/CodeGenCXX/rtti.cpp207
-rw-r--r--test/CodeGenCXX/static-init-1.cpp23
-rw-r--r--test/CodeGenCXX/static-init-2.cpp6
-rw-r--r--test/CodeGenCXX/static-init.cpp4
-rw-r--r--test/CodeGenCXX/temporaries.cpp87
-rw-r--r--test/CodeGenCXX/trivial-constructor-init.cpp5
-rw-r--r--test/CodeGenCXX/typeinfo16
-rw-r--r--test/CodeGenCXX/vararg-conversion-ctor.cpp23
-rw-r--r--test/CodeGenCXX/virt-dtor-gen.cpp10
-rw-r--r--test/CodeGenCXX/virt.cpp675
-rw-r--r--test/CodeGenCXX/virtual-operator-call.cpp10
-rw-r--r--test/CodeGenCXX/virtual-pseudo-destructor-call.cpp10
-rw-r--r--test/CodeGenCXX/x86_64-arguments.cpp7
-rw-r--r--test/CodeGenObjC/bitfield-1.m4
-rw-r--r--test/CodeGenObjC/bitfield-ivar-metadata.m2
-rw-r--r--test/CodeGenObjC/bitfield-ivar-offsets.m19
-rw-r--r--test/CodeGenObjC/blocks-1.m18
-rw-r--r--test/CodeGenObjC/blocks-2.m5
-rw-r--r--test/CodeGenObjC/blocks-3.m4
-rw-r--r--test/CodeGenObjC/blocks.m5
-rw-r--r--test/CodeGenObjC/category-super-class-meth.m2
-rw-r--r--test/CodeGenObjC/class-getter-dotsyntax.m2
-rw-r--r--test/CodeGenObjC/class-type.m4
-rw-r--r--test/CodeGenObjC/constant-strings.m4
-rw-r--r--test/CodeGenObjC/continuation-class.m2
-rw-r--r--test/CodeGenObjC/deadcode_strip_used_var.m6
-rw-r--r--test/CodeGenObjC/debug-info-linkagename.m2
-rw-r--r--test/CodeGenObjC/dot-syntax-1.m4
-rw-r--r--test/CodeGenObjC/dot-syntax.m4
-rw-r--r--test/CodeGenObjC/encode-test-1.m4
-rw-r--r--test/CodeGenObjC/encode-test-2.m10
-rw-r--r--test/CodeGenObjC/encode-test-3.m4
-rw-r--r--test/CodeGenObjC/encode-test-5.m10
-rw-r--r--test/CodeGenObjC/encode-test.m12
-rw-r--r--test/CodeGenObjC/forward-class-impl-metadata.m2
-rw-r--r--test/CodeGenObjC/hidden-visibility.m25
-rw-r--r--test/CodeGenObjC/hidden.m2
-rw-r--r--test/CodeGenObjC/image-info.m2
-rw-r--r--test/CodeGenObjC/implicit-objc_msgSend.m2
-rw-r--r--test/CodeGenObjC/interface-layout-64.m45
-rw-r--r--test/CodeGenObjC/interface.m2
-rw-r--r--test/CodeGenObjC/ivar-layout-64.m11
-rw-r--r--test/CodeGenObjC/ivar-layout-no-optimize.m5
-rw-r--r--test/CodeGenObjC/ivars.m2
-rw-r--r--test/CodeGenObjC/link-errors.m10
-rw-r--r--test/CodeGenObjC/message-arrays.m2
-rw-r--r--test/CodeGenObjC/messages-2.m4
-rw-r--r--test/CodeGenObjC/messages.m13
-rw-r--r--test/CodeGenObjC/metadata-symbols-32.m51
-rw-r--r--test/CodeGenObjC/metadata-symbols-64.m69
-rw-r--r--test/CodeGenObjC/metadata_symbols.m45
-rw-r--r--test/CodeGenObjC/missing-atend-metadata.m24
-rw-r--r--test/CodeGenObjC/newproperty-nested-synthesis-1.m2
-rw-r--r--test/CodeGenObjC/non-lazy-classes.m7
-rw-r--r--test/CodeGenObjC/objc-align.m21
-rw-r--r--test/CodeGenObjC/objc-assign-ivar.m5
-rw-r--r--test/CodeGenObjC/objc-gc-aggr-assign.m2
-rw-r--r--test/CodeGenObjC/objc-read-weak-byref.m9
-rw-r--r--test/CodeGenObjC/objc2-assign-global.m5
-rw-r--r--test/CodeGenObjC/objc2-ivar-assign.m5
-rw-r--r--test/CodeGenObjC/objc2-new-gc-api-strongcast.m5
-rw-r--r--test/CodeGenObjC/objc2-no-write-barrier.m2
-rw-r--r--test/CodeGenObjC/objc2-property-encode.m2
-rw-r--r--test/CodeGenObjC/objc2-protocol-enc.m8
-rw-r--r--test/CodeGenObjC/objc2-strong-cast.m2
-rw-r--r--test/CodeGenObjC/objc2-weak-assign.m2
-rw-r--r--test/CodeGenObjC/objc2-weak-compare.m2
-rw-r--r--test/CodeGenObjC/objc2-weak-import-attribute.m34
-rw-r--r--test/CodeGenObjC/objc2-weak-ivar-debug.m2
-rw-r--r--test/CodeGenObjC/objc2-write-barrier-2.m9
-rw-r--r--test/CodeGenObjC/objc2-write-barrier-3.m7
-rw-r--r--test/CodeGenObjC/objc2-write-barrier-4.m7
-rw-r--r--test/CodeGenObjC/objc2-write-barrier-5.m7
-rw-r--r--test/CodeGenObjC/objc2-write-barrier.m7
-rw-r--r--test/CodeGenObjC/object-incr-decr-1.m2
-rw-r--r--test/CodeGenObjC/overloadable.m4
-rw-r--r--test/CodeGenObjC/property-aggr-type.m2
-rw-r--r--test/CodeGenObjC/property-agrr-getter.m2
-rw-r--r--test/CodeGenObjC/property-complex.m2
-rw-r--r--test/CodeGenObjC/property-getter-dot-syntax.m2
-rw-r--r--test/CodeGenObjC/property-incr-decr-1.m2
-rw-r--r--test/CodeGenObjC/property-setter-attr.m2
-rw-r--r--test/CodeGenObjC/property.m4
-rw-r--r--test/CodeGenObjC/protocol-in-extended-class.m9
-rw-r--r--test/CodeGenObjC/protocol-property-synth.m2
-rw-r--r--test/CodeGenObjC/protocols-lazy.m27
-rw-r--r--test/CodeGenObjC/protocols.m2
-rw-r--r--test/CodeGenObjC/runtime-fns.m6
-rw-r--r--test/CodeGenObjC/super-classmethod-category.m2
-rw-r--r--test/CodeGenObjC/super-message-fragileabi.m32
-rw-r--r--test/CodeGenObjC/synchronized.m4
-rw-r--r--test/CodeGenObjC/synthesize_ivar-cont-class.m2
-rw-r--r--test/CodeGenObjC/synthesize_ivar.m2
-rw-r--r--test/CodeGenObjC/try.m2
-rw-r--r--test/CodeGenObjC/unname-bf-metadata.m2
-rw-r--r--test/CodeGenObjC/variadic-sends.m4
-rw-r--r--test/Coverage/ast-printing.c6
-rw-r--r--test/Coverage/ast-printing.cpp4
-rw-r--r--test/Coverage/ast-printing.m4
-rw-r--r--test/Coverage/codegen-next.m4
-rw-r--r--test/Coverage/codegen.c8
-rw-r--r--test/Coverage/html-diagnostics.c4
-rw-r--r--test/Coverage/parse-callbacks.c2
-rw-r--r--test/Coverage/parse-callbacks.m2
-rw-r--r--test/Coverage/targets.c39
-rw-r--r--test/Driver/Xarch.c17
-rw-r--r--test/Driver/analyze.c2
-rw-r--r--test/Driver/arm-darwin-builtin.c4
-rw-r--r--test/Driver/ast.c12
-rw-r--r--test/Driver/bindings.c97
-rw-r--r--test/Driver/clang-translation.c31
-rw-r--r--test/Driver/clang_cpp.c2
-rw-r--r--test/Driver/clang_f_opts.c21
-rw-r--r--test/Driver/cxx-pth.cpp8
-rw-r--r--test/Driver/darwin-as.c6
-rw-r--r--test/Driver/darwin-cc.c7
-rw-r--r--test/Driver/darwin-ld.c49
-rw-r--r--test/Driver/default-toolchain.c10
-rw-r--r--test/Driver/dragonfly.c2
-rw-r--r--test/Driver/emit-llvm.c2
-rw-r--r--test/Driver/flags.c10
-rw-r--r--test/Driver/freebsd.c4
-rw-r--r--test/Driver/hello.c6
-rw-r--r--test/Driver/immediate-options.c9
-rw-r--r--test/Driver/lto.c31
-rw-r--r--test/Driver/openbsd.c2
-rw-r--r--test/Driver/parsing.c35
-rw-r--r--test/Driver/phases.c25
-rw-r--r--test/Driver/preprocessor.c2
-rw-r--r--test/Driver/pth.c8
-rw-r--r--test/Driver/redzone.c6
-rw-r--r--test/Driver/std.c4
-rw-r--r--test/Driver/unknown-gcc-arch.c14
-rw-r--r--test/Driver/x86_features.c2
-rw-r--r--test/FixIt/fixit-at.c2
-rw-r--r--test/FixIt/fixit-c90.c2
-rw-r--r--test/FixIt/fixit-errors-1.c2
-rw-r--r--test/FixIt/fixit-errors.c12
-rw-r--r--test/FixIt/fixit-objc.m32
-rw-r--r--test/FixIt/fixit-pmem.cpp2
-rw-r--r--test/FixIt/fixit.c14
-rw-r--r--test/FixIt/fixit.cpp11
-rw-r--r--test/Frontend/ast-codegen.c2
-rw-r--r--test/Frontend/ast-main.c6
-rw-r--r--test/Frontend/cpp-output.c13
-rw-r--r--test/Frontend/darwin-version.c45
-rw-r--r--test/Frontend/dependency-gen.c10
-rw-r--r--test/Frontend/rewrite-macros.c11
-rw-r--r--test/Frontend/stdin.c2
-rw-r--r--test/Index/Inputs/c-index-pch.h7
-rw-r--r--test/Index/Inputs/foo.h8
-rw-r--r--test/Index/Inputs/lit.local.cfg1
-rw-r--r--test/Index/Inputs/objc.h11
-rw-r--r--test/Index/Inputs/t1.c28
-rw-r--r--test/Index/Inputs/t1.m20
-rw-r--r--test/Index/Inputs/t2.c11
-rw-r--r--test/Index/Inputs/t2.m13
-rw-r--r--test/Index/TestClassDecl.m52
-rw-r--r--test/Index/TestClassForwardDecl.m46
-rw-r--r--test/Index/c-index-api-loadTU-test.m224
-rw-r--r--test/Index/c-index-api-test.m2
-rw-r--r--test/Index/c-index-getCursor-test.m160
-rw-r--r--test/Index/c-index-pch.c8
-rw-r--r--test/Index/code-completion.cpp53
-rw-r--r--test/Index/comments.c18
-rw-r--r--test/Index/complete-member-access.m30
-rw-r--r--test/Index/complete-objc-message.m107
-rw-r--r--test/Index/complete-protocols.m25
-rw-r--r--test/Index/find-decls.c34
-rw-r--r--test/Index/find-defs.c26
-rw-r--r--test/Index/find-refs.c80
-rw-r--r--test/Index/multiple-redecls.c4
-rw-r--r--test/Index/objc-decls.m24
-rw-r--r--test/Index/objc-message.m60
-rw-r--r--test/Index/resolve-loc.c32
-rw-r--r--test/Lexer/block_cmt_end.c8
-rw-r--r--test/Lexer/counter.c8
-rw-r--r--test/Lexer/digraph.c2
-rw-r--r--test/Lexer/dollar-idents.c6
-rw-r--r--test/Lexer/escape_newline.c4
-rw-r--r--test/Lexer/rdr-6096838.c2
-rw-r--r--test/Lexer/token-concat.c2
-rw-r--r--test/Misc/caret-diags-macros.c14
-rw-r--r--test/Misc/diag-mapping.c16
-rw-r--r--test/Misc/diag-mapping2.c12
-rw-r--r--test/Misc/message-length.c2
-rw-r--r--test/PCH/asm.c4
-rw-r--r--test/PCH/attrs.c4
-rw-r--r--test/PCH/blocks.c4
-rw-r--r--test/PCH/builtins.c4
-rw-r--r--test/PCH/enum.c4
-rw-r--r--test/PCH/exprs.c4
-rw-r--r--test/PCH/ext_vector.c4
-rw-r--r--test/PCH/external-defs.c14
-rw-r--r--test/PCH/functions.c4
-rw-r--r--test/PCH/fuzzy-pch.c6
-rw-r--r--test/PCH/line-directive.c4
-rw-r--r--test/PCH/method_pool.m4
-rw-r--r--test/PCH/multiple_decls.c4
-rw-r--r--test/PCH/nonvisible-external-defs.c4
-rw-r--r--test/PCH/objc_exprs.m4
-rw-r--r--test/PCH/objc_import.m4
-rw-r--r--test/PCH/objc_methods.m4
-rw-r--r--test/PCH/objc_property.m4
-rw-r--r--test/PCH/pr4489.c4
-rw-r--r--test/PCH/preprocess.c11
-rw-r--r--test/PCH/reloc.c4
-rw-r--r--test/PCH/stmts.c4
-rw-r--r--test/PCH/struct.c4
-rw-r--r--test/PCH/tentative-defs.c6
-rw-r--r--test/PCH/types.c4
-rw-r--r--test/PCH/va_arg.c4
-rw-r--r--test/PCH/variables.c4
-rwxr-xr-xtest/Parser/2008-10-31-parse-noop-failure.c2
-rw-r--r--test/Parser/block-block-storageclass.c2
-rw-r--r--test/Parser/control-scope.c2
-rw-r--r--test/Parser/cxx-using-declaration.cpp4
-rw-r--r--test/Parser/objc-init.m18
-rw-r--r--test/Parser/objc-try-catch-1.m2
-rw-r--r--test/Preprocessor/_Pragma-dependency.c2
-rw-r--r--test/Preprocessor/_Pragma-physloc.c2
-rw-r--r--test/Preprocessor/assembler-with-cpp.c5
-rw-r--r--test/Preprocessor/builtin_line.c2
-rw-r--r--test/Preprocessor/comment_save_macro.c4
-rw-r--r--test/Preprocessor/cxx_and.cpp6
-rw-r--r--test/Preprocessor/cxx_bitand.cpp4
-rw-r--r--test/Preprocessor/cxx_bitor.cpp8
-rw-r--r--test/Preprocessor/cxx_compl.cpp4
-rw-r--r--test/Preprocessor/cxx_not.cpp2
-rw-r--r--test/Preprocessor/cxx_not_eq.cpp4
-rw-r--r--test/Preprocessor/cxx_oper_keyword.cpp2
-rw-r--r--test/Preprocessor/cxx_or.cpp6
-rw-r--r--test/Preprocessor/cxx_true.cpp4
-rw-r--r--test/Preprocessor/cxx_xor.cpp8
-rw-r--r--test/Preprocessor/dependencies-and-pp.c8
-rw-r--r--test/Preprocessor/dump-options.c2
-rw-r--r--test/Preprocessor/dump_macros.c16
-rw-r--r--test/Preprocessor/expr_comma.c2
-rw-r--r--test/Preprocessor/expr_invalid_tok.c4
-rw-r--r--test/Preprocessor/expr_liveness.c2
-rw-r--r--test/Preprocessor/feature_tests.c2
-rw-r--r--test/Preprocessor/hash_line.c4
-rw-r--r--test/Preprocessor/header_lookup1.c2
-rw-r--r--test/Preprocessor/if_warning.c2
-rw-r--r--test/Preprocessor/include-pth.c2
-rw-r--r--test/Preprocessor/init.c83
-rw-r--r--test/Preprocessor/line-directive.c4
-rw-r--r--test/Preprocessor/macro-multiline.c6
-rw-r--r--test/Preprocessor/macro_disable.c2
-rw-r--r--test/Preprocessor/macro_expand.c4
-rw-r--r--test/Preprocessor/macro_fn_comma_swallow.c6
-rw-r--r--test/Preprocessor/macro_fn_disable_expand.c2
-rw-r--r--test/Preprocessor/macro_fn_lparen_scan.c6
-rw-r--r--test/Preprocessor/macro_fn_preexpand.c2
-rw-r--r--test/Preprocessor/macro_fn_varargs_iso.c4
-rw-r--r--test/Preprocessor/macro_fn_varargs_named.c4
-rw-r--r--test/Preprocessor/macro_paste_c_block_comment.c4
-rw-r--r--test/Preprocessor/macro_paste_commaext.c8
-rw-r--r--test/Preprocessor/macro_paste_empty.c4
-rw-r--r--test/Preprocessor/macro_paste_hard.c4
-rw-r--r--test/Preprocessor/macro_rescan.c2
-rw-r--r--test/Preprocessor/macro_rescan2.c2
-rw-r--r--test/Preprocessor/objc-pp.m2
-rw-r--r--test/Preprocessor/optimize.c4
-rw-r--r--test/Preprocessor/pic.c19
-rw-r--r--test/Preprocessor/pragma_unknown.c2
-rw-r--r--test/Preprocessor/print_line_track.c8
-rw-r--r--test/Preprocessor/stdint.c593
-rw-r--r--test/Preprocessor/x86_target_features.c55
-rw-r--r--test/Rewriter/objc-ivar-receiver-1.m2
-rw-r--r--test/Sema/128bitint.c5
-rw-r--r--test/Sema/PR2727.c2
-rw-r--r--test/Sema/PR2728.c2
-rw-r--r--test/Sema/attr-format_arg.c2
-rw-r--r--test/Sema/attr-malloc.c6
-rw-r--r--test/Sema/block-byref-args.c2
-rw-r--r--test/Sema/block-storageclass.c2
-rw-r--r--test/Sema/builtin-object-size.c2
-rw-r--r--test/Sema/callingconv.c4
-rw-r--r--test/Sema/check-increment.c2
-rw-r--r--test/Sema/compare.c207
-rw-r--r--test/Sema/conditional-expr.c2
-rw-r--r--test/Sema/const-eval.c7
-rw-r--r--test/Sema/conversion-64-32.c5
-rw-r--r--test/Sema/conversion.c237
-rw-r--r--test/Sema/expr-comma-c89.c1
-rw-r--r--test/Sema/expr-comma.c1
-rw-r--r--test/Sema/format-attr-pr4470.c2
-rw-r--r--test/Sema/format-strings.c19
-rw-r--r--test/Sema/i-c-e.c2
-rw-r--r--test/Sema/implicit-builtin-redecl.c2
-rw-r--r--test/Sema/implicit-def.c2
-rw-r--r--test/Sema/parentheses.c2
-rw-r--r--test/Sema/pointer-conversion.c10
-rw-r--r--test/Sema/pragma-pack-4.c2
-rw-r--r--test/Sema/return.c2
-rw-r--r--test/Sema/shift.c2
-rw-r--r--test/Sema/ucn-cstring.c2
-rw-r--r--test/Sema/varargs.c2
-rw-r--r--test/Sema/wchar.c20
-rw-r--r--test/Sema/x86-intrinsics-headers.c4
-rw-r--r--test/SemaCXX/__null.cpp2
-rw-r--r--test/SemaCXX/arrow-operator.cpp7
-rw-r--r--test/SemaCXX/builtins.cpp7
-rw-r--r--test/SemaCXX/cast-conversion.cpp25
-rw-r--r--test/SemaCXX/compare.cpp204
-rw-r--r--test/SemaCXX/composite-pointer-type.cpp12
-rw-r--r--test/SemaCXX/conditional-expr.cpp2
-rw-r--r--test/SemaCXX/constructor-initializer.cpp26
-rw-r--r--test/SemaCXX/conversion-function.cpp30
-rw-r--r--test/SemaCXX/decltype-this.cpp3
-rw-r--r--test/SemaCXX/default-constructor-initializers.cpp16
-rw-r--r--test/SemaCXX/dependent-types.cpp2
-rw-r--r--test/SemaCXX/format-attribute.cpp8
-rw-r--r--test/SemaCXX/friend-class-nodecl.cpp2
-rw-r--r--test/SemaCXX/linkage-spec.cpp9
-rw-r--r--test/SemaCXX/member-expr.cpp3
-rw-r--r--test/SemaCXX/member-pointer-size.cpp2
-rw-r--r--test/SemaCXX/new-delete.cpp57
-rw-r--r--test/SemaCXX/overload-call.cpp13
-rw-r--r--test/SemaCXX/overloaded-builtin-operators.cpp13
-rw-r--r--test/SemaCXX/overloaded-operator.cpp9
-rw-r--r--test/SemaCXX/pseudo-destructors.cpp2
-rw-r--r--test/SemaCXX/static-cast.cpp42
-rw-r--r--test/SemaCXX/using-decl-1.cpp21
-rw-r--r--test/SemaCXX/using-decl-templates.cpp4
-rw-r--r--test/SemaCXX/value-initialization.cpp4
-rw-r--r--test/SemaCXX/vararg-default-arg.cpp10
-rw-r--r--test/SemaCXX/vararg-non-pod.cpp2
-rw-r--r--test/SemaCXX/warn-for-var-in-else.cpp14
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp28
-rw-r--r--test/SemaObjC/atomoic-property-synnthesis-rules.m369
-rw-r--r--test/SemaObjC/call-super-2.m10
-rw-r--r--test/SemaObjC/class-method-lookup.m2
-rw-r--r--test/SemaObjC/compare-qualified-id.m5
-rw-r--r--test/SemaObjC/continuation-class-err.m2
-rw-r--r--test/SemaObjC/deref-interface.m2
-rw-r--r--test/SemaObjC/idiomatic-parentheses.m35
-rw-r--r--test/SemaObjC/ivar-sem-check-2.m2
-rw-r--r--test/SemaObjC/method-arg-decay.m5
-rw-r--r--test/SemaObjC/objc-string-constant.m2
-rw-r--r--test/SemaObjC/property-category-1.m1
-rw-r--r--test/SemaObjC/property-nonfragile-abi.m2
-rw-r--r--test/SemaObjC/sizeof-interface.m2
-rw-r--r--test/SemaObjC/static-ivar-ref-1.m2
-rw-r--r--test/SemaObjC/string.m2
-rw-r--r--test/SemaObjC/synthesized-ivar.m2
-rw-r--r--test/SemaObjC/unused.m5
-rw-r--r--test/SemaObjC/warn-selector-selection.m2
-rw-r--r--test/SemaTemplate/class-template-decl.cpp8
-rw-r--r--test/SemaTemplate/class-template-spec.cpp7
-rw-r--r--test/SemaTemplate/constructor-template.cpp32
-rw-r--r--test/SemaTemplate/deduction.cpp83
-rw-r--r--test/SemaTemplate/default-arguments.cpp81
-rw-r--r--test/SemaTemplate/default-expr-arguments.cpp40
-rw-r--r--test/SemaTemplate/enum-argument.cpp16
-rw-r--r--test/SemaTemplate/example-dynarray.cpp2
-rw-r--r--test/SemaTemplate/instantiate-attr.cpp7
-rw-r--r--test/SemaTemplate/instantiate-decl-init.cpp22
-rw-r--r--test/SemaTemplate/instantiate-member-pointers.cpp30
-rw-r--r--test/SemaTemplate/instantiate-member-template.cpp13
-rw-r--r--test/SemaTemplate/instantiate-overloaded-arrow.cpp20
-rw-r--r--test/SemaTemplate/instantiate-template-template-parm.cpp27
-rw-r--r--test/SemaTemplate/instantiate-using-decl.cpp3
-rw-r--r--test/SemaTemplate/instantiation-default-2.cpp2
-rw-r--r--test/SemaTemplate/member-function-template.cpp24
-rw-r--r--test/SemaTemplate/nested-name-spec-template.cpp17
-rw-r--r--test/SemaTemplate/nested-template.cpp18
-rw-r--r--test/SemaTemplate/operator-template.cpp2
-rw-r--r--test/SemaTemplate/temp_arg_nontype.cpp3
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp7
-rw-r--r--test/SemaTemplate/value-dependent-null-pointer-constant.cpp2
-rw-r--r--test/lit.cfg8
-rw-r--r--test/lit.site.cfg.in9
-rw-r--r--tools/CIndex/CIndex.cpp597
-rw-r--r--tools/CIndex/CIndex.exports9
-rw-r--r--tools/CIndex/CMakeLists.txt2
-rw-r--r--tools/CIndex/Makefile2
-rw-r--r--tools/CMakeLists.txt4
-rw-r--r--tools/c-index-test/c-index-test.c352
-rw-r--r--tools/clang-cc/CMakeLists.txt1
-rw-r--r--tools/clang-cc/Options.cpp1330
-rw-r--r--tools/clang-cc/Options.h57
-rw-r--r--tools/clang-cc/clang-cc.cpp2391
-rw-r--r--tools/driver/driver.cpp10
-rw-r--r--utils/C++Tests/Clang-Code-Compile/lit.local.cfg26
-rw-r--r--utils/C++Tests/Clang-Code-Syntax/lit.local.cfg25
-rw-r--r--utils/C++Tests/Clang-Syntax/lit.local.cfg23
-rw-r--r--utils/C++Tests/LLVM-Syntax/lit.local.cfg3
-rw-r--r--utils/C++Tests/lit.cfg12
-rwxr-xr-xutils/ccc-analyzer6
-rwxr-xr-xutils/scan-build8
-rw-r--r--www/get_started.html28
-rw-r--r--www/hacking.html64
918 files changed, 27114 insertions, 11704 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f4ab33b33a4..9e84d94a3b64 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,6 +94,11 @@ install(DIRECTORY include/
add_definitions( -D_GNU_SOURCE )
+option(CLANG_BUILD_EXAMPLES "Build CLANG example programs." OFF)
+if(CLANG_BUILD_EXAMPLES)
+ add_subdirectory(examples)
+endif ()
+
add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(tools)
diff --git a/Makefile b/Makefile
index 22fe214705cd..17ccc7320ec8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,12 @@
LEVEL = ../..
DIRS := include lib tools docs
+PARALLEL_DIRS :=
+
+ifeq ($(BUILD_EXAMPLES),1)
+ PARALLEL_DIRS += examples
+endif
+
include $(LEVEL)/Makefile.common
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
diff --git a/NOTES.txt b/NOTES.txt
index c658fe96bdfb..dc7a9bc0e754 100644
--- a/NOTES.txt
+++ b/NOTES.txt
@@ -50,7 +50,7 @@ TODO: File Manager Speedup:
//===---------------------------------------------------------------------===//
// Specifying targets: -triple and -arch
-===---------------------------------------------------------------------===//
+//===---------------------------------------------------------------------===//
The clang supports "-triple" and "-arch" options. At most one -triple and one
-arch option may be specified. Both are optional.
diff --git a/TODO.txt b/TODO.txt
index 522dcd37b365..7ceb0da15b36 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -66,3 +66,12 @@ More ideas for code modification hints:
- If a class member is defined out-of-line but isn't in the class declaration (and there are no close matches!), provide the option to add an in-class declaration.
- Fix-it hints for the inclusion of headers when needed for particular features (e.g., <typeinfo> for typeid)
- Change "foo.bar" to "foo->bar" when "foo" is a pointer.
+
+//===---------------------------------------------------------------------===//
+
+Options to support:
+ -Wfatal-errors
+ -ftabstop=width
+ -fpreprocessed mode.
+ -nostdinc++
+ -imultilib
diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj
index 2b4aa04ca33c..f0a2194cb2c7 100644
--- a/clang.xcodeproj/project.pbxproj
+++ b/clang.xcodeproj/project.pbxproj
@@ -46,6 +46,9 @@
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
1AA1D91810125DE30078DEBC /* RecordLayoutBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA1D91610125DE30078DEBC /* RecordLayoutBuilder.cpp */; };
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
+ 1ADD795410A90C6100741BBA /* TypePrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADD795110A90C6100741BBA /* TypePrinter.cpp */; };
+ 1ADD795510A90C6100741BBA /* TypeLoc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADD795210A90C6100741BBA /* TypeLoc.cpp */; };
+ 1ADD795610A90C6100741BBA /* TemplateBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADD795310A90C6100741BBA /* TemplateBase.cpp */; };
1ADF47AF0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */; };
1AE4EE3E103B89ED00888A23 /* StmtProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */; };
1AE4EE40103B8A0A00888A23 /* TargetABIInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */; };
@@ -362,6 +365,7 @@
1A2A54B30FD1DD1C00F4CE45 /* StmtXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtXML.cpp; path = lib/Frontend/StmtXML.cpp; sourceTree = "<group>"; };
1A2A54B40FD1DD1C00F4CE45 /* Warnings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Warnings.cpp; path = lib/Frontend/Warnings.cpp; sourceTree = "<group>"; };
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; tabWidth = 2; };
+ 1A31B27210ACE6DA009E0C8B /* GlobalDecl.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = GlobalDecl.h; path = lib/CodeGen/GlobalDecl.h; sourceTree = "<group>"; tabWidth = 2; };
1A32C17E0E1C87AD00A6B483 /* ExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ExprConstant.cpp; path = lib/AST/ExprConstant.cpp; sourceTree = "<group>"; tabWidth = 2; };
1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprConstant.cpp; path = lib/CodeGen/CGExprConstant.cpp; sourceTree = "<group>"; tabWidth = 2; };
1A471AB40F437BC500753CE8 /* CGBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGBlocks.cpp; path = lib/CodeGen/CGBlocks.cpp; sourceTree = "<group>"; tabWidth = 2; };
@@ -396,6 +400,9 @@
1AA1D91710125DE30078DEBC /* RecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = RecordLayoutBuilder.h; path = lib/AST/RecordLayoutBuilder.h; sourceTree = "<group>"; tabWidth = 2; };
1AB290021045858B00FE33D8 /* PartialDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = PartialDiagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = lib/CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; tabWidth = 2; };
+ 1ADD795110A90C6100741BBA /* TypePrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypePrinter.cpp; path = lib/AST/TypePrinter.cpp; sourceTree = "<group>"; };
+ 1ADD795210A90C6100741BBA /* TypeLoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeLoc.cpp; path = lib/AST/TypeLoc.cpp; sourceTree = "<group>"; };
+ 1ADD795310A90C6100741BBA /* TemplateBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateBase.cpp; path = lib/AST/TemplateBase.cpp; sourceTree = "<group>"; };
1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiateDecl.cpp; path = lib/Sema/SemaTemplateInstantiateDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
1AE4EE3B103B89CA00888A23 /* TreeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TreeTransform.h; path = lib/Sema/TreeTransform.h; sourceTree = "<group>"; tabWidth = 2; };
1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtProfile.cpp; path = lib/AST/StmtProfile.cpp; sourceTree = "<group>"; tabWidth = 2; };
@@ -1289,6 +1296,7 @@
DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */,
DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */,
DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */,
+ 1A31B27210ACE6DA009E0C8B /* GlobalDecl.h */,
1A2193CC0F45EEB700C0713D /* Mangle.cpp */,
1A2193CD0F45EEB700C0713D /* Mangle.h */,
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
@@ -1385,8 +1393,11 @@
DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */,
1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */,
35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */,
+ 1ADD795310A90C6100741BBA /* TemplateBase.cpp */,
DEDFF8870F848CF80035BD10 /* TemplateName.cpp */,
DE75EDF00B06880E0020CF81 /* Type.cpp */,
+ 1ADD795210A90C6100741BBA /* TypeLoc.cpp */,
+ 1ADD795110A90C6100741BBA /* TypePrinter.cpp */,
);
name = AST;
sourceTree = "<group>";
@@ -1919,6 +1930,9 @@
1A6C01F7108128710072DEE4 /* CGRtti.cpp in Sources */,
1A81AA19108144F40094E50B /* CGVtable.cpp in Sources */,
1AF1B50F109A4FB800AFAFAC /* CGException.cpp in Sources */,
+ 1ADD795410A90C6100741BBA /* TypePrinter.cpp in Sources */,
+ 1ADD795510A90C6100741BBA /* TypeLoc.cpp in Sources */,
+ 1ADD795610A90C6100741BBA /* TemplateBase.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/docs/UsersManual.html b/docs/UsersManual.html
index 20fdda72dced..cfaa071083bc 100644
--- a/docs/UsersManual.html
+++ b/docs/UsersManual.html
@@ -126,7 +126,7 @@ reasonably possible, easing migration from GCC to Clang. In most cases, code
<p>In addition to language specific features, Clang has a variety of features
that depend on what CPU architecture or operating system is being compiled for.
-Please see the <a href="target_features">Target-Specific Features and
+Please see the <a href="#target_features">Target-Specific Features and
Limitations</a> section for more details.</p>
<p>The rest of the introduction introduces some basic <a
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 1a58f44ff4c2..85f7a6a31bcb 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -115,6 +115,26 @@ typedef struct {
/* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */
typedef void *CXEntity;
+/**
+ * For functions returning a string that might or might not need
+ * to be internally allocated and freed.
+ * Use clang_getCString to access the C string value.
+ * Use clang_disposeString to free the value.
+ * Treat it as an opaque type.
+ */
+typedef struct {
+ const char *Spelling;
+ /* A 1 value indicates the clang_ indexing API needed to allocate the string
+ (and it must be freed by clang_disposeString()). */
+ int MustFreeString;
+} CXString;
+
+/* Get C string pointer from a CXString. */
+CINDEX_LINKAGE const char *clang_getCString(CXString string);
+
+/* Free CXString. */
+CINDEX_LINKAGE void clang_disposeString(CXString string);
+
/**
* \brief clang_createIndex() provides a shared context for creating
* translation units. It provides two options:
@@ -155,8 +175,7 @@ typedef void *CXEntity;
CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
int displayDiagnostics);
CINDEX_LINKAGE void clang_disposeIndex(CXIndex);
-
-CINDEX_LINKAGE const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+CINDEX_LINKAGE CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
/*
* \brief Create a translation unit from an AST file (-emit-ast).
@@ -260,7 +279,7 @@ CINDEX_LINKAGE CXEntity clang_getEntity(const char *URI);
*/
CINDEX_LINKAGE CXCursor clang_getCursorFromDecl(CXDecl);
CINDEX_LINKAGE CXEntity clang_getEntityFromDecl(CXDecl);
-CINDEX_LINKAGE const char *clang_getDeclSpelling(CXDecl);
+CINDEX_LINKAGE CXString clang_getDeclSpelling(CXDecl);
CINDEX_LINKAGE unsigned clang_getDeclLine(CXDecl);
CINDEX_LINKAGE unsigned clang_getDeclColumn(CXDecl);
CINDEX_LINKAGE const char *clang_getDeclSource(CXDecl); /* deprecate */
@@ -275,6 +294,8 @@ CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl);
*/
CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
unsigned line, unsigned column);
+
+CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor);
CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
@@ -282,9 +303,11 @@ CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_isDefinition(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
+CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor);
+
CINDEX_LINKAGE unsigned clang_getCursorLine(CXCursor);
CINDEX_LINKAGE unsigned clang_getCursorColumn(CXCursor);
-CINDEX_LINKAGE const char *clang_getCursorSpelling(CXCursor);
+CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
CINDEX_LINKAGE const char *clang_getCursorSource(CXCursor); /* deprecate */
CINDEX_LINKAGE CXFile clang_getCursorSourceFile(CXCursor);
@@ -305,6 +328,328 @@ CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
*/
CINDEX_LINKAGE CXDecl clang_getCursorDecl(CXCursor);
+/**
+ * \brief A semantic string that describes a code-completion result.
+ *
+ * A semantic string that describes the formatting of a code-completion
+ * result as a single "template" of text that should be inserted into the
+ * source buffer when a particular code-completion result is selected.
+ * Each semantic string is made up of some number of "chunks", each of which
+ * contains some text along with a description of what that text means, e.g.,
+ * the name of the entity being referenced, whether the text chunk is part of
+ * the template, or whether it is a "placeholder" that the user should replace
+ * with actual code,of a specific kind. See \c CXCompletionChunkKind for a
+ * description of the different kinds of chunks.
+ */
+typedef void *CXCompletionString;
+
+/**
+ * \brief A single result of code completion.
+ */
+typedef struct {
+ /**
+ * \brief The kind of entity that this completion refers to.
+ *
+ * The cursor kind will be a macro, keyword, or a declaration (one of the
+ * *Decl cursor kinds), describing the entity that the completion is
+ * referring to.
+ *
+ * \todo In the future, we would like to provide a full cursor, to allow
+ * the client to extract additional information from declaration.
+ */
+ enum CXCursorKind CursorKind;
+
+ /**
+ * \brief The code-completion string that describes how to insert this
+ * code-completion result into the editing buffer.
+ */
+ CXCompletionString CompletionString;
+} CXCompletionResult;
+
+/**
+ * \brief Describes a single piece of text within a code-completion string.
+ *
+ * Each "chunk" within a code-completion string (\c CXCompletionString) is
+ * either a piece of text with a specific "kind" that describes how that text
+ * should be interpreted by the client or is another completion string.
+ */
+enum CXCompletionChunkKind {
+ /**
+ * \brief A code-completion string that describes "optional" text that
+ * could be a part of the template (but is not required).
+ *
+ * The Optional chunk is the only kind of chunk that has a code-completion
+ * string for its representation, which is accessible via
+ * \c clang_getCompletionChunkCompletionString(). The code-completion string
+ * describes an additional part of the template that is completely optional.
+ * For example, optional chunks can be used to describe the placeholders for
+ * arguments that match up with defaulted function parameters, e.g. given:
+ *
+ * \code
+ * void f(int x, float y = 3.14, double z = 2.71828);
+ * \endcode
+ *
+ * The code-completion string for this function would contain:
+ * - a TypedText chunk for "f".
+ * - a LeftParen chunk for "(".
+ * - a Placeholder chunk for "int x"
+ * - an Optional chunk containing the remaining defaulted arguments, e.g.,
+ * - a Comma chunk for ","
+ * - a Placeholder chunk for "float x"
+ * - an Optional chunk containing the last defaulted argument:
+ * - a Comma chunk for ","
+ * - a Placeholder chunk for "double z"
+ * - a RightParen chunk for ")"
+ *
+ * There are many ways two handle Optional chunks. Two simple approaches are:
+ * - Completely ignore optional chunks, in which case the template for the
+ * function "f" would only include the first parameter ("int x").
+ * - Fully expand all optional chunks, in which case the template for the
+ * function "f" would have all of the parameters.
+ */
+ CXCompletionChunk_Optional,
+ /**
+ * \brief Text that a user would be expected to type to get this
+ * code-completion result.
+ *
+ * There will be exactly one "typed text" chunk in a semantic string, which
+ * will typically provide the spelling of a keyword or the name of a
+ * declaration that could be used at the current code point. Clients are
+ * expected to filter the code-completion results based on the text in this
+ * chunk.
+ */
+ CXCompletionChunk_TypedText,
+ /**
+ * \brief Text that should be inserted as part of a code-completion result.
+ *
+ * A "text" chunk represents text that is part of the template to be
+ * inserted into user code should this particular code-completion result
+ * be selected.
+ */
+ CXCompletionChunk_Text,
+ /**
+ * \brief Placeholder text that should be replaced by the user.
+ *
+ * A "placeholder" chunk marks a place where the user should insert text
+ * into the code-completion template. For example, placeholders might mark
+ * the function parameters for a function declaration, to indicate that the
+ * user should provide arguments for each of those parameters. The actual
+ * text in a placeholder is a suggestion for the text to display before
+ * the user replaces the placeholder with real code.
+ */
+ CXCompletionChunk_Placeholder,
+ /**
+ * \brief Informative text that should be displayed but never inserted as
+ * part of the template.
+ *
+ * An "informative" chunk contains annotations that can be displayed to
+ * help the user decide whether a particular code-completion result is the
+ * right option, but which is not part of the actual template to be inserted
+ * by code completion.
+ */
+ CXCompletionChunk_Informative,
+ /**
+ * \brief Text that describes the current parameter when code-completion is
+ * referring to function call, message send, or template specialization.
+ *
+ * A "current parameter" chunk occurs when code-completion is providing
+ * information about a parameter corresponding to the argument at the
+ * code-completion point. For example, given a function
+ *
+ * \code
+ * int add(int x, int y);
+ * \endcode
+ *
+ * and the source code \c add(, where the code-completion point is after the
+ * "(", the code-completion string will contain a "current parameter" chunk
+ * for "int x", indicating that the current argument will initialize that
+ * parameter. After typing further, to \c add(17, (where the code-completion
+ * point is after the ","), the code-completion string will contain a
+ * "current paremeter" chunk to "int y".
+ */
+ CXCompletionChunk_CurrentParameter,
+ /**
+ * \brief A left parenthesis ('('), used to initiate a function call or
+ * signal the beginning of a function parameter list.
+ */
+ CXCompletionChunk_LeftParen,
+ /**
+ * \brief A right parenthesis (')'), used to finish a function call or
+ * signal the end of a function parameter list.
+ */
+ CXCompletionChunk_RightParen,
+ /**
+ * \brief A left bracket ('[').
+ */
+ CXCompletionChunk_LeftBracket,
+ /**
+ * \brief A right bracket (']').
+ */
+ CXCompletionChunk_RightBracket,
+ /**
+ * \brief A left brace ('{').
+ */
+ CXCompletionChunk_LeftBrace,
+ /**
+ * \brief A right brace ('}').
+ */
+ CXCompletionChunk_RightBrace,
+ /**
+ * \brief A left angle bracket ('<').
+ */
+ CXCompletionChunk_LeftAngle,
+ /**
+ * \brief A right angle bracket ('>').
+ */
+ CXCompletionChunk_RightAngle,
+ /**
+ * \brief A comma separator (',').
+ */
+ CXCompletionChunk_Comma
+};
+
+/**
+ * \brief Callback function that receives a single code-completion result.
+ *
+ * This callback will be invoked by \c clang_codeComplete() for each
+ * code-completion result.
+ *
+ * \param completion_result a pointer to the current code-completion result,
+ * providing one possible completion. The pointer itself is only valid
+ * during the execution of the completion callback.
+ *
+ * \param client_data the client data provided to \c clang_codeComplete().
+ */
+typedef void (*CXCompletionIterator)(CXCompletionResult *completion_result,
+ CXClientData client_data);
+
+/**
+ * \brief Determine the kind of a particular chunk within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the kind of the chunk at the index \c chunk_number.
+ */
+CINDEX_LINKAGE enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+ unsigned chunk_number);
+
+/**
+ * \brief Retrieve the text associated with a particular chunk within a
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the text associated with the chunk at index \c chunk_number.
+ */
+CINDEX_LINKAGE const char *
+clang_getCompletionChunkText(CXCompletionString completion_string,
+ unsigned chunk_number);
+
+/**
+ * \brief Retrieve the completion string associated with a particular chunk
+ * within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the completion string associated with the chunk at index
+ * \c chunk_number, or NULL if that chunk is not represented by a completion
+ * string.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
+ unsigned chunk_number);
+
+/**
+ * \brief Retrieve the number of chunks in the given code-completion string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getNumCompletionChunks(CXCompletionString completion_string);
+
+/**
+ * \brief Perform code completion at a given location in a source file.
+ *
+ * This function performs code completion at a particular file, line, and
+ * column within source code, providing results that suggest potential
+ * code snippets based on the context of the completion. The basic model
+ * for code completion is that Clang will parse a complete source file,
+ * performing syntax checking up to the location where code-completion has
+ * been requested. At that point, a special code-completion token is passed
+ * to the parser, which recognizes this token and determines, based on the
+ * current location in the C/Objective-C/C++ grammar and the state of
+ * semantic analysis, what completions to provide. These completions are
+ * enumerated through a callback interface to the client.
+ *
+ * Code completion itself is meant to be triggered by the client when the
+ * user types punctuation characters or whitespace, at which point the
+ * code-completion location will coincide with the cursor. For example, if \c p
+ * is a pointer, code-completion might be triggered after the "-" and then
+ * after the ">" in \c p->. When the code-completion location is afer the ">",
+ * the completion results will provide, e.g., the members of the struct that
+ * "p" points to. The client is responsible for placing the cursor at the
+ * beginning of the token currently being typed, then filtering the results
+ * based on the contents of the token. For example, when code-completing for
+ * the expression \c p->get, the client should provide the location just after
+ * the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the
+ * client can filter the results based on the current token text ("get"), only
+ * showing those results that start with "get". The intent of this interface
+ * is to separate the relatively high-latency acquisition of code-competion
+ * results from the filtering of results on a per-character basis, which must
+ * have a lower latency.
+ *
+ * \param CIdx the \c CXIndex instance that will be used to perform code
+ * completion.
+ *
+ * \param source_filename the name of the source file that should be parsed
+ * to perform code-completion. This source file must be the same as or
+ * include the filename described by \p complete_filename, or no code-completion
+ * results will be produced. NOTE: One can also specify NULL for this argument if
+ * the source file is included in command_line_args.
+ *
+ * \param num_command_line_args the number of command-line arguments stored in
+ * \p command_line_args.
+ *
+ * \param command_line_args the command-line arguments to pass to the Clang
+ * compiler to build the given source file. This should include all of the
+ * necessary include paths, language-dialect switches, precompiled header
+ * includes, etc., but should not include any information specific to
+ * code completion.
+ *
+ * \param complete_filename the name of the source file where code completion
+ * should be performed. In many cases, this name will be the same as the
+ * source filename. However, the completion filename may also be a file
+ * included by the source file, which is required when producing
+ * code-completion results for a header.
+ *
+ * \param complete_line the line at which code-completion should occur.
+ *
+ * \param complete_column the column at which code-completion should occur.
+ * Note that the column should point just after the syntactic construct that
+ * initiated code completion, and not in the middle of a lexical token.
+ *
+ * \param completion_iterator a callback function that will receive
+ * code-completion results.
+ *
+ * \param client_data client-specific data that will be passed back via the
+ * code-completion callback function.
+ */
+CINDEX_LINKAGE void clang_codeComplete(CXIndex CIdx,
+ const char *source_filename,
+ int num_command_line_args,
+ const char **command_line_args,
+ const char *complete_filename,
+ unsigned complete_line,
+ unsigned complete_column,
+ CXCompletionIterator completion_iterator,
+ CXClientData client_data);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7392170be995..f9d2f71b1f28 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -37,6 +37,7 @@ namespace llvm {
namespace clang {
class FileManager;
class ASTRecordLayout;
+ class BlockExpr;
class Expr;
class ExternalASTSource;
class IdentifierTable;
@@ -55,7 +56,6 @@ namespace clang {
class TranslationUnitDecl;
class TypeDecl;
class TypedefDecl;
- class UnresolvedUsingDecl;
class UsingDecl;
namespace Builtin { class Context; }
@@ -204,7 +204,7 @@ class ASTContext {
///
/// This mapping will contain an entry that maps from the UsingDecl in
/// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
+ llvm::DenseMap<UsingDecl *, NamedDecl *>
InstantiatedFromUnresolvedUsingDecl;
llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
@@ -232,7 +232,7 @@ class ASTContext {
llvm::DenseMap<const Decl *, std::string> DeclComments;
public:
- TargetInfo &Target;
+ const TargetInfo &Target;
IdentifierTable &Idents;
SelectorTable &Selectors;
Builtin::Context &BuiltinInfo;
@@ -284,12 +284,11 @@ public:
/// \brief If this using decl is instantiated from an unresolved using decl,
/// return it.
- UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
+ NamedDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
/// \brief Note that the using decl \p Inst is an instantiation of
/// the unresolved using decl \p Tmpl of a class template.
- void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst,
- UnresolvedUsingDecl *Tmpl);
+ void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst, NamedDecl *Tmpl);
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
@@ -319,7 +318,7 @@ public:
CanQualType UndeducedAutoTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
- ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
+ ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
Builtin::Context &builtins,
bool FreeMemory = true, unsigned size_reserve=0);
@@ -672,6 +671,10 @@ public:
/// declaration.
void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S);
+ /// getObjCEncodingForBlockDecl - Return the encoded type for this block
+ /// declaration.
+ void getObjCEncodingForBlock(const BlockExpr *Expr, std::string& S);
+
/// getObjCEncodingForPropertyDecl - Return the encoded type for
/// this method declaration. If non-NULL, Container must be either
/// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
@@ -872,9 +875,9 @@ public:
/// \brief Determine whether the given types are equivalent after
/// cvr-qualifiers have been removed.
bool hasSameUnqualifiedType(QualType T1, QualType T2) {
- T1 = getCanonicalType(T1);
- T2 = getCanonicalType(T2);
- return T1.getUnqualifiedType() == T2.getUnqualifiedType();
+ CanQualType CT1 = getCanonicalType(T1);
+ CanQualType CT2 = getCanonicalType(T2);
+ return CT1.getUnqualifiedType() == CT2.getUnqualifiedType();
}
/// \brief Retrieves the "canonical" declaration of
@@ -925,6 +928,10 @@ public:
/// types, values, and templates.
TemplateName getCanonicalTemplateName(TemplateName Name);
+ /// \brief Determine whether the given template names refer to the same
+ /// template.
+ bool hasSameTemplateName(TemplateName X, TemplateName Y);
+
/// \brief Retrieve the "canonical" template argument.
///
/// The canonical template argument is the simplest template argument
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index f7a47364a7f6..b36ff1229376 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -50,6 +50,7 @@ public:
Annotate,
AsmLabel, // Represent GCC asm label extension.
Blocks,
+ CDecl,
Cleanup,
Const,
Constructor,
@@ -442,6 +443,7 @@ DEF_SIMPLE_ATTR(DLLImport);
DEF_SIMPLE_ATTR(DLLExport);
DEF_SIMPLE_ATTR(FastCall);
DEF_SIMPLE_ATTR(StdCall);
+DEF_SIMPLE_ATTR(CDecl);
DEF_SIMPLE_ATTR(TransparentUnion);
DEF_SIMPLE_ATTR(ObjCNSObject);
DEF_SIMPLE_ATTR(ObjCException);
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index a7750517090e..9b1187770f6a 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -71,6 +71,9 @@ public:
/// \brief Implicit conversion to a qualified type.
operator QualType() const { return Stored; }
+ /// \brief Implicit conversion to bool.
+ operator bool() const { return !isNull(); }
+
bool isNull() const {
return Stored.isNull();
}
@@ -99,22 +102,22 @@ public:
CanProxy<T> operator->() const;
/// \brief Retrieve all qualifiers.
- Qualifiers getQualifiers() const { return Stored.getQualifiers(); }
+ Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
/// \brief Retrieve the const/volatile/restrict qualifiers.
- unsigned getCVRQualifiers() const { return Stored.getCVRQualifiers(); }
+ unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
/// \brief Determines whether this type has any qualifiers
- bool hasQualifiers() const { return Stored.hasQualifiers(); }
+ bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
bool isConstQualified() const {
- return Stored.isConstQualified();
+ return Stored.isLocalConstQualified();
}
bool isVolatileQualified() const {
- return Stored.isVolatileQualified();
+ return Stored.isLocalVolatileQualified();
}
bool isRestrictQualified() const {
- return Stored.isRestrictQualified();
+ return Stored.isLocalRestrictQualified();
}
/// \brief Retrieve the unqualified form of this type.
@@ -635,7 +638,7 @@ struct CanProxyAdaptor<ObjCObjectPointerType>
//----------------------------------------------------------------------------//
template<typename T>
inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
- return CanQual<T>::CreateUnsafe(Stored.getUnqualifiedType());
+ return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
}
template<typename T>
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 813e83accdb1..ac79a91792d7 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -232,6 +232,7 @@ public:
void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
+ const NamespaceDecl *getCanonicalDecl() const { return OrigNamespace; }
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), RBracLoc);
@@ -552,6 +553,9 @@ public:
}
virtual VarDecl *getCanonicalDecl();
+ const VarDecl *getCanonicalDecl() const {
+ return const_cast<VarDecl*>(this)->getCanonicalDecl();
+ }
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
@@ -1424,6 +1428,9 @@ public:
virtual SourceRange getSourceRange() const;
virtual TagDecl* getCanonicalDecl();
+ const TagDecl* getCanonicalDecl() const {
+ return const_cast<TagDecl*>(this)->getCanonicalDecl();
+ }
/// isDefinition - Return true if this decl has its body specified.
bool isDefinition() const {
@@ -1515,6 +1522,9 @@ public:
EnumDecl *getCanonicalDecl() {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
+ const EnumDecl *getCanonicalDecl() const {
+ return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ }
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 10db7030db18..79f766356138 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -79,9 +79,11 @@ public:
/// namespaces, labels, tags, members and ordinary
/// identifiers. These are meant as bitmasks, so that searches in
/// C++ can look into the "tag" namespace during ordinary lookup. We
- /// use additional namespaces for Objective-C entities. We also
- /// put C++ friend declarations (of previously-undeclared entities) in
- /// shadow namespaces.
+ /// use additional namespaces for Objective-C entities. We also put
+ /// C++ friend declarations (of previously-undeclared entities) in
+ /// shadow namespaces, and 'using' declarations (as opposed to their
+ /// implicit shadow declarations) can be found in their own
+ /// namespace.
enum IdentifierNamespace {
IDNS_Label = 0x1,
IDNS_Tag = 0x2,
@@ -91,7 +93,8 @@ public:
IDNS_ObjCImplementation = 0x20,
IDNS_ObjCCategoryImpl = 0x40,
IDNS_OrdinaryFriend = 0x80,
- IDNS_TagFriend = 0x100
+ IDNS_TagFriend = 0x100,
+ IDNS_Using = 0x200
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index c858c5c0df78..e5bf78cd10d2 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -432,6 +432,9 @@ public:
virtual CXXRecordDecl *getCanonicalDecl() {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
+ virtual const CXXRecordDecl *getCanonicalDecl() const {
+ return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+ }
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -768,7 +771,7 @@ public:
/// \param Base the base class we are searching for.
///
/// \returns true if this class is derived from Base, false otherwise.
- bool isDerivedFrom(CXXRecordDecl *Base);
+ bool isDerivedFrom(CXXRecordDecl *Base) const;
/// \brief Determine whether this class is derived from the type \p Base.
///
@@ -786,7 +789,7 @@ public:
///
/// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
- bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths);
+ bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
/// \brief Function type used by lookupInBases() to determine whether a
/// specific base class subobject matches the lookup criteria.
@@ -801,7 +804,7 @@ public:
/// lookupInBases().
///
/// \returns true if this base matched the search criteria, false otherwise.
- typedef bool BaseMatchesCallback(CXXBaseSpecifier *Specifier,
+ typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *UserData);
@@ -826,7 +829,7 @@ public:
/// \returns true if there exists any path from this class to a base class
/// subobject that matches the search criteria.
bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
- CXXBasePaths &Paths);
+ CXXBasePaths &Paths) const;
/// \brief Base-class lookup callback that determines whether the given
/// base class specifier refers to a specific class declaration.
@@ -835,8 +838,8 @@ public:
/// a given derived class has is a base class subobject of a particular type.
/// The user data pointer should refer to the canonical CXXRecordDecl of the
/// base class that we are searching for.
- static bool FindBaseClass(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
- void *BaseRecord);
+ static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *BaseRecord);
/// \brief Base-class lookup callback that determines whether there exists
/// a tag with the given name.
@@ -844,8 +847,8 @@ public:
/// This callback can be used with \c lookupInBases() to find tag members
/// of the given name within a C++ class hierarchy. The user data pointer
/// is an opaque \c DeclarationName pointer.
- static bool FindTagMember(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
- void *Name);
+ static bool FindTagMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *Name);
/// \brief Base-class lookup callback that determines whether there exists
/// a member with the given name.
@@ -853,8 +856,8 @@ public:
/// This callback can be used with \c lookupInBases() to find members
/// of the given name within a C++ class hierarchy. The user data pointer
/// is an opaque \c DeclarationName pointer.
- static bool FindOrdinaryMember(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
- void *Name);
+ static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *Name);
/// \brief Base-class lookup callback that determines whether there exists
/// a member with the given name that can be used in a nested-name-specifier.
@@ -862,7 +865,7 @@ public:
/// This callback can be used with \c lookupInBases() to find membes of
/// the given name within a C++ class hierarchy that can occur within
/// nested-name-specifiers.
- static bool FindNestedNameSpecifierMember(CXXBaseSpecifier *Specifier,
+ static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *UserData);
@@ -1244,6 +1247,11 @@ public:
/// used for user-defined conversions.
bool isConvertingConstructor(bool AllowExplicit) const;
+ /// \brief Determine whether this is a member template specialization that
+ /// looks like a copy constructor. Such constructors are never used to copy
+ /// an object.
+ bool isCopyConstructorLikeSpecialization() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == CXXConstructor;
@@ -1261,13 +1269,6 @@ public:
/// };
/// @endcode
class CXXDestructorDecl : public CXXMethodDecl {
-public:
- enum KindOfObjectToDestroy {
- VBASE = 0x1,
- DRCTNONVBASE = 0x2,
- ANYBASE = 0x3
- };
-private:
/// ImplicitlyDefined - Whether this destructor was implicitly
/// defined by the compiler. When false, the destructor was defined
/// by the user. In C++03, this flag will have the same value as
@@ -1276,24 +1277,15 @@ private:
/// @c !Implicit && ImplicitlyDefined.
bool ImplicitlyDefined : 1;
- /// Support for base and member destruction.
- /// BaseOrMemberDestructions - The arguments used to destruct the base
- /// or member. Each uintptr_t value represents one of base classes (either
- /// virtual or direct non-virtual base), or non-static data member
- /// to be destroyed. The low two bits encode the kind of object
- /// being destroyed.
- uintptr_t *BaseOrMemberDestructions;
- unsigned NumBaseOrMemberDestructions;
-
+ FunctionDecl *OperatorDelete;
+
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXDestructor, RD, L, N, T, /*DInfo=*/0, false, isInline),
- ImplicitlyDefined(false),
- BaseOrMemberDestructions(0), NumBaseOrMemberDestructions(0) {
+ ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
- virtual void Destroy(ASTContext& C);
public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@@ -1319,95 +1311,8 @@ public:
ImplicitlyDefined = ID;
}
- /// destr_iterator - Iterates through the member/base destruction list.
-
- /// destr_const_iterator - Iterates through the member/base destruction list.
- typedef uintptr_t const destr_const_iterator;
-
- /// destr_begin() - Retrieve an iterator to the first destructed member/base.
- uintptr_t* destr_begin() {
- return BaseOrMemberDestructions;
- }
- /// destr_begin() - Retrieve an iterator to the first destructed member/base.
- uintptr_t* destr_begin() const {
- return BaseOrMemberDestructions;
- }
-
- /// destr_end() - Retrieve an iterator past the last destructed member/base.
- uintptr_t* destr_end() {
- return BaseOrMemberDestructions + NumBaseOrMemberDestructions;
- }
- /// destr_end() - Retrieve an iterator past the last destructed member/base.
- uintptr_t* destr_end() const {
- return BaseOrMemberDestructions + NumBaseOrMemberDestructions;
- }
-
- /// getNumBaseOrMemberDestructions - Number of base and non-static members
- /// to destroy.
- unsigned getNumBaseOrMemberDestructions() const {
- return NumBaseOrMemberDestructions;
- }
-
- /// setNumBaseOrMemberDestructions - Set number of base and non-static members
- /// to destroy.
- void setNumBaseOrMemberDestructions(unsigned numBaseOrMemberDestructions) {
- NumBaseOrMemberDestructions = numBaseOrMemberDestructions;
- }
-
- /// getBaseOrMemberToDestroy - get the generic 'member' representing either
- /// the field or a base class.
- uintptr_t* getBaseOrMemberToDestroy() const {
- return BaseOrMemberDestructions;
- }
-
- /// setBaseOrMemberToDestroy - set the generic 'member' representing either
- /// the field or a base class.
- void setBaseOrMemberDestructions(uintptr_t* baseOrMemberDestructions) {
- BaseOrMemberDestructions = baseOrMemberDestructions;
- }
-
- /// isVbaseToDestroy - returns true, if object is virtual base.
- bool isVbaseToDestroy(uintptr_t Vbase) const {
- return (Vbase & VBASE) != 0;
- }
- /// isDirectNonVBaseToDestroy - returns true, if object is direct non-virtual
- /// base.
- bool isDirectNonVBaseToDestroy(uintptr_t DrctNonVbase) const {
- return (DrctNonVbase & DRCTNONVBASE) != 0;
- }
- /// isAnyBaseToDestroy - returns true, if object is any base (virtual or
- /// direct non-virtual)
- bool isAnyBaseToDestroy(uintptr_t AnyBase) const {
- return (AnyBase & ANYBASE) != 0;
- }
- /// isMemberToDestroy - returns true if object is a non-static data member.
- bool isMemberToDestroy(uintptr_t Member) const {
- return (Member & ANYBASE) == 0;
- }
- /// getAnyBaseClassToDestroy - Get the type for the given base class object.
- Type *getAnyBaseClassToDestroy(uintptr_t Base) const {
- if (isAnyBaseToDestroy(Base))
- return reinterpret_cast<Type*>(Base & ~0x03);
- return 0;
- }
- /// getMemberToDestroy - Get the member for the given object.
- FieldDecl *getMemberToDestroy(uintptr_t Member) const {
- if (isMemberToDestroy(Member))
- return reinterpret_cast<FieldDecl *>(Member);
- return 0;
- }
- /// getVbaseClassToDestroy - Get the virtual base.
- Type *getVbaseClassToDestroy(uintptr_t Vbase) const {
- if (isVbaseToDestroy(Vbase))
- return reinterpret_cast<Type*>(Vbase & ~0x01);
- return 0;
- }
- /// getDirectNonVBaseClassToDestroy - Get the virtual base.
- Type *getDirectNonVBaseClassToDestroy(uintptr_t Base) const {
- if (isDirectNonVBaseToDestroy(Base))
- return reinterpret_cast<Type*>(Base & ~0x02);
- return 0;
- }
+ void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
+ const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
@@ -1739,6 +1644,56 @@ public:
static bool classof(const NamespaceAliasDecl *D) { return true; }
};
+/// UsingShadowDecl - Represents a shadow declaration introduced into
+/// a scope by a (resolved) using declaration. For example,
+///
+/// namespace A {
+/// void foo();
+/// }
+/// namespace B {
+/// using A::foo(); // <- a UsingDecl
+/// // Also creates a UsingShadowDecl for A::foo in B
+/// }
+///
+class UsingShadowDecl : public NamedDecl {
+ /// The referenced declaration.
+ NamedDecl *Underlying;
+
+ /// The using declaration which introduced this decl.
+ UsingDecl *Using;
+
+ UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target)
+ : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+ Underlying(Target), Using(Using) {
+ IdentifierNamespace = Target->getIdentifierNamespace();
+ setImplicit();
+ }
+
+public:
+ static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target) {
+ return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ }
+
+ /// Gets the underlying declaration which has been brought into the
+ /// local scope.
+ NamedDecl *getTargetDecl() const {
+ return Underlying;
+ }
+
+ /// Gets the using declaration to which this declaration is tied.
+ UsingDecl *getUsingDecl() const {
+ return Using;
+ }
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Decl::UsingShadow;
+ }
+ static bool classof(const UsingShadowDecl *D) { return true; }
+};
+
/// UsingDecl - Represents a C++ using-declaration. For example:
/// using someNameSpace::someIdentifier;
class UsingDecl : public NamedDecl {
@@ -1746,29 +1701,26 @@ class UsingDecl : public NamedDecl {
/// preceding the declaration name.
SourceRange NestedNameRange;
- /// \brief The source location of the target declaration name.
- SourceLocation TargetNameLocation;
-
/// \brief The source location of the "using" location itself.
SourceLocation UsingLocation;
- /// \brief Target declaration.
- NamedDecl* TargetDecl;
-
/// \brief Target nested name specifier.
- NestedNameSpecifier* TargetNestedNameDecl;
+ NestedNameSpecifier* TargetNestedName;
+
+ /// \brief The collection of shadow declarations associated with
+ /// this using declaration. This set can change as a class is
+ /// processed.
+ llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
// \brief Has 'typename' keyword.
bool IsTypeName;
UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
- SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg)
- : NamedDecl(Decl::Using, DC, L, Target->getDeclName()),
- NestedNameRange(NNR), TargetNameLocation(TargetNL),
- UsingLocation(UL), TargetDecl(Target),
- TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) {
- this->IdentifierNamespace = TargetDecl->getIdentifierNamespace();
+ SourceLocation UL, NestedNameSpecifier* TargetNNS,
+ DeclarationName Name, bool IsTypeNameArg)
+ : NamedDecl(Decl::Using, DC, L, Name),
+ NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
+ IsTypeName(IsTypeNameArg) {
}
public:
@@ -1776,28 +1728,37 @@ public:
/// preceding the namespace name.
SourceRange getNestedNameRange() { return NestedNameRange; }
- /// \brief Returns the source location of the target declaration name.
- SourceLocation getTargetNameLocation() { return TargetNameLocation; }
-
/// \brief Returns the source location of the "using" location itself.
SourceLocation getUsingLocation() { return UsingLocation; }
- /// \brief getTargetDecl - Returns target specified by using-decl.
- NamedDecl *getTargetDecl() { return TargetDecl; }
- const NamedDecl *getTargetDecl() const { return TargetDecl; }
-
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameDecl() {
- return TargetNestedNameDecl;
+ return TargetNestedName;
}
/// isTypeName - Return true if using decl has 'typename'.
bool isTypeName() const { return IsTypeName; }
+ typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
+ shadow_iterator shadow_begin() const { return Shadows.begin(); }
+ shadow_iterator shadow_end() const { return Shadows.end(); }
+
+ void addShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.insert(S)) {
+ assert(false && "declaration already in set");
+ }
+ }
+ void removeShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.erase(S)) {
+ assert(false && "declaration not in set");
+ }
+ }
+
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
- SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg);
+ SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
+ NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
static bool classof(const Decl *D) {
return D->getKind() == Decl::Using;
@@ -1805,31 +1766,88 @@ public:
static bool classof(const UsingDecl *D) { return true; }
};
-/// UnresolvedUsingDecl - Represents a using declaration whose name can not
-/// yet be resolved.
-class UnresolvedUsingDecl : public NamedDecl {
+/// UnresolvedUsingValueDecl - Represents a dependent using
+/// declaration which was not marked with 'typename'. Unlike
+/// non-dependent using declarations, these *only* bring through
+/// non-types; otherwise they would break two-phase lookup.
+///
+/// template <class T> class A : public Base<T> {
+/// using Base<T>::foo;
+/// };
+class UnresolvedUsingValueDecl : public ValueDecl {
/// \brief The source range that covers the nested-name-specifier
/// preceding the declaration name.
SourceRange TargetNestedNameRange;
- /// \brief The source location of the target declaration name.
- SourceLocation TargetNameLocation;
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
NestedNameSpecifier *TargetNestedNameSpecifier;
- DeclarationName TargetName;
+ UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
+ SourceLocation UsingLoc, SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName)
+ : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TargetNestedNameSpecifier(TargetNNS)
+ { }
- // \brief Has 'typename' keyword.
- bool IsTypeName;
+public:
+ /// \brief Returns the source range that covers the nested-name-specifier
+ /// preceding the namespace name.
+ SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
- UnresolvedUsingDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc, DeclarationName TargetName,
- bool IsTypeNameArg)
- : NamedDecl(Decl::UnresolvedUsing, DC, UsingLoc, TargetName),
- TargetNestedNameRange(TargetNNR), TargetNameLocation(TargetNameLoc),
- TargetNestedNameSpecifier(TargetNNS), TargetName(TargetName),
- IsTypeName(IsTypeNameArg) { }
+ /// \brief Get target nested name declaration.
+ NestedNameSpecifier* getTargetNestedNameSpecifier() {
+ return TargetNestedNameSpecifier;
+ }
+
+ /// \brief Returns the source location of the 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
+
+ static UnresolvedUsingValueDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Decl::UnresolvedUsingValue;
+ }
+ static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+};
+
+/// UnresolvedUsingTypenameDecl - Represents a dependent using
+/// declaration which was marked with 'typename'.
+///
+/// template <class T> class A : public Base<T> {
+/// using typename Base<T>::foo;
+/// };
+///
+/// The type associated with a unresolved using typename decl is
+/// currently always a typename type.
+class UnresolvedUsingTypenameDecl : public TypeDecl {
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the declaration name.
+ SourceRange TargetNestedNameRange;
+
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
+
+ /// \brief The source location of the 'typename' keyword
+ SourceLocation TypenameLocation;
+
+ NestedNameSpecifier *TargetNestedNameSpecifier;
+
+ UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
+ : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
+ { }
public:
/// \brief Returns the source range that covers the nested-name-specifier
@@ -1841,26 +1859,22 @@ public:
return TargetNestedNameSpecifier;
}
- /// \brief Returns the source location of the target declaration name.
- SourceLocation getTargetNameLocation() const { return TargetNameLocation; }
+ /// \brief Returns the source location of the 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
- /// \brief Returns the source location of the target declaration name.
- DeclarationName getTargetName() const { return TargetName; }
-
- bool isTypeName() const { return IsTypeName; }
+ /// \brief Returns the source location of the 'typename' keyword.
+ SourceLocation getTypenameLoc() const { return TypenameLocation; }
- static UnresolvedUsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc,
- DeclarationName TargetName,
- bool IsTypeNameArg);
+ static UnresolvedUsingTypenameDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsing;
+ return D->getKind() == Decl::UnresolvedUsingTypename;
}
- static bool classof(const UnresolvedUsingDecl *D) { return true; }
+ static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index d9e40d478907..c2b48cee36f4 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -14,8 +14,9 @@
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
-#include "clang/AST/DeclBase.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
index 3ef3cc3f0975..ec1b3b055cab 100644
--- a/include/clang/AST/DeclNodes.def
+++ b/include/clang/AST/DeclNodes.def
@@ -81,6 +81,7 @@ ABSTRACT_DECL(Named, Decl)
DECL(NamespaceAlias, NamedDecl)
ABSTRACT_DECL(Type, NamedDecl)
DECL(Typedef, TypeDecl)
+ DECL(UnresolvedUsingTypename, TypeDecl)
ABSTRACT_DECL(Tag, TypeDecl)
DECL(Enum, TagDecl)
DECL(Record, TagDecl)
@@ -91,6 +92,7 @@ ABSTRACT_DECL(Named, Decl)
DECL(TemplateTypeParm, TypeDecl)
ABSTRACT_DECL(Value, NamedDecl)
DECL(EnumConstant, ValueDecl)
+ DECL(UnresolvedUsingValue, ValueDecl)
ABSTRACT_DECL(Declarator, ValueDecl)
DECL(Function, DeclaratorDecl)
DECL(CXXMethod, FunctionDecl)
@@ -109,7 +111,7 @@ ABSTRACT_DECL(Named, Decl)
DECL(ClassTemplate, TemplateDecl)
DECL(TemplateTemplateParm, TemplateDecl)
DECL(Using, NamedDecl)
- DECL(UnresolvedUsing, NamedDecl)
+ DECL(UsingShadow, NamedDecl)
DECL(ObjCMethod, NamedDecl)
DECL(ObjCContainer, NamedDecl)
DECL(ObjCCategory, ObjCContainerDecl)
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index bcd28eab039f..13193ffab55e 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -718,10 +718,22 @@ public:
/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
///
class ObjCClassDecl : public Decl {
- ObjCList<ObjCInterfaceDecl> ForwardDecls;
+public:
+ class ObjCClassRef {
+ ObjCInterfaceDecl *ID;
+ SourceLocation L;
+ public:
+ ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
+ SourceLocation getLocation() const { return L; }
+ ObjCInterfaceDecl *getInterface() const { return ID; }
+ };
+private:
+ ObjCClassRef *ForwardDecls;
+ unsigned NumDecls;
ObjCClassDecl(DeclContext *DC, SourceLocation L,
- ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C);
+ ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,
+ unsigned nElts, ASTContext &C);
virtual ~ObjCClassDecl() {}
public:
@@ -730,17 +742,19 @@ public:
static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *const *Elts = 0,
+ const SourceLocation *Locs = 0,
unsigned nElts = 0);
+
+ virtual SourceRange getSourceRange() const;
- typedef ObjCList<ObjCInterfaceDecl>::iterator iterator;
- iterator begin() const { return ForwardDecls.begin(); }
- iterator end() const { return ForwardDecls.end(); }
- unsigned size() const { return ForwardDecls.size(); }
+ typedef const ObjCClassRef* iterator;
+ iterator begin() const { return ForwardDecls; }
+ iterator end() const { return ForwardDecls + NumDecls; }
+ unsigned size() const { return NumDecls; }
/// setClassList - Set the list of forward classes.
- void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) {
- ForwardDecls.set(List, Num, C);
- }
+ void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+ const SourceLocation *Locs, unsigned Num);
static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
static bool classof(const ObjCClassDecl *D) { return true; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index f1a27933a1b3..14f666005cd6 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -699,13 +699,13 @@ class TemplateTemplateParmDecl
: public TemplateDecl, protected TemplateParmPosition {
/// \brief The default template argument, if any.
- Expr *DefaultArgument;
+ TemplateArgumentLoc DefaultArgument;
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), DefaultArgument(0)
+ TemplateParmPosition(D, P), DefaultArgument()
{ }
public:
@@ -720,16 +720,17 @@ public:
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return DefaultArgument; }
+ bool hasDefaultArgument() const {
+ return !DefaultArgument.getArgument().isNull();
+ }
/// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const { return DefaultArgument; }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
+ const TemplateArgumentLoc &getDefaultArgument() const {
+ return DefaultArgument;
+ }
/// \brief Set the default argument for this template parameter.
- void setDefaultArgument(Expr *DefArg) {
+ void setDefaultArgument(const TemplateArgumentLoc &DefArg) {
DefaultArgument = DefArg;
}
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index ed4ac6b5d4e7..a30f6e860dde 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -176,7 +176,6 @@ public:
/// getNameKind - Determine what kind of name this is.
NameKind getNameKind() const;
-
/// getName - Retrieve the human-readable string for this name.
std::string getAsString() const;
@@ -249,6 +248,8 @@ public:
static DeclarationName getTombstoneMarker() {
return DeclarationName(uintptr_t(-2));
}
+
+ void dump() const;
};
/// Ordering on two declaration names. If both names are identifiers,
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 2a87f5883588..dfc5b13f28d3 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -87,7 +87,7 @@ public:
// type. Additionally, inspect Expr::isLvalue to determine whether
// an expression that is adjusted in this manner should be
// considered an lvalue.
- assert((TR.isNull() || !TR->isReferenceType()) &&
+ assert((t.isNull() || !t->isReferenceType()) &&
"Expressions can't have reference type");
TR = t;
@@ -250,6 +250,12 @@ public:
/// folded, but discard the result.
bool isEvaluatable(ASTContext &Ctx) const;
+ /// HasSideEffects - This routine returns true for all those expressions
+ /// which must be evaluated each time and must not be optimization away
+ /// or evaluated at compile time. Example is a function call, volatile
+ /// variable read.
+ bool HasSideEffects(ASTContext &Ctx) const;
+
/// EvaluateAsInt - Call Evaluate and return the folded integer. This
/// must be called on an expression that constant folds to an integer.
llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const;
@@ -1513,6 +1519,9 @@ public:
/// CK_NoOp - Used for const_cast.
CK_NoOp,
+ /// CK_BaseToDerived - Base to derived class casts.
+ CK_BaseToDerived,
+
/// CK_DerivedToBase - Derived to base class casts.
CK_DerivedToBase,
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 5931a3fcf984..9e6fd4fd065b 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -95,6 +95,8 @@ public:
/// operation would return "x".
Expr *getImplicitObjectArgument();
+ virtual SourceRange getSourceRange() const;
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXMemberCallExprClass;
}
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 5f318ba0b33b..9b1c640a40b2 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -15,6 +15,8 @@
#define LLVM_CLANG_AST_LAYOUTINFO_H
#include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/DeclCXX.h"
namespace clang {
class ASTContext;
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 1e6871ff3b9c..867932332d09 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "llvm/ADT/PointerIntPair.h"
+#include <iterator>
namespace clang {
@@ -23,6 +24,8 @@ template<typename decl_type>
class Redeclarable {
protected:
+ // FIXME: PointerIntPair is a value class that should not be inherited from.
+ // This should change to using containment.
struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> {
DeclLink(decl_type *D, bool isLatest)
: llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { }
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index bb14c62d7770..6db095872b0e 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/ErrorHandling.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TemplateName.h"
namespace llvm {
class FoldingSetNodeID;
@@ -48,21 +49,27 @@ class TemplateArgument {
public:
/// \brief The type of template argument we're storing.
enum ArgKind {
+ /// \brief Represents an empty template argument, e.g., one that has not
+ /// been deduced.
Null = 0,
/// The template argument is a type. Its value is stored in the
/// TypeOrValue field.
- Type = 1,
- /// The template argument is a declaration
- Declaration = 2,
- /// The template argument is an integral value stored in an llvm::APSInt.
- Integral = 3,
+ Type,
+ /// The template argument is a declaration that was provided for a pointer
+ /// or reference non-type template parameter.
+ Declaration,
+ /// The template argument is an integral value stored in an llvm::APSInt
+ /// that was provided for an integral non-type template parameter.
+ Integral,
+ /// The template argument is a template name that was provided for a
+ /// template template parameter.
+ Template,
/// The template argument is a value- or type-dependent expression
/// stored in an Expr*.
- Expression = 4,
-
+ Expression,
/// The template argument is actually a parameter pack. Arguments are stored
/// in the Args struct.
- Pack = 5
+ Pack
} Kind;
/// \brief Construct an empty, invalid template argument.
@@ -82,12 +89,21 @@ public:
}
/// \brief Construct an integral constant template argument.
- TemplateArgument(const llvm::APSInt &Value, QualType Type)
- : Kind(Integral) {
+ TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
new (Integer.Value) llvm::APSInt(Value);
Integer.Type = Type.getAsOpaquePtr();
}
+ /// \brief Construct a template argument that is a template.
+ ///
+ /// This form of template argument is generally used for template template
+ /// parameters. However, the template name could be a dependent template
+ /// name that ends up being instantiated to a function template whose address
+ /// is taken.
+ TemplateArgument(TemplateName Name) : Kind(Template) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
+ }
+
/// \brief Construct a template argument that is an expression.
///
/// This form of template argument only occurs in template argument
@@ -172,6 +188,15 @@ public:
return reinterpret_cast<Decl *>(TypeOrValue);
}
+ /// \brief Retrieve the template argument as a template name.
+ TemplateName getAsTemplate() const {
+ if (Kind != Template)
+ return TemplateName();
+
+ return TemplateName::getFromVoidPointer(
+ reinterpret_cast<void *> (TypeOrValue));
+ }
+
/// \brief Retrieve the template argument as an integral value.
llvm::APSInt *getAsIntegral() {
if (Kind != Integral)
@@ -242,13 +267,18 @@ private:
union {
Expr *Expression;
DeclaratorInfo *Declarator;
+ struct {
+ unsigned QualifierRange[2];
+ unsigned TemplateNameLoc;
+ } Template;
};
#ifndef NDEBUG
enum Kind {
K_None,
K_DeclaratorInfo,
- K_Expression
+ K_Expression,
+ K_Template
} Kind;
#endif
@@ -273,6 +303,17 @@ public:
, Kind(K_Expression)
#endif
{}
+
+ TemplateArgumentLocInfo(SourceRange QualifierRange,
+ SourceLocation TemplateNameLoc)
+#ifndef NDEBUG
+ : Kind(K_Template)
+#endif
+ {
+ Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
+ Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
+ Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+ }
DeclaratorInfo *getAsDeclaratorInfo() const {
assert(Kind == K_DeclaratorInfo);
@@ -284,6 +325,18 @@ public:
return Expression;
}
+ SourceRange getTemplateQualifierRange() const {
+ assert(Kind == K_Template);
+ return SourceRange(
+ SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
+ SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ assert(Kind == K_Template);
+ return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
+ }
+
#ifndef NDEBUG
void validateForArgument(const TemplateArgument &Arg) {
switch (Arg.getKind()) {
@@ -294,6 +347,9 @@ public:
case TemplateArgument::Declaration:
assert(Kind == K_Expression);
break;
+ case TemplateArgument::Template:
+ assert(Kind == K_Template);
+ break;
case TemplateArgument::Integral:
case TemplateArgument::Pack:
assert(Kind == K_None);
@@ -329,8 +385,18 @@ public:
assert(Argument.getKind() == TemplateArgument::Expression);
}
- /// \brief - Fetches the start location of the argument.
+ TemplateArgumentLoc(const TemplateArgument &Argument,
+ SourceRange QualifierRange,
+ SourceLocation TemplateNameLoc)
+ : Argument(Argument), LocInfo(QualifierRange, TemplateNameLoc) {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ }
+
+ /// \brief - Fetches the primary location of the argument.
SourceLocation getLocation() const {
+ if (Argument.getKind() == TemplateArgument::Template)
+ return getTemplateNameLoc();
+
return getSourceRange().getBegin();
}
@@ -359,6 +425,16 @@ public:
assert(Argument.getKind() == TemplateArgument::Declaration);
return LocInfo.getAsExpr();
}
+
+ SourceRange getTemplateQualifierRange() const {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ return LocInfo.getTemplateQualifierRange();
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ assert(Argument.getKind() == TemplateArgument::Template);
+ return LocInfo.getTemplateNameLoc();
+ }
};
}
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index daa814739182..c28bafe9a30f 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -396,10 +396,6 @@ class QualType {
llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
Qualifiers::FastWidth> Value;
- bool hasExtQuals() const {
- return Value.getPointer().is<const ExtQuals*>();
- }
-
const ExtQuals *getExtQualsUnsafe() const {
return Value.getPointer().get<const ExtQuals*>();
}
@@ -408,6 +404,8 @@ class QualType {
return Value.getPointer().get<const Type*>();
}
+ QualType getUnqualifiedTypeSlow() const;
+
friend class QualifierCollector;
public:
QualType() {}
@@ -417,14 +415,14 @@ public:
QualType(const ExtQuals *Ptr, unsigned Quals)
: Value(Ptr, Quals) {}
- unsigned getFastQualifiers() const { return Value.getInt(); }
- void setFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+ unsigned getLocalFastQualifiers() const { return Value.getInt(); }
+ void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
/// Retrieves a pointer to the underlying (unqualified) type.
/// This should really return a const Type, but it's not worth
/// changing all the users right now.
Type *getTypePtr() const {
- if (hasNonFastQualifiers())
+ if (hasLocalNonFastQualifiers())
return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
return const_cast<Type*>(getTypePtrUnsafe());
}
@@ -452,41 +450,81 @@ public:
return Value.getPointer().isNull();
}
- bool isConstQualified() const {
- return (getFastQualifiers() & Qualifiers::Const);
- }
- bool isRestrictQualified() const {
- return (getFastQualifiers() & Qualifiers::Restrict);
- }
- bool isVolatileQualified() const {
- return (hasNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
- }
-
- // Determines whether this type has any direct qualifiers.
- bool hasQualifiers() const {
- return getFastQualifiers() || hasNonFastQualifiers();
- }
-
- bool hasNonFastQualifiers() const {
- return hasExtQuals();
+ /// \brief Determine whether this particular QualType instance has the
+ /// "const" qualifier set, without looking through typedefs that may have
+ /// added "const" at a different level.
+ bool isLocalConstQualified() const {
+ return (getLocalFastQualifiers() & Qualifiers::Const);
+ }
+
+ /// \brief Determine whether this type is const-qualified.
+ bool isConstQualified() const;
+
+ /// \brief Determine whether this particular QualType instance has the
+ /// "restrict" qualifier set, without looking through typedefs that may have
+ /// added "restrict" at a different level.
+ bool isLocalRestrictQualified() const {
+ return (getLocalFastQualifiers() & Qualifiers::Restrict);
+ }
+
+ /// \brief Determine whether this type is restrict-qualified.
+ bool isRestrictQualified() const;
+
+ /// \brief Determine whether this particular QualType instance has the
+ /// "volatile" qualifier set, without looking through typedefs that may have
+ /// added "volatile" at a different level.
+ bool isLocalVolatileQualified() const {
+ return (hasLocalNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
+ }
+
+ /// \brief Determine whether this type is volatile-qualified.
+ bool isVolatileQualified() const;
+
+ /// \brief Determine whether this particular QualType instance has any
+ /// qualifiers, without looking through any typedefs that might add
+ /// qualifiers at a different level.
+ bool hasLocalQualifiers() const {
+ return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
+ }
+
+ /// \brief Determine whether this type has any qualifiers.
+ bool hasQualifiers() const;
+
+ /// \brief Determine whether this particular QualType instance has any
+ /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
+ /// instance.
+ bool hasLocalNonFastQualifiers() const {
+ return Value.getPointer().is<const ExtQuals*>();
}
- // Retrieves the set of qualifiers belonging to this type.
- Qualifiers getQualifiers() const {
+ /// \brief Retrieve the set of qualifiers local to this particular QualType
+ /// instance, not including any qualifiers acquired through typedefs or
+ /// other sugar.
+ Qualifiers getLocalQualifiers() const {
Qualifiers Quals;
- if (hasNonFastQualifiers())
+ if (hasLocalNonFastQualifiers())
Quals = getExtQualsUnsafe()->getQualifiers();
- Quals.addFastQualifiers(getFastQualifiers());
+ Quals.addFastQualifiers(getLocalFastQualifiers());
return Quals;
}
- // Retrieves the CVR qualifiers of this type.
- unsigned getCVRQualifiers() const {
- unsigned CVR = getFastQualifiers();
- if (isVolatileQualified()) CVR |= Qualifiers::Volatile;
+ /// \brief Retrieve the set of qualifiers applied to this type.
+ Qualifiers getQualifiers() const;
+
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// local to this particular QualType instance, not including any qualifiers
+ /// acquired through typedefs or other sugar.
+ unsigned getLocalCVRQualifiers() const {
+ unsigned CVR = getLocalFastQualifiers();
+ if (isLocalVolatileQualified())
+ CVR |= Qualifiers::Volatile;
return CVR;
}
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// applied to this type.
+ unsigned getCVRQualifiers() const;
+
bool isConstant(ASTContext& Ctx) const {
return QualType::isConstant(*this, Ctx);
}
@@ -508,6 +546,9 @@ public:
Value.setInt(Value.getInt() | TQs);
}
+ // FIXME: The remove* functions are semantically broken, because they might
+ // not remove a qualifier stored on a typedef. Most of the with* functions
+ // have the same problem.
void removeConst();
void removeVolatile();
void removeRestrict();
@@ -540,8 +581,21 @@ public:
return T;
}
- QualType getUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+ /// \brief Return this type with all of the instance-specific qualifiers
+ /// removed, but without removing any qualifiers that may have been applied
+ /// through typedefs.
+ QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+ /// \brief Return the unqualified form of the given type, which might be
+ /// desugared to eliminate qualifiers introduced via typedefs.
+ QualType getUnqualifiedType() const {
+ QualType T = getLocalUnqualifiedType();
+ if (!T.hasQualifiers())
+ return T;
+
+ return getUnqualifiedTypeSlow();
+ }
+
bool isMoreQualifiedThan(QualType Other) const;
bool isAtLeastAsQualifiedAs(QualType Other) const;
QualType getNonReferenceType() const;
@@ -892,8 +946,6 @@ public:
QualType getCanonicalTypeInternal() const { return CanonicalType; }
void dump() const;
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const = 0;
static bool classof(const Type *) { return true; }
};
@@ -963,8 +1015,21 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
+ bool isInteger() const {
+ return TypeKind >= Bool && TypeKind <= Int128;
+ }
+
+ bool isSignedInteger() const {
+ return TypeKind >= Char_S && TypeKind <= Int128;
+ }
+
+ bool isUnsignedInteger() const {
+ return TypeKind >= Bool && TypeKind <= UInt128;
+ }
+
+ bool isFloatingPoint() const {
+ return TypeKind >= Float && TypeKind <= LongDouble;
+ }
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
@@ -988,9 +1053,6 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == FixedWidthInt; }
static bool classof(const FixedWidthIntType *) { return true; }
};
@@ -1008,9 +1070,6 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
public:
QualType getElementType() const { return ElementType; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1036,9 +1095,6 @@ class PointerType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these.
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
QualType getPointeeType() const { return PointeeType; }
bool isSugared() const { return false; }
@@ -1071,9 +1127,6 @@ public:
// Get the pointee type. Pointee is required to always be a function type.
QualType getPointeeType() const { return PointeeType; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1157,9 +1210,6 @@ class LValueReferenceType : public ReferenceType {
{}
friend class ASTContext; // ASTContext creates these
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1177,9 +1227,6 @@ class RValueReferenceType : public ReferenceType {
}
friend class ASTContext; // ASTContext creates these
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1209,9 +1256,6 @@ public:
const Type *getClass() const { return Class; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1302,9 +1346,6 @@ protected:
friend class ASTContext; // ASTContext creates these.
public:
const llvm::APInt &getSize() const { return Size; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1336,9 +1377,6 @@ class IncompleteArrayType : public ArrayType {
: ArrayType(IncompleteArray, et, can, sm, tq) {}
friend class ASTContext; // ASTContext creates these.
public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1402,9 +1440,6 @@ public:
SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1458,9 +1493,6 @@ public:
SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1510,9 +1542,6 @@ public:
QualType getElementType() const { return ElementType; }
SourceLocation getAttributeLoc() const { return loc; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1555,9 +1584,6 @@ public:
QualType getElementType() const { return ElementType; }
unsigned getNumElements() const { return NumElements; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1633,9 +1659,6 @@ public:
return unsigned(idx-1) < NumElements;
return false;
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1699,9 +1722,6 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
public:
// No additional state past what FunctionType provides.
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1812,9 +1832,6 @@ public:
return exception_begin() + NumExceptions;
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -1856,9 +1873,6 @@ public:
bool isSugared() const { return true; }
QualType desugar() const;
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
static bool classof(const TypedefType *) { return true; }
};
@@ -1879,9 +1893,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
static bool classof(const TypeOfExprType *) { return true; }
};
@@ -1924,9 +1935,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
static bool classof(const TypeOfType *) { return true; }
};
@@ -1953,9 +1961,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return !isDependentType(); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
static bool classof(const DecltypeType *) { return true; }
};
@@ -2000,9 +2005,6 @@ public:
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@@ -2117,9 +2119,6 @@ public:
}
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getUnderlyingType(), getTagKind());
}
@@ -2155,9 +2154,6 @@ public:
bool isParameterPack() const { return ParameterPack; }
IdentifierInfo *getName() const { return Name; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2211,9 +2207,6 @@ public:
return getCanonicalTypeInternal();
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return true; }
QualType desugar() const { return getReplacementType(); }
@@ -2309,9 +2302,6 @@ public:
/// \precondition @c isArgType(Arg)
const TemplateArgument &getArg(unsigned Idx) const;
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return !isDependentType(); }
QualType desugar() const { return getCanonicalTypeInternal(); }
@@ -2363,9 +2353,6 @@ public:
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, NNS, NamedType);
}
@@ -2440,9 +2427,6 @@ public:
return Name.dyn_cast<const TemplateSpecializationType *>();
}
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2493,9 +2477,6 @@ public:
qual_iterator qual_end() const { return Protocols.end(); }
bool qual_empty() const { return Protocols.size() == 0; }
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2581,8 +2562,6 @@ public:
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
ObjCProtocolDecl **protocols, unsigned NumProtocols);
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}
@@ -2604,8 +2583,8 @@ public:
/// Collect any qualifiers on the given type and return an
/// unqualified type.
const Type *strip(QualType QT) {
- addFastQualifiers(QT.getFastQualifiers());
- if (QT.hasNonFastQualifiers()) {
+ addFastQualifiers(QT.getLocalFastQualifiers());
+ if (QT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = QT.getExtQualsUnsafe();
Context = &EQ->getContext();
addQualifiers(EQ->getQualifiers());
@@ -2627,18 +2606,51 @@ public:
inline bool QualType::isCanonical() const {
const Type *T = getTypePtr();
- if (hasQualifiers())
+ if (hasLocalQualifiers())
return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
return T->isCanonicalUnqualified();
}
inline bool QualType::isCanonicalAsParam() const {
- if (hasQualifiers()) return false;
+ if (hasLocalQualifiers()) return false;
const Type *T = getTypePtr();
return T->isCanonicalUnqualified() &&
!isa<FunctionType>(T) && !isa<ArrayType>(T);
}
+inline bool QualType::isConstQualified() const {
+ return isLocalConstQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+ return isLocalRestrictQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+ return isLocalVolatileQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalVolatileQualified();
+}
+
+inline bool QualType::hasQualifiers() const {
+ return hasLocalQualifiers() ||
+ getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers();
+}
+
+inline Qualifiers QualType::getQualifiers() const {
+ Qualifiers Quals = getLocalQualifiers();
+ Quals.addQualifiers(
+ getTypePtr()->getCanonicalTypeInternal().getLocalQualifiers());
+ return Quals;
+}
+
+inline unsigned QualType::getCVRQualifiers() const {
+ return getLocalCVRQualifiers() |
+ getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
+}
+
inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const);
}
@@ -2673,14 +2685,14 @@ inline void QualType::removeCVRQualifiers(unsigned Mask) {
/// getAddressSpace - Return the address space of this type.
inline unsigned QualType::getAddressSpace() const {
- if (hasNonFastQualifiers()) {
+ if (hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = getExtQualsUnsafe();
if (EQ->hasAddressSpace())
return EQ->getAddressSpace();
}
QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (CT.hasNonFastQualifiers()) {
+ if (CT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = CT.getExtQualsUnsafe();
if (EQ->hasAddressSpace())
return EQ->getAddressSpace();
@@ -2695,14 +2707,14 @@ inline unsigned QualType::getAddressSpace() const {
/// getObjCGCAttr - Return the gc attribute of this type.
inline Qualifiers::GC QualType::getObjCGCAttr() const {
- if (hasNonFastQualifiers()) {
+ if (hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = getExtQualsUnsafe();
if (EQ->hasObjCGCAttr())
return EQ->getObjCGCAttr();
}
QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (CT.hasNonFastQualifiers()) {
+ if (CT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = CT.getExtQualsUnsafe();
if (EQ->hasObjCGCAttr())
return EQ->getObjCGCAttr();
@@ -2780,28 +2792,26 @@ inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
return 0;
}
-// NOTE: All of these methods use "getUnqualifiedType" to strip off address
-// space qualifiers if present.
inline bool Type::isFunctionType() const {
- return isa<FunctionType>(CanonicalType.getUnqualifiedType());
+ return isa<FunctionType>(CanonicalType);
}
inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType.getUnqualifiedType());
+ return isa<PointerType>(CanonicalType);
}
inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
inline bool Type::isBlockPointerType() const {
- return isa<BlockPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<BlockPointerType>(CanonicalType);
}
inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<ReferenceType>(CanonicalType);
}
inline bool Type::isLValueReferenceType() const {
- return isa<LValueReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<LValueReferenceType>(CanonicalType);
}
inline bool Type::isRValueReferenceType() const {
- return isa<RValueReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<RValueReferenceType>(CanonicalType);
}
inline bool Type::isFunctionPointerType() const {
if (const PointerType* T = getAs<PointerType>())
@@ -2810,7 +2820,7 @@ inline bool Type::isFunctionPointerType() const {
return false;
}
inline bool Type::isMemberPointerType() const {
- return isa<MemberPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<MemberPointerType>(CanonicalType);
}
inline bool Type::isMemberFunctionPointerType() const {
if (const MemberPointerType* T = getAs<MemberPointerType>())
@@ -2819,37 +2829,37 @@ inline bool Type::isMemberFunctionPointerType() const {
return false;
}
inline bool Type::isArrayType() const {
- return isa<ArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<ArrayType>(CanonicalType);
}
inline bool Type::isConstantArrayType() const {
- return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<ConstantArrayType>(CanonicalType);
}
inline bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<IncompleteArrayType>(CanonicalType);
}
inline bool Type::isVariableArrayType() const {
- return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<VariableArrayType>(CanonicalType);
}
inline bool Type::isDependentSizedArrayType() const {
- return isa<DependentSizedArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<DependentSizedArrayType>(CanonicalType);
}
inline bool Type::isRecordType() const {
- return isa<RecordType>(CanonicalType.getUnqualifiedType());
+ return isa<RecordType>(CanonicalType);
}
inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType.getUnqualifiedType());
+ return isa<ComplexType>(CanonicalType);
}
inline bool Type::isVectorType() const {
- return isa<VectorType>(CanonicalType.getUnqualifiedType());
+ return isa<VectorType>(CanonicalType);
}
inline bool Type::isExtVectorType() const {
- return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
+ return isa<ExtVectorType>(CanonicalType);
}
inline bool Type::isObjCObjectPointerType() const {
- return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<ObjCObjectPointerType>(CanonicalType);
}
inline bool Type::isObjCInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
+ return isa<ObjCInterfaceType>(CanonicalType);
}
inline bool Type::isObjCQualifiedIdType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
@@ -2875,7 +2885,7 @@ inline bool Type::isObjCBuiltinType() const {
return isObjCIdType() || isObjCClassType();
}
inline bool Type::isTemplateTypeParmType() const {
- return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
+ return isa<TemplateTypeParmType>(CanonicalType);
}
inline bool Type::isSpecificBuiltinType(unsigned K) const {
@@ -2911,8 +2921,21 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
+// 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.
+template<typename T,
+ bool isArrayType = (llvm::is_same<T, ArrayType>::value ||
+ llvm::is_base_of<ArrayType, T>::value)>
+struct ArrayType_cannot_be_used_with_getAs { };
+
+template<typename T>
+struct ArrayType_cannot_be_used_with_getAs<T, true>;
+
/// Member-template getAs<specific type>'.
template <typename T> const T *Type::getAs() const {
+ ArrayType_cannot_be_used_with_getAs<T> at;
+ (void)at;
+
// If this is directly a T type, return it.
if (const T *Ty = dyn_cast<T>(this))
return Ty;
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index da7857822e9c..f08ca6bf469b 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -58,7 +58,7 @@ public:
: Ty(ty), Data(opaqueData) { }
TypeLocClass getTypeLocClass() const {
- if (getType().hasQualifiers()) return Qualified;
+ if (getType().hasLocalQualifiers()) return Qualified;
return (TypeLocClass) getType()->getTypeClass();
}
@@ -155,7 +155,7 @@ public:
}
static bool classof(const TypeLoc *TL) {
- return !TL->getType().hasQualifiers();
+ return !TL->getType().hasLocalQualifiers();
}
static bool classof(const UnqualTypeLoc *TL) { return true; }
};
@@ -196,11 +196,11 @@ public:
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getLocalDataSize() +
- getFullDataSizeForType(getType().getUnqualifiedType());
+ getFullDataSizeForType(getType().getLocalUnqualifiedType());
}
static bool classof(const TypeLoc *TL) {
- return TL->getType().hasQualifiers();
+ return TL->getType().hasLocalQualifiers();
}
static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
@@ -919,6 +919,10 @@ public:
Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
break;
+ case TemplateArgument::Template:
+ Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+ break;
+
case TemplateArgument::Integral:
case TemplateArgument::Pack:
case TemplateArgument::Null:
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
index 4e1fbaaf4c5e..00e2b7f83219 100644
--- a/include/clang/AST/TypeLocBuilder.h
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -17,6 +17,7 @@
#include "clang/AST/TypeLoc.h"
#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/ASTContext.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 17f772da0c6d..867494396020 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -88,11 +88,11 @@ public:
/// dumpLiveness - Print to stderr the liveness information encoded
/// by a specified bitvector.
- void dumpLiveness(const ValTy& V, SourceManager& M) const;
+ void dumpLiveness(const ValTy& V, const SourceManager& M) const;
/// dumpBlockLiveness - Print to stderr the liveness information
/// associated with each basic block.
- void dumpBlockLiveness(SourceManager& M) const;
+ void dumpBlockLiveness(const SourceManager& M) const;
/// getNumDecls - Return the number of variables (declarations) that
/// whose liveness status is being tracked by the dataflow
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index f505bca9519c..cbf7010bfdb5 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -16,6 +16,7 @@
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/FlowSensitive/DataflowValues.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "functional" // STL
diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h
index 1da15fbae6c4..8c70e4fc7b6c 100644
--- a/include/clang/Analysis/LocalCheckers.h
+++ b/include/clang/Analysis/LocalCheckers.h
@@ -50,10 +50,12 @@ void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
void CheckObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter& BR);
void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
+void RegisterExperimentalChecks(GRExprEngine &Eng);
+void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
-
+void CheckSizeofPointer(const Decl *D, BugReporter &BR);
} // end namespace clang
#endif
diff --git a/include/clang/Analysis/ManagerRegistry.h b/include/clang/Analysis/ManagerRegistry.h
new file mode 100644
index 000000000000..972993855c28
--- /dev/null
+++ b/include/clang/Analysis/ManagerRegistry.h
@@ -0,0 +1,53 @@
+//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- 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 ManagerRegistry and Register* classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
+
+#include "clang/Analysis/PathSensitive/GRState.h"
+
+namespace clang {
+
+/// ManagerRegistry - This class records manager creators registered at
+/// runtime. The information is communicated to AnalysisManager through static
+/// members. Better design is expected.
+
+class ManagerRegistry {
+public:
+ static StoreManagerCreator StoreMgrCreator;
+ static ConstraintManagerCreator ConstraintMgrCreator;
+};
+
+/// RegisterConstraintManager - This class is used to setup the constraint
+/// manager of the static analyzer. The constructor takes a creator function
+/// pointer for creating the constraint manager.
+///
+/// It is used like this:
+///
+/// class MyConstraintManager {};
+/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
+/// return new MyConstraintManager(statemgr);
+/// }
+/// RegisterConstraintManager X(CreateMyConstraintManager);
+
+class RegisterConstraintManager {
+public:
+ RegisterConstraintManager(ConstraintManagerCreator CMC) {
+ assert(ManagerRegistry::ConstraintMgrCreator == 0
+ && "ConstraintMgrCreator already set!");
+ ManagerRegistry::ConstraintMgrCreator = CMC;
+ }
+};
+
+}
+#endif
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index 66e850a91444..9b58f745f0a5 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#include "clang/AST/Stmt.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h
index 488334623b34..18eae9ac9f14 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h
@@ -37,7 +37,6 @@ class AnalysisManager : public BugReporterData {
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
- bool DisplayedFunction;
bool VisualizeEGDot;
bool VisualizeEGUbi;
bool PurgeDead;
@@ -62,7 +61,7 @@ public:
: Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
- AScope(ScopeDecl), DisplayedFunction(!displayProgress),
+ AScope(ScopeDecl),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim) {}
@@ -120,8 +119,6 @@ public:
bool shouldEagerlyAssume() const { return EagerlyAssume; }
- void DisplayFunction(Decl *D);
-
CFG *getCFG(Decl const *D) {
return AnaCtxMgr.getContext(D)->getCFG();
}
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index 914118cb430d..f4297350ec70 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -81,10 +81,10 @@ public:
getOriginalNode(const ExplodedNode* N) = 0;
};
- BugReport(BugType& bt, const char* desc, const ExplodedNode *n)
+ BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *n)
: BT(bt), Description(desc), EndNode(n) {}
- BugReport(BugType& bt, const char* shortDesc, const char* desc,
+ BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc,
const ExplodedNode *n)
: BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
@@ -193,11 +193,11 @@ public:
class RangedBugReport : public BugReport {
std::vector<SourceRange> Ranges;
public:
- RangedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ RangedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
: BugReport(D, description, n) {}
- RangedBugReport(BugType& D, const char *shortDescription,
- const char *description, ExplodedNode *n)
+ RangedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
: BugReport(D, shortDescription, description, n) {}
~RangedBugReport();
@@ -229,11 +229,11 @@ private:
Creators creators;
public:
- EnhancedBugReport(BugType& D, const char* description, ExplodedNode *n)
+ EnhancedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
: RangedBugReport(D, description, n) {}
- EnhancedBugReport(BugType& D, const char *shortDescription,
- const char *description, ExplodedNode *n)
+ EnhancedBugReport(BugType& D, llvm::StringRef shortDescription,
+ llvm::StringRef description, ExplodedNode *n)
: RangedBugReport(D, shortDescription, description, n) {}
~EnhancedBugReport() {}
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h
index 242b8e9afebe..8303dee49afa 100644
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ b/include/clang/Analysis/PathSensitive/BugType.h
@@ -23,6 +23,7 @@ class BugReportEquivClass;
class BugReporter;
class BuiltinBugReport;
class BugReporterContext;
+class ExplodedNode;
class GRExprEngine;
class BugType {
@@ -59,21 +60,27 @@ public:
};
class BuiltinBug : public BugType {
- GRExprEngine &Eng;
+ GRExprEngine *Eng;
protected:
const std::string desc;
public:
+ BuiltinBug(const char *name, const char *description)
+ : BugType(name, "Logic error"), Eng(0), desc(description) {}
+
+ BuiltinBug(const char *name)
+ : BugType(name, "Logic error"), Eng(0), desc(name) {}
+
BuiltinBug(GRExprEngine *eng, const char* n, const char* d)
- : BugType(n, "Logic error"), Eng(*eng), desc(d) {}
+ : BugType(n, "Logic error"), Eng(eng), desc(d) {}
BuiltinBug(GRExprEngine *eng, const char* n)
- : BugType(n, "Logic error"), Eng(*eng), desc(n) {}
+ : BugType(n, "Logic error"), Eng(eng), desc(n) {}
const std::string &getDescription() const { return desc; }
virtual void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {}
- void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, Eng); }
+ void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, *Eng); }
virtual void registerInitialVisitors(BugReporterContext& BRC,
const ExplodedNode* N,
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 4fc0a617ecf0..b7ed20fab250 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -39,22 +39,19 @@ class CheckerContext {
SaveAndRestore<const void*> OldTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
+ const GRState *state;
public:
- CheckerContext(ExplodedNodeSet &dst,
- GRStmtNodeBuilder &builder,
- GRExprEngine &eng,
- ExplodedNode *pred,
- const void *tag, bool preVisit)
+ CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
+ GRExprEngine &eng, ExplodedNode *pred,
+ const void *tag, ProgramPoint::Kind K,
+ const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
- OldSink(B.BuildSinks), OldTag(B.Tag),
- OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) {
- //assert(Dst.empty()); // This is a fake assertion.
- // See GRExprEngine::CheckerVisit(), CurrSet is repeatedly used.
- B.Tag = tag;
- if (preVisit)
- B.PointKind = ProgramPoint::PreStmtKind;
- }
+ OldSink(B.BuildSinks),
+ OldTag(B.Tag, tag),
+ OldPointKind(B.PointKind, K),
+ OldHasGen(B.HasGeneratedNode),
+ state(st) {}
~CheckerContext() {
if (!B.BuildSinks && !B.HasGeneratedNode)
@@ -64,10 +61,15 @@ public:
ConstraintManager &getConstraintManager() {
return Eng.getConstraintManager();
}
+
+ StoreManager &getStoreManager() {
+ return Eng.getStoreManager();
+ }
+
ExplodedNodeSet &getNodeSet() { return Dst; }
GRStmtNodeBuilder &getNodeBuilder() { return B; }
ExplodedNode *&getPredecessor() { return Pred; }
- const GRState *getState() { return B.GetState(Pred); }
+ const GRState *getState() { return state ? state : B.GetState(Pred); }
ASTContext &getASTContext() {
return Eng.getContext();
@@ -76,6 +78,10 @@ public:
BugReporter &getBugReporter() {
return Eng.getBugReporter();
}
+
+ SourceManager &getSourceManager() {
+ return getBugReporter().getSourceManager();
+ }
ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) {
return GenerateNode(S, getState(), markAsSink);
@@ -104,50 +110,69 @@ class Checker {
private:
friend class GRExprEngine;
+ // FIXME: Remove the 'tag' option.
void GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
- const Stmt *stmt,
+ const Stmt *S,
ExplodedNode *Pred, void *tag, bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
- assert(isPrevisit && "Only previsit supported for now.");
- _PreVisit(C, stmt);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
+ if (isPrevisit)
+ _PreVisit(C, S);
+ else
+ _PostVisit(C, S);
}
+ // FIXME: Remove the 'tag' option.
void GR_VisitBind(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
const Stmt *AssignE,
const Stmt *StoreE, ExplodedNode *Pred, void *tag,
SVal location, SVal val,
bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isPrevisit ? ProgramPoint::PreStmtKind :
+ ProgramPoint::PostStmtKind);
assert(isPrevisit && "Only previsit supported for now.");
PreVisitBind(C, AssignE, StoreE, location, val);
}
-
-public:
- virtual ~Checker() {}
- virtual void _PreVisit(CheckerContext &C, const Stmt *ST) {}
- // This is a previsit which takes a node returns a node.
- virtual ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V,
- GRExprEngine &Eng) {
- return Pred;
+ // FIXME: Remove the 'tag' option.
+ void GR_VisitLocation(ExplodedNodeSet &Dst,
+ GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ const Stmt *S,
+ ExplodedNode *Pred, const GRState *state,
+ SVal location,
+ void *tag, bool isLoad) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ isLoad ? ProgramPoint::PreLoadKind :
+ ProgramPoint::PreStoreKind, state);
+ VisitLocation(C, S, location);
}
-
- virtual void PreVisitBind(CheckerContext &C,
- const Stmt *AssignE, const Stmt *StoreE,
- SVal location, SVal val) {}
-
- virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
- const GRState *state, Stmt *S,
- GRExprEngine &Eng) {
- return Pred;
+
+ void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
+ SymbolReaper &SymReaper, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag,
+ ProgramPoint::PostPurgeDeadSymbolsKind, Pred->getState());
+ EvalDeadSymbols(C, S, SymReaper);
}
+public:
+ virtual ~Checker() {}
+ virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
+ virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
+ virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
+ virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+ const Stmt *StoreE, SVal location, SVal val) {}
+ virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
+ SymbolReaper &SymReaper) {}
+ virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
+ GRExprEngine &Eng) {}
};
-
} // end clang namespace
#endif
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
index ff6528dae8f5..090a5d397549 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.def
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
@@ -11,8 +11,19 @@
//
//===---------------------------------------------------------------------===//
+#ifdef PREVISIT
+PREVISIT(ArraySubscriptExpr)
+PREVISIT(BinaryOperator)
PREVISIT(CallExpr)
+PREVISIT(CastExpr)
+PREVISIT(DeclStmt)
PREVISIT(ObjCMessageExpr)
-PREVISIT(BinaryOperator)
-
+PREVISIT(ReturnStmt)
#undef PREVISIT
+#endif
+
+#ifdef POSTVISIT
+POSTVISIT(CallExpr)
+#undef POSTVISIT
+#endif
+
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
index e74f49c9a761..7cef17eb6591 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.h
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
@@ -27,8 +27,12 @@ namespace clang {
template<typename ImplClass>
class CheckerVisitor : public Checker {
public:
- virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) {
- PreVisit(C, stmt);
+ virtual void _PreVisit(CheckerContext &C, const Stmt *S) {
+ PreVisit(C, S);
+ }
+
+ virtual void _PostVisit(CheckerContext &C, const Stmt *S) {
+ PostVisit(C, S);
}
void PreVisit(CheckerContext &C, const Stmt *S) {
@@ -36,10 +40,19 @@ public:
default:
assert(false && "Unsupport statement.");
return;
+
+ case Stmt::ImplicitCastExprClass:
+ case Stmt::ExplicitCastExprClass:
+ case Stmt::CStyleCastExprClass:
+ static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
+ static_cast<const CastExpr*>(S));
+ break;
+
case Stmt::CompoundAssignOperatorClass:
static_cast<ImplClass*>(this)->PreVisitBinaryOperator(C,
static_cast<const BinaryOperator*>(S));
break;
+
#define PREVISIT(NAME) \
case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
@@ -47,13 +60,30 @@ break;
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
}
}
+
+ void PostVisit(CheckerContext &C, const Stmt *S) {
+ switch (S->getStmtClass()) {
+ default:
+ assert(false && "Unsupport statement.");
+ return;
+#define POSTVISIT(NAME) \
+case Stmt::NAME ## Class:\
+static_cast<ImplClass*>(this)->\
+PostVisit ## NAME(C,static_cast<const NAME*>(S));\
+break;
+#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+ }
+ }
#define PREVISIT(NAME) \
void PreVisit ## NAME(CheckerContext &C, const NAME* S) {}
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
+
+#define POSTVISIT(NAME) \
+void PostVisit ## NAME(CheckerContext &C, const NAME* S) {}
+#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
};
} // end clang namespace
#endif
-
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
index 688cf641491d..a84183e7f27f 100644
--- a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
+++ b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
@@ -16,38 +16,16 @@
#ifndef LLVM_CLANG_DEREFCHECKER
#define LLVM_CLANG_DEREFCHECKER
-#include "clang/Analysis/PathSensitive/Checker.h"
-#include "clang/Analysis/PathSensitive/BugType.h"
+#include <utility>
namespace clang {
+class GRExprEngine;
class ExplodedNode;
-class NullDerefChecker : public Checker {
- BuiltinBug *BT;
- llvm::SmallVector<ExplodedNode*, 2> ImplicitNullDerefNodes;
-
-public:
- NullDerefChecker() : BT(0) {}
- ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V,GRExprEngine &Eng);
-
- static void *getTag();
- typedef llvm::SmallVectorImpl<ExplodedNode*>::iterator iterator;
- iterator implicit_nodes_begin() { return ImplicitNullDerefNodes.begin(); }
- iterator implicit_nodes_end() { return ImplicitNullDerefNodes.end(); }
-};
-
-class UndefDerefChecker : public Checker {
- BuiltinBug *BT;
-public:
- UndefDerefChecker() : BT(0) {}
-
- ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
- const GRState *state, SVal V, GRExprEngine &Eng);
-
- static void *getTag();
-};
+std::pair<ExplodedNode * const *, ExplodedNode * const *>
+GetImplicitNullDereferences(GRExprEngine &Eng);
} // end clang namespace
+
#endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 25e47038d72c..1b6d0bdf9c10 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -111,14 +111,6 @@ public:
// was larger than sizeof(void *) (an undefined value).
ErrorNodes NilReceiverLargerThanVoidPtrRetImplicit;
- /// RetsStackAddr - Nodes in the ExplodedGraph that result from returning
- /// the address of a stack variable.
- ErrorNodes RetsStackAddr;
-
- /// RetsUndef - Nodes in the ExplodedGraph that result from returning
- /// an undefined value.
- ErrorNodes RetsUndef;
-
/// UndefBranches - Nodes in the ExplodedGraph that result from
/// taking a branch based on an undefined value.
ErrorNodes UndefBranches;
@@ -131,22 +123,10 @@ public:
// calling a function with the attribute "noreturn".
ErrorNodes NoReturnCalls;
- /// ImplicitBadSizedVLA - Nodes in the ExplodedGraph that result from
- /// constructing a zero-sized VLA where the size may be zero.
- ErrorNodes ImplicitBadSizedVLA;
-
- /// ExplicitBadSizedVLA - Nodes in the ExplodedGraph that result from
- /// constructing a zero-sized VLA where the size must be zero.
- ErrorNodes ExplicitBadSizedVLA;
-
/// UndefResults - Nodes in the ExplodedGraph where the operands are defined
/// by the result is not. Excludes divide-by-zero errors.
ErrorNodes UndefResults;
- /// BadCalls - Nodes in the ExplodedGraph resulting from calls to function
- /// pointers that are NULL (or other constants) or Undefined.
- ErrorNodes BadCalls;
-
/// UndefReceiver - Nodes in the ExplodedGraph resulting from message
/// ObjC message expressions where the receiver is undefined (uninitialized).
ErrorNodes UndefReceivers;
@@ -156,14 +136,6 @@ public:
/// value.
UndefArgsTy MsgExprUndefArgs;
- /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
- /// out-of-bound memory accesses where the index MAY be out-of-bound.
- ErrorNodes ImplicitOOBMemAccesses;
-
- /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
- /// out-of-bound memory accesses where the index MUST be out-of-bound.
- ErrorNodes ExplicitOOBMemAccesses;
-
public:
GRExprEngine(AnalysisManager &mgr);
@@ -223,58 +195,10 @@ public:
return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
}
- bool isRetStackAddr(const ExplodedNode* N) const {
- return N->isSink() && RetsStackAddr.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isUndefControlFlow(const ExplodedNode* N) const {
- return N->isSink() && UndefBranches.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isUndefStore(const ExplodedNode* N) const {
- return N->isSink() && UndefStores.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isImplicitNullDeref(const ExplodedNode* N) const {
- return false;
- }
-
- bool isExplicitNullDeref(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefDeref(const ExplodedNode* N) const {
- return false;
- }
-
bool isNoReturnCall(const ExplodedNode* N) const {
return N->isSink() && NoReturnCalls.count(const_cast<ExplodedNode*>(N)) != 0;
}
- bool isUndefResult(const ExplodedNode* N) const {
- return N->isSink() && UndefResults.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- bool isBadCall(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefArg(const ExplodedNode* N) const {
- return false;
- }
-
- bool isUndefReceiver(const ExplodedNode* N) const {
- return N->isSink() && UndefReceivers.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- typedef ErrorNodes::iterator ret_stackaddr_iterator;
- ret_stackaddr_iterator ret_stackaddr_begin() { return RetsStackAddr.begin(); }
- ret_stackaddr_iterator ret_stackaddr_end() { return RetsStackAddr.end(); }
-
- typedef ErrorNodes::iterator ret_undef_iterator;
- ret_undef_iterator ret_undef_begin() { return RetsUndef.begin(); }
- ret_undef_iterator ret_undef_end() { return RetsUndef.end(); }
-
typedef ErrorNodes::iterator undef_branch_iterator;
undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }
@@ -305,10 +229,6 @@ public:
undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
undef_result_iterator undef_results_end() { return UndefResults.end(); }
- typedef ErrorNodes::iterator bad_calls_iterator;
- bad_calls_iterator bad_calls_begin() { return BadCalls.begin(); }
- bad_calls_iterator bad_calls_end() { return BadCalls.end(); }
-
typedef UndefArgsTy::iterator undef_arg_iterator;
undef_arg_iterator msg_expr_undef_arg_begin() {
return MsgExprUndefArgs.begin();
@@ -327,20 +247,6 @@ public:
return UndefReceivers.end();
}
- typedef ErrorNodes::iterator oob_memacc_iterator;
- oob_memacc_iterator implicit_oob_memacc_begin() {
- return ImplicitOOBMemAccesses.begin();
- }
- oob_memacc_iterator implicit_oob_memacc_end() {
- return ImplicitOOBMemAccesses.end();
- }
- oob_memacc_iterator explicit_oob_memacc_begin() {
- return ExplicitOOBMemAccesses.begin();
- }
- oob_memacc_iterator explicit_oob_memacc_end() {
- return ExplicitOOBMemAccesses.end();
- }
-
void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
void AddCheck(GRSimpleAPICheck* A);
@@ -368,10 +274,7 @@ public:
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function.
- void ProcessEndPath(GREndPathNodeBuilder& builder) {
- getTF().EvalEndPath(*this, builder);
- StateMgr.EndPath(builder.getState());
- }
+ void ProcessEndPath(GREndPathNodeBuilder& builder);
GRStateManager& getStateManager() { return StateMgr; }
const GRStateManager& getStateManager() const { return StateMgr; }
@@ -516,9 +419,6 @@ protected:
void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst,
bool asLValue);
- const GRState* CheckDivideZero(Expr* Ex, const GRState* St, ExplodedNode* Pred,
- SVal Denom);
-
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions.
@@ -553,15 +453,11 @@ public:
}
protected:
- void EvalCall(ExplodedNodeSet& Dst, CallExpr* CE, SVal L, ExplodedNode* Pred);
-
void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, ExplodedNode* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
}
- void EvalReturn(ExplodedNodeSet& Dst, ReturnStmt* s, ExplodedNode* Pred);
-
const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
bool branchTaken);
@@ -573,16 +469,22 @@ protected:
bool atDeclInit = false);
public:
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
- const GRState* St, SVal location, const void *tag = 0);
+ const GRState* St, SVal location, const void *tag = 0,
+ QualType LoadTy = QualType());
- ExplodedNode* EvalLocation(Stmt* Ex, ExplodedNode* Pred,
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
+ void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
const GRState* St, SVal location,
- const void *tag = 0);
+ const void *tag, bool isLoad);
+ // FIXME: 'tag' should be removed, and a LocationContext should be used
+ // instead.
void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
- ExplodedNode* Pred,
- const GRState* St, SVal TargetLV, SVal Val,
+ ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
const void *tag = 0);
};
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index 8678ca9b5b9b..ef0c36c44d9f 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -195,6 +195,9 @@ public:
//
const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const;
+
+ std::pair<const GRState*, const GRState*>
+ Assume(DefinedOrUnknownSVal cond) const;
const GRState *AssumeInBound(DefinedOrUnknownSVal idx,
DefinedOrUnknownSVal upperBound,
@@ -330,12 +333,6 @@ public:
void printStdErr() const;
void printDOT(llvm::raw_ostream& Out) const;
-
- // Tags used for the Generic Data Map.
- struct NullDerefTag {
- static int TagInt;
- typedef const SVal* data_type;
- };
};
class GRStateSet {
@@ -403,10 +400,6 @@ private:
/// Alloc - A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator& Alloc;
- /// CurrentStmt - The block-level statement currently being visited. This
- /// is set by GRExprEngine.
- Stmt* CurrentStmt;
-
/// TF - Object that represents a bundle of transfer functions
/// for manipulating and creating SVals.
GRTransferFuncs* TF;
@@ -583,6 +576,15 @@ inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond),
Assumption);
}
+
+inline std::pair<const GRState*, const GRState*>
+GRState::Assume(DefinedOrUnknownSVal Cond) const {
+ if (Cond.isUnknown())
+ return std::make_pair(this, this);
+
+ return getStateManager().ConstraintMgr->AssumeDual(this,
+ cast<DefinedSVal>(Cond));
+}
inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
DefinedOrUnknownSVal UpperBound,
diff --git a/include/clang/Analysis/PathSensitive/GRWorkList.h b/include/clang/Analysis/PathSensitive/GRWorkList.h
index 17b83fdf9fdc..857fa316911f 100644
--- a/include/clang/Analysis/PathSensitive/GRWorkList.h
+++ b/include/clang/Analysis/PathSensitive/GRWorkList.h
@@ -16,16 +16,19 @@
#define LLVM_CLANG_ANALYSIS_GRWORKLIST
#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+#include <cstddef>
namespace clang {
-
+
+class CFGBlock;
+class ExplodedNode;
class ExplodedNodeImpl;
class GRWorkListUnit {
ExplodedNode* Node;
GRBlockCounter Counter;
CFGBlock* Block;
- unsigned BlockIdx;
+ unsigned BlockIdx; // This is the index of the next statement.
public:
GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 0e487691a891..06d0d976df01 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -77,6 +77,8 @@ public:
const MemRegion *getBaseRegion() const;
+ const MemRegion *StripCasts() const;
+
bool hasStackStorage() const;
bool hasParametersStorage() const;
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h
index 4ba3c7396822..8b5cf40e29cb 100644
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ b/include/clang/Analysis/PathSensitive/SVals.h
@@ -96,6 +96,8 @@ public:
return getRawKind() > UnknownKind;
}
+ bool isConstant() const;
+
bool isZeroConstant() const;
/// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
@@ -434,7 +436,7 @@ public:
return static_cast<MemRegion*>(Data);
}
- const MemRegion* getBaseRegion() const;
+ const MemRegion* StripCasts() const;
template <typename REGION>
const REGION* getRegionAs() const {
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 6ca2e9e9aa68..55fa83d9ecc3 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -102,7 +102,8 @@ public:
virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
// FIXME: Make out-of-line.
- virtual SVal getSizeInElements(const GRState *state, const MemRegion *region){
+ virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
+ const MemRegion *region) {
return UnknownVal();
}
@@ -180,8 +181,7 @@ protected:
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted
/// as another region.
- SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
- const TypedRegion *R, QualType castTy);
+ SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
};
// FIXME: Do we still need this?
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 7aaae9c86653..78827dfabe2f 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -33,13 +33,10 @@ public:
BlockEntranceKind,
BlockExitKind,
PreStmtKind,
- // Keep the following together and in this order.
PostStmtKind,
- PostLocationChecksSucceedKind,
- PostOutOfBoundsCheckFailedKind,
- PostNullCheckFailedKind,
- PostUndefLocationCheckFailedKind,
+ PreLoadKind,
PostLoadKind,
+ PreStoreKind,
PostStoreKind,
PostPurgeDeadSymbolsKind,
PostStmtCustomKind,
@@ -194,17 +191,6 @@ public:
}
};
-class PostLocationChecksSucceed : public PostStmt {
-public:
- PostLocationChecksSucceed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostLocationChecksSucceedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLocationChecksSucceedKind;
- }
-};
-
class PostStmtCustom : public PostStmt {
public:
PostStmtCustom(const Stmt* S,
@@ -226,36 +212,36 @@ public:
}
};
-class PostOutOfBoundsCheckFailed : public PostStmt {
-public:
- PostOutOfBoundsCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostOutOfBoundsCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostOutOfBoundsCheckFailedKind;
+
+class LocationCheck : public StmtPoint {
+protected:
+ LocationCheck(const Stmt *S, const LocationContext *L,
+ ProgramPoint::Kind K, const void *tag)
+ : StmtPoint(S, NULL, K, L, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ unsigned k = location->getKind();
+ return k == PreLoadKind || k == PreStoreKind;
}
};
-
-class PostUndefLocationCheckFailed : public PostStmt {
+
+class PreLoad : public LocationCheck {
public:
- PostUndefLocationCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostUndefLocationCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostUndefLocationCheckFailedKind;
+ PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreLoadKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreLoadKind;
}
};
-class PostNullCheckFailed : public PostStmt {
+class PreStore : public LocationCheck {
public:
- PostNullCheckFailed(const Stmt* S, const LocationContext *L,
- const void *tag = 0)
- : PostStmt(S, PostNullCheckFailedKind, L, tag) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostNullCheckFailedKind;
+ PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
+ : LocationCheck(S, L, PreStoreKind, tag) {}
+
+ static bool classof(const ProgramPoint *location) {
+ return location->getKind() == PreStoreKind;
}
};
diff --git a/include/clang/Analysis/Support/Optional.h b/include/clang/Analysis/Support/Optional.h
index 3940007bb574..40f38be020a9 100644
--- a/include/clang/Analysis/Support/Optional.h
+++ b/include/clang/Analysis/Support/Optional.h
@@ -39,6 +39,9 @@ public:
} //end clang namespace
namespace llvm {
+
+template<typename T> struct simplify_type;
+
template <typename T>
struct simplify_type<const ::clang::Optional<T> > {
typedef const T* SimpleType;
diff --git a/include/clang/Analysis/Support/SaveAndRestore.h b/include/clang/Analysis/Support/SaveAndRestore.h
index 4720c22d990e..f720639490d9 100644
--- a/include/clang/Analysis/Support/SaveAndRestore.h
+++ b/include/clang/Analysis/Support/SaveAndRestore.h
@@ -22,6 +22,9 @@ namespace clang {
template<typename T>
struct SaveAndRestore {
SaveAndRestore(T& x) : X(x), old_value(x) {}
+ SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
+ X = new_value;
+ }
~SaveAndRestore() { X = old_value; }
T get() { return old_value; }
private:
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 77a2079b766d..3a70e134b82b 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -32,6 +32,7 @@ namespace clang {
class IdentifierInfo;
class LangOptions;
class PartialDiagnostic;
+ class Preprocessor;
class SourceRange;
// Import the diagnostic enums themselves.
@@ -105,6 +106,10 @@ public:
/// modification is known.
CodeModificationHint() : RemoveRange(), InsertionLoc() { }
+ bool isNull() const {
+ return !RemoveRange.isValid() && !InsertionLoc.isValid();
+ }
+
/// \brief Create a code modification hint that inserts the given
/// code string at a specific location.
static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
@@ -382,6 +387,7 @@ public:
/// @c Pos represents the source location associated with the diagnostic,
/// which can be an invalid location if no position information is available.
inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
+ inline DiagnosticBuilder Report(unsigned DiagID);
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
@@ -586,6 +592,9 @@ public:
}
void AddCodeModificationHint(const CodeModificationHint &Hint) const {
+ if (Hint.isNull())
+ return;
+
assert(NumCodeModificationHints < Diagnostic::MaxCodeModificationHints &&
"Too many code modification hints!");
if (DiagObj)
@@ -664,6 +673,9 @@ inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
CurDiagID = DiagID;
return DiagnosticBuilder(this);
}
+inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) {
+ return Report(FullSourceLoc(), DiagID);
+}
//===----------------------------------------------------------------------===//
// DiagnosticInfo
@@ -780,7 +792,8 @@ public:
/// \arg LO - The language options for the source file being processed.
/// \arg PP - The preprocessor object being used for the source; this optional
/// and may not be present, for example when processing AST source files.
- virtual void BeginSourceFile(const LangOptions &LangOpts) {}
+ virtual void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP = 0) {}
/// EndSourceFile - Callback to inform the diagnostic client that processing
/// of a source file has ended. The diagnostic client should assume that any
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index bb251ad73bd8..9a342b592ca5 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -52,4 +52,11 @@ def warn_integer_too_large_for_signed : Warning<
def note_invalid_subexpr_in_ice : Note<
"subexpression not valid in an integer constant expression">;
+// Targets
+
+def err_target_unknown_triple : Error<
+ "unknown target triple '%0', please use -triple or -arch">;
+def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
+def err_target_invalid_feature : Error<"invalid target feature '%0'">;
+
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index ae8b92394443..e9b351ffe995 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -9,19 +9,33 @@
let Component = "Frontend" in {
-def err_fe_unknown_triple : Error<
- "unknown target triple '%0', please use -triple or -arch">;
-def err_fe_unknown_target_abi : Error<"unknown target ABI '%0'">;
def err_fe_error_opening : Error<"error opening '%0': %1">;
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;
-def err_fe_invalid_code_complete_file
+def err_fe_invalid_code_complete_file
: Error<"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
"-dependency-file requires at least one -MT 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_verify_bogus_characters : Error<
+ "bogus characters before '{{' in expected string">;
+def err_verify_missing_start : Error<
+ "cannot find start ('{{') of expected string">;
+def err_verify_missing_end : Error<
+ "cannot find end ('}}') of expected string">;
+def err_verify_inconsistent_diags : Error<
+ "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2">;
def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
def note_fixit_in_macro : Note<
@@ -162,6 +176,9 @@ def warn_pch_access_control : Error<
def warn_pch_char_signed : Error<
"char was %select{unsigned|signed}0 in the PCH file but "
"is currently %select{unsigned|signed}1">;
+def warn_pch_short_wchar : Error<
+ "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but "
+ "is currently %select{disabled|enabled}1">;
def err_not_a_pch_file : Error<
"'%0' does not appear to be a precompiled header file">, DefaultFatal;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 8cfdd4095027..93c655b50500 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -28,7 +28,7 @@ def : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
-def : DiagGroup<"conversion">;
+def : DiagGroup<"ctor-dtor-privacy">;
def : DiagGroup<"declaration-after-statement">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
@@ -40,6 +40,7 @@ def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
+def : DiagGroup<"idiomatic-parentheses">;
def : DiagGroup<"import">;
def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
@@ -58,19 +59,21 @@ def MismatchedTags : DiagGroup<"mismatched-tags">;
def : DiagGroup<"missing-field-initializers">;
def NonNull : DiagGroup<"nonnull">;
def : DiagGroup<"nonportable-cfstrings">;
+def : DiagGroup<"non-virtual-dtor">;
def : DiagGroup<"old-style-definition">;
def : DiagGroup<"overflow">;
def : DiagGroup<"overloaded-virtual">;
def : DiagGroup<"packed">;
-def Parentheses : DiagGroup<"parentheses">;
def PointerArith : DiagGroup<"pointer-arith">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def ReturnType : DiagGroup<"return-type">;
+def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def : DiagGroup<"sequence-point">;
def : DiagGroup<"shadow">;
def : DiagGroup<"shorten-64-to-32">;
-def : DiagGroup<"sign-compare">;
+def SignCompare : DiagGroup<"sign-compare">;
+def : DiagGroup<"synth">;
// Preprocessor warnings.
def : DiagGroup<"builtin-macro-redefined">;
@@ -114,6 +117,14 @@ def CharSubscript : DiagGroup<"char-subscripts">;
// Aggregation warning settings.
+// -Widiomatic-parentheses contains warnings about 'idiomatic'
+// missing parentheses; it is off by default.
+def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>;
+
+// -Wconversion has its own warnings, but we split this one out for
+// legacy reasons.
+def Conversion : DiagGroup<"conversion",
+ [DiagGroup<"shorten-64-to-32">]>;
def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
@@ -127,8 +138,9 @@ def FormatY2K : DiagGroup<"format-y2k", [Format]>;
def Format2 : DiagGroup<"format=2",
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
-
def Extra : DiagGroup<"extra", [
+ SemiBeforeMethodBody,
+ SignCompare,
UnusedParameter
]>;
@@ -158,3 +170,7 @@ def : DiagGroup<"all", [Most, Parentheses]>;
def : DiagGroup<"", [Extra]>; // -W = -Wextra
def : DiagGroup<"endif-labels", [ExtraTokens]>; // endif-labels = endif-tokens
+// A warning group for warnings that we want to have on by default in clang,
+// but which aren't on by default in GCC.
+def NonGCC : DiagGroup<"non-gcc",
+ [SignCompare, Conversion]>;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index bbc551373d96..7f3f4ea1fca0 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -90,6 +90,14 @@ def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">;
def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">;
//===----------------------------------------------------------------------===//
+// 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'">;
+
+//===----------------------------------------------------------------------===//
// Preprocessor Diagnostics
//===----------------------------------------------------------------------===//
def pp_hash_warning : Warning<"#warning%0">, InGroup<DiagGroup<"#warnings">>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index e173cffdfd2b..28c46cd2d707 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -201,9 +201,9 @@ def warn_expected_implementation : Warning<
"@end must appear in an @implementation context">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
-def warn_semicolon_before_method_nody : Warning<
+def warn_semicolon_before_method_body : Warning<
"semicolon before method body is ignored">,
- InGroup<DiagGroup<"semicolon-before-method-body">>;
+ InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
def err_expected_field_designator : Error<
"expected a field designator, such as '.field = 4'">;
@@ -230,7 +230,7 @@ def ext_ellipsis_exception_spec : Extension<
def err_expected_catch : Error<"expected catch">;
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
def err_using_namespace_in_class : Error<
- "'using namespace' in class not allowed">;
+ "'using namespace' is not allowed in classes">;
def err_ident_in_pseudo_dtor_not_a_type : Error<
"identifier %0 in pseudo-destructor expression does not name a type">;
@@ -289,6 +289,10 @@ def err_explicit_spec_non_template : Error<
def err_variadic_templates : Error<
"variadic templates are only allowed in C++0x">;
+def err_default_template_template_parameter_not_template : Error<
+ "default template argument for a template template parameter must be a class "
+ "template">;
+
// C++ declarations
def err_friend_decl_defines_class : Error<
"cannot define a type in a friend declaration">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2309908df7b4..78a3ae5d47b7 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -103,6 +103,8 @@ def err_using_requires_qualname : Error<
"using declaration requires a qualified name">;
def err_using_typename_non_type : Error<
"'typename' keyword used on a non-type">;
+def err_using_dependent_value_is_type : Error<
+ "dependent using declaration resolved to type without 'typename'">;
def err_using_decl_nested_name_specifier_is_not_a_base_class : Error<
"using declaration refers into '%0', which is not a base class of %1">;
def err_using_decl_can_not_refer_to_class_member : Error<
@@ -115,6 +117,8 @@ def err_using_decl_destructor : Error<
"using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error<
"using declaration can not refer to a template specialization">;
+def note_using_decl_target : Note<
+ "target of using declaration">;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
@@ -251,6 +255,7 @@ def warn_accessor_property_type_mismatch : Warning<
def note_declared_at : Note<"declared at">;
def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
+def warn_missing_atend : Warning<"'@end' is missing in implementation context">;
def err_objc_var_decl_inclass :
Error<"cannot declare variable inside @interface or @protocol">;
def error_missing_method_context : Error<
@@ -269,6 +274,9 @@ def warn_property_attr_mismatch : Warning<
def warn_objc_property_copy_missing_on_block : Warning<
"'copy' attribute must be specified for the block property "
"when -fobjc-gc-only is specified">;
+def warn_atomic_property_rule : Warning<
+ "writable atomic property %0 cannot pair a synthesized setter/getter "
+ "with a user defined setter/getter">;
def err_use_continuation_class : Error<
"property declaration in continuation class of %0 is to change a 'readonly' "
"property to 'readwrite'">;
@@ -397,7 +405,9 @@ def note_ambig_member_ref_scope : Note<
"lookup from the current scope refers here">;
def err_qualified_member_nonclass : Error<
"qualified member access refers to a member in %0">;
-
+def err_incomplete_member_access : Error<
+ "member access into incomplete type %0">;
+
// C++ class members
def err_storageclass_invalid_for_member : Error<
"storage class specified for a member declaration">;
@@ -430,9 +440,15 @@ def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
-def err_missing_default_constructor : Error<
- "default constructor for %1 is missing in initialization of "
- "%select{base class|member}0">;
+def note_field_decl : Note<"member is declared here">;
+def note_previous_class_decl : Note<
+ "%0 declared here">;
+def note_ctor_synthesized_at : Note<
+ "implicit default constructor for %0 first required here">;
+def err_missing_default_ctor : Error<
+ "%select{|implicit default }0constructor for %1 must explicitly initialize "
+ "the %select{base class|member}2 %3 which does not have a default "
+ "constructor">;
def err_illegal_union_member : Error<
"union member %0 has a non-trivial %select{constructor|"
"copy constructor|copy assignment operator|destructor}1">;
@@ -632,6 +648,25 @@ def err_cconv_knr : Error<
def err_cconv_varargs : Error<
"variadic function cannot use '%0' calling convention">;
+def warn_impcast_vector_scalar : Warning<
+ "implicit cast turns vector to scalar: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_complex_scalar : Warning<
+ "implicit cast discards imaginary component: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_precision : Warning<
+ "implicit cast loses floating-point precision: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_float_integer : Warning<
+ "implicit cast turns floating-point number into integer: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_precision : Warning<
+ "implicit cast loses integer precision: %0 to %1">,
+ InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_integer_64_32 : Warning<
+ "implicit cast loses integer precision: %0 to %1">,
+ InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
+
def warn_attribute_ignored_for_field_of_type : Warning<
"%0 attribute ignored for field of type %1">;
def warn_transparent_union_attribute_field_size_align : Warning<
@@ -744,27 +779,18 @@ def err_param_default_argument_member_template_redecl : Error<
"default arguments cannot be added to an out-of-line definition of a member "
"of a %select{class template|class template partial specialization|nested "
"class in a template}0">;
-def note_field_decl : Note<"member is declared here">;
-def err_defining_default_ctor : Error<
- "cannot define the implicit default constructor for %0, because %select{base class|member's type}1 "
- "%2 does not have any default constructor">;
-def note_previous_class_decl : Note<
- "%0 declared here">;
def err_uninitialized_member_for_assign : Error<
"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_unintialized_member : Error<
- "cannot define the implicit default constructor for %0, because "
- "%select{reference|const}1 member %2 cannot be default-initialized">;
def err_null_intialized_reference_member : Error<
"cannot initialize the member to null in default constructor because "
"reference member %0 cannot be null-initialized">;
def err_unintialized_member_in_ctor : Error<
- "constructor for %0 must explicitly initialize the "
- "%select{reference|const}1 member %2 ">;
+ "%select{|implicit default }0constructor for %1 must explicitly initialize "
+ "the %select{reference|const}2 member %3">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
@@ -993,6 +1019,9 @@ def err_template_spec_friend : Error<
def err_template_spec_default_arg : Error<
"default argument not permitted on an explicit "
"%select{instantiation|specialization}0 of function %1">;
+def err_not_class_template_specialization : Error<
+ "cannot specialize a %select{dependent template|template template "
+ "parameter}0">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<
@@ -1083,6 +1112,12 @@ def note_function_template_deduction_instantiation_here : Note<
def note_partial_spec_deduct_instantiation_here : Note<
"during template argument deduction for class template partial "
"specialization %0, here">;
+def note_prior_template_arg_substitution : Note<
+ "while substituting prior template arguments into %select{non-type|template}0"
+ " template parameter%1 %2">;
+def note_template_default_arg_checking : Note<
+ "while checking a default template argument used here">;
+
def err_field_instantiates_to_function : Error<
"data member instantiated with function type %0">;
def err_nested_name_spec_non_tag : Error<
@@ -1447,8 +1482,9 @@ def err_typecheck_member_reference_type : Error<
"cannot refer to type member %0 with '%select{.|->}1'">;
def err_typecheck_member_reference_unknown : Error<
"cannot refer to member %0 with '%select{.|->}1'">;
-def note_member_reference_needs_call : Note<
- "perhaps you meant to call this function with '()'?">;
+def err_member_reference_needs_call : Error<
+ "base of member reference has function type %0; perhaps you meant to call "
+ "this function with '()'?">;
def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
InGroup<CharSubscript>, DefaultIgnore;
@@ -1488,6 +1524,9 @@ def err_tentative_def_incomplete_type_arr : Error<
"tentative definition has array of type %0 that is never completed">;
def warn_tentative_incomplete_array : Warning<
"tentative array definition assumed to have one element">;
+def err_typecheck_incomplete_array_needs_initializer : Error<
+ "definition of variable with array type needs an explicit size "
+ "or an initializer">;
def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
def err_typecheck_sclass_fscope : Error<
@@ -1539,10 +1578,10 @@ def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
def warn_mixed_sign_comparison : Warning<
"comparison of integers of different signs: %0 and %1">,
- InGroup<DiagGroup<"sign-compare">>;
+ InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
def warn_mixed_sign_conditional : Warning<
"operands of ? are integers of different signs: %0 and %1">,
- InGroup<DiagGroup<"sign-compare">>;
+ InGroup<DiagGroup<"sign-compare">>, DefaultIgnore;
def err_invalid_this_use : Error<
"invalid use of 'this' outside of a nonstatic member function">;
@@ -1707,6 +1746,10 @@ def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
"expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behaviour">;
+def err_no_suitable_delete_member_function_found : Error<
+ "no suitable member %0 in %1">;
+def note_delete_member_function_declared_here : Note<
+ "%0 declared here">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
def warn_increment_bool : Warning<
"incrementing expression of type bool is deprecated">;
@@ -1786,9 +1829,13 @@ def err_incomplete_object_call : Error<
def warn_condition_is_assignment : Warning<"using the result of an "
"assignment as a condition without parentheses">,
InGroup<Parentheses>;
+// Completely identical except off by default.
+def warn_condition_is_idiomatic_assignment : Warning<"using the result "
+ "of an assignment as a condition without parentheses">,
+ InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
-def warn_value_always_zero : Warning<"%0 is always zero in this context">;
-def warn_value_always_false : Warning<"%0 is always false in this context">;
+def warn_value_always_zero : Warning<
+ "%0 is always %select{zero|false|NULL}1 in this context">;
// assignment related diagnostics (also for argument passing, returning, etc).
// FIXME: %2 is an english string here.
@@ -1816,6 +1863,8 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
"incompatible pointer types %2 %1, expected %0">;
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
"%2 %1 discards qualifiers, expected %0">;
+def ext_nested_pointer_qualifier_mismatch : ExtWarn<
+ "%2, %0 and %1 have different qualifiers in nested pointer types">;
def warn_incompatible_vectors : Warning<
"incompatible vector types %2 %1, expected %0">,
InGroup<VectorConversions>, DefaultIgnore;
@@ -2086,6 +2135,10 @@ def err_operator_overload_needs_class_or_enum : Error<
def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
def err_operator_overload_static : Error<
"overloaded %0 cannot be a static member function">;
+def err_operator_new_param_type : Error<
+ "%0 takes type size_t (%1) as first parameter">;
+def err_operator_new_result_type : Error<
+ "%0 must return type %1">;
def err_operator_overload_default_arg : Error<
"parameter of overloaded %0 cannot have a default argument">;
def err_operator_overload_must_be : Error<
@@ -2328,7 +2381,7 @@ def error_private_ivar_access : Error<"instance variable %0 is private">,
NoSFINAE;
def error_protected_ivar_access : Error<"instance variable %0 is protected">,
NoSFINAE;
-def warn_maynot_respond : Warning<"%0 may not respond to %1">;
+def warn_maynot_respond : Warning<"%0 may not respond to %1">;
def warn_attribute_method_def : Warning<
"method attribute can only be specified on method declarations">;
def ext_typecheck_base_super : Warning<
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index d4d3fe50eba0..99c100d55e7e 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -55,6 +55,7 @@ public:
unsigned POSIXThreads : 1; // Compiling with POSIX thread support
// (-pthread)
unsigned Blocks : 1; // block extension to C
+ unsigned BlockIntrospection: 1; // block have ObjC type encodings.
unsigned EmitAllDecls : 1; // Emit all declarations, even if
// they are unused.
unsigned MathErrno : 1; // Math functions must respect errno
@@ -83,6 +84,7 @@ public:
unsigned AccessControl : 1; // Whether C++ access control should
// be enabled.
unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type
+ unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int.
unsigned OpenCL : 1; // OpenCL C99 language extensions.
@@ -125,7 +127,8 @@ public:
ObjCConstantStringClass = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = 0;
- Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
+ Exceptions = Freestanding = NoBuiltin = 0;
+ NeXTRuntime = 1;
Rtti = 1;
LaxVectorConversions = 1;
HeinousExtensions = 0;
@@ -137,6 +140,7 @@ public:
ThreadsafeStatics = 0;
POSIXThreads = 0;
Blocks = 0;
+ BlockIntrospection = 0;
EmitAllDecls = 0;
MathErrno = 1;
@@ -159,6 +163,7 @@ public:
NoInline = 0;
CharIsSigned = 1;
+ ShortWChar = 0;
MainFileName = 0;
}
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index 6ed5fefb7e64..b85eb0725ef0 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -9,12 +9,14 @@ TABLEGEN_INC_FILES_COMMON = 1
include $(LEVEL)/Makefile.common
+INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td)
+
$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN)
$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
$(Verb) -$(MKDIR) $(@D)
$(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
-$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(wildcard Diagnostic*.td) $(TBLGEN)
+$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN)
$(Echo) "Building Clang diagnostic groups with tblgen"
$(Verb) -$(MKDIR) $(@D)
$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index e61ef9265cfb..695f51d2c4c9 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -28,11 +28,12 @@ class StringRef;
}
namespace clang {
-
class Diagnostic;
+class LangOptions;
class SourceLocation;
class SourceManager;
-class LangOptions;
+class TargetOptions;
+
namespace Builtin { struct Info; }
/// TargetInfo - This class exposes information about the current target.
@@ -44,16 +45,12 @@ protected:
// values are specified by the TargetInfo constructor.
bool TLSSupported;
unsigned char PointerWidth, PointerAlign;
- unsigned char WCharWidth, WCharAlign;
- unsigned char Char16Width, Char16Align;
- unsigned char Char32Width, Char32Align;
unsigned char IntWidth, IntAlign;
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
unsigned char LongDoubleWidth, LongDoubleAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
- unsigned char IntMaxTWidth;
const char *DescriptionString;
const char *UserLabelPrefix;
const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
@@ -63,9 +60,9 @@ protected:
TargetInfo(const std::string &T);
public:
- /// CreateTargetInfo - Return the target info object for the specified target
- /// triple.
- static TargetInfo* CreateTargetInfo(const std::string &Triple);
+ /// CreateTargetInfo - Construct a target for the given options.
+ static TargetInfo* CreateTargetInfo(Diagnostic &Diags,
+ const TargetOptions &Opts);
virtual ~TargetInfo();
@@ -103,6 +100,10 @@ public:
/// enum. For example, SignedInt -> getIntWidth().
unsigned getTypeWidth(IntType T) const;
+ /// getTypeAlign - Return the alignment (in bits) of the specified integer
+ /// type enum. For example, SignedInt -> getIntAlign().
+ unsigned getTypeAlign(IntType T) const;
+
/// isTypeSigned - Return whether an integer types is signed. Returns true if
/// the type is signed; false otherwise.
bool isTypeSigned(IntType T) const;
@@ -146,18 +147,18 @@ public:
/// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
/// bits.
- unsigned getWCharWidth() const { return WCharWidth; }
- unsigned getWCharAlign() const { return WCharAlign; }
+ unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
+ unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
/// getChar16Width/Align - Return the size of 'char16_t' for this target, in
/// bits.
- unsigned getChar16Width() const { return Char16Width; }
- unsigned getChar16Align() const { return Char16Align; }
+ unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
+ unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
/// getChar32Width/Align - Return the size of 'char32_t' for this target, in
/// bits.
- unsigned getChar32Width() const { return Char32Width; }
- unsigned getChar32Align() const { return Char32Align; }
+ unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
+ unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
/// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
unsigned getFloatWidth() const { return FloatWidth; }
@@ -180,7 +181,7 @@ public:
/// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
/// target, in bits.
unsigned getIntMaxTWidth() const {
- return IntMaxTWidth;
+ return getTypeWidth(IntMaxType);
}
/// getUserLabelPrefix - This returns the default value of the
@@ -341,10 +342,10 @@ public:
return "";
}
- /// getDefaultLangOptions - Allow the target to specify default settings for
- /// various language options. These may be overridden by command line
- /// options.
- virtual void getDefaultLangOptions(LangOptions &Opts) {}
+ /// setForcedLangOptions - Set forced language options.
+ /// Apply changes to the target information with respect to certain
+ /// language options which change the target configuration.
+ virtual void setForcedLangOptions(LangOptions &Opts);
/// getDefaultFeatures - Get the default set of target features for
/// the \args CPU; this should include all legal feature strings on
@@ -375,9 +376,10 @@ public:
return false;
}
- /// HandleTargetOptions - Perform initialization based on the user
- /// configured set of features.
- virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features) {
+ /// HandleTargetOptions - Perform initialization based on the user configured
+ /// set of features (e.g., +sse4). The list is guaranteed to have at most one
+ /// entry per feature.
+ virtual void HandleTargetFeatures(const std::vector<std::string> &Features) {
}
// getRegParmMax - Returns maximal number of args passed in registers.
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
new file mode 100644
index 000000000000..eeaab1558fd1
--- /dev/null
+++ b/include/clang/Basic/TargetOptions.h
@@ -0,0 +1,39 @@
+//===--- TargetOptions.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// TargetOptions - Options for controlling the target.
+class TargetOptions {
+public:
+
+ /// If given, the name of the target triple to compile for. If not given the
+ /// target will be selected to match the host.
+ std::string Triple;
+
+ /// If given, the name of the target CPU to generate code for.
+ std::string CPU;
+
+ /// If given, the name of the target ABI to use.
+ std::string ABI;
+
+ /// The list of target specific features to enable or disable -- this should
+ /// be a list of strings starting with by '+' or '-'.
+ std::vector<std::string> Features;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
new file mode 100644
index 000000000000..02679cd99895
--- /dev/null
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -0,0 +1,75 @@
+//===--- CodeGenOptions.h ---------------------------------------*- 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 CodeGenOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+#define LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// CodeGenOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+class CodeGenOptions {
+public:
+ enum InliningMethod {
+ NoInlining, // Perform no inlining whatsoever.
+ NormalInlining, // Use the standard function inlining pass.
+ OnlyAlwaysInlining // Only run the always inlining pass.
+ };
+
+ unsigned DebugInfo : 1; /// Should generate deubg info (-g).
+ unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
+ /// getting .bc files that correspond to the
+ /// internal state before optimizations are
+ /// done.
+ unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
+ unsigned MergeAllConstants : 1; /// Merge identical constants.
+ unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
+ unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
+ unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
+ unsigned OptimizeSize : 1; /// If -Os is specified.
+ unsigned SimplifyLibCalls : 1; /// Should standard library calls be treated
+ /// specially.
+ unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
+ unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
+ /// selection.
+ unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
+ unsigned VerifyModule : 1; /// Control whether the module should be run
+ /// through the LLVM Verifier.
+
+ /// Inlining - The kind of inlining to perform.
+ InliningMethod Inlining;
+
+public:
+ CodeGenOptions() {
+ OptimizationLevel = 0;
+ OptimizeSize = 0;
+ DebugInfo = 0;
+ UnitAtATime = 1;
+ SimplifyLibCalls = UnrollLoops = 0;
+ VerifyModule = 1;
+ TimePasses = 0;
+ NoCommon = 0;
+ Inlining = NoInlining;
+ DisableRedZone = 0;
+ NoImplicitFloat = 0;
+ MergeAllConstants = 1;
+ DisableLLVMOpts = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 1871c8f206f3..2a3aa6a90404 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -25,7 +25,7 @@ namespace llvm {
namespace clang {
class Diagnostic;
class LangOptions;
- class CompileOptions;
+ class CodeGenOptions;
class CodeGenerator : public ASTConsumer {
public:
@@ -35,7 +35,7 @@ namespace clang {
CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
const std::string &ModuleName,
- const CompileOptions &CO,
+ const CodeGenOptions &CGO,
llvm::LLVMContext& C);
}
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index c0327a2f1d1c..d3ab1153371a 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -48,7 +48,7 @@ class Driver {
public:
// Diag - Forwarding function for diagnostics.
DiagnosticBuilder Diag(unsigned DiagID) const {
- return Diags.Report(FullSourceLoc(), DiagID);
+ return Diags.Report(DiagID);
}
// FIXME: Privatize once interface is stable.
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index 5370114ee824..2b66b3506b01 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -368,6 +368,7 @@ OPTION("-fastcp", fastcp, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fastf", fastf, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fast", fast, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fasynchronous-unwind-tables", fasynchronous_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fblock-introspection", fblock_introspection, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fblocks", fblocks, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fbootclasspath=", fbootclasspath_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fbuiltin-strcat", fbuiltin_strcat, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -430,6 +431,7 @@ OPTION("-fno-inline", fno_inline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0
OPTION("-fno-keep-inline-functions", fno_keep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-merge-all-constants", fno_merge_all_constants, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fno-ms-extensions", fno_ms_extensions, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-omit-frame-pointer", fno_omit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fno-rtti", fno_rtti, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -448,7 +450,6 @@ OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-tight-layout", fobjc_tight_layout, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fopenmp", fopenmp, Flag, f_Group, INVALID, "", 0, 0, 0)
@@ -463,6 +464,7 @@ OPTION("-fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
OPTION("-frtti", frtti, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fshort-wchar", fshort_wchar, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index b7630d8afdb8..df651a6c3d00 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -90,6 +90,17 @@ public:
/// default.
virtual bool IsMathErrnoDefault() const = 0;
+ /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
+ virtual bool IsBlocksDefault() const { return false; }
+
+ /// IsObjCNonFragileABIDefault - Does this tool chain set
+ /// -fobjc-nonfragile-abi by default.
+ virtual bool IsObjCNonFragileABIDefault() const { return false; }
+
+ /// GetDefaultStackProtectorLevel - Get the default stack protector level for
+ /// this tool chain (0=off, 1=on, 2=all).
+ virtual unsigned GetDefaultStackProtectorLevel() const { return 0; }
+
/// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
/// by default.
virtual bool IsUnwindTablesDefault() const = 0;
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index 92520a77b33b..3a343b385e7a 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -62,6 +62,9 @@ namespace types {
/// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
bool isCXX(ID Id);
+ /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
+ bool isObjC(ID Id);
+
/// lookupTypeForExtension - Lookup the type to use for the file
/// extension \arg Ext.
ID lookupTypeForExtension(const char *Ext);
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 742813c66907..0e7d55e6e45b 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -25,11 +25,12 @@ namespace llvm {
namespace clang {
class ASTConsumer;
+class CodeGenOptions;
class Diagnostic;
class FileManager;
-class Preprocessor;
-class CompileOptions;
class LangOptions;
+class Preprocessor;
+class TargetOptions;
// AST pretty-printer: prints out the AST in a format that is close to the
// original C code. The output is intended to be in a format such that
@@ -69,7 +70,7 @@ ASTConsumer *CreateObjCRewriter(const std::string &InFile,
bool SilenceRewriteMacroWarning);
// LLVM code generator: uses the code generation backend to generate LLVM
-// assembly. This runs optimizations depending on the CompileOptions
+// assembly. This runs optimizations depending on the CodeGenOptions
// parameter. The output depends on the Action parameter.
enum BackendAction {
Backend_EmitAssembly, // Emit native assembly
@@ -80,7 +81,8 @@ enum BackendAction {
ASTConsumer *CreateBackendConsumer(BackendAction Action,
Diagnostic &Diags,
const LangOptions &Features,
- const CompileOptions &CompileOpts,
+ const CodeGenOptions &CodeGenOpts,
+ const TargetOptions &TargetOpts,
const std::string &ModuleID,
llvm::raw_ostream *OS,
llvm::LLVMContext& C);
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index d5e408020a98..7d55673a612f 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -48,6 +48,9 @@ ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars",
ANALYSIS(CheckerCFRef, "checker-cfref",
"Run the [Core] Foundation reference count checker", Code)
+ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
+ "Warn about unintended use of sizeof() on pointer expressions", Code)
+
ANALYSIS(InlineCall, "inline-call",
"Experimental transfer function inling callees when its definition"
" is available.", TranslationUnit)
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
index 34054a7aa00e..7a324331ecdc 100644
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ b/include/clang/Frontend/AnalysisConsumer.h
@@ -1,4 +1,4 @@
-//===--- AnalysisConsumer.h - Front-end hooks for the analysis engine------===//
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,6 +12,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+#define LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H
+
#include <string>
#include <vector>
@@ -50,19 +53,37 @@ enum AnalysisDiagClients {
NUM_ANALYSIS_DIAG_CLIENTS
};
-struct AnalyzerOptions {
+class AnalyzerOptions {
+public:
std::vector<Analyses> AnalysisList;
AnalysisStores AnalysisStoreOpt;
AnalysisConstraints AnalysisConstraintsOpt;
AnalysisDiagClients AnalysisDiagOpt;
- bool VisualizeEGDot;
- bool VisualizeEGUbi;
- bool AnalyzeAll;
- bool AnalyzerDisplayProgress;
- bool PurgeDead;
- bool EagerlyAssume;
std::string AnalyzeSpecificFunction;
- bool TrimGraph;
+ unsigned AnalyzeAll : 1;
+ unsigned AnalyzerDisplayProgress : 1;
+ unsigned EagerlyAssume : 1;
+ unsigned PurgeDead : 1;
+ unsigned TrimGraph : 1;
+ unsigned VisualizeEGDot : 1;
+ unsigned VisualizeEGUbi : 1;
+ unsigned EnableExperimentalChecks : 1;
+ unsigned EnableExperimentalInternalChecks : 1;
+public:
+ AnalyzerOptions() {
+ AnalysisStoreOpt = BasicStoreModel;
+ AnalysisConstraintsOpt = RangeConstraintsModel;
+ AnalysisDiagOpt = PD_HTML;
+ AnalyzeAll = 0;
+ AnalyzerDisplayProgress = 0;
+ EagerlyAssume = 0;
+ PurgeDead = 0;
+ TrimGraph = 0;
+ VisualizeEGDot = 0;
+ VisualizeEGUbi = 0;
+ EnableExperimentalChecks = 0;
+ EnableExperimentalInternalChecks = 0;
+ }
};
/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
@@ -73,3 +94,5 @@ ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
const AnalyzerOptions& Opts);
}
+
+#endif
diff --git a/include/clang/Frontend/ChainedDiagnosticClient.h b/include/clang/Frontend/ChainedDiagnosticClient.h
new file mode 100644
index 000000000000..2d5e128dac37
--- /dev/null
+++ b/include/clang/Frontend/ChainedDiagnosticClient.h
@@ -0,0 +1,58 @@
+//===--- ChainedDiagnosticClient.h - Chain Diagnostic Clients ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+class LangOptions;
+
+/// ChainedDiagnosticClient - Chain two diagnostic clients so that diagnostics
+/// go to the first client and then the second. The first diagnostic client
+/// should be the "primary" client, and will be used for computing whether the
+/// diagnostics should be included in counts.
+class ChainedDiagnosticClient : public DiagnosticClient {
+ llvm::OwningPtr<DiagnosticClient> Primary;
+ llvm::OwningPtr<DiagnosticClient> Secondary;
+
+public:
+ ChainedDiagnosticClient(DiagnosticClient *_Primary,
+ DiagnosticClient *_Secondary) {
+ Primary.reset(_Primary);
+ Secondary.reset(_Secondary);
+ }
+
+ virtual void BeginSourceFile(const LangOptions &LO,
+ const Preprocessor *PP) {
+ Primary->BeginSourceFile(LO, PP);
+ Secondary->BeginSourceFile(LO, PP);
+ }
+
+ virtual void EndSourceFile() {
+ Secondary->EndSourceFile();
+ Primary->EndSourceFile();
+ }
+
+ virtual bool IncludeInDiagnosticCounts() const {
+ return Primary->IncludeInDiagnosticCounts();
+ }
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info) {
+ Primary->HandleDiagnostic(DiagLevel, Info);
+ Secondary->HandleDiagnostic(DiagLevel, Info);
+ }
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
index 59f70ede9129..d5a0598dfab2 100644
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -1,3 +1,4 @@
+
//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
@@ -37,7 +38,7 @@ namespace llvm {
class parser<clang::ParsedSourceLocation>
: public basic_parser<clang::ParsedSourceLocation> {
public:
- bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
+ inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
clang::ParsedSourceLocation &Val);
};
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
new file mode 100644
index 000000000000..ed280508778a
--- /dev/null
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -0,0 +1,523 @@
+//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+
+#include "clang/Frontend/CompilerInvocation.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <cassert>
+#include <list>
+#include <string>
+
+namespace llvm {
+class LLVMContext;
+class raw_ostream;
+class raw_fd_ostream;
+}
+
+namespace clang {
+class ASTContext;
+class ASTConsumer;
+class CodeCompleteConsumer;
+class Diagnostic;
+class DiagnosticClient;
+class ExternalASTSource;
+class FileManager;
+class Preprocessor;
+class Source;
+class SourceManager;
+class TargetInfo;
+
+/// CompilerInstance - Helper class for managing a single instance of the Clang
+/// compiler.
+///
+/// The CompilerInstance serves two purposes:
+/// (1) It manages the various objects which are necessary to run the compiler,
+/// for example the preprocessor, the target information, and the AST
+/// context.
+/// (2) It provides utility routines for constructing and manipulating the
+/// common Clang objects.
+///
+/// The compiler instance generally owns the instance of all the objects that it
+/// manages. However, clients can still share objects by manually setting the
+/// object and retaking ownership prior to destroying the CompilerInstance.
+///
+/// The compiler instance is intended to simplify clients, but not to lock them
+/// in to the compiler instance for everything. When possible, utility functions
+/// come in two forms; a short form that reuses the CompilerInstance objects,
+/// and a long form that takes explicit instances of any required objects.
+class CompilerInstance {
+ /// The LLVM context used for this instance.
+ llvm::LLVMContext *LLVMContext;
+ bool OwnsLLVMContext;
+
+ /// The options used in this compiler instance.
+ CompilerInvocation Invocation;
+
+ /// The diagnostics engine instance.
+ llvm::OwningPtr<Diagnostic> Diagnostics;
+
+ /// The diagnostics client instance.
+ llvm::OwningPtr<DiagnosticClient> DiagClient;
+
+ /// The target being compiled for.
+ llvm::OwningPtr<TargetInfo> Target;
+
+ /// The file manager.
+ llvm::OwningPtr<FileManager> FileMgr;
+
+ /// The source manager.
+ llvm::OwningPtr<SourceManager> SourceMgr;
+
+ /// The preprocessor.
+ llvm::OwningPtr<Preprocessor> PP;
+
+ /// The AST context.
+ llvm::OwningPtr<ASTContext> Context;
+
+ /// The AST consumer.
+ llvm::OwningPtr<ASTConsumer> Consumer;
+
+ /// The code completion consumer.
+ llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+
+ /// The list of active output files.
+ std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
+
+public:
+ /// Create a new compiler instance with the given LLVM context, optionally
+ /// taking ownership of it.
+ CompilerInstance(llvm::LLVMContext *_LLVMContext = 0,
+ bool _OwnsLLVMContext = true);
+ ~CompilerInstance();
+
+ /// @name LLVM Context
+ /// {
+
+ bool hasLLVMContext() const { return LLVMContext != 0; }
+
+ llvm::LLVMContext &getLLVMContext() const {
+ assert(LLVMContext && "Compiler instance has no LLVM context!");
+ return *LLVMContext;
+ }
+
+ /// setLLVMContext - Replace the current LLVM context and take ownership of
+ /// \arg Value.
+ void setLLVMContext(llvm::LLVMContext *Value, bool TakeOwnership = true) {
+ LLVMContext = Value;
+ OwnsLLVMContext = TakeOwnership;
+ }
+
+ /// }
+ /// @name Compiler Invocation and Options
+ /// {
+
+ CompilerInvocation &getInvocation() { return Invocation; }
+ const CompilerInvocation &getInvocation() const { return Invocation; }
+ void setInvocation(const CompilerInvocation &Value) { Invocation = Value; }
+
+ /// }
+ /// @name Forwarding Methods
+ /// {
+
+ AnalyzerOptions &getAnalyzerOpts() {
+ return Invocation.getAnalyzerOpts();
+ }
+ const AnalyzerOptions &getAnalyzerOpts() const {
+ return Invocation.getAnalyzerOpts();
+ }
+
+ CodeGenOptions &getCodeGenOpts() {
+ return Invocation.getCodeGenOpts();
+ }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return Invocation.getCodeGenOpts();
+ }
+
+ DependencyOutputOptions &getDependencyOutputOpts() {
+ return Invocation.getDependencyOutputOpts();
+ }
+ const DependencyOutputOptions &getDependencyOutputOpts() const {
+ return Invocation.getDependencyOutputOpts();
+ }
+
+ DiagnosticOptions &getDiagnosticOpts() {
+ return Invocation.getDiagnosticOpts();
+ }
+ const DiagnosticOptions &getDiagnosticOpts() const {
+ return Invocation.getDiagnosticOpts();
+ }
+
+ FrontendOptions &getFrontendOpts() {
+ return Invocation.getFrontendOpts();
+ }
+ const FrontendOptions &getFrontendOpts() const {
+ return Invocation.getFrontendOpts();
+ }
+
+ HeaderSearchOptions &getHeaderSearchOpts() {
+ return Invocation.getHeaderSearchOpts();
+ }
+ const HeaderSearchOptions &getHeaderSearchOpts() const {
+ return Invocation.getHeaderSearchOpts();
+ }
+
+ LangOptions &getLangOpts() {
+ return Invocation.getLangOpts();
+ }
+ const LangOptions &getLangOpts() const {
+ return Invocation.getLangOpts();
+ }
+
+ PreprocessorOptions &getPreprocessorOpts() {
+ return Invocation.getPreprocessorOpts();
+ }
+ const PreprocessorOptions &getPreprocessorOpts() const {
+ return Invocation.getPreprocessorOpts();
+ }
+
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+ return Invocation.getPreprocessorOutputOpts();
+ }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+ return Invocation.getPreprocessorOutputOpts();
+ }
+
+ TargetOptions &getTargetOpts() {
+ return Invocation.getTargetOpts();
+ }
+ const TargetOptions &getTargetOpts() const {
+ return Invocation.getTargetOpts();
+ }
+
+ /// }
+ /// @name Diagnostics Engine
+ /// {
+
+ bool hasDiagnostics() const { return Diagnostics != 0; }
+
+ Diagnostic &getDiagnostics() const {
+ assert(Diagnostics && "Compiler instance has no diagnostics!");
+ return *Diagnostics;
+ }
+
+ /// takeDiagnostics - Remove the current diagnostics engine and give ownership
+ /// to the caller.
+ Diagnostic *takeDiagnostics() { return Diagnostics.take(); }
+
+ /// setDiagnostics - Replace the current diagnostics engine; the compiler
+ /// instance takes ownership of \arg Value.
+ void setDiagnostics(Diagnostic *Value);
+
+ DiagnosticClient &getDiagnosticClient() const {
+ assert(Target && "Compiler instance has no diagnostic client!");
+ return *DiagClient;
+ }
+
+ /// takeDiagnosticClient - Remove the current diagnostics client and give
+ /// ownership to the caller.
+ DiagnosticClient *takeDiagnosticClient() { return DiagClient.take(); }
+
+ /// setDiagnosticClient - Replace the current diagnostics client; the compiler
+ /// instance takes ownership of \arg Value.
+ void setDiagnosticClient(DiagnosticClient *Value);
+
+ /// }
+ /// @name Target Info
+ /// {
+
+ bool hasTarget() const { return Target != 0; }
+
+ TargetInfo &getTarget() const {
+ assert(Target && "Compiler instance has no target!");
+ return *Target;
+ }
+
+ /// takeTarget - Remove the current diagnostics engine and give ownership
+ /// to the caller.
+ TargetInfo *takeTarget() { return Target.take(); }
+
+ /// setTarget - Replace the current diagnostics engine; the compiler
+ /// instance takes ownership of \arg Value.
+ void setTarget(TargetInfo *Value);
+
+ /// }
+ /// @name File Manager
+ /// {
+
+ bool hasFileManager() const { return FileMgr != 0; }
+
+ FileManager &getFileManager() const {
+ assert(FileMgr && "Compiler instance has no file manager!");
+ return *FileMgr;
+ }
+
+ /// takeFileManager - Remove the current file manager and give ownership to
+ /// the caller.
+ FileManager *takeFileManager() { return FileMgr.take(); }
+
+ /// setFileManager - Replace the current file manager; the compiler instance
+ /// takes ownership of \arg Value.
+ void setFileManager(FileManager *Value);
+
+ /// }
+ /// @name Source Manager
+ /// {
+
+ bool hasSourceManager() const { return SourceMgr != 0; }
+
+ SourceManager &getSourceManager() const {
+ assert(SourceMgr && "Compiler instance has no source manager!");
+ return *SourceMgr;
+ }
+
+ /// takeSourceManager - Remove the current source manager and give ownership
+ /// to the caller.
+ SourceManager *takeSourceManager() { return SourceMgr.take(); }
+
+ /// setSourceManager - Replace the current source manager; the compiler
+ /// instance takes ownership of \arg Value.
+ void setSourceManager(SourceManager *Value);
+
+ /// }
+ /// @name Preprocessor
+ /// {
+
+ bool hasPreprocessor() const { return PP != 0; }
+
+ Preprocessor &getPreprocessor() const {
+ assert(PP && "Compiler instance has no preprocessor!");
+ return *PP;
+ }
+
+ /// takePreprocessor - Remove the current preprocessor and give ownership to
+ /// the caller.
+ Preprocessor *takePreprocessor() { return PP.take(); }
+
+ /// setPreprocessor - Replace the current preprocessor; the compiler instance
+ /// takes ownership of \arg Value.
+ void setPreprocessor(Preprocessor *Value);
+
+ /// }
+ /// @name ASTContext
+ /// {
+
+ bool hasASTContext() const { return Context != 0; }
+
+ ASTContext &getASTContext() const {
+ assert(Context && "Compiler instance has no AST context!");
+ return *Context;
+ }
+
+ /// takeASTContext - Remove the current AST context and give ownership to the
+ /// caller.
+ ASTContext *takeASTContext() { return Context.take(); }
+
+ /// setASTContext - Replace the current AST context; the compiler instance
+ /// takes ownership of \arg Value.
+ void setASTContext(ASTContext *Value);
+
+ /// }
+ /// @name ASTConsumer
+ /// {
+
+ bool hasASTConsumer() const { return Consumer != 0; }
+
+ ASTConsumer &getASTConsumer() const {
+ assert(Consumer && "Compiler instance has no AST consumer!");
+ return *Consumer;
+ }
+
+ /// takeASTConsumer - Remove the current AST consumer and give ownership to
+ /// the caller.
+ ASTConsumer *takeASTConsumer() { return Consumer.take(); }
+
+ /// setASTConsumer - Replace the current AST consumer; the compiler instance
+ /// takes ownership of \arg Value.
+ void setASTConsumer(ASTConsumer *Value);
+
+ /// }
+ /// @name Code Completion
+ /// {
+
+ bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
+
+ CodeCompleteConsumer &getCodeCompletionConsumer() const {
+ assert(CompletionConsumer &&
+ "Compiler instance has no code completion consumer!");
+ return *CompletionConsumer;
+ }
+
+ /// takeCodeCompletionConsumer - Remove the current code completion consumer
+ /// and give ownership to the caller.
+ CodeCompleteConsumer *takeCodeCompletionConsumer() {
+ return CompletionConsumer.take();
+ }
+
+ /// setCodeCompletionConsumer - Replace the current code completion consumer;
+ /// the compiler instance takes ownership of \arg Value.
+ void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
+
+ /// }
+ /// @name Output Files
+ /// {
+
+ /// getOutputFileList - Get the list of (path, output stream) pairs of output
+ /// files; the path may be empty but the stream will always be non-null.
+ const std::list< std::pair<std::string,
+ llvm::raw_ostream*> > &getOutputFileList() const;
+
+ /// addOutputFile - Add an output file onto the list of tracked output files.
+ ///
+ /// \param Path - The path to the output file, or empty.
+ /// \param OS - The output stream, which should be non-null.
+ void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS);
+
+ /// ClearOutputFiles - Clear the output file list, destroying the contained
+ /// output streams.
+ ///
+ /// \param EraseFiles - If true, attempt to erase the files from disk.
+ void ClearOutputFiles(bool EraseFiles);
+
+ /// }
+ /// @name Construction Utility Methods
+ /// {
+
+ /// Create the diagnostics engine using the invocation's diagnostic options
+ /// and replace any existing one with it.
+ ///
+ /// Note that this routine also replaces the diagnostic client.
+ void createDiagnostics(int Argc, char **Argv);
+
+ /// Create a Diagnostic object with a the TextDiagnosticPrinter.
+ ///
+ /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
+ /// when the diagnostic options indicate that the compiler should output
+ /// logging information.
+ ///
+ /// Note that this creates an unowned DiagnosticClient, if using directly the
+ /// caller is responsible for releaseing the returned Diagnostic's client
+ /// eventually.
+ ///
+ /// \return The new object on success, or null on failure.
+ static Diagnostic *createDiagnostics(const DiagnosticOptions &Opts,
+ int Argc, char **Argv);
+
+ /// Create the file manager and replace any existing one with it.
+ void createFileManager();
+
+ /// Create the source manager and replace any existing one with it.
+ void createSourceManager();
+
+ /// Create the preprocessor, using the invocation, file, and source managers,
+ /// and replace any existing one with it.
+ void createPreprocessor();
+
+ /// Create a Preprocessor object.
+ ///
+ /// Note that this also creates a new HeaderSearch object which will be owned
+ /// by the resulting Preprocessor.
+ ///
+ /// \return The new object on success, or null on failure.
+ static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
+ const PreprocessorOptions &,
+ const HeaderSearchOptions &,
+ const DependencyOutputOptions &,
+ const TargetInfo &,
+ SourceManager &, FileManager &);
+
+ /// Create the AST context.
+ void createASTContext();
+
+ /// Create an external AST source to read a PCH file and attach it to the AST
+ /// context.
+ void createPCHExternalASTSource(llvm::StringRef Path);
+
+ /// Create an external AST source to read a PCH file.
+ ///
+ /// \return - The new object on success, or null on failure.
+ static ExternalASTSource *
+ createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
+ Preprocessor &PP, ASTContext &Context);
+
+ /// Create a code completion consumer using the invocation; note that this
+ /// will cause the source manager to truncate the input source file at the
+ /// completion point.
+ void createCodeCompletionConsumer();
+
+ /// Create a code completion consumer to print code completion results, at
+ /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
+ /// OS.
+ static CodeCompleteConsumer *
+ createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
+ unsigned Line, unsigned Column,
+ bool UseDebugPrinter, bool ShowMacros,
+ llvm::raw_ostream &OS);
+
+ /// Create the default output file (from the invocation's options) and add it
+ /// to the list of tracked output files.
+ llvm::raw_fd_ostream *
+ createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "");
+
+ /// Create a new output file and add it to the list of tracked output files,
+ /// optionally deriving the output path name.
+ llvm::raw_fd_ostream *
+ createOutputFile(llvm::StringRef OutputPath, bool Binary = true,
+ llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "");
+
+ /// Create a new output file, optionally deriving the output path name.
+ ///
+ /// If \arg OutputPath is empty, then createOutputFile will derive an output
+ /// path location as \arg BaseInput, with any suffix removed, and \arg
+ /// Extension appended.
+ ///
+ /// \param OutputPath - If given, the path to the output file.
+ /// \param Error [out] - On failure, the error message.
+ /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
+ /// for deriving the output path.
+ /// \param Extension - The extension to use for derived output names.
+ /// \param Binary - The mode to open the file in.
+ /// \param ResultPathName [out] - If given, the result path name will be
+ /// stored here on success.
+ static llvm::raw_fd_ostream *
+ createOutputFile(llvm::StringRef OutputPath, std::string &Error,
+ bool Binary = true, llvm::StringRef BaseInput = "",
+ llvm::StringRef Extension = "",
+ std::string *ResultPathName = 0);
+
+ /// }
+ /// @name Initialization Utility Methods
+ /// {
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ bool InitializeSourceManager(llvm::StringRef InputFile);
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ static bool InitializeSourceManager(llvm::StringRef InputFile,
+ Diagnostic &Diags,
+ FileManager &FileMgr,
+ SourceManager &SourceMgr,
+ const FrontendOptions &Opts);
+
+ /// }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
new file mode 100644
index 000000000000..9d068c523c69
--- /dev/null
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -0,0 +1,150 @@
+//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/CodeGen/CodeGenOptions.h"
+#include "clang/Frontend/AnalysisConsumer.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/HeaderSearchOptions.h"
+#include "clang/Frontend/PreprocessorOptions.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+ template<typename T> class SmallVectorImpl;
+}
+
+namespace clang {
+
+/// CompilerInvocation - Helper class for holding the data necessary to invoke
+/// the compiler.
+///
+/// This class is designed to represent an abstract "invocation" of the
+/// compiler, including data such as the include paths, the code generation
+/// options, the warning flags, and so on.
+class CompilerInvocation {
+ /// Options controlling the static analyzer.
+ AnalyzerOptions AnalyzerOpts;
+
+ /// Options controlling IRgen and the backend.
+ CodeGenOptions CodeGenOpts;
+
+ /// Options controlling dependency output.
+ DependencyOutputOptions DependencyOutputOpts;
+
+ /// Options controlling the diagnostic engine.
+ DiagnosticOptions DiagnosticOpts;
+
+ /// Options controlling the frontend itself.
+ FrontendOptions FrontendOpts;
+
+ /// Options controlling the #include directive.
+ HeaderSearchOptions HeaderSearchOpts;
+
+ /// Options controlling the language variant.
+ LangOptions LangOpts;
+
+ /// Options controlling the preprocessor (aside from #include handling).
+ PreprocessorOptions PreprocessorOpts;
+
+ /// Options controlling preprocessed output.
+ PreprocessorOutputOptions PreprocessorOutputOpts;
+
+ /// Options controlling the target.
+ TargetOptions TargetOpts;
+
+public:
+ CompilerInvocation() {}
+
+ /// @name Utility Methods
+ /// @{
+
+ /// CreateFromArgs - Create a compiler invocation from a list of input
+ /// options.
+ ///
+ /// FIXME: Documenting error behavior.
+ ///
+ /// \param Res [out] - The resulting invocation.
+ /// \param Args - The input argument strings.
+ static void CreateFromArgs(CompilerInvocation &Res,
+ const llvm::SmallVectorImpl<llvm::StringRef> &Args);
+
+ /// toArgs - Convert the CompilerInvocation to a list of strings suitable for
+ /// passing to CreateFromArgs.
+ void toArgs(std::vector<std::string> &Res);
+
+ /// @}
+ /// @name Option Subgroups
+ /// @{
+
+ AnalyzerOptions &getAnalyzerOpts() { return AnalyzerOpts; }
+ const AnalyzerOptions &getAnalyzerOpts() const {
+ return AnalyzerOpts;
+ }
+
+ CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return CodeGenOpts;
+ }
+
+ DependencyOutputOptions &getDependencyOutputOpts() {
+ return DependencyOutputOpts;
+ }
+ const DependencyOutputOptions &getDependencyOutputOpts() const {
+ return DependencyOutputOpts;
+ }
+
+ DiagnosticOptions &getDiagnosticOpts() { return DiagnosticOpts; }
+ const DiagnosticOptions &getDiagnosticOpts() const { return DiagnosticOpts; }
+
+ HeaderSearchOptions &getHeaderSearchOpts() { return HeaderSearchOpts; }
+ const HeaderSearchOptions &getHeaderSearchOpts() const {
+ return HeaderSearchOpts;
+ }
+
+ FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+ const FrontendOptions &getFrontendOpts() const {
+ return FrontendOpts;
+ }
+
+ LangOptions &getLangOpts() { return LangOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
+
+ PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; }
+ const PreprocessorOptions &getPreprocessorOpts() const {
+ return PreprocessorOpts;
+ }
+
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+ return PreprocessorOutputOpts;
+ }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+ return PreprocessorOutputOpts;
+ }
+
+ TargetOptions &getTargetOpts() { return TargetOpts; }
+ const TargetOptions &getTargetOpts() const {
+ return TargetOpts;
+ }
+
+ /// @}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
new file mode 100644
index 000000000000..ab8e49df9a88
--- /dev/null
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -0,0 +1,43 @@
+//===--- DependencyOutputOptions.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// DependencyOutputOptions - Options for controlling the compiler dependency
+/// file generation.
+class DependencyOutputOptions {
+public:
+ unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
+ unsigned UsePhonyTargets : 1; ///< Include phony targets for each
+ /// dependency, which can avoid some 'make'
+ /// problems.
+
+ /// The file to write depencency output to.
+ std::string OutputFile;
+
+ /// A list of names to use as the targets in the dependency file; this list
+ /// must contain at least one entry.
+ std::vector<std::string> Targets;
+
+public:
+ DependencyOutputOptions() {
+ IncludeSystemHeaders = 0;
+ UsePhonyTargets = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
index 58673e4dad6b..6346dc0bfdec 100644
--- a/include/clang/Frontend/DiagnosticOptions.h
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -19,6 +19,10 @@ namespace clang {
/// engine.
class DiagnosticOptions {
public:
+ unsigned IgnoreWarnings : 1; /// -w
+ unsigned NoRewriteMacros : 1; /// -Wno-rewrite-macros
+ unsigned Pedantic : 1; /// -pedantic
+ unsigned PedanticErrors : 1; /// -pedantic-errors
unsigned ShowColumn : 1; /// Show column number on diagnostics.
unsigned ShowLocation : 1; /// Show source location information.
unsigned ShowCarets : 1; /// Show carets in diagnostics.
@@ -27,20 +31,36 @@ public:
unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable
/// diagnostics.
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
+ unsigned VerifyDiagnostics; /// Check that diagnostics match the expected
+ /// diagnostics, indicated by markers in the
+ /// input source file.
/// Column limit for formatting message diagnostics, or 0 if unused.
unsigned MessageLength;
+ /// If non-empty, a file to log extended build information to, for development
+ /// testing and analysis.
+ std::string DumpBuildInformation;
+
+ /// The list of -W... options used to alter the diagnostic mappings, with the
+ /// prefixes removed.
+ std::vector<std::string> Warnings;
+
public:
DiagnosticOptions() {
- ShowColumn = 1;
- ShowLocation = 1;
+ IgnoreWarnings = 0;
+ MessageLength = 0;
+ NoRewriteMacros = 0;
+ Pedantic = 0;
+ PedanticErrors = 0;
ShowCarets = 1;
+ ShowColors = 0;
+ ShowColumn = 1;
ShowFixits = 1;
- ShowSourceRanges = 0;
+ ShowLocation = 1;
ShowOptionNames = 0;
- ShowColors = 0;
- MessageLength = 0;
+ ShowSourceRanges = 0;
+ VerifyDiagnostics = 0;
}
};
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
new file mode 100644
index 000000000000..469ea535f6aa
--- /dev/null
+++ b/include/clang/Frontend/FrontendAction.h
@@ -0,0 +1,215 @@
+//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <string>
+
+namespace llvm {
+class Timer;
+}
+
+namespace clang {
+class ASTUnit;
+class ASTConsumer;
+class CompilerInstance;
+
+/// FrontendAction - Abstract base class for actions which can be performed by
+/// the frontend.
+class FrontendAction {
+ std::string CurrentFile;
+ llvm::OwningPtr<ASTUnit> CurrentASTUnit;
+ CompilerInstance *Instance;
+ llvm::Timer *CurrentTimer;
+
+protected:
+ /// @name Implementation Action Interface
+ /// @{
+
+ /// CreateASTConsumer - Create the AST consumer object for this action, if
+ /// supported.
+ ///
+ /// This routine is called as part of \see BeginSourceAction(), which will
+ /// fail if the AST consumer cannot be created. This will not be called if the
+ /// action has indicated that it only uses the preprocessor.
+ ///
+ /// \param CI - The current compiler instance, provided as a convenience, \see
+ /// getCompilerInstance().
+ ///
+ /// \param InFile - The current input file, provided as a convenience, \see
+ /// getCurrentFile().
+ ///
+ /// \return The new AST consumer, or 0 on failure.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) = 0;
+
+ /// BeginSourceFileAction - Callback at the start of processing a single
+ /// input.
+ ///
+ /// \return True on success; on failure \see ExecutionAction() and
+ /// EndSourceFileAction() will not be called.
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename) {
+ return true;
+ }
+
+ /// ExecuteAction - Callback to run the program action, using the initialized
+ /// compiler instance.
+ ///
+ /// This routine is guaranteed to only be called between \see
+ /// BeginSourceFileAction() and \see EndSourceFileAction().
+ virtual void ExecuteAction() = 0;
+
+ /// EndSourceFileAction - Callback at the end of processing a single input;
+ /// this is guaranteed to only be called following a successful call to
+ /// BeginSourceFileAction (and BeingSourceFile).
+ virtual void EndSourceFileAction() {}
+
+ /// @}
+
+public:
+ FrontendAction();
+ virtual ~FrontendAction();
+
+ /// @name Compiler Instance Access
+ /// @{
+
+ CompilerInstance &getCompilerInstance() const {
+ assert(Instance && "Compiler instance not registered!");
+ return *Instance;
+ }
+
+ void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
+
+ /// @}
+ /// @name Current File Information
+ /// @{
+
+ bool isCurrentFileAST() const {
+ assert(!CurrentFile.empty() && "No current file!");
+ return CurrentASTUnit != 0;
+ }
+
+ const std::string &getCurrentFile() const {
+ assert(!CurrentFile.empty() && "No current file!");
+ return CurrentFile;
+ }
+
+ ASTUnit &getCurrentASTUnit() const {
+ assert(!CurrentASTUnit && "No current AST unit!");
+ return *CurrentASTUnit;
+ }
+
+ void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
+
+ /// @}
+ /// @name Timing Utilities
+ /// @{
+
+ llvm::Timer *getCurrentTimer() const {
+ return CurrentTimer;
+ }
+
+ void setCurrentTimer(llvm::Timer *Value) {
+ CurrentTimer = Value;
+ }
+
+ /// @}
+ /// @name Supported Modes
+ /// @{
+
+ /// usesPreprocessorOnly - Does this action only use the preprocessor? If so
+ /// no AST context will be created and this action will be invalid with PCH
+ /// inputs.
+ virtual bool usesPreprocessorOnly() const = 0;
+
+ /// usesCompleteTranslationUnit - For AST based actions, should the
+ /// translation unit be completed?
+ virtual bool usesCompleteTranslationUnit() { return true; }
+
+ /// hasPCHSupport - Does this action support use with PCH?
+ virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasASTSupport - Does this action support use with AST files?
+ virtual bool hasASTSupport() const { return !usesPreprocessorOnly(); }
+
+ /// hasCodeCompletionSupport - Does this action support use with code
+ /// completion?
+ virtual bool hasCodeCompletionSupport() const { return false; }
+
+ /// @}
+ /// @name Public Action Interface
+ /// @{
+
+ /// BeginSourceFile - Prepare the action for processing the input file \arg
+ /// Filename; this is run after the options and frontend have been
+ /// initialized, but prior to executing any per-file processing.
+ ///
+ /// \param CI - The compiler instance this action is being run from. The
+ /// action may store and use this object up until the matching EndSourceFile
+ /// action.
+ ///
+ /// \param Filename - The input filename, which will be made available to
+ /// clients via \see getCurrentFile().
+ ///
+ /// \param IsAST - Indicates whether this is an AST input. AST inputs require
+ /// special handling, since the AST file itself contains several objects which
+ /// would normally be owned by the CompilerInstance. When processing AST input
+ /// files, these objects should generally not be initialized in the
+ /// CompilerInstance -- they will automatically be shared with the AST file in
+ /// between \see BeginSourceFile() and \see EndSourceFile().
+ ///
+ /// \return True on success; the compilation of this file should be aborted
+ /// and neither Execute nor EndSourceFile should be called.
+ bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename,
+ bool IsAST = false);
+
+ /// Execute - Set the source managers main input file, and run the action.
+ void Execute();
+
+ /// EndSourceFile - Perform any per-file post processing, deallocate per-file
+ /// objects, and run statistics and output file cleanup code.
+ void EndSourceFile();
+
+ /// @}
+};
+
+/// ASTFrontendAction - Abstract base class to use for AST consumer based
+/// frontend actios.
+class ASTFrontendAction : public FrontendAction {
+ /// ExecuteAction - Implement the ExecuteAction interface by running Sema on
+ /// the already initialized AST consumer.
+ ///
+ /// This will also take care of instantiating a code completion consumer if
+ /// the user requested it and the action supports it.
+ virtual void ExecuteAction();
+
+public:
+ virtual bool usesPreprocessorOnly() const { return false; }
+};
+
+/// PreprocessorFrontendAction - Abstract base class to use for preprocessor
+/// based frontend actions.
+class PreprocessorFrontendAction : public FrontendAction {
+protected:
+ /// CreateASTConsumer - Provide a default implementation which returns aborts,
+ /// this method should never be called by FrontendAction clients.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ virtual bool usesPreprocessorOnly() const { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
new file mode 100644
index 000000000000..e755fe1b1b5f
--- /dev/null
+++ b/include/clang/Frontend/FrontendActions.h
@@ -0,0 +1,216 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+class FixItRewriter;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTPrintXMLAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTDumpAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class ASTViewAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class DeclContextPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class DumpRecordAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class FixItAction : public ASTFrontendAction {
+private:
+ llvm::OwningPtr<FixItRewriter> Rewriter;
+
+protected:
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename);
+
+ virtual void EndSourceFileAction();
+
+ virtual bool hasASTSupport() const { return false; }
+
+public:
+ FixItAction();
+ ~FixItAction();
+};
+
+class GeneratePCHAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual bool usesCompleteTranslationUnit() { return false; }
+
+ virtual bool hasASTSupport() const { return false; }
+};
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class InheritanceViewAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class RewriteBlocksAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class SyntaxOnlyAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+public:
+ virtual bool hasCodeCompletionSupport() const { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Code Gen AST Actions
+//===----------------------------------------------------------------------===//
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+ unsigned Act;
+
+protected:
+ CodeGenAction(unsigned _Act);
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+public:
+ EmitAssemblyAction();
+};
+
+class EmitBCAction : public CodeGenAction {
+public:
+ EmitBCAction();
+};
+
+class EmitLLVMAction : public CodeGenAction {
+public:
+ EmitLLVMAction();
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+public:
+ EmitLLVMOnlyAction();
+};
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+class DumpRawTokensAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class DumpTokensAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class GeneratePTHAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class ParseOnlyAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PreprocessOnlyAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PrintParseAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class PrintPreprocessedAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+
+ virtual bool hasPCHSupport() const { return true; }
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+ void ExecuteAction();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
new file mode 100644
index 000000000000..197a2a05e5e0
--- /dev/null
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -0,0 +1,131 @@
+//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+
+#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+ enum ActionKind {
+ ASTDump, ///< Parse ASTs and dump them.
+ ASTPrint, ///< Parse ASTs and print them.
+ ASTPrintXML, ///< Parse ASTs and print them in XML.
+ ASTView, ///< Parse ASTs and view them in Graphviz.
+ DumpRawTokens, ///< Dump out raw tokens.
+ DumpRecordLayouts, ///< Dump record layout information.
+ DumpTokens, ///< Dump out preprocessed tokens.
+ EmitAssembly, ///< Emit a .s file.
+ EmitBC, ///< Emit a .bc file.
+ EmitHTML, ///< Translate input source into HTML.
+ EmitLLVM, ///< Emit a .ll file.
+ EmitLLVMOnly, ///< Generate LLVM IR, but do not
+ FixIt, ///< Parse and apply any fixits to the source.
+ GeneratePCH, ///< Generate pre-compiled header.
+ GeneratePTH, ///< Generate pre-tokenized header.
+ InheritanceView, ///< View C++ inheritance for a specified class.
+ ParseNoop, ///< Parse with noop callbacks.
+ ParsePrintCallbacks, ///< Parse and print each callback.
+ ParseSyntaxOnly, ///< Parse and perform semantic analysis.
+ PluginAction, ///< Run a plugin action, \see ActionName.
+ PrintDeclContext, ///< Print DeclContext and their Decls.
+ PrintPreprocessedInput, ///< -E mode.
+ RewriteBlocks, ///< ObjC->C Rewriter for Blocks.
+ RewriteMacros, ///< Expand macros but not #includes.
+ RewriteObjC, ///< ObjC->C Rewriter.
+ RewriteTest, ///< Rewriter playground
+ RunAnalysis, ///< Run one or more source code analyses.
+ RunPreprocessorOnly ///< Just lex, no output.
+ };
+}
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+ enum InputKind {
+ IK_None,
+ IK_Asm,
+ IK_C,
+ IK_CXX,
+ IK_ObjC,
+ IK_ObjCXX,
+ IK_PreprocessedC,
+ IK_PreprocessedCXX,
+ IK_PreprocessedObjC,
+ IK_PreprocessedObjCXX,
+ IK_OpenCL,
+ IK_AST
+ };
+
+ unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code
+ /// completion results.
+ unsigned DisableFree : 1; ///< Disable memory freeing on exit.
+ unsigned EmptyInputOnly : 1; ///< Force input files to be treated
+ /// as if they were empty, for timing
+ /// the frontend startup.
+ unsigned RelocatablePCH : 1; ///< When generating PCH files,
+ /// instruct the PCH writer to create
+ /// relocatable PCH files.
+ unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
+ /// results.
+ unsigned ShowStats : 1; ///< Show frontend performance
+ /// metrics and statistics.
+ unsigned ShowTimers : 1; ///< Show timers for individual
+ /// actions.
+
+ /// The input files and their types.
+ std::vector<std::pair<InputKind, std::string> > Inputs;
+
+ /// The output file, if any.
+ std::string OutputFile;
+
+ /// If given, the name for a C++ class to view the inheritance of.
+ std::string ViewClassInheritance;
+
+ /// A list of locations to apply fix-its at.
+ std::vector<ParsedSourceLocation> FixItLocations;
+
+ /// If given, enable code completion at the provided location.
+ ParsedSourceLocation CodeCompletionAt;
+
+ /// The frontend action to perform.
+ frontend::ActionKind ProgramAction;
+
+ /// The name of the action to run when using a plugin action.
+ std::string ActionName;
+
+public:
+ FrontendOptions() {
+ DebugCodeCompletionPrinter = 0;
+ DisableFree = 0;
+ EmptyInputOnly = 0;
+ ProgramAction = frontend::ParseSyntaxOnly;
+ ActionName = "";
+ RelocatablePCH = 0;
+ ShowMacrosInCodeCompletion = 0;
+ ShowStats = 0;
+ ShowTimers = 0;
+ }
+
+ /// getInputKindForExtension - Return the appropriate input kind for a file
+ /// extension. For example, "c" would return IK_C.
+ ///
+ /// \return The input kind for the extension, or IK_None if the extension is
+ /// not recognized.
+ static InputKind getInputKindForExtension(llvm::StringRef Extension);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
new file mode 100644
index 000000000000..8341492cfd23
--- /dev/null
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -0,0 +1,23 @@
+//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+
+/// The frontend plugin registry.
+typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
new file mode 100644
index 000000000000..2edc7e1f4ab4
--- /dev/null
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -0,0 +1,87 @@
+//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+#define LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+ /// IncludeDirGroup - Identifiers the group a include entry belongs to, which
+ /// represents its relative positive in the search list.
+ enum IncludeDirGroup {
+ Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`.
+ Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`)
+ System, ///< Like Angled, but marks system directories.
+ After ///< Like System, but searched after the system directories.
+ };
+}
+
+/// HeaderSearchOptions - Helper class for storing options related to the
+/// initialization of the HeaderSearch object.
+class HeaderSearchOptions {
+public:
+ struct Entry {
+ std::string Path;
+ frontend::IncludeDirGroup Group;
+ unsigned IsUserSupplied : 1;
+ unsigned IsFramework : 1;
+
+ Entry(llvm::StringRef _Path, frontend::IncludeDirGroup _Group,
+ bool _IsUserSupplied, bool _IsFramework)
+ : Path(_Path), Group(_Group), IsUserSupplied(_IsUserSupplied),
+ IsFramework(_IsFramework) {}
+ };
+
+ /// If non-empty, the directory to use as a "virtual system root" for include
+ /// paths.
+ std::string Sysroot;
+
+ /// User specified include entries.
+ std::vector<Entry> UserEntries;
+
+ /// A (system-path) delimited list of include paths to be added from the
+ /// environment following the user specified includes (but prior to builtin
+ /// and standard includes). This is parsed in the same manner as the CPATH
+ /// environment variable for gcc.
+ std::string EnvIncPath;
+
+ /// Per-language environmental include paths, see \see EnvIncPath.
+ std::string CEnvIncPath;
+ std::string ObjCEnvIncPath;
+ std::string CXXEnvIncPath;
+ std::string ObjCXXEnvIncPath;
+
+ /// If non-empty, the path to the compiler builtin include directory, which
+ /// will be searched following the user and environment includes.
+ std::string BuiltinIncludePath;
+
+ /// Include the system standard include search directories.
+ unsigned UseStandardIncludes : 1;
+
+ /// Whether header search information should be output as for -v.
+ unsigned Verbose : 1;
+
+public:
+ HeaderSearchOptions(llvm::StringRef _Sysroot = "")
+ : Sysroot(_Sysroot), UseStandardIncludes(true) {}
+
+ /// AddPath - Add the \arg Path path to the specified \arg Group list.
+ void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
+ bool IsUserSupplied, bool IsFramework) {
+ UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework));
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index cc8b3a03e3e8..85861fab4a22 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -29,6 +29,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/System/DataTypes.h"
#include <deque>
@@ -78,7 +79,7 @@ public:
/// \brief Receives the target triple.
///
/// \returns true to indicate the target triple is invalid or false otherwise.
- virtual bool ReadTargetTriple(const std::string &Triple) {
+ virtual bool ReadTargetTriple(llvm::StringRef Triple) {
return false;
}
@@ -87,18 +88,18 @@ public:
/// \param PCHPredef The start of the predefines buffer in the PCH
/// file.
///
- /// \param PCHPredefLen The length of the predefines buffer in the PCH
- /// file.
- ///
/// \param PCHBufferID The FileID for the PCH predefines buffer.
///
+ /// \param OriginalFileName The original file name for the PCH, which will
+ /// appear as an entry in the predefines buffer.
+ ///
/// \param SuggestedPredefines If necessary, additional definitions are added
/// here.
///
/// \returns true to indicate the predefines are invalid or false otherwise.
- virtual bool ReadPredefinesBuffer(const char *PCHPredef,
- unsigned PCHPredefLen,
+ virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
std::string &SuggestedPredefines) {
return false;
}
@@ -123,10 +124,10 @@ public:
: PP(PP), Reader(Reader), NumHeaderInfos(0) {}
virtual bool ReadLanguageOptions(const LangOptions &LangOpts);
- virtual bool ReadTargetTriple(const std::string &Triple);
- virtual bool ReadPredefinesBuffer(const char *PCHPredef,
- unsigned PCHPredefLen,
+ virtual bool ReadTargetTriple(llvm::StringRef Triple);
+ virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
std::string &SuggestedPredefines);
virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI);
virtual void ReadCounter(unsigned Value);
@@ -312,10 +313,13 @@ private:
/// the PCH file.
llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls;
- /// \brief The original file name that was used to build the PCH
- /// file.
+ /// \brief The original file name that was used to build the PCH file, which
+ /// may have been modified for relocatable-pch support.
std::string OriginalFileName;
+ /// \brief The actual original file name that was used to build the PCH file.
+ std::string ActualOriginalFileName;
+
/// \brief Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH;
@@ -444,9 +448,7 @@ private:
void MaybeAddSystemRootToFilename(std::string &Filename);
PCHReadResult ReadPCHBlock();
- bool CheckPredefinesBuffer(const char *PCHPredef,
- unsigned PCHPredefLen,
- FileID PCHBufferID);
+ bool CheckPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID);
bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record);
PCHReadResult ReadSourceManagerBlock();
PCHReadResult ReadSLocEntryRecord(unsigned ID);
@@ -625,13 +627,15 @@ public:
/// \brief Retrieve the IdentifierInfo for the named identifier.
///
- /// This routine builds a new IdentifierInfo for the given
- /// identifier. If any declarations with this name are visible from
- /// translation unit scope, their declarations will be deserialized
- /// and introduced into the declaration chain of the
- /// identifier. FIXME: if this identifier names a macro, deserialize
- /// the macro.
+ /// This routine builds a new IdentifierInfo for the given identifier. If any
+ /// declarations with this name are visible from translation unit scope, their
+ /// declarations will be deserialized and introduced into the declaration
+ /// chain of the identifier. FIXME: if this identifier names a macro,
+ /// deserialize the macro.
virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd);
+ IdentifierInfo* get(llvm::StringRef Name) {
+ return get(Name.begin(), Name.end());
+ }
/// \brief Load the contents of the global method pool for a given
/// selector.
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 22427eb67103..b520f4be1d31 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -52,7 +52,8 @@ struct UnsafeQualTypeDenseMapInfo {
return QualType::getFromOpaquePtr((void*) 2);
}
static inline unsigned getHashValue(QualType T) {
- assert(!T.getFastQualifiers() && "hash invalid for types with fast quals");
+ assert(!T.getLocalFastQualifiers() &&
+ "hash invalid for types with fast quals");
uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
}
diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h
new file mode 100644
index 000000000000..f0c1d3c2c38d
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -0,0 +1,57 @@
+//===--- PreprocessorOptionms.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class LangOptions;
+
+/// PreprocessorOptions - This class is used for passing the various options
+/// used in preprocessor initialization to InitializePreprocessor().
+class PreprocessorOptions {
+public:
+ std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+ std::vector<std::string> Includes;
+ std::vector<std::string> MacroIncludes;
+
+ unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
+ /// and target specific predefines.
+
+ /// The implicit PCH included at the start of the translation unit, or empty.
+ std::string ImplicitPCHInclude;
+
+ /// The implicit PTH input included at the start of the translation unit, or
+ /// empty.
+ std::string ImplicitPTHInclude;
+
+ /// If given, a PTH cache file to use for speeding up header parsing.
+ std::string TokenCache;
+
+public:
+ PreprocessorOptions() : UsePredefines(true) {}
+
+ void addMacroDef(llvm::StringRef Name) {
+ Macros.push_back(std::make_pair(Name, false));
+ }
+ void addMacroUndef(llvm::StringRef Name) {
+ Macros.push_back(std::make_pair(Name, true));
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
new file mode 100644
index 000000000000..a712a3d1bb05
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -0,0 +1,37 @@
+//===--- PreprocessorOutputOptions.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+
+namespace clang {
+
+/// PreprocessorOutputOptions - Options for controlling the C preprocessor
+/// output (e.g., -E).
+class PreprocessorOutputOptions {
+public:
+ unsigned ShowCPP : 1; ///< Print normal preprocessed output.
+ unsigned ShowMacros : 1; ///< Print macro definitions.
+ unsigned ShowLineMarkers : 1; ///< Show #line markers.
+ unsigned ShowComments : 1; ///< Show comments.
+ unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+
+public:
+ PreprocessorOutputOptions() {
+ ShowCPP = 1;
+ ShowMacros = 0;
+ ShowLineMarkers = 1;
+ ShowComments = 0;
+ ShowMacroComments = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 3c5c6267c632..d727e4800727 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -34,12 +34,15 @@ class TextDiagnosticPrinter : public DiagnosticClient {
SourceLocation LastWarningLoc;
FullSourceLoc LastLoc;
- bool LastCaretDiagnosticWasNote;
+ unsigned LastCaretDiagnosticWasNote : 1;
+ unsigned OwnsOutputStream : 1;
public:
- TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags);
+ TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags,
+ bool OwnsOutputStream = false);
+ virtual ~TextDiagnosticPrinter();
- void BeginSourceFile(const LangOptions &LO) {
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
LangOpts = &LO;
}
diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def
index 6aca15a75427..35f5debe5cf0 100644
--- a/include/clang/Frontend/TypeXML.def
+++ b/include/clang/Frontend/TypeXML.def
@@ -65,9 +65,9 @@
NODE_XML(QualType, "CvQualifiedType")
ID_ATTRIBUTE_XML
TYPE_ATTRIBUTE_XML(getTypePtr()) // the qualified type, e.g. for 'T* const' it's 'T*'
- ATTRIBUTE_OPT_XML(isConstQualified(), "const") // boolean
- ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile") // boolean
- ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict") // boolean
+ ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const") // boolean
+ ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile") // boolean
+ ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict") // boolean
ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc") // Qualifiers::GC
ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned
END_NODE_XML
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 3c670286545b..27c14c917015 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -1,4 +1,4 @@
-//===--- Utils.h - Misc utilities for the front-end------------------------===//
+//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,42 +14,57 @@
#ifndef LLVM_CLANG_FRONTEND_UTILS_H
#define LLVM_CLANG_FRONTEND_UTILS_H
+#include "llvm/ADT/StringRef.h"
#include <vector>
#include <string>
namespace llvm {
+class Triple;
class raw_ostream;
class raw_fd_ostream;
}
namespace clang {
-class Preprocessor;
-class MinimalAction;
-class TargetInfo;
-class Diagnostic;
class ASTConsumer;
+class Decl;
+class DependencyOutputOptions;
+class Diagnostic;
+class DiagnosticOptions;
+class HeaderSearch;
+class HeaderSearchOptions;
class IdentifierTable;
-class SourceManager;
class LangOptions;
-class Decl;
+class MinimalAction;
+class Preprocessor;
+class PreprocessorOptions;
+class PreprocessorOutputOptions;
+class SourceManager;
class Stmt;
+class TargetInfo;
+
+/// Normalize \arg File for use in a user defined #include directive (in the
+/// predefines buffer).
+std::string NormalizeDashIncludePath(llvm::StringRef File);
+
+/// Apply the header search options to get given HeaderSearch object.
+void ApplyHeaderSearchOptions(HeaderSearch &HS,
+ const HeaderSearchOptions &HSOpts,
+ const LangOptions &Lang,
+ const llvm::Triple &triple);
+
+/// InitializePreprocessor - Initialize the preprocessor getting it and the
+/// environment ready to process a single file.
+void InitializePreprocessor(Preprocessor &PP,
+ const PreprocessorOptions &PPOpts,
+ const HeaderSearchOptions &HSOpts);
/// ProcessWarningOptions - Initialize the diagnostic client and process the
/// warning options specified on the command line.
-bool ProcessWarningOptions(Diagnostic &Diags,
- std::vector<std::string> &Warnings,
- bool Pedantic, bool PedanticErrors,
- bool NoWarnings);
-
-/// DoPrintPreprocessedInput - Implement -E -dM mode.
-void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream* OS);
+bool ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS,
- bool EnableCommentOutput,
- bool EnableMacroCommentOutput,
- bool DisableLineMarkers,
- bool DumpDefines);
+ const PreprocessorOutputOptions &Opts);
/// RewriteMacrosInInput - Implement -rewrite-macros mode.
void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS);
@@ -67,13 +82,12 @@ bool CheckDiagnostics(Preprocessor &PP);
/// AttachDependencyFileGen - Create a dependency file generator, and attach
/// it to the given preprocessor. This takes ownership of the output stream.
-void AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS,
- std::vector<std::string> &Targets,
- bool IncludeSystemHeaders, bool PhonyTarget);
+void AttachDependencyFileGen(Preprocessor &PP,
+ const DependencyOutputOptions &Opts);
/// CacheTokens - Cache tokens for use with PCH. Note that this requires
/// a seekable stream.
-void CacheTokens(Preprocessor& PP, llvm::raw_fd_ostream* OS);
+void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
} // end namespace clang
diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h
new file mode 100644
index 000000000000..6f7ebbe537f9
--- /dev/null
+++ b/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -0,0 +1,82 @@
+//===-- VerifyDiagnosticsClient.h - Verifying Diagnostic Client -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace clang {
+
+class Diagnostic;
+class SourceMgr;
+class TextDiagnosticBuffer;
+
+/// VerifyDiagnosticsClient - Create a diagnostic client which will use markers
+/// in the input source to check that all the emitted diagnostics match those
+/// expected.
+///
+/// USING THE DIAGNOSTIC CHECKER:
+///
+/// Indicating that a line expects an error or a warning is simple. Put a
+/// comment on the line that has the diagnostic, use "expected-{error,warning}"
+/// to tag if it's an expected error or warning, and place the expected text
+/// between {{ and }} markers. The full text doesn't have to be included, only
+/// enough to ensure that the correct diagnostic was emitted.
+///
+/// Here's an example:
+///
+/// int A = B; // expected-error {{use of undeclared identifier 'B'}}
+///
+/// You can place as many diagnostics on one line as you wish. To make the code
+/// more readable, you can use slash-newline to separate out the diagnostics.
+///
+/// The simple syntax above allows each specification to match exactly one
+/// error. You can use the extended syntax to customize this. The extended
+/// syntax is "expected-<type> <n> {{diag text}}", where <type> is one of
+/// "error", "warning" or "note", and <n> is a positive integer. This allows the
+/// diagnostic to appear as many times as specified. Example:
+///
+/// void f(); // expected-note 2 {{previous declaration is here}}
+///
+class VerifyDiagnosticsClient : public DiagnosticClient {
+public:
+ Diagnostic &Diags;
+ llvm::OwningPtr<DiagnosticClient> PrimaryClient;
+ llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
+ Preprocessor *CurrentPreprocessor;
+ unsigned NumErrors;
+
+private:
+ void CheckDiagnostics();
+
+public:
+ /// Create a new verifying diagnostic client, which will issue errors to \arg
+ /// PrimaryClient when a diagnostic does not match what is expected (as
+ /// indicated in the source file). The verifying diagnostic client takes
+ /// ownership of \arg PrimaryClient.
+ VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient);
+ ~VerifyDiagnosticsClient();
+
+ virtual void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP);
+
+ virtual void EndSourceFile();
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+
+ /// HadErrors - Check if there were any mismatches in expected diagnostics.
+ bool HadErrors();
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index ff1a17259e8a..ac5594e55d7d 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -119,8 +119,7 @@ public:
/// Create - This method creates PTHManager objects. The 'file' argument
/// is the name of the PTH file. This method returns NULL upon failure.
- static PTHManager *Create(const std::string& file, Diagnostic* Diags = 0,
- Diagnostic::Level failureLevel=Diagnostic::Warning);
+ static PTHManager *Create(const std::string& file, Diagnostic &Diags);
void setPreprocessor(Preprocessor *pp) { PP = pp; }
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 2783716b89ff..1c0036e3edcb 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -51,7 +51,7 @@ class DirectoryLookup;
class Preprocessor {
Diagnostic *Diags;
LangOptions Features;
- TargetInfo &Target;
+ const TargetInfo &Target;
FileManager &FileMgr;
SourceManager &SourceMgr;
ScratchBuffer *ScratchBuf;
@@ -94,6 +94,9 @@ class Preprocessor {
bool DisableMacroExpansion : 1; // True if macro expansion is disabled.
bool InMacroArgs : 1; // True if parsing fn macro invocation args.
+ /// Whether the preprocessor owns the header search object.
+ bool OwnsHeaderSearch : 1;
+
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
@@ -207,9 +210,11 @@ private: // Cached tokens state.
std::vector<CachedTokensTy::size_type> BacktrackPositions;
public:
- Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
+ Preprocessor(Diagnostic &diags, const LangOptions &opts,
+ const TargetInfo &target,
SourceManager &SM, HeaderSearch &Headers,
- IdentifierInfoLookup *IILookup = 0);
+ IdentifierInfoLookup *IILookup = 0,
+ bool OwnsHeaderSearch = false);
~Preprocessor();
@@ -217,7 +222,7 @@ public:
void setDiagnostics(Diagnostic &D) { Diags = &D; }
const LangOptions &getLangOptions() const { return Features; }
- TargetInfo &getTargetInfo() const { return Target; }
+ const TargetInfo &getTargetInfo() const { return Target; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
@@ -498,6 +503,15 @@ public:
/// UCNs, etc.
std::string getSpelling(const Token &Tok) const;
+ /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
+ /// token is the characters used to represent the token in the source file
+ /// after trigraph expansion and escaped-newline folding. In particular, this
+ /// wants to get the true, uncanonicalized, spelling of things like digraphs
+ /// UCNs, etc.
+ static std::string getSpelling(const Token &Tok,
+ const SourceManager &SourceMgr,
+ const LangOptions &Features);
+
/// getSpelling - This method is used to get the spelling of a token into a
/// preallocated buffer, instead of as an std::string. The caller is required
/// to allocate enough space for the token, which is guaranteed to be at least
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 8d910959b9fa..604eae1027aa 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -248,69 +248,6 @@ struct PPConditionalInfo {
bool FoundElse;
};
-/// TemplateIdAnnotation - Information about a template-id annotation
-/// token, which contains the template declaration, template
-/// arguments, whether those template arguments were types or
-/// expressions, and the source locations for important tokens. All of
-/// the information about template arguments is allocated directly
-/// after this structure.
-struct TemplateIdAnnotation {
- /// TemplateNameLoc - The location of the template name within the
- /// source.
- SourceLocation TemplateNameLoc;
-
- /// FIXME: Temporarily stores the name of a specialization
- IdentifierInfo *Name;
-
- /// FIXME: Temporarily stores the overloaded operator kind.
- OverloadedOperatorKind Operator;
-
- /// The declaration of the template corresponding to the
- /// template-name. This is an Action::DeclTy*.
- void *Template;
-
- /// The kind of template that Template refers to.
- TemplateNameKind Kind;
-
- /// The location of the '<' before the template argument
- /// list.
- SourceLocation LAngleLoc;
-
- /// The location of the '>' after the template argument
- /// list.
- SourceLocation RAngleLoc;
-
- /// NumArgs - The number of template arguments.
- unsigned NumArgs;
-
- /// \brief Retrieves a pointer to the template arguments
- void **getTemplateArgs() { return (void **)(this + 1); }
-
- /// \brief Retrieves a pointer to the array of template argument
- /// locations.
- SourceLocation *getTemplateArgLocations() {
- return (SourceLocation *)(getTemplateArgs() + NumArgs);
- }
-
- /// \brief Retrieves a pointer to the array of flags that states
- /// whether the template arguments are types.
- bool *getTemplateArgIsType() {
- return (bool *)(getTemplateArgLocations() + NumArgs);
- }
-
- static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
- TemplateIdAnnotation *TemplateId
- = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
- sizeof(void*) * NumArgs +
- sizeof(SourceLocation) * NumArgs +
- sizeof(bool) * NumArgs);
- TemplateId->NumArgs = NumArgs;
- return TemplateId;
- }
-
- void Destroy() { free(this); }
-};
-
} // end namespace clang
#endif
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 657a14fff082..a9b32133234a 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -1203,6 +1203,8 @@ public:
/// 'typename' keyword. FIXME: This will eventually be split into a
/// separate action.
///
+ /// \param TypenameLoc the location of the 'typename' keyword, if present
+ ///
/// \returns a representation of the using declaration.
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
@@ -1210,7 +1212,8 @@ public:
const CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
- bool IsTypeName);
+ bool IsTypeName,
+ SourceLocation TypenameLoc);
/// ActOnParamDefaultArgument - Parse default argument for function parameter
virtual void ActOnParamDefaultArgument(DeclPtrTy param,
@@ -1577,7 +1580,7 @@ public:
/// parameter.
virtual void ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParam,
SourceLocation EqualLoc,
- ExprArg Default) {
+ const ParsedTemplateArgument &Default) {
}
/// ActOnTemplateParameterList - Called when a complete template
@@ -1632,7 +1635,6 @@ public:
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc) {
return TypeResult();
};
@@ -1737,7 +1739,6 @@ public:
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc,
AttributeList *Attr,
MultiTemplateParamsArg TemplateParameterLists) {
@@ -1817,7 +1818,6 @@ public:
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc,
AttributeList *Attr) {
return DeclResult();
@@ -2105,6 +2105,7 @@ public:
virtual DeclPtrTy ActOnForwardClassDeclaration(
SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
+ SourceLocation *IdentLocs,
unsigned NumElts) {
return DeclPtrTy();
}
@@ -2329,6 +2330,47 @@ public:
///
/// \param S the scope in which the operator keyword occurs.
virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) { }
+
+ /// \brief Code completion for an ObjC message expression that refers to
+ /// a class method.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the class name.
+ ///
+ /// \param S the scope in which the message expression occurs.
+ /// \param FName the factory name.
+ /// \param FNameLoc the source location of the factory name.
+ virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
+ SourceLocation FNameLoc){ }
+
+ /// \brief Code completion for an ObjC message expression that refers to
+ /// an instance method.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the receiver expression.
+ ///
+ /// \param S the scope in which the operator keyword occurs.
+ /// \param Receiver an expression for the receiver of the message.
+ virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) { }
+
+ /// \brief Code completion for a list of protocol references in Objective-C,
+ /// such as P1 and P2 in \c id<P1,P2>.
+ ///
+ /// This code completion action is invoked prior to each identifier
+ /// in the protocol list.
+ ///
+ /// \param Protocols the set of protocols that have already been parsed.
+ ///
+ /// \param NumProtocols the number of protocols that have already been
+ /// parsed.
+ virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+ unsigned NumProtocols) { }
+
+ /// \brief Code completion for a protocol declaration or definition, after
+ /// the @protocol but before any identifier.
+ ///
+ /// \param S the scope in which the protocol declaration occurs.
+ virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
//@}
};
@@ -2398,6 +2440,7 @@ public:
virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
+ SourceLocation *SLocs,
unsigned NumElts);
virtual DeclPtrTy ActOnStartClassInterface(SourceLocation interLoc,
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 9fcc845cb006..81bb3007baea 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -57,6 +57,7 @@ public:
AT_analyzer_noreturn,
AT_annotate,
AT_blocks,
+ AT_cdecl,
AT_cleanup,
AT_const,
AT_constructor,
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index d539508e973b..7e7d0b3f28e8 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -25,7 +25,8 @@ namespace clang {
class IdentifierInfo;
class Preprocessor;
class Declarator;
-
+ struct TemplateIdAnnotation;
+
/// DeclSpec - This class captures information about "declaration specifiers",
/// which encompasses storage-class-specifiers, type-specifiers,
/// type-qualifiers, and function-specifiers.
@@ -642,13 +643,7 @@ public:
/// \param TemplateId the template-id annotation that describes the parsed
/// template-id. This UnqualifiedId instance will take ownership of the
/// \p TemplateId and will free it on destruction.
- void setTemplateId(TemplateIdAnnotation *TemplateId) {
- assert(TemplateId && "NULL template-id annotation?");
- Kind = IK_TemplateId;
- this->TemplateId = TemplateId;
- StartLocation = TemplateId->TemplateNameLoc;
- EndLocation = TemplateId->RAngleLoc;
- }
+ void setTemplateId(TemplateIdAnnotation *TemplateId);
/// \brief Return the source range that covers this unqualified-id.
SourceRange getSourceRange() const {
diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h
index 9bd69c5fdb68..5eb9635f06a1 100644
--- a/include/clang/Parse/Ownership.h
+++ b/include/clang/Parse/Ownership.h
@@ -654,41 +654,33 @@ namespace clang {
#endif
};
+ class ParsedTemplateArgument;
+
class ASTTemplateArgsPtr {
#if !defined(DISABLE_SMART_POINTERS)
ActionBase &Actions;
#endif
- void **Args;
- bool *ArgIsType;
+ ParsedTemplateArgument *Args;
mutable unsigned Count;
#if !defined(DISABLE_SMART_POINTERS)
- void destroy() {
- if (!Count)
- return;
-
- for (unsigned i = 0; i != Count; ++i)
- if (Args[i] && !ArgIsType[i])
- Actions.DeleteExpr((ActionBase::ExprTy *)Args[i]);
-
- Count = 0;
- }
+ void destroy();
#endif
-
+
public:
- ASTTemplateArgsPtr(ActionBase &actions, void **args, bool *argIsType,
+ ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args,
unsigned count) :
#if !defined(DISABLE_SMART_POINTERS)
Actions(actions),
#endif
- Args(args), ArgIsType(argIsType), Count(count) { }
+ Args(args), Count(count) { }
// FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
#if !defined(DISABLE_SMART_POINTERS)
Actions(Other.Actions),
#endif
- Args(Other.Args), ArgIsType(Other.ArgIsType), Count(Other.Count) {
+ Args(Other.Args), Count(Other.Count) {
#if !defined(DISABLE_SMART_POINTERS)
Other.Count = 0;
#endif
@@ -700,7 +692,6 @@ namespace clang {
Actions = Other.Actions;
#endif
Args = Other.Args;
- ArgIsType = Other.ArgIsType;
Count = Other.Count;
#if !defined(DISABLE_SMART_POINTERS)
Other.Count = 0;
@@ -712,22 +703,20 @@ namespace clang {
~ASTTemplateArgsPtr() { destroy(); }
#endif
- void **getArgs() const { return Args; }
- bool *getArgIsType() const {return ArgIsType; }
+ ParsedTemplateArgument *getArgs() const { return Args; }
unsigned size() const { return Count; }
- void reset(void **args, bool *argIsType, unsigned count) {
+ void reset(ParsedTemplateArgument *args, unsigned count) {
#if !defined(DISABLE_SMART_POINTERS)
destroy();
#endif
Args = args;
- ArgIsType = argIsType;
Count = count;
}
- void *operator[](unsigned Arg) const { return Args[Arg]; }
+ const ParsedTemplateArgument &operator[](unsigned Arg) const;
- void **release() const {
+ ParsedTemplateArgument *release() const {
#if !defined(DISABLE_SMART_POINTERS)
Count = 0;
#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 1ca92edc9a8b..e7dabdbd5b66 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -114,7 +114,7 @@ public:
~Parser();
const LangOptions &getLang() const { return PP.getLangOptions(); }
- TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+ const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
Preprocessor &getPreprocessor() const { return PP; }
Action &getActions() const { return Actions; }
@@ -179,6 +179,8 @@ public:
/// the EOF was encountered.
bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+ DeclGroupPtrTy RetrievePendingObjCImpDecl();
+
private:
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
@@ -331,7 +333,7 @@ private:
/// either "commit the consumed tokens" or revert to the previously marked
/// token position. Example:
///
- /// TentativeParsingAction TPA;
+ /// TentativeParsingAction TPA(*this);
/// ConsumeToken();
/// ....
/// TPA.Revert();
@@ -783,6 +785,7 @@ private:
AttributeList *prefixAttrs = 0);
DeclPtrTy ObjCImpDecl;
+ llvm::SmallVector<DeclPtrTy, 4> PendingObjCImpDecl;
DeclPtrTy ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
DeclPtrTy ParseObjCAtEndDeclaration(SourceLocation atLoc);
@@ -1226,13 +1229,18 @@ private:
Parser &P;
CXXScopeSpec &SS;
bool EnteredScope;
+ bool CreatedScope;
public:
DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
- : P(p), SS(ss), EnteredScope(false) {}
+ : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
void EnterDeclaratorScope() {
assert(!EnteredScope && "Already entered the scope!");
assert(SS.isSet() && "C++ scope was not set!");
+
+ CreatedScope = true;
+ P.EnterScope(0); // Not a decl scope.
+
if (P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
SS.setScopeRep(0);
@@ -1245,6 +1253,8 @@ private:
assert(SS.isSet() && "C++ scope was cleared ?");
P.Actions.ActOnCXXExitDeclaratorScope(P.CurScope, SS);
}
+ if (CreatedScope)
+ P.ExitScope();
}
};
@@ -1347,9 +1357,7 @@ private:
DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
// C++ 14.3: Template arguments [temp.arg]
- typedef llvm::SmallVector<void *, 16> TemplateArgList;
- typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList;
- typedef llvm::SmallVector<SourceLocation, 16> TemplateArgLocationList;
+ typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
SourceLocation TemplateNameLoc,
@@ -1357,8 +1365,6 @@ private:
bool ConsumeLastToken,
SourceLocation &LAngleLoc,
TemplateArgList &TemplateArgs,
- TemplateArgIsTypeList &TemplateArgIsType,
- TemplateArgLocationList &TemplateArgLocations,
SourceLocation &RAngleLoc);
bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
@@ -1367,10 +1373,9 @@ private:
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
- bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
- TemplateArgIsTypeList &TemplateArgIsType,
- TemplateArgLocationList &TemplateArgLocations);
- void *ParseTemplateArgument(bool &ArgIsType);
+ bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+ ParsedTemplateArgument ParseTemplateTemplateArgument();
+ ParsedTemplateArgument ParseTemplateArgument();
DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd);
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
index 480b94f73f62..c6a1e53472c1 100644
--- a/include/clang/Parse/Scope.h
+++ b/include/clang/Parse/Scope.h
@@ -275,7 +275,8 @@ public:
AnyParent = Parent;
Depth = AnyParent ? AnyParent->Depth+1 : 0;
Flags = ScopeFlags;
-
+ WithinElse = false;
+
if (AnyParent) {
FnParent = AnyParent->FnParent;
BreakParent = AnyParent->BreakParent;
@@ -283,13 +284,10 @@ public:
ControlParent = AnyParent->ControlParent;
BlockParent = AnyParent->BlockParent;
TemplateParamParent = AnyParent->TemplateParamParent;
- WithinElse = AnyParent->WithinElse;
-
} else {
FnParent = BreakParent = ContinueParent = BlockParent = 0;
ControlParent = 0;
TemplateParamParent = 0;
- WithinElse = false;
}
// If this scope is a function or contains breaks/continues, remember it.
diff --git a/include/clang/Parse/Template.h b/include/clang/Parse/Template.h
new file mode 100644
index 000000000000..1f8ccfbf05c6
--- /dev/null
+++ b/include/clang/Parse/Template.h
@@ -0,0 +1,183 @@
+//===--- Template.h - Template Parsing Data Types -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides data structures that store the parsed representation of
+// templates.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_PARSE_TEMPLATE_H
+#define LLVM_CLANG_PARSE_TEMPLATE_H
+
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Ownership.h"
+#include <cassert>
+
+namespace clang {
+ /// \brief Represents the parsed form of a C++ template argument.
+ class ParsedTemplateArgument {
+ public:
+ /// \brief Describes the kind of template argument that was parsed.
+ enum KindType {
+ /// \brief A template type parameter, stored as a type.
+ Type,
+ /// \brief A non-type template parameter, stored as an expression.
+ NonType,
+ /// \brief A template template argument, stored as a template name.
+ Template
+ };
+
+ /// \brief Build an empty template argument. This template argument
+ ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+
+ /// \brief Create a template type argument or non-type template argument.
+ ///
+ /// \param Arg the template type argument or non-type template argument.
+ /// \param Loc the location of the type.
+ ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
+ : Kind(Kind), Arg(Arg), Loc(Loc) { }
+
+ /// \brief Create a template template argument.
+ ///
+ /// \param SS the C++ scope specifier that precedes the template name, if
+ /// any.
+ ///
+ /// \param Template the template to which this template template
+ /// argument refers.
+ ///
+ /// \param TemplateLoc the location of the template name.
+ ParsedTemplateArgument(const CXXScopeSpec &SS,
+ ActionBase::TemplateTy Template,
+ SourceLocation TemplateLoc)
+ : Kind(ParsedTemplateArgument::Template), Arg(Template.get()),
+ Loc(TemplateLoc), SS(SS) { }
+
+ /// \brief Determine whether the given template argument is invalid.
+ bool isInvalid() { return Arg == 0; }
+
+ /// \brief Determine what kind of template argument we have.
+ KindType getKind() const { return Kind; }
+
+ /// \brief Retrieve the template type argument's type.
+ ActionBase::TypeTy *getAsType() const {
+ assert(Kind == Type && "Not a template type argument");
+ return Arg;
+ }
+
+ /// \brief Retrieve the non-type template argument's expression.
+ ActionBase::ExprTy *getAsExpr() const {
+ assert(Kind == NonType && "Not a non-type template argument");
+ return Arg;
+ }
+
+ /// \brief Retrieve the template template argument's template name.
+ ActionBase::TemplateTy getAsTemplate() const {
+ assert(Kind == Template && "Not a template template argument");
+ return ActionBase::TemplateTy::make(Arg);
+ }
+
+ /// \brief Retrieve the location of the template argument.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Retrieve the nested-name-specifier that precedes the template
+ /// name in a template template argument.
+ const CXXScopeSpec &getScopeSpec() const {
+ assert(Kind == Template &&
+ "Only template template arguments can have a scope specifier");
+ return SS;
+ }
+
+ private:
+ KindType Kind;
+
+ /// \brief The actual template argument representation, which may be
+ /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an
+ /// expression), or an ActionBase::TemplateTy (for a template).
+ void *Arg;
+
+ /// \brief the location of the template argument.
+ SourceLocation Loc;
+
+ /// \brief The nested-name-specifier that can accompany a template template
+ /// argument.
+ CXXScopeSpec SS;
+ };
+
+ /// \brief Information about a template-id annotation
+ /// token.
+ ///
+ /// A template-id annotation token contains the template declaration,
+ /// template arguments, whether those template arguments were types,
+ /// expressions, or template names, and the source locations for important
+ /// tokens. All of the information about template arguments is allocated
+ /// directly after this structure.
+ struct TemplateIdAnnotation {
+ /// TemplateNameLoc - The location of the template name within the
+ /// source.
+ SourceLocation TemplateNameLoc;
+
+ /// FIXME: Temporarily stores the name of a specialization
+ IdentifierInfo *Name;
+
+ /// FIXME: Temporarily stores the overloaded operator kind.
+ OverloadedOperatorKind Operator;
+
+ /// The declaration of the template corresponding to the
+ /// template-name. This is an Action::TemplateTy.
+ void *Template;
+
+ /// The kind of template that Template refers to.
+ TemplateNameKind Kind;
+
+ /// The location of the '<' before the template argument
+ /// list.
+ SourceLocation LAngleLoc;
+
+ /// The location of the '>' after the template argument
+ /// list.
+ SourceLocation RAngleLoc;
+
+ /// NumArgs - The number of template arguments.
+ unsigned NumArgs;
+
+ /// \brief Retrieves a pointer to the template arguments
+ ParsedTemplateArgument *getTemplateArgs() {
+ return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
+ }
+
+ static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
+ TemplateIdAnnotation *TemplateId
+ = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
+ sizeof(ParsedTemplateArgument) * NumArgs);
+ TemplateId->NumArgs = NumArgs;
+ return TemplateId;
+ }
+
+ void Destroy() { free(this); }
+ };
+
+#if !defined(DISABLE_SMART_POINTERS)
+ inline void ASTTemplateArgsPtr::destroy() {
+ if (!Count)
+ return;
+
+ for (unsigned I = 0; I != Count; ++I)
+ if (Args[I].getKind() == ParsedTemplateArgument::NonType)
+ Actions.DeleteExpr(Args[I].getAsExpr());
+
+ Count = 0;
+ }
+#endif
+
+ inline const ParsedTemplateArgument &
+ ASTTemplateArgsPtr::operator[](unsigned Arg) const {
+ return Args[Arg];
+ }
+}
+
+#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 5b3522c9eb49..43ff6869184d 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <memory>
#include <string>
@@ -43,6 +44,10 @@ public:
/// \brief The different kinds of "chunks" that can occur within a code
/// completion string.
enum ChunkKind {
+ /// \brief The piece of text that the user is expected to type to
+ /// match the code-completion string, typically a keyword or the name of a
+ /// declarator or macro.
+ CK_TypedText,
/// \brief A piece of text that should be placed in the buffer, e.g.,
/// parentheses or a comma in a function call.
CK_Text,
@@ -55,7 +60,29 @@ public:
CK_Placeholder,
/// \brief A piece of text that describes something about the result but
/// should not be inserted into the buffer.
- CK_Informative
+ CK_Informative,
+ /// \brief A piece of text that describes the parameter that corresponds
+ /// to the code-completion location within a function call, message send,
+ /// macro invocation, etc.
+ CK_CurrentParameter,
+ /// \brief A left parenthesis ('(').
+ CK_LeftParen,
+ /// \brief A right parenthesis (')').
+ CK_RightParen,
+ /// \brief A left bracket ('[').
+ CK_LeftBracket,
+ /// \brief A right bracket (']').
+ CK_RightBracket,
+ /// \brief A left brace ('{').
+ CK_LeftBrace,
+ /// \brief A right brace ('}').
+ CK_RightBrace,
+ /// \brief A left angle bracket ('<').
+ CK_LeftAngle,
+ /// \brief A right angle bracket ('>').
+ CK_RightAngle,
+ /// \brief A comma separator (',').
+ CK_Comma
};
/// \brief One piece of the code completion string.
@@ -66,7 +93,7 @@ public:
union {
/// \brief The text string associated with a CK_Text, CK_Placeholder,
- /// or CK_Informative chunk.
+ /// CK_Informative, or CK_Comma chunk.
/// The string is owned by the chunk and will be deallocated
/// (with delete[]) when the chunk is destroyed.
const char *Text;
@@ -79,21 +106,22 @@ public:
Chunk() : Kind(CK_Text), Text(0) { }
- private:
- Chunk(ChunkKind Kind, const char *Text);
-
- public:
+ Chunk(ChunkKind Kind, llvm::StringRef Text = "");
+
/// \brief Create a new text chunk.
- static Chunk CreateText(const char *Text);
+ static Chunk CreateText(llvm::StringRef Text);
/// \brief Create a new optional chunk.
static Chunk CreateOptional(std::auto_ptr<CodeCompletionString> Optional);
/// \brief Create a new placeholder chunk.
- static Chunk CreatePlaceholder(const char *Placeholder);
+ static Chunk CreatePlaceholder(llvm::StringRef Placeholder);
/// \brief Create a new informative chunk.
- static Chunk CreateInformative(const char *Informative);
+ static Chunk CreateInformative(llvm::StringRef Informative);
+
+ /// \brief Create a new current-parameter chunk.
+ static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
/// \brief Destroy this chunk, deallocating any memory it owns.
void Destroy();
@@ -113,10 +141,28 @@ public:
typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator;
iterator begin() const { return Chunks.begin(); }
iterator end() const { return Chunks.end(); }
+ bool empty() const { return Chunks.empty(); }
+ unsigned size() const { return Chunks.size(); }
+
+ Chunk &operator[](unsigned I) {
+ assert(I < size() && "Chunk index out-of-range");
+ return Chunks[I];
+ }
+
+ const Chunk &operator[](unsigned I) const {
+ assert(I < size() && "Chunk index out-of-range");
+ return Chunks[I];
+ }
+
+ /// \brief Add a new typed-text chunk.
+ /// The text string will be copied.
+ void AddTypedTextChunk(llvm::StringRef Text) {
+ Chunks.push_back(Chunk(CK_TypedText, Text));
+ }
/// \brief Add a new text chunk.
/// The text string will be copied.
- void AddTextChunk(const char *Text) {
+ void AddTextChunk(llvm::StringRef Text) {
Chunks.push_back(Chunk::CreateText(Text));
}
@@ -127,24 +173,46 @@ public:
/// \brief Add a new placeholder chunk.
/// The placeholder text will be copied.
- void AddPlaceholderChunk(const char *Placeholder) {
+ void AddPlaceholderChunk(llvm::StringRef Placeholder) {
Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
}
/// \brief Add a new informative chunk.
/// The text will be copied.
- void AddInformativeChunk(const char *Text) {
+ void AddInformativeChunk(llvm::StringRef Text) {
Chunks.push_back(Chunk::CreateInformative(Text));
}
+
+ /// \brief Add a new current-parameter chunk.
+ /// The text will be copied.
+ void AddCurrentParameterChunk(llvm::StringRef CurrentParameter) {
+ Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
+ }
+
+ /// \brief Add a new chunk.
+ void AddChunk(Chunk C) { Chunks.push_back(C); }
/// \brief Retrieve a string representation of the code completion string,
/// which is mainly useful for debugging.
- std::string getAsString() const;
+ std::string getAsString() const;
+
+ /// \brief Serialize this code-completion string to the given stream.
+ void Serialize(llvm::raw_ostream &OS) const;
+
+ /// \brief Deserialize a code-completion string from the given string.
+ static CodeCompletionString *Deserialize(llvm::StringRef &Str);
};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const CodeCompletionString &CCS);
+
/// \brief Abstract interface for a consumer of code-completion
/// information.
class CodeCompleteConsumer {
+protected:
+ /// \brief Whether to include macros in the code-completion results.
+ bool IncludeMacros;
+
public:
/// \brief Captures a result of code completion.
struct Result {
@@ -291,23 +359,32 @@ public:
Sema &S) const;
};
+ CodeCompleteConsumer() : IncludeMacros(false) { }
+
+ explicit CodeCompleteConsumer(bool IncludeMacros)
+ : IncludeMacros(IncludeMacros) { }
+
+ /// \brief Whether the code-completion consumer wants to see macros.
+ bool includeMacros() const { return IncludeMacros; }
+
/// \brief Deregisters and destroys this code-completion consumer.
virtual ~CodeCompleteConsumer();
/// \name Code-completion callbacks
//@{
/// \brief Process the finalized code-completion results.
- virtual void ProcessCodeCompleteResults(Result *Results,
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
unsigned NumResults) { }
-
- /// \brief Process the set of overload candidates.
+
+ /// \param S the semantic-analyzer object for which code-completion is being
+ /// done.
///
/// \param CurrentArg the index of the current argument.
///
/// \param Candidates an array of overload candidates.
///
/// \param NumCandidates the number of overload candidates
- virtual void ProcessOverloadCandidates(unsigned CurrentArg,
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
unsigned NumCandidates) { }
//@}
@@ -316,24 +393,43 @@ public:
/// \brief A simple code-completion consumer that prints the results it
/// receives in a simple format.
class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
- /// \brief The semantic-analysis object to which this code-completion
- /// consumer is attached.
- Sema &SemaRef;
-
/// \brief The raw output stream.
llvm::raw_ostream &OS;
public:
/// \brief Create a new printing code-completion consumer that prints its
/// results to the given raw output stream.
- PrintingCodeCompleteConsumer(Sema &S, llvm::raw_ostream &OS)
- : SemaRef(S), OS(OS) { }
+ PrintingCodeCompleteConsumer(bool IncludeMacros,
+ llvm::raw_ostream &OS)
+ : CodeCompleteConsumer(IncludeMacros), OS(OS) { }
+
+ /// \brief Prints the finalized code-completion results.
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
+ unsigned NumResults);
+
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates);
+};
+
+/// \brief A code-completion consumer that prints the results it receives
+/// in a format that is parsable by the CIndex library.
+class CIndexCodeCompleteConsumer : public CodeCompleteConsumer {
+ /// \brief The raw output stream.
+ llvm::raw_ostream &OS;
+
+public:
+ /// \brief Create a new CIndex code-completion consumer that prints its
+ /// results to the given raw output stream in a format readable to the CIndex
+ /// library.
+ CIndexCodeCompleteConsumer(bool IncludeMacros, llvm::raw_ostream &OS)
+ : CodeCompleteConsumer(IncludeMacros), OS(OS) { }
/// \brief Prints the finalized code-completion results.
- virtual void ProcessCodeCompleteResults(Result *Results,
+ virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
unsigned NumResults);
- virtual void ProcessOverloadCandidates(unsigned CurrentArg,
+ virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
unsigned NumCandidates);
};
diff --git a/include/clang/Sema/ParseAST.h b/include/clang/Sema/ParseAST.h
index 8a245d03cdaa..f6cff2a023e6 100644
--- a/include/clang/Sema/ParseAST.h
+++ b/include/clang/Sema/ParseAST.h
@@ -20,7 +20,7 @@ namespace clang {
class ASTContext;
class CodeCompleteConsumer;
class Sema;
-
+
/// \brief Parse the entire file specified, notifying the ASTConsumer as
/// the file is parsed.
///
@@ -30,11 +30,13 @@ namespace clang {
/// \param CompleteTranslationUnit When true, the parsed file is
/// considered to be a complete translation unit, and any
/// end-of-translation-unit wrapup will be performed.
+ ///
+ /// \param CompletionConsumer If given, an object to consume code completion
+ /// results.
void ParseAST(Preprocessor &pp, ASTConsumer *C,
ASTContext &Ctx, bool PrintStats = false,
bool CompleteTranslationUnit = true,
- CodeCompleteConsumer *(*CreateCodeCompleter)(Sema &, void *Data) = 0,
- void *CreateCodeCompleterData = 0);
+ CodeCompleteConsumer *CompletionConsumer = 0);
} // end namespace clang
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 8562249479ca..dc13e7f4688c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -35,7 +35,7 @@ enum FloatingRank {
};
ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
- TargetInfo &t,
+ const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
Builtin::Context &builtins,
bool FreeMem, unsigned size_reserve) :
@@ -256,9 +256,9 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
= new (*this) MemberSpecializationInfo(Tmpl, TSK);
}
-UnresolvedUsingDecl *
+NamedDecl *
ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) {
- llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>::iterator Pos
+ llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
= InstantiatedFromUnresolvedUsingDecl.find(UUD);
if (Pos == InstantiatedFromUnresolvedUsingDecl.end())
return 0;
@@ -268,7 +268,10 @@ ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) {
void
ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
- UnresolvedUsingDecl *UUD) {
+ NamedDecl *UUD) {
+ assert((isa<UnresolvedUsingValueDecl>(UUD) ||
+ isa<UnresolvedUsingTypenameDecl>(UUD)) &&
+ "original declaration is not an unresolved using decl");
assert(!InstantiatedFromUnresolvedUsingDecl[UD] &&
"Already noted what using decl what instantiated from");
InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
@@ -1186,7 +1189,7 @@ QualType ASTContext::getNoReturnType(QualType T) {
}
}
- return getQualifiedType(ResultType, T.getQualifiers());
+ return getQualifiedType(ResultType, T.getLocalQualifiers());
}
/// getComplexType - Return the uniqued reference to the type for a complex
@@ -2350,6 +2353,12 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
return DTN->CanonicalTemplateName;
}
+bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) {
+ X = getCanonicalTemplateName(X);
+ Y = getCanonicalTemplateName(Y);
+ return X.getAsVoidPointer() == Y.getAsVoidPointer();
+}
+
TemplateArgument
ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) {
switch (Arg.getKind()) {
@@ -2357,12 +2366,14 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) {
return Arg;
case TemplateArgument::Expression:
- // FIXME: Build canonical expression?
return Arg;
case TemplateArgument::Declaration:
return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl());
+ case TemplateArgument::Template:
+ return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
+
case TemplateArgument::Integral:
return TemplateArgument(*Arg.getAsIntegral(),
getCanonicalType(Arg.getIntegralType()));
@@ -2427,7 +2438,7 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
const ArrayType *ASTContext::getAsArrayType(QualType T) {
// Handle the non-qualified case efficiently.
- if (!T.hasQualifiers()) {
+ if (!T.hasLocalQualifiers()) {
// Handle the common positive case fast.
if (const ArrayType *AT = dyn_cast<ArrayType>(T))
return AT;
@@ -2732,12 +2743,22 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) {
return 1;
}
+static RecordDecl *
+CreateRecordDecl(ASTContext &Ctx, RecordDecl::TagKind TK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id) {
+ if (Ctx.getLangOptions().CPlusPlus)
+ return CXXRecordDecl::Create(Ctx, TK, DC, L, Id);
+ else
+ return RecordDecl::Create(Ctx, TK, DC, L, Id);
+}
+
// getCFConstantStringType - Return the type used for constant CFStrings.
QualType ASTContext::getCFConstantStringType() {
if (!CFConstantStringTypeDecl) {
CFConstantStringTypeDecl =
- RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get("NSConstantString"));
+ CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("NSConstantString"));
+
QualType FieldTypes[4];
// const int *isa;
@@ -2774,8 +2795,8 @@ void ASTContext::setCFConstantStringType(QualType T) {
QualType ASTContext::getObjCFastEnumerationStateType() {
if (!ObjCFastEnumerationStateTypeDecl) {
ObjCFastEnumerationStateTypeDecl =
- RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get("__objcFastEnumerationState"));
+ CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("__objcFastEnumerationState"));
QualType FieldTypes[] = {
UnsignedLongTy,
@@ -2807,8 +2828,8 @@ QualType ASTContext::getBlockDescriptorType() {
RecordDecl *T;
// FIXME: Needs the FlagAppleBlock bit.
- T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get("__block_descriptor"));
+ T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("__block_descriptor"));
QualType FieldTypes[] = {
UnsignedLongTy,
@@ -2850,8 +2871,8 @@ QualType ASTContext::getBlockDescriptorExtendedType() {
RecordDecl *T;
// FIXME: Needs the FlagAppleBlock bit.
- T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get("__block_descriptor_withcopydispose"));
+ T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("__block_descriptor_withcopydispose"));
QualType FieldTypes[] = {
UnsignedLongTy,
@@ -2920,8 +2941,8 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
llvm::raw_svector_ostream(Name) << "__Block_byref_" <<
++UniqueBlockByRefTypeID << '_' << DeclName;
RecordDecl *T;
- T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get(Name.str()));
+ T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get(Name.str()));
T->startDefinition();
QualType Int32Ty = IntTy;
assert(getIntWidth(IntTy) == 32 && "non-32bit int not supported");
@@ -2970,8 +2991,8 @@ QualType ASTContext::getBlockParmType(
llvm::raw_svector_ostream(Name) << "__block_literal_"
<< ++UniqueBlockParmTypeID;
RecordDecl *T;
- T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get(Name.str()));
+ T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get(Name.str()));
QualType FieldTypes[] = {
getPointerType(VoidPtrTy),
IntTy,
@@ -3053,6 +3074,54 @@ int ASTContext::getObjCEncodingTypeSize(QualType type) {
return sz / getTypeSize(CharTy);
}
+/// getObjCEncodingForBlockDecl - Return the encoded type for this method
+/// declaration.
+void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr,
+ std::string& S) {
+ const BlockDecl *Decl = Expr->getBlockDecl();
+ QualType BlockTy =
+ Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
+ // Encode result type.
+ getObjCEncodingForType(cast<FunctionType>(BlockTy)->getResultType(), S);
+ // Compute size of all parameters.
+ // Start with computing size of a pointer in number of bytes.
+ // FIXME: There might(should) be a better way of doing this computation!
+ SourceLocation Loc;
+ int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy);
+ int ParmOffset = PtrSize;
+ for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(),
+ E = Decl->param_end(); PI != E; ++PI) {
+ QualType PType = (*PI)->getType();
+ int sz = getObjCEncodingTypeSize(PType);
+ assert (sz > 0 && "BlockExpr - Incomplete param type");
+ ParmOffset += sz;
+ }
+ // Size of the argument frame
+ S += llvm::utostr(ParmOffset);
+ // Block pointer and offset.
+ S += "@?0";
+ ParmOffset = PtrSize;
+
+ // Argument types.
+ ParmOffset = PtrSize;
+ for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E =
+ Decl->param_end(); PI != E; ++PI) {
+ ParmVarDecl *PVDecl = *PI;
+ QualType PType = PVDecl->getOriginalType();
+ if (const ArrayType *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ // Use array's original type only if it has known number of
+ // elements.
+ if (!isa<ConstantArrayType>(AT))
+ PType = PVDecl->getType();
+ } else if (PType->isFunctionType())
+ PType = PVDecl->getType();
+ getObjCEncodingForType(PType, S);
+ S += llvm::utostr(ParmOffset);
+ ParmOffset += getObjCEncodingTypeSize(PType);
+ }
+}
+
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
/// declaration.
void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
@@ -4186,8 +4255,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
return LHS;
// If the qualifiers are different, the types aren't compatible... mostly.
- Qualifiers LQuals = LHSCan.getQualifiers();
- Qualifiers RQuals = RHSCan.getQualifiers();
+ Qualifiers LQuals = LHSCan.getLocalQualifiers();
+ Qualifiers RQuals = RHSCan.getLocalQualifiers();
if (LQuals != RQuals) {
// If any of these qualifiers are different, we have a type
// mismatch.
@@ -4394,7 +4463,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
//===----------------------------------------------------------------------===//
unsigned ASTContext::getIntWidth(QualType T) {
- if (T == BoolTy)
+ if (T->isBooleanType())
return 1;
if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) {
return FWIT->getWidth();
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index e541406790a6..0f0b22d65f6f 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -30,6 +30,7 @@ add_clang_library(clangAST
TemplateName.cpp
Type.cpp
TypeLoc.cpp
+ TypePrinter.cpp
)
add_dependencies(clangAST ClangDiagnosticAST)
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index b59b45f6467e..023bca436339 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -76,31 +76,31 @@ void CXXBasePaths::swap(CXXBasePaths &Other) {
std::swap(DetectedVirtual, Other.DetectedVirtual);
}
-bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base) {
+bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base) const {
CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
/*DetectVirtual=*/false);
return isDerivedFrom(Base, Paths);
}
-bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) {
+bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const {
if (getCanonicalDecl() == Base->getCanonicalDecl())
return false;
- Paths.setOrigin(this);
+ Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
return lookupInBases(&FindBaseClass, Base->getCanonicalDecl(), Paths);
}
bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
void *UserData,
- CXXBasePaths &Paths) {
+ CXXBasePaths &Paths) const {
bool FoundPath = false;
ASTContext &Context = getASTContext();
- for (base_class_iterator BaseSpec = bases_begin(), BaseSpecEnd = bases_end();
- BaseSpec != BaseSpecEnd; ++BaseSpec) {
+ for (base_class_const_iterator BaseSpec = bases_begin(),
+ BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) {
// Find the record of the base class subobjects for this type.
- QualType BaseType = Context.getCanonicalType(BaseSpec->getType());
- BaseType = BaseType.getUnqualifiedType();
+ QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
+ .getUnqualifiedType();
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
@@ -183,7 +183,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
return FoundPath;
}
-bool CXXRecordDecl::FindBaseClass(CXXBaseSpecifier *Specifier,
+bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *BaseRecord) {
assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
@@ -192,7 +192,7 @@ bool CXXRecordDecl::FindBaseClass(CXXBaseSpecifier *Specifier,
->getCanonicalDecl() == BaseRecord;
}
-bool CXXRecordDecl::FindTagMember(CXXBaseSpecifier *Specifier,
+bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *Name) {
RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
@@ -208,7 +208,7 @@ bool CXXRecordDecl::FindTagMember(CXXBaseSpecifier *Specifier,
return false;
}
-bool CXXRecordDecl::FindOrdinaryMember(CXXBaseSpecifier *Specifier,
+bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *Name) {
RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
@@ -225,9 +225,10 @@ bool CXXRecordDecl::FindOrdinaryMember(CXXBaseSpecifier *Specifier,
return false;
}
-bool CXXRecordDecl::FindNestedNameSpecifierMember(CXXBaseSpecifier *Specifier,
- CXXBasePath &Path,
- void *Name) {
+bool CXXRecordDecl::
+FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ void *Name) {
RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index a6996a4bfe5c..bdc804722c41 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -289,6 +289,10 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
return true;
+ if (isa<UsingShadowDecl>(this) && isa<UsingShadowDecl>(OldD))
+ return cast<UsingShadowDecl>(this)->getTargetDecl() ==
+ cast<UsingShadowDecl>(OldD)->getTargetDecl();
+
// For non-function declarations, if the declarations are of the
// same kind then this must be a redeclaration, or semantic analysis
// would not have given us the new declaration.
@@ -308,7 +312,7 @@ bool NamedDecl::hasLinkage() const {
NamedDecl *NamedDecl::getUnderlyingDecl() {
NamedDecl *ND = this;
while (true) {
- if (UsingDecl *UD = dyn_cast<UsingDecl>(ND))
+ if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
ND = UD->getTargetDecl();
else if (ObjCCompatibleAliasDecl *AD
= dyn_cast<ObjCCompatibleAliasDecl>(ND))
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 6cfdcdd3e50e..831f552489f9 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -97,7 +97,7 @@ bool Decl::isTemplateParameterPack() const {
}
bool Decl::isFunctionOrFunctionTemplate() const {
- if (const UsingDecl *UD = dyn_cast<UsingDecl>(this))
+ if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
@@ -189,10 +189,11 @@ ASTContext &Decl::getASTContext() const {
unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
switch (DeclKind) {
- default:
- if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast)
- return IDNS_Ordinary;
- assert(0 && "Unknown decl kind!");
+ case Function:
+ case CXXMethod:
+ case CXXConstructor:
+ case CXXDestructor:
+ case CXXConversion:
case OverloadedFunction:
case Typedef:
case EnumConstant:
@@ -200,8 +201,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ImplicitParam:
case ParmVar:
case NonTypeTemplateParm:
- case Using:
- case UnresolvedUsing:
case ObjCMethod:
case ObjCContainer:
case ObjCCategory:
@@ -210,6 +209,16 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCompatibleAlias:
return IDNS_Ordinary;
+ case UsingShadow:
+ return 0; // we'll actually overwrite this later
+
+ case UnresolvedUsingValue:
+ case UnresolvedUsingTypename:
+ return IDNS_Ordinary | IDNS_Using;
+
+ case Using:
+ return IDNS_Using;
+
case ObjCProtocol:
return IDNS_ObjCProtocol;
@@ -256,6 +265,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ClassTemplatePartialSpecialization:
return 0;
}
+
+ return 0;
}
void Decl::addAttr(Attr *NewAttr) {
@@ -663,6 +674,13 @@ void DeclContext::buildLookup(DeclContext *DCtx) {
if (D->getDeclContext() == DCtx)
makeDeclVisibleInContextImpl(ND);
+ // Insert any forward-declared Objective-C interfaces into the lookup
+ // data structure.
+ if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
+ for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
+ I != IEnd; ++I)
+ makeDeclVisibleInContextImpl(I->getInterface());
+
// If this declaration is itself a transparent declaration context,
// add its members (recursively).
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index b4c0c59733e5..a21c93ffcdc9 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -211,7 +211,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context,
if (!ArgType.isConstQualified())
AcceptsConst = false;
}
- if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType)
+ if (!Context.hasSameUnqualifiedType(ArgType, ClassType))
continue;
MD = Method;
// We have a single argument of type cv X or cv X&, i.e. we've found the
@@ -276,10 +276,13 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
const_cast<CXXRecordDecl*>(this)));
- if (ClassType != Context.getCanonicalType(ArgType))
+ if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
return;
// This is a copy assignment operator.
+ // Note on the decl that it is a copy assignment operator.
+ OpDecl->setCopyAssignment(true);
+
// Suppress the implicit declaration of a copy constructor.
UserDeclaredCopyAssignment = true;
@@ -749,6 +752,33 @@ bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
(getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
}
+bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
+ if ((getNumParams() < 1) ||
+ (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
+ (getPrimaryTemplate() == 0) ||
+ (getDescribedFunctionTemplate() != 0))
+ return false;
+
+ const ParmVarDecl *Param = getParamDecl(0);
+
+ ASTContext &Context = getASTContext();
+ CanQualType ParamType = Context.getCanonicalType(Param->getType());
+
+ // Strip off the lvalue reference, if any.
+ if (CanQual<LValueReferenceType> ParamRefType
+ = ParamType->getAs<LValueReferenceType>())
+ ParamType = ParamRefType->getPointeeType();
+
+
+ // Is it the same as our our class type?
+ CanQualType ClassTy
+ = Context.getCanonicalType(Context.getTagDeclType(getParent()));
+ if (ParamType.getUnqualifiedType() != ClassTy)
+ return false;
+
+ return true;
+}
+
CXXDestructorDecl *
CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@@ -761,12 +791,6 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
}
void
-CXXDestructorDecl::Destroy(ASTContext& C) {
- C.Deallocate(BaseOrMemberDestructions);
- CXXMethodDecl::Destroy(C);
-}
-
-void
CXXConstructorDecl::Destroy(ASTContext& C) {
C.Deallocate(BaseOrMemberInitializers);
CXXMethodDecl::Destroy(C);
@@ -890,22 +914,36 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
}
UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
- SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) {
- return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target,
- TargetNNS, IsTypeNameArg);
-}
-
-UnresolvedUsingDecl *UnresolvedUsingDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc,
- DeclarationName TargetName,
- bool IsTypeNameArg) {
- return new (C) UnresolvedUsingDecl(DC, UsingLoc, TargetNNR, TargetNNS,
- TargetNameLoc, TargetName, IsTypeNameArg);
+ SourceLocation L, SourceRange NNR, SourceLocation UL,
+ NestedNameSpecifier* TargetNNS, DeclarationName Name,
+ bool IsTypeNameArg) {
+ return new (C) UsingDecl(DC, L, NNR, UL, TargetNNS, Name, IsTypeNameArg);
+}
+
+UnresolvedUsingValueDecl *
+UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation UsingLoc,
+ SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName) {
+ return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
+ TargetNNR, TargetNNS,
+ TargetNameLoc, TargetName);
+}
+
+UnresolvedUsingTypenameDecl *
+UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName) {
+ return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
+ TargetNNR, TargetNNS,
+ TargetNameLoc,
+ TargetName.getAsIdentifierInfo());
}
StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 7b48b724c0eb..c33720f5633a 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -571,34 +571,55 @@ ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
//===----------------------------------------------------------------------===//
ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
- ObjCInterfaceDecl *const *Elts, unsigned nElts,
+ ObjCInterfaceDecl *const *Elts,
+ const SourceLocation *Locs,
+ unsigned nElts,
ASTContext &C)
: Decl(ObjCClass, DC, L) {
- ForwardDecls.set(Elts, nElts, C);
+ setClassList(C, Elts, Locs, nElts);
}
+void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+ const SourceLocation *Locs, unsigned Num) {
+ ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
+ llvm::alignof<ObjCClassRef>());
+ for (unsigned i = 0; i < Num; ++i)
+ new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
+
+ NumDecls = Num;
+}
ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
ObjCInterfaceDecl *const *Elts,
+ const SourceLocation *Locs,
unsigned nElts) {
- return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
+ return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
}
void ObjCClassDecl::Destroy(ASTContext &C) {
-
- // FIXME: There is no clear ownership policy now for referenced
- // ObjCInterfaceDecls. Some of them can be forward declarations that
- // are never later defined (in which case the ObjCClassDecl owns them)
- // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
- // we should have separate objects for forward declarations and definitions,
- // obviating this problem. Because of this situation, referenced
- // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
-
- ForwardDecls.Destroy(C);
+ // ObjCInterfaceDecls registered with a DeclContext will get destroyed
+ // when the DeclContext is destroyed. For those created only by a forward
+ // declaration, the first @class that created the ObjCInterfaceDecl gets
+ // to destroy it.
+ // FIXME: Note that this ownership role is very brittle; a better
+ // polict is surely need in the future.
+ for (iterator I = begin(), E = end(); I !=E ; ++I) {
+ ObjCInterfaceDecl *ID = I->getInterface();
+ if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
+ ID->Destroy(C);
+ }
+
+ C.Deallocate(ForwardDecls);
Decl::Destroy(C);
}
+SourceRange ObjCClassDecl::getSourceRange() const {
+ // FIXME: We should include the semicolon
+ assert(NumDecls);
+ return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation());
+}
+
//===----------------------------------------------------------------------===//
// ObjCForwardProtocolDecl
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index d9d195016bf3..131de8b2e11b 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -71,8 +71,10 @@ namespace {
void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- void VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
+ void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+ void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
void VisitUsingDecl(UsingDecl *D);
+ void VisitUsingShadowDecl(UsingShadowDecl *D);
};
}
@@ -401,37 +403,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
}
}
}
- else if (CXXDestructorDecl *DDecl = dyn_cast<CXXDestructorDecl>(D)) {
- if (DDecl->getNumBaseOrMemberDestructions() > 0) {
- // List order of base/member destruction for visualization purposes.
- assert (D->isThisDeclarationADefinition() && "Destructor with dtor-list");
- Proto += "/* : ";
- for (CXXDestructorDecl::destr_const_iterator *B = DDecl->destr_begin(),
- *E = DDecl->destr_end();
- B != E; ++B) {
- uintptr_t BaseOrMember = (*B);
- if (B != DDecl->destr_begin())
- Proto += ", ";
-
- if (DDecl->isMemberToDestroy(BaseOrMember)) {
- FieldDecl *FD = DDecl->getMemberToDestroy(BaseOrMember);
- Proto += "~";
- Proto += FD->getNameAsString();
- }
- else // FIXME. skip dependent types for now.
- if (const RecordType *RT =
- DDecl->getAnyBaseClassToDestroy(BaseOrMember)
- ->getAs<RecordType>()) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(RT->getDecl());
- Proto += "~";
- Proto += BaseDecl->getNameAsString();
- }
- Proto += "()";
- }
- Proto += " */";
- }
- }
else
AFT->getResultType().getAsStringInternal(Proto, Policy);
} else {
@@ -654,7 +625,7 @@ void DeclPrinter::VisitObjCClassDecl(ObjCClassDecl *D) {
for (ObjCClassDecl::iterator I = D->begin(), E = D->end();
I != E; ++I) {
if (I != D->begin()) Out << ", ";
- Out << (*I)->getNameAsString();
+ Out << I->getInterface()->getNameAsString();
}
}
@@ -856,11 +827,22 @@ void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
Out << "using ";
D->getTargetNestedNameDecl()->print(Out, Policy);
- Out << D->getTargetDecl()->getNameAsString();
+ Out << D->getNameAsString();
+}
+
+void
+DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ Out << "using typename ";
+ D->getTargetNestedNameSpecifier()->print(Out, Policy);
+ Out << D->getDeclName().getAsString();
}
-void DeclPrinter::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
+void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Out << "using ";
D->getTargetNestedNameSpecifier()->print(Out, Policy);
- Out << D->getTargetName().getAsString();
+ Out << D->getDeclName().getAsString();
+}
+
+void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ // ignore
}
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 9ebc91afe142..0c14714812f5 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -220,7 +220,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
TemplateArgs.push_back(TemplateArgument(E));
} else {
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
- TemplateArgs.push_back(TemplateArgument(TTP));
+ TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
}
}
@@ -285,11 +285,6 @@ TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
}
-SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
- return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
- : SourceLocation();
-}
-
//===----------------------------------------------------------------------===//
// TemplateArgumentListBuilder Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 8664c508615f..1ff068c9862c 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -18,6 +18,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include <cstdio>
using namespace clang;
namespace clang {
@@ -310,6 +311,10 @@ DeclarationName DeclarationName::getUsingDirectiveName() {
return DeclarationName(Ptr);
}
+void DeclarationName::dump() const {
+ fprintf(stderr, "%s\n", getAsString().c_str());
+}
+
DeclarationNameTable::DeclarationNameTable() {
CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index a8ea752a4a7e..90b50c61f989 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -490,6 +490,8 @@ const char *CastExpr::getCastKindName() const {
return "BitCast";
case CastExpr::CK_NoOp:
return "NoOp";
+ case CastExpr::CK_BaseToDerived:
+ return "BaseToDerived";
case CastExpr::CK_DerivedToBase:
return "DerivedToBase";
case CastExpr::CK_Dynamic:
@@ -812,6 +814,11 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
}
return false;
}
+
+ case CXXTemporaryObjectExprClass:
+ case CXXConstructExprClass:
+ return false;
+
case ObjCMessageExprClass:
return false;
@@ -853,15 +860,19 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
- case CXXFunctionalCastExprClass:
- // If this is a cast to void, check the operand. Otherwise, the result of
- // the cast is unused.
- if (getType()->isVoidType())
+ case CXXFunctionalCastExprClass: {
+ const CastExpr *CE = cast<CastExpr>(this);
+
+ // If this is a cast to void or a constructor conversion, check the operand.
+ // Otherwise, the result of the cast is unused.
+ if (CE->getCastKind() == CastExpr::CK_ToVoid ||
+ CE->getCastKind() == CastExpr::CK_ConstructorConversion)
return (cast<CastExpr>(this)->getSubExpr()
->isUnusedResultAWarning(Loc, R1, R2, Ctx));
Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
+ }
case ImplicitCastExprClass:
// Check the operand, since implicit casts are inserted by Sema
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 7c6fc41ef12b..0ba4608ee198 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -323,6 +323,14 @@ Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
return 0;
}
+SourceRange CXXMemberCallExpr::getSourceRange() const {
+ SourceLocation LocStart = getCallee()->getLocStart();
+ if (LocStart.isInvalid() && getNumArgs() > 0)
+ LocStart = getArg(0)->getLocStart();
+ return SourceRange(LocStart, getRParenLoc());
+}
+
+
//===----------------------------------------------------------------------===//
// Named casts
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 7862c57c2d47..2689859e8e4a 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -204,13 +204,6 @@ public:
bool VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); }
};
-bool HasSideEffects(const Expr* E, ASTContext &Ctx) {
- Expr::EvalResult Result;
- EvalInfo Info(Ctx, Result);
-
- return HasSideEffect(Info).Visit(const_cast<Expr*>(E));
-}
-
} // end anonymous namespace
//===----------------------------------------------------------------------===//
@@ -964,7 +957,7 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
}
}
- if (HasSideEffects(E->getArg(0), Info.Ctx)) {
+ if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() < 2)
return Success(-1ULL, E);
return Success(0, E);
@@ -1495,7 +1488,7 @@ public:
// FIXME: Missing: __real__/__imag__, array subscript of vector,
// member of vector, ImplicitValueInitExpr,
- // conditional ?:, comma
+ // conditional ?:
};
} // end anonymous namespace
@@ -1584,6 +1577,18 @@ bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
}
bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+ if (E->getOpcode() == BinaryOperator::Comma) {
+ if (!EvaluateFloat(E->getRHS(), Result, Info))
+ return false;
+
+ // If we can't evaluate the LHS, it might have side effects;
+ // conservatively mark it.
+ if (!E->getLHS()->isEvaluatable(Info.Ctx))
+ Info.EvalResult.HasSideEffects = true;
+
+ return true;
+ }
+
// FIXME: Diagnostics? I really don't understand how the warnings
// and errors are supposed to work.
APFloat RHS(0.0);
@@ -1947,6 +1952,12 @@ bool Expr::isEvaluatable(ASTContext &Ctx) const {
return Evaluate(Result, Ctx) && !Result.HasSideEffects;
}
+bool Expr::HasSideEffects(ASTContext &Ctx) const {
+ Expr::EvalResult Result;
+ EvalInfo Info(Ctx, Result);
+ return HasSideEffect(Info).Visit(const_cast<Expr*>(this));
+}
+
APSInt Expr::EvaluateAsInt(ASTContext &Ctx) const {
EvalResult EvalResult;
bool Result = Evaluate(EvalResult, Ctx);
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index d969776aa0ee..e26c0bba4934 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -167,7 +167,7 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS,
InnerPolicy);
} else {
// Print the type normally
- T->getAsStringInternal(TypeStr, InnerPolicy);
+ TypeStr = QualType(T, 0).getAsString(InnerPolicy);
}
OS << TypeStr;
break;
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 021c53e9514f..b9cfcfec74f0 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -226,8 +226,7 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
if (RD == Class)
BaseOffset = getBaseOffset(Base);
else {
- const ASTRecordLayout &Layout
- = Ctx.getASTRecordLayout(RD);
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
BaseOffset = Offset + Layout.getBaseClassOffset(Base);
}
}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index cf71d6b986a2..93bf8755d580 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -115,6 +115,7 @@ namespace {
// Exprs
void VisitExpr(Expr *Node);
void VisitCastExpr(CastExpr *Node);
+ void VisitImplicitCastExpr(ImplicitCastExpr *Node);
void VisitDeclRefExpr(DeclRefExpr *Node);
void VisitPredefinedExpr(PredefinedExpr *Node);
void VisitCharacterLiteral(CharacterLiteral *Node);
@@ -301,6 +302,12 @@ void StmtDumper::VisitCastExpr(CastExpr *Node) {
fprintf(F, " <%s>", Node->getCastKindName());
}
+void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
+ VisitCastExpr(Node);
+ if (Node->isLvalueCast())
+ fprintf(F, " lvalue");
+}
+
void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
DumpExpr(Node);
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 02e0c74bb63a..4458c2b9cd25 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -695,6 +695,10 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
VisitType(Arg.getAsType());
break;
+ case TemplateArgument::Template:
+ VisitTemplateName(Arg.getAsTemplate());
+ break;
+
case TemplateArgument::Declaration:
VisitDecl(Arg.getAsDecl());
break;
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 94e1ca1e06e7..ff02f9a31cb2 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -58,6 +58,11 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
break;
+ case Template:
+ ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
+ .getAsVoidPointer());
+ break;
+
case Integral:
getAsIntegral()->Profile(ID);
getIntegralType().Profile(ID);
@@ -82,10 +87,19 @@ SourceRange TemplateArgumentLoc::getSourceRange() const {
switch (Argument.getKind()) {
case TemplateArgument::Expression:
return getSourceExpression()->getSourceRange();
+
case TemplateArgument::Declaration:
return getSourceDeclExpression()->getSourceRange();
+
case TemplateArgument::Type:
return getSourceDeclaratorInfo()->getTypeLoc().getFullSourceRange();
+
+ case TemplateArgument::Template:
+ if (getTemplateQualifierRange().isValid())
+ return SourceRange(getTemplateQualifierRange().getBegin(),
+ getTemplateNameLoc());
+ return SourceRange(getTemplateNameLoc());
+
case TemplateArgument::Integral:
case TemplateArgument::Pack:
case TemplateArgument::Null:
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 779f6808b6c1..297534eaf1fc 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -98,6 +98,44 @@ const Type *Type::getArrayElementTypeNoTypeQual() const {
->getElementType().getTypePtr();
}
+/// \brief Retrieve the unqualified variant of the given type, removing as
+/// little sugar as possible.
+///
+/// This routine looks through various kinds of sugar to find the
+/// least-desuraged type that is unqualified. For example, given:
+///
+/// \code
+/// typedef int Integer;
+/// typedef const Integer CInteger;
+/// typedef CInteger DifferenceType;
+/// \endcode
+///
+/// Executing \c getUnqualifiedTypeSlow() on the type \c DifferenceType will
+/// desugar until we hit the type \c Integer, which has no qualifiers on it.
+QualType QualType::getUnqualifiedTypeSlow() const {
+ QualType Cur = *this;
+ while (true) {
+ if (!Cur.hasQualifiers())
+ return Cur;
+
+ const Type *CurTy = Cur.getTypePtr();
+ switch (CurTy->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 Cur.getLocalUnqualifiedType(); \
+ Cur = Ty->desugar(); \
+ break; \
+ }
+#include "clang/AST/TypeNodes.def"
+ }
+ }
+
+ return Cur.getUnqualifiedType();
+}
+
/// getDesugaredType - Return the specified type with any "sugar" removed from
/// the type. This takes off typedefs, typeof's etc. If the outer level of
/// the type is already concrete, it returns it unmodified. This is similar
@@ -425,7 +463,7 @@ bool Type::isSignedIntegerType() const {
bool Type::isUnsignedIntegerType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::ULongLong;
+ BT->getKind() <= BuiltinType::UInt128;
}
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
@@ -453,8 +491,7 @@ bool Type::isFloatingType() const {
bool Type::isRealFloatingType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Float &&
- BT->getKind() <= BuiltinType::LongDouble;
+ return BT->isFloatingPoint();
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isRealFloatingType();
return false;
@@ -808,6 +845,9 @@ static bool isDependent(const TemplateArgument &Arg) {
case TemplateArgument::Type:
return Arg.getAsType()->isDependentType();
+ case TemplateArgument::Template:
+ return Arg.getAsTemplate().isDependent();
+
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
// Never dependent
@@ -907,539 +947,6 @@ QualType QualifierCollector::apply(const Type *T) const {
return Context->getQualifiedType(T, *this);
}
-
-//===----------------------------------------------------------------------===//
-// Type Printing
-//===----------------------------------------------------------------------===//
-
-void QualType::dump(const char *msg) const {
- std::string R = "identifier";
- LangOptions LO;
- getAsStringInternal(R, PrintingPolicy(LO));
- if (msg)
- fprintf(stderr, "%s: %s\n", msg, R.c_str());
- else
- fprintf(stderr, "%s\n", R.c_str());
-}
-void QualType::dump() const {
- dump("");
-}
-
-void Type::dump() const {
- std::string S = "identifier";
- LangOptions LO;
- getAsStringInternal(S, PrintingPolicy(LO));
- fprintf(stderr, "%s\n", S.c_str());
-}
-
-
-
-static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
- if (TypeQuals & Qualifiers::Const) {
- if (!S.empty()) S += ' ';
- S += "const";
- }
- if (TypeQuals & Qualifiers::Volatile) {
- if (!S.empty()) S += ' ';
- S += "volatile";
- }
- if (TypeQuals & Qualifiers::Restrict) {
- if (!S.empty()) S += ' ';
- S += "restrict";
- }
-}
-
-std::string Qualifiers::getAsString() const {
- LangOptions LO;
- return getAsString(PrintingPolicy(LO));
-}
-
-// Appends qualifiers to the given string, separated by spaces. Will
-// prefix a space if the string is non-empty. Will not append a final
-// space.
-void Qualifiers::getAsStringInternal(std::string &S,
- const PrintingPolicy&) const {
- AppendTypeQualList(S, getCVRQualifiers());
- if (unsigned AddressSpace = getAddressSpace()) {
- if (!S.empty()) S += ' ';
- S += "__attribute__((address_space(";
- S += llvm::utostr_32(AddressSpace);
- S += ")))";
- }
- if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
- if (!S.empty()) S += ' ';
- S += "__attribute__((objc_gc(";
- if (GCAttrType == Qualifiers::Weak)
- S += "weak";
- else
- S += "strong";
- S += ")))";
- }
-}
-
-std::string QualType::getAsString() const {
- std::string S;
- LangOptions LO;
- getAsStringInternal(S, PrintingPolicy(LO));
- return S;
-}
-
-void
-QualType::getAsStringInternal(std::string &S,
- const PrintingPolicy &Policy) const {
- if (isNull()) {
- S += "NULL TYPE";
- return;
- }
-
- if (Policy.SuppressSpecifiers && getTypePtr()->isSpecifierType())
- return;
-
- // Print qualifiers as appropriate.
- Qualifiers Quals = getQualifiers();
- if (!Quals.empty()) {
- std::string TQS;
- Quals.getAsStringInternal(TQS, Policy);
-
- if (!S.empty()) {
- TQS += ' ';
- TQS += S;
- }
- std::swap(S, TQS);
- }
-
- getTypePtr()->getAsStringInternal(S, Policy);
-}
-
-void BuiltinType::getAsStringInternal(std::string &S,
- const PrintingPolicy &Policy) const {
- if (S.empty()) {
- S = getName(Policy.LangOpts);
- } else {
- // Prefix the basic type, e.g. 'int X'.
- S = ' ' + S;
- S = getName(Policy.LangOpts) + S;
- }
-}
-
-void FixedWidthIntType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- // FIXME: Once we get bitwidth attribute, write as
- // "int __attribute__((bitwidth(x)))".
- std::string prefix = "__clang_fixedwidth";
- prefix += llvm::utostr_32(Width);
- prefix += (char)(Signed ? 'S' : 'U');
- if (S.empty()) {
- S = prefix;
- } else {
- // Prefix the basic type, e.g. 'int X'.
- S = prefix + S;
- }
-}
-
-
-void ComplexType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- ElementType->getAsStringInternal(S, Policy);
- S = "_Complex " + S;
-}
-
-void PointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S = '*' + S;
-
- // Handle things like 'int (*A)[4];' correctly.
- // FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(getPointeeType()))
- S = '(' + S + ')';
-
- getPointeeType().getAsStringInternal(S, Policy);
-}
-
-void BlockPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S = '^' + S;
- PointeeType.getAsStringInternal(S, Policy);
-}
-
-void LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S = '&' + S;
-
- // Handle things like 'int (&A)[4];' correctly.
- // FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(getPointeeTypeAsWritten()))
- S = '(' + S + ')';
-
- getPointeeTypeAsWritten().getAsStringInternal(S, Policy);
-}
-
-void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S = "&&" + S;
-
- // Handle things like 'int (&&A)[4];' correctly.
- // FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(getPointeeTypeAsWritten()))
- S = '(' + S + ')';
-
- getPointeeTypeAsWritten().getAsStringInternal(S, Policy);
-}
-
-void MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- std::string C;
- Class->getAsStringInternal(C, Policy);
- C += "::*";
- S = C + S;
-
- // Handle things like 'int (Cls::*A)[4];' correctly.
- // FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(getPointeeType()))
- S = '(' + S + ')';
-
- getPointeeType().getAsStringInternal(S, Policy);
-}
-
-void ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S += '[';
- S += llvm::utostr(getSize().getZExtValue());
- S += ']';
-
- getElementType().getAsStringInternal(S, Policy);
-}
-
-void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S += "[]";
-
- getElementType().getAsStringInternal(S, Policy);
-}
-
-void VariableArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S += '[';
-
- if (getIndexTypeQualifiers().hasQualifiers()) {
- AppendTypeQualList(S, getIndexTypeCVRQualifiers());
- S += ' ';
- }
-
- if (getSizeModifier() == Static)
- S += "static";
- else if (getSizeModifier() == Star)
- S += '*';
-
- if (getSizeExpr()) {
- std::string SStr;
- llvm::raw_string_ostream s(SStr);
- getSizeExpr()->printPretty(s, 0, Policy);
- S += s.str();
- }
- S += ']';
-
- getElementType().getAsStringInternal(S, Policy);
-}
-
-void DependentSizedArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S += '[';
-
- if (getIndexTypeQualifiers().hasQualifiers()) {
- AppendTypeQualList(S, getIndexTypeCVRQualifiers());
- S += ' ';
- }
-
- if (getSizeModifier() == Static)
- S += "static";
- else if (getSizeModifier() == Star)
- S += '*';
-
- if (getSizeExpr()) {
- std::string SStr;
- llvm::raw_string_ostream s(SStr);
- getSizeExpr()->printPretty(s, 0, Policy);
- S += s.str();
- }
- S += ']';
-
- getElementType().getAsStringInternal(S, Policy);
-}
-
-void DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- getElementType().getAsStringInternal(S, Policy);
-
- S += " __attribute__((ext_vector_type(";
- if (getSizeExpr()) {
- std::string SStr;
- llvm::raw_string_ostream s(SStr);
- getSizeExpr()->printPretty(s, 0, Policy);
- S += s.str();
- }
- S += ")))";
-}
-
-void VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- // FIXME: We prefer to print the size directly here, but have no way
- // to get the size of the type.
- S += " __attribute__((__vector_size__(";
- S += llvm::utostr_32(NumElements); // convert back to bytes.
- S += " * sizeof(" + ElementType.getAsString() + "))))";
- ElementType.getAsStringInternal(S, Policy);
-}
-
-void ExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- S += " __attribute__((ext_vector_type(";
- S += llvm::utostr_32(NumElements);
- S += ")))";
- ElementType.getAsStringInternal(S, Policy);
-}
-
-void TypeOfExprType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(e) X'.
- InnerString = ' ' + InnerString;
- std::string Str;
- llvm::raw_string_ostream s(Str);
- getUnderlyingExpr()->printPretty(s, 0, Policy);
- InnerString = "typeof " + s.str() + InnerString;
-}
-
-void TypeOfType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(t) X'.
- InnerString = ' ' + InnerString;
- std::string Tmp;
- getUnderlyingType().getAsStringInternal(Tmp, Policy);
- InnerString = "typeof(" + Tmp + ")" + InnerString;
-}
-
-void DecltypeType::getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'decltype(t) X'.
- InnerString = ' ' + InnerString;
- std::string Str;
- llvm::raw_string_ostream s(Str);
- getUnderlyingExpr()->printPretty(s, 0, Policy);
- InnerString = "decltype(" + s.str() + ")" + InnerString;
-}
-
-void FunctionNoProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- // If needed for precedence reasons, wrap the inner part in grouping parens.
- if (!S.empty())
- S = "(" + S + ")";
-
- S += "()";
- if (getNoReturnAttr())
- S += " __attribute__((noreturn))";
- getResultType().getAsStringInternal(S, Policy);
-}
-
-void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- // If needed for precedence reasons, wrap the inner part in grouping parens.
- if (!S.empty())
- S = "(" + S + ")";
-
- S += "(";
- std::string Tmp;
- PrintingPolicy ParamPolicy(Policy);
- ParamPolicy.SuppressSpecifiers = false;
- for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
- if (i) S += ", ";
- getArgType(i).getAsStringInternal(Tmp, ParamPolicy);
- S += Tmp;
- Tmp.clear();
- }
-
- if (isVariadic()) {
- if (getNumArgs())
- S += ", ";
- S += "...";
- } else if (getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
- // Do not emit int() if we have a proto, emit 'int(void)'.
- S += "void";
- }
-
- S += ")";
- if (getNoReturnAttr())
- S += " __attribute__((noreturn))";
- getResultType().getAsStringInternal(S, Policy);
-}
-
-
-void TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
- InnerString = getDecl()->getIdentifier()->getName().str() + InnerString;
-}
-
-void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'parmname X'.
- InnerString = ' ' + InnerString;
-
- if (!Name)
- InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' +
- llvm::utostr_32(Index) + InnerString;
- else
- InnerString = Name->getName().str() + InnerString;
-}
-
-void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- getReplacementType().getAsStringInternal(InnerString, Policy);
-}
-
-static void PrintTemplateArgument(std::string &Buffer,
- const TemplateArgument &Arg,
- const PrintingPolicy &Policy) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- assert(false && "Null template argument");
- break;
-
- case TemplateArgument::Type:
- Arg.getAsType().getAsStringInternal(Buffer, Policy);
- break;
-
- case TemplateArgument::Declaration:
- Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
- break;
-
- case TemplateArgument::Integral:
- Buffer = Arg.getAsIntegral()->toString(10, true);
- break;
-
- case TemplateArgument::Expression: {
- llvm::raw_string_ostream s(Buffer);
- Arg.getAsExpr()->printPretty(s, 0, Policy);
- break;
- }
-
- case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
- break;
- }
-}
-
-std::string
-TemplateSpecializationType::PrintTemplateArgumentList(
- const TemplateArgument *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy) {
- std::string SpecString;
- SpecString += '<';
- for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
- if (Arg)
- SpecString += ", ";
-
- // Print the argument into a string.
- std::string ArgString;
- PrintTemplateArgument(ArgString, Args[Arg], Policy);
-
- // If this is the first argument and its string representation
- // begins with the global scope specifier ('::foo'), add a space
- // to avoid printing the diagraph '<:'.
- if (!Arg && !ArgString.empty() && ArgString[0] == ':')
- SpecString += ' ';
-
- SpecString += ArgString;
- }
-
- // If the last character of our string is '>', add another space to
- // keep the two '>''s separate tokens. We don't *have* to do this in
- // C++0x, but it's still good hygiene.
- if (SpecString[SpecString.size() - 1] == '>')
- SpecString += ' ';
-
- SpecString += '>';
-
- return SpecString;
-}
-
-// Sadly, repeat all that with TemplateArgLoc.
-std::string TemplateSpecializationType::
-PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
- const PrintingPolicy &Policy) {
- std::string SpecString;
- SpecString += '<';
- for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
- if (Arg)
- SpecString += ", ";
-
- // Print the argument into a string.
- std::string ArgString;
- PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
-
- // If this is the first argument and its string representation
- // begins with the global scope specifier ('::foo'), add a space
- // to avoid printing the diagraph '<:'.
- if (!Arg && !ArgString.empty() && ArgString[0] == ':')
- SpecString += ' ';
-
- SpecString += ArgString;
- }
-
- // If the last character of our string is '>', add another space to
- // keep the two '>''s separate tokens. We don't *have* to do this in
- // C++0x, but it's still good hygiene.
- if (SpecString[SpecString.size() - 1] == '>')
- SpecString += ' ';
-
- SpecString += '>';
-
- return SpecString;
-}
-
-void
-TemplateSpecializationType::
-getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- std::string SpecString;
-
- {
- llvm::raw_string_ostream OS(SpecString);
- Template.print(OS, Policy);
- }
-
- SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs(), Policy);
- if (InnerString.empty())
- InnerString.swap(SpecString);
- else
- InnerString = SpecString + ' ' + InnerString;
-}
-
-void QualifiedNameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- std::string MyString;
-
- {
- llvm::raw_string_ostream OS(MyString);
- NNS->print(OS, Policy);
- }
-
- std::string TypeStr;
- PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
- InnerPolicy.SuppressScope = true;
- NamedType.getAsStringInternal(TypeStr, InnerPolicy);
-
- MyString += TypeStr;
- if (InnerString.empty())
- InnerString.swap(MyString);
- else
- InnerString = MyString + ' ' + InnerString;
-}
-
-void TypenameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- std::string MyString;
-
- {
- llvm::raw_string_ostream OS(MyString);
- OS << "typename ";
- NNS->print(OS, Policy);
-
- if (const IdentifierInfo *Ident = getIdentifier())
- OS << Ident->getName();
- else if (const TemplateSpecializationType *Spec = getTemplateId()) {
- Spec->getTemplateName().print(OS, Policy, true);
- OS << TemplateSpecializationType::PrintTemplateArgumentList(
- Spec->getArgs(),
- Spec->getNumArgs(),
- Policy);
- }
- }
-
- if (InnerString.empty())
- InnerString.swap(MyString);
- else
- InnerString = MyString + ' ' + InnerString;
-}
-
void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
const ObjCInterfaceDecl *Decl,
ObjCProtocolDecl **protocols,
@@ -1455,134 +962,3 @@ void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
else
Profile(ID, getDecl(), 0, 0);
}
-
-void ObjCInterfaceType::getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
-
- std::string ObjCQIString = getDecl()->getNameAsString();
- if (getNumProtocols()) {
- ObjCQIString += '<';
- bool isFirst = true;
- for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
- if (isFirst)
- isFirst = false;
- else
- ObjCQIString += ',';
- ObjCQIString += (*I)->getNameAsString();
- }
- ObjCQIString += '>';
- }
- InnerString = ObjCQIString + InnerString;
-}
-
-void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const {
- std::string ObjCQIString;
-
- if (isObjCIdType() || isObjCQualifiedIdType())
- ObjCQIString = "id";
- else if (isObjCClassType() || isObjCQualifiedClassType())
- ObjCQIString = "Class";
- else
- ObjCQIString = getInterfaceDecl()->getNameAsString();
-
- if (!qual_empty()) {
- ObjCQIString += '<';
- for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
- ObjCQIString += (*I)->getNameAsString();
- if (I+1 != E)
- ObjCQIString += ',';
- }
- ObjCQIString += '>';
- }
-
- PointeeType.getQualifiers().getAsStringInternal(ObjCQIString, Policy);
-
- if (!isObjCIdType() && !isObjCQualifiedIdType())
- ObjCQIString += " *"; // Don't forget the implicit pointer.
- else if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
-
- InnerString = ObjCQIString + InnerString;
-}
-
-void ElaboratedType::getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const {
- std::string TypeStr;
- PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
- UnderlyingType.getAsStringInternal(InnerString, InnerPolicy);
-
- InnerString = std::string(getNameForTagKind(getTagKind())) + ' ' + InnerString;
-}
-
-void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- if (Policy.SuppressTag)
- return;
-
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
-
- const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName();
- const char *ID;
- if (const IdentifierInfo *II = getDecl()->getIdentifier())
- ID = II->getNameStart();
- else if (TypedefDecl *Typedef = getDecl()->getTypedefForAnonDecl()) {
- Kind = 0;
- assert(Typedef->getIdentifier() && "Typedef without identifier?");
- ID = Typedef->getIdentifier()->getNameStart();
- } else
- ID = "<anonymous>";
-
- // If this is a class template specialization, print the template
- // arguments.
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- std::string TemplateArgsStr
- = TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
- Policy);
- InnerString = TemplateArgsStr + InnerString;
- }
-
- if (!Policy.SuppressScope) {
- // Compute the full nested-name-specifier for this type. In C,
- // this will always be empty.
- std::string ContextStr;
- for (DeclContext *DC = getDecl()->getDeclContext();
- !DC->isTranslationUnit(); DC = DC->getParent()) {
- std::string MyPart;
- if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
- if (NS->getIdentifier())
- MyPart = NS->getNameAsString();
- } else if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- std::string TemplateArgsStr
- = TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
- Policy);
- MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
- } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
- if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
- MyPart = Typedef->getIdentifier()->getName();
- else if (Tag->getIdentifier())
- MyPart = Tag->getIdentifier()->getName();
- }
-
- if (!MyPart.empty())
- ContextStr = MyPart + "::" + ContextStr;
- }
-
- if (Kind)
- InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
- else
- InnerString = ContextStr + ID + InnerString;
- } else
- InnerString = ID + InnerString;
-}
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
new file mode 100644
index 000000000000..a48233378286
--- /dev/null
+++ b/lib/AST/TypePrinter.cpp
@@ -0,0 +1,728 @@
+//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to print types from Clang's type system.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+ class TypePrinter {
+ PrintingPolicy Policy;
+
+ public:
+ explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
+
+ void Print(QualType T, std::string &S);
+ void PrintTag(const TagType *T, std::string &S);
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) \
+ void Print##CLASS(const CLASS##Type *T, std::string &S);
+#include "clang/AST/TypeNodes.def"
+ };
+}
+
+static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
+ if (TypeQuals & Qualifiers::Const) {
+ if (!S.empty()) S += ' ';
+ S += "const";
+ }
+ if (TypeQuals & Qualifiers::Volatile) {
+ if (!S.empty()) S += ' ';
+ S += "volatile";
+ }
+ if (TypeQuals & Qualifiers::Restrict) {
+ if (!S.empty()) S += ' ';
+ S += "restrict";
+ }
+}
+
+void TypePrinter::Print(QualType T, std::string &S) {
+ if (T.isNull()) {
+ S += "NULL TYPE";
+ return;
+ }
+
+ if (Policy.SuppressSpecifiers && T->isSpecifierType())
+ return;
+
+ // Print qualifiers as appropriate.
+ Qualifiers Quals = T.getLocalQualifiers();
+ if (!Quals.empty()) {
+ std::string TQS;
+ Quals.getAsStringInternal(TQS, Policy);
+
+ if (!S.empty()) {
+ TQS += ' ';
+ TQS += S;
+ }
+ std::swap(S, TQS);
+ }
+
+ switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) case Type::CLASS: \
+ Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S); \
+ break;
+#include "clang/AST/TypeNodes.def"
+ }
+}
+
+void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
+ if (S.empty()) {
+ S = T->getName(Policy.LangOpts);
+ } else {
+ // Prefix the basic type, e.g. 'int X'.
+ S = ' ' + S;
+ S = T->getName(Policy.LangOpts) + S;
+ }
+}
+
+void TypePrinter::PrintFixedWidthInt(const FixedWidthIntType *T,
+ std::string &S) {
+ // FIXME: Once we get bitwidth attribute, write as
+ // "int __attribute__((bitwidth(x)))".
+ std::string prefix = "__clang_fixedwidth";
+ prefix += llvm::utostr_32(T->getWidth());
+ prefix += (char)(T->isSigned() ? 'S' : 'U');
+ if (S.empty()) {
+ S = prefix;
+ } else {
+ // Prefix the basic type, e.g. 'int X'.
+ S = prefix + S;
+ }
+}
+
+void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
+ Print(T->getElementType(), S);
+ S = "_Complex " + S;
+}
+
+void TypePrinter::PrintPointer(const PointerType *T, std::string &S) {
+ S = '*' + S;
+
+ // Handle things like 'int (*A)[4];' correctly.
+ // FIXME: this should include vectors, but vectors use attributes I guess.
+ if (isa<ArrayType>(T->getPointeeType()))
+ S = '(' + S + ')';
+
+ Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
+ S = '^' + S;
+ Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintLValueReference(const LValueReferenceType *T,
+ std::string &S) {
+ S = '&' + S;
+
+ // Handle things like 'int (&A)[4];' correctly.
+ // FIXME: this should include vectors, but vectors use attributes I guess.
+ if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+ S = '(' + S + ')';
+
+ Print(T->getPointeeTypeAsWritten(), S);
+}
+
+void TypePrinter::PrintRValueReference(const RValueReferenceType *T,
+ std::string &S) {
+ S = "&&" + S;
+
+ // Handle things like 'int (&&A)[4];' correctly.
+ // FIXME: this should include vectors, but vectors use attributes I guess.
+ if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+ S = '(' + S + ')';
+
+ Print(T->getPointeeTypeAsWritten(), S);
+}
+
+void TypePrinter::PrintMemberPointer(const MemberPointerType *T,
+ std::string &S) {
+ std::string C;
+ Print(QualType(T->getClass(), 0), C);
+ C += "::*";
+ S = C + S;
+
+ // Handle things like 'int (Cls::*A)[4];' correctly.
+ // FIXME: this should include vectors, but vectors use attributes I guess.
+ if (isa<ArrayType>(T->getPointeeType()))
+ S = '(' + S + ')';
+
+ Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintConstantArray(const ConstantArrayType *T,
+ std::string &S) {
+ S += '[';
+ S += llvm::utostr(T->getSize().getZExtValue());
+ S += ']';
+
+ Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T,
+ std::string &S) {
+ S += "[]";
+ Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintVariableArray(const VariableArrayType *T,
+ std::string &S) {
+ S += '[';
+
+ if (T->getIndexTypeQualifiers().hasQualifiers()) {
+ AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
+ S += ' ';
+ }
+
+ if (T->getSizeModifier() == VariableArrayType::Static)
+ S += "static";
+ else if (T->getSizeModifier() == VariableArrayType::Star)
+ S += '*';
+
+ if (T->getSizeExpr()) {
+ std::string SStr;
+ llvm::raw_string_ostream s(SStr);
+ T->getSizeExpr()->printPretty(s, 0, Policy);
+ S += s.str();
+ }
+ S += ']';
+
+ Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T,
+ std::string &S) {
+ S += '[';
+
+ if (T->getSizeExpr()) {
+ std::string SStr;
+ llvm::raw_string_ostream s(SStr);
+ T->getSizeExpr()->printPretty(s, 0, Policy);
+ S += s.str();
+ }
+ S += ']';
+
+ Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintDependentSizedExtVector(
+ const DependentSizedExtVectorType *T,
+ std::string &S) {
+ Print(T->getElementType(), S);
+
+ S += " __attribute__((ext_vector_type(";
+ if (T->getSizeExpr()) {
+ std::string SStr;
+ llvm::raw_string_ostream s(SStr);
+ T->getSizeExpr()->printPretty(s, 0, Policy);
+ S += s.str();
+ }
+ S += ")))";
+}
+
+void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
+ // FIXME: We prefer to print the size directly here, but have no way
+ // to get the size of the type.
+ S += " __attribute__((__vector_size__(";
+ S += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
+ std::string ET;
+ Print(T->getElementType(), ET);
+ S += " * sizeof(" + ET + "))))";
+ Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
+ S += " __attribute__((ext_vector_type(";
+ S += llvm::utostr_32(T->getNumElements());
+ S += ")))";
+ Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
+ std::string &S) {
+ // If needed for precedence reasons, wrap the inner part in grouping parens.
+ if (!S.empty())
+ S = "(" + S + ")";
+
+ S += "(";
+ std::string Tmp;
+ PrintingPolicy ParamPolicy(Policy);
+ ParamPolicy.SuppressSpecifiers = false;
+ for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+ if (i) S += ", ";
+ Print(T->getArgType(i), Tmp);
+ S += Tmp;
+ Tmp.clear();
+ }
+
+ if (T->isVariadic()) {
+ if (T->getNumArgs())
+ S += ", ";
+ S += "...";
+ } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
+ // Do not emit int() if we have a proto, emit 'int(void)'.
+ S += "void";
+ }
+
+ S += ")";
+ if (T->getNoReturnAttr())
+ S += " __attribute__((noreturn))";
+ Print(T->getResultType(), S);
+
+}
+
+void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
+ std::string &S) {
+ // If needed for precedence reasons, wrap the inner part in grouping parens.
+ if (!S.empty())
+ S = "(" + S + ")";
+
+ S += "()";
+ if (T->getNoReturnAttr())
+ S += " __attribute__((noreturn))";
+ Print(T->getResultType(), S);
+}
+
+void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
+ if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+ S = ' ' + S;
+ S = T->getDecl()->getIdentifier()->getName().str() + S;
+}
+
+void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
+ if (!S.empty()) // Prefix the basic type, e.g. 'typeof(e) X'.
+ S = ' ' + S;
+ std::string Str;
+ llvm::raw_string_ostream s(Str);
+ T->getUnderlyingExpr()->printPretty(s, 0, Policy);
+ S = "typeof " + s.str() + S;
+}
+
+void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) {
+ if (!S.empty()) // Prefix the basic type, e.g. 'typeof(t) X'.
+ S = ' ' + S;
+ std::string Tmp;
+ Print(T->getUnderlyingType(), Tmp);
+ S = "typeof(" + Tmp + ")" + S;
+}
+
+void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
+ if (!S.empty()) // Prefix the basic type, e.g. 'decltype(t) X'.
+ S = ' ' + S;
+ std::string Str;
+ llvm::raw_string_ostream s(Str);
+ T->getUnderlyingExpr()->printPretty(s, 0, Policy);
+ S = "decltype(" + s.str() + ")" + S;
+}
+
+void TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
+ if (Policy.SuppressTag)
+ return;
+
+ if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+ InnerString = ' ' + InnerString;
+
+ const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
+ const char *ID;
+ if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
+ ID = II->getNameStart();
+ else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
+ Kind = 0;
+ assert(Typedef->getIdentifier() && "Typedef without identifier?");
+ ID = Typedef->getIdentifier()->getNameStart();
+ } else
+ ID = "<anonymous>";
+
+ // If this is a class template specialization, print the template
+ // arguments.
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ std::string TemplateArgsStr
+ = TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size(),
+ Policy);
+ InnerString = TemplateArgsStr + InnerString;
+ }
+
+ if (!Policy.SuppressScope) {
+ // Compute the full nested-name-specifier for this type. In C,
+ // this will always be empty.
+ std::string ContextStr;
+ for (DeclContext *DC = T->getDecl()->getDeclContext();
+ !DC->isTranslationUnit(); DC = DC->getParent()) {
+ std::string MyPart;
+ if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+ if (NS->getIdentifier())
+ MyPart = NS->getNameAsString();
+ } else if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ std::string TemplateArgsStr
+ = TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size(),
+ Policy);
+ MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
+ } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
+ if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
+ MyPart = Typedef->getIdentifier()->getName();
+ else if (Tag->getIdentifier())
+ MyPart = Tag->getIdentifier()->getName();
+ }
+
+ if (!MyPart.empty())
+ ContextStr = MyPart + "::" + ContextStr;
+ }
+
+ if (Kind)
+ InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
+ else
+ InnerString = ContextStr + ID + InnerString;
+ } else
+ InnerString = ID + InnerString;
+}
+
+void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
+ PrintTag(T, S);
+}
+
+void TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
+ PrintTag(T, S);
+}
+
+void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
+ std::string TypeStr;
+ PrintingPolicy InnerPolicy(Policy);
+ InnerPolicy.SuppressTagKind = true;
+ TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
+
+ S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;
+}
+
+void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T,
+ std::string &S) {
+ if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'.
+ S = ' ' + S;
+
+ if (!T->getName())
+ S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
+ llvm::utostr_32(T->getIndex()) + S;
+ else
+ S = T->getName()->getName().str() + S;
+}
+
+void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T,
+ std::string &S) {
+ Print(T->getReplacementType(), S);
+}
+
+void TypePrinter::PrintTemplateSpecialization(
+ const TemplateSpecializationType *T,
+ std::string &S) {
+ std::string SpecString;
+
+ {
+ llvm::raw_string_ostream OS(SpecString);
+ T->getTemplateName().print(OS, Policy);
+ }
+
+ SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
+ T->getArgs(),
+ T->getNumArgs(),
+ Policy);
+ if (S.empty())
+ S.swap(SpecString);
+ else
+ S = SpecString + ' ' + S;
+}
+
+void TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
+ std::string &S) {
+ std::string MyString;
+
+ {
+ llvm::ra