summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanya Lattner <tonic@nondot.org>2008-10-07 04:06:01 +0000
committerTanya Lattner <tonic@nondot.org>2008-10-07 04:06:01 +0000
commit4ee26f1ed6e7fd894c7c2d7e61d6c50f793a97b1 (patch)
tree8845f921323f78ed80181886c3bac91ef42af3cb
parent3b893a905eea107d96d4c76fe3365fcc3c3b7c8a (diff)
downloadllvm-4ee26f1ed6e7fd894c7c2d7e61d6c50f793a97b1.tar.gz
Create 2.4 release branch.
llvm-svn: 57229
-rw-r--r--clang/Driver/ASTConsumers.cpp734
-rw-r--r--clang/Driver/ASTConsumers.h69
-rw-r--r--clang/Driver/Analyses.def46
-rw-r--r--clang/Driver/AnalysisConsumer.cpp575
-rw-r--r--clang/Driver/AnalysisConsumer.h37
-rw-r--r--clang/Driver/DiagChecker.cpp267
-rw-r--r--clang/Driver/HTMLPrint.cpp97
-rw-r--r--clang/Driver/Makefile12
-rw-r--r--clang/Driver/PrintParserCallbacks.cpp572
-rw-r--r--clang/Driver/PrintPreprocessedOutput.cpp551
-rw-r--r--clang/Driver/RewriteBlocks.cpp1114
-rw-r--r--clang/Driver/RewriteMacros.cpp238
-rw-r--r--clang/Driver/RewriteObjC.cpp3236
-rw-r--r--clang/Driver/SerializationTest.cpp193
-rw-r--r--clang/Driver/clang.cpp1366
-rw-r--r--clang/Driver/clang.h52
-rw-r--r--clang/INPUTS/Cocoa_h.m2
-rw-r--r--clang/INPUTS/carbon_h.c4
-rw-r--r--clang/INPUTS/iostream.cc5
-rw-r--r--clang/INPUTS/macro_pounder_fn.c17
-rw-r--r--clang/INPUTS/macro_pounder_obj.c16
-rw-r--r--clang/INPUTS/stpcpy-test.c47
-rw-r--r--clang/LICENSE.TXT63
-rw-r--r--clang/Makefile15
-rw-r--r--clang/ModuleInfo.txt5
-rw-r--r--clang/NOTES.txt136
-rw-r--r--clang/README.txt199
-rw-r--r--clang/TODO.txt34
-rw-r--r--clang/clang.xcodeproj/project.pbxproj1380
-rw-r--r--clang/docs/InternalsManual.html624
-rw-r--r--clang/docs/Makefile94
-rw-r--r--clang/docs/doxygen.cfg1230
-rw-r--r--clang/docs/doxygen.cfg.in1230
-rw-r--r--clang/docs/doxygen.css378
-rw-r--r--clang/docs/doxygen.footer10
-rw-r--r--clang/docs/doxygen.header9
-rw-r--r--clang/docs/doxygen.intro15
-rw-r--r--clang/docs/index.html4
-rw-r--r--clang/include/clang/AST/APValue.h246
-rw-r--r--clang/include/clang/AST/AST.h27
-rw-r--r--clang/include/clang/AST/ASTConsumer.h60
-rw-r--r--clang/include/clang/AST/ASTContext.h480
-rw-r--r--clang/include/clang/AST/Attr.h409
-rw-r--r--clang/include/clang/AST/Builtins.def168
-rw-r--r--clang/include/clang/AST/Builtins.h95
-rw-r--r--clang/include/clang/AST/CFG.h397
-rw-r--r--clang/include/clang/AST/Decl.h986
-rw-r--r--clang/include/clang/AST/DeclBase.h403
-rw-r--r--clang/include/clang/AST/DeclCXX.h194
-rw-r--r--clang/include/clang/AST/DeclGroup.h120
-rw-r--r--clang/include/clang/AST/DeclObjC.h1318
-rw-r--r--clang/include/clang/AST/Expr.h1575
-rw-r--r--clang/include/clang/AST/ExprCXX.h276
-rw-r--r--clang/include/clang/AST/ExprObjC.h418
-rw-r--r--clang/include/clang/AST/PPCBuiltins.def24
-rw-r--r--clang/include/clang/AST/ParentMap.h36
-rw-r--r--clang/include/clang/AST/PrettyPrinter.h31
-rw-r--r--clang/include/clang/AST/RecordLayout.h84
-rw-r--r--clang/include/clang/AST/Stmt.h1133
-rw-r--r--clang/include/clang/AST/StmtGraphTraits.h83
-rw-r--r--clang/include/clang/AST/StmtIterator.h129
-rw-r--r--clang/include/clang/AST/StmtNodes.def121
-rw-r--r--clang/include/clang/AST/StmtVisitor.h174
-rw-r--r--clang/include/clang/AST/TargetBuiltins.h38
-rw-r--r--clang/include/clang/AST/TranslationUnit.h112
-rw-r--r--clang/include/clang/AST/Type.h1412
-rw-r--r--clang/include/clang/AST/X86Builtins.def465
-rw-r--r--clang/include/clang/Analysis/Analyses/LiveVariables.h119
-rw-r--r--clang/include/clang/Analysis/Analyses/UninitializedValues.h74
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h311
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/DataflowValues.h172
-rw-r--r--clang/include/clang/Analysis/LocalCheckers.h54
-rw-r--r--clang/include/clang/Analysis/PathDiagnostic.h213
-rw-r--r--clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h86
-rw-r--r--clang/include/clang/Analysis/PathSensitive/BugReporter.h352
-rw-r--r--clang/include/clang/Analysis/PathSensitive/ConstraintManager.h56
-rw-r--r--clang/include/clang/Analysis/PathSensitive/Environment.h150
-rw-r--r--clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h525
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRAuditor.h39
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRBlockCounter.h50
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h639
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRExprEngine.h645
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h41
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRState.h584
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRStateTrait.h67
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h132
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRWorkList.h74
-rw-r--r--clang/include/clang/Analysis/PathSensitive/MemRegion.h267
-rw-r--r--clang/include/clang/Analysis/PathSensitive/RValues.h513
-rw-r--r--clang/include/clang/Analysis/PathSensitive/Store.h73
-rw-r--r--clang/include/clang/Analysis/PathSensitive/SymbolManager.h264
-rw-r--r--clang/include/clang/Analysis/ProgramPoint.h228
-rw-r--r--clang/include/clang/Analysis/Support/ExprDeclBitVector.h276
-rw-r--r--clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h92
-rw-r--r--clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h35
-rw-r--r--clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h151
-rw-r--r--clang/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h64
-rw-r--r--clang/include/clang/Basic/Diagnostic.h213
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def1276
-rw-r--r--clang/include/clang/Basic/FileManager.h125
-rw-r--r--clang/include/clang/Basic/IdentifierTable.h335
-rw-r--r--clang/include/clang/Basic/LangOptions.h85
-rw-r--r--clang/include/clang/Basic/SourceLocation.h275
-rw-r--r--clang/include/clang/Basic/SourceManager.h508
-rw-r--r--clang/include/clang/Basic/TargetInfo.h233
-rw-r--r--clang/include/clang/Basic/TokenKinds.def364
-rw-r--r--clang/include/clang/Basic/TokenKinds.h51
-rw-r--r--clang/include/clang/CodeGen/ModuleBuilder.h39
-rw-r--r--clang/include/clang/Driver/HTMLDiagnostics.h31
-rw-r--r--clang/include/clang/Driver/InitHeaderSearch.h74
-rw-r--r--clang/include/clang/Driver/TextDiagnosticBuffer.h54
-rw-r--r--clang/include/clang/Driver/TextDiagnosticPrinter.h56
-rw-r--r--clang/include/clang/Lex/DirectoryLookup.h133
-rw-r--r--clang/include/clang/Lex/HeaderMap.h67
-rw-r--r--clang/include/clang/Lex/HeaderSearch.h204
-rw-r--r--clang/include/clang/Lex/Lexer.h383
-rw-r--r--clang/include/clang/Lex/LiteralSupport.h166
-rw-r--r--clang/include/clang/Lex/MacroInfo.h190
-rw-r--r--clang/include/clang/Lex/MultipleIncludeOpt.h130
-rw-r--r--clang/include/clang/Lex/PPCallbacks.h53
-rw-r--r--clang/include/clang/Lex/Pragma.h90
-rw-r--r--clang/include/clang/Lex/Preprocessor.h612
-rw-r--r--clang/include/clang/Lex/ScratchBuffer.h50
-rw-r--r--clang/include/clang/Lex/Token.h154
-rw-r--r--clang/include/clang/Lex/TokenLexer.h146
-rw-r--r--clang/include/clang/Parse/AccessSpecifier.h30
-rw-r--r--clang/include/clang/Parse/Action.h938
-rw-r--r--clang/include/clang/Parse/AttributeList.h150
-rw-r--r--clang/include/clang/Parse/DeclSpec.h758
-rw-r--r--clang/include/clang/Parse/Parser.h721
-rw-r--r--clang/include/clang/Parse/Scope.h203
-rw-r--r--clang/include/clang/Rewrite/DeltaTree.h48
-rw-r--r--clang/include/clang/Rewrite/HTMLRewrite.h90
-rw-r--r--clang/include/clang/Rewrite/RewriteRope.h230
-rw-r--r--clang/include/clang/Rewrite/Rewriter.h227
-rw-r--r--clang/include/clang/Sema/ParseAST.h28
-rw-r--r--clang/lib/AST/ASTConsumer.cpp24
-rw-r--r--clang/lib/AST/ASTContext.cpp2191
-rw-r--r--clang/lib/AST/Builtins.cpp203
-rw-r--r--clang/lib/AST/CFG.cpp1692
-rw-r--r--clang/lib/AST/Decl.cpp287
-rw-r--r--clang/lib/AST/DeclBase.cpp349
-rw-r--r--clang/lib/AST/DeclCXX.cpp68
-rw-r--r--clang/lib/AST/DeclGroup.cpp122
-rw-r--r--clang/lib/AST/DeclObjC.cpp794
-rw-r--r--clang/lib/AST/DeclSerialization.cpp541
-rw-r--r--clang/lib/AST/Expr.cpp1407
-rw-r--r--clang/lib/AST/ExprCXX.cpp69
-rw-r--r--clang/lib/AST/ExprConstant.cpp699
-rw-r--r--clang/lib/AST/Makefile22
-rw-r--r--clang/lib/AST/ParentMap.cpp55
-rw-r--r--clang/lib/AST/Stmt.cpp322
-rw-r--r--clang/lib/AST/StmtDumper.cpp504
-rw-r--r--clang/lib/AST/StmtIterator.cpp116
-rw-r--r--clang/lib/AST/StmtPrinter.cpp950
-rw-r--r--clang/lib/AST/StmtSerialization.cpp1184
-rw-r--r--clang/lib/AST/StmtViz.cpp60
-rw-r--r--clang/lib/AST/TranslationUnit.cpp345
-rw-r--r--clang/lib/AST/Type.cpp1049
-rw-r--r--clang/lib/AST/TypeSerialization.cpp310
-rw-r--r--clang/lib/Analysis/BasicConstraintManager.cpp478
-rw-r--r--clang/lib/Analysis/BasicObjCFoundationChecks.cpp579
-rw-r--r--clang/lib/Analysis/BasicObjCFoundationChecks.h44
-rw-r--r--clang/lib/Analysis/BasicStore.cpp352
-rw-r--r--clang/lib/Analysis/BasicValueFactory.cpp254
-rw-r--r--clang/lib/Analysis/BugReporter.cpp816
-rw-r--r--clang/lib/Analysis/CFRefCount.cpp2533
-rw-r--r--clang/lib/Analysis/CheckDeadStores.cpp199
-rw-r--r--clang/lib/Analysis/CheckNSError.cpp256
-rw-r--r--clang/lib/Analysis/CheckObjCDealloc.cpp132
-rw-r--r--clang/lib/Analysis/CheckObjCInstMethSignature.cpp119
-rw-r--r--clang/lib/Analysis/CheckObjCUnusedIVars.cpp110
-rw-r--r--clang/lib/Analysis/Environment.cpp152
-rw-r--r--clang/lib/Analysis/ExplodedGraph.cpp288
-rw-r--r--clang/lib/Analysis/GRBlockCounter.cpp54
-rw-r--r--clang/lib/Analysis/GRCoreEngine.cpp470
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp2430
-rw-r--r--clang/lib/Analysis/GRExprEngineInternalChecks.cpp360
-rw-r--r--clang/lib/Analysis/GRSimpleVals.cpp435
-rw-r--r--clang/lib/Analysis/GRSimpleVals.h88
-rw-r--r--clang/lib/Analysis/GRState.cpp268
-rw-r--r--clang/lib/Analysis/GRTransferFuncs.cpp48
-rw-r--r--clang/lib/Analysis/LiveVariables.cpp339
-rw-r--r--clang/lib/Analysis/Makefile22
-rw-r--r--clang/lib/Analysis/MemRegion.cpp158
-rw-r--r--clang/lib/Analysis/PathDiagnostic.cpp62
-rw-r--r--clang/lib/Analysis/RValues.cpp446
-rw-r--r--clang/lib/Analysis/SymbolManager.cpp125
-rw-r--r--clang/lib/Analysis/UninitializedValues.cpp284
-rw-r--r--clang/lib/Basic/Diagnostic.cpp272
-rw-r--r--clang/lib/Basic/FileManager.cpp275
-rw-r--r--clang/lib/Basic/IdentifierTable.cpp551
-rw-r--r--clang/lib/Basic/LangOptions.cpp60
-rw-r--r--clang/lib/Basic/Makefile22
-rw-r--r--clang/lib/Basic/SourceLocation.cpp134
-rw-r--r--clang/lib/Basic/SourceManager.cpp516
-rw-r--r--clang/lib/Basic/TargetInfo.cpp224
-rw-r--r--clang/lib/Basic/Targets.cpp856
-rw-r--r--clang/lib/Basic/TokenKinds.cpp29
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp952
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp150
-rw-r--r--clang/lib/CodeGen/CGCall.cpp798
-rw-r--r--clang/lib/CodeGen/CGCall.h88
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp788
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h149
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp249
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp887
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp465
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp560
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp861
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp1235
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp544
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp969
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp2357
-rw-r--r--clang/lib/CodeGen/CGObjCRuntime.h154
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp892
-rw-r--r--clang/lib/CodeGen/CGValue.h235
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp250
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h518
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp1044
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h283
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp551
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.h200
-rw-r--r--clang/lib/CodeGen/Makefile23
-rw-r--r--clang/lib/CodeGen/ModuleBuilder.cpp100
-rw-r--r--clang/lib/Driver/HTMLDiagnostics.cpp503
-rw-r--r--clang/lib/Driver/InitHeaderSearch.cpp362
-rw-r--r--clang/lib/Driver/Makefile22
-rw-r--r--clang/lib/Driver/TextDiagnosticBuffer.cpp45
-rw-r--r--clang/lib/Driver/TextDiagnosticPrinter.cpp200
-rw-r--r--clang/lib/Headers/Makefile39
-rw-r--r--clang/lib/Headers/iso646.h43
-rw-r--r--clang/lib/Headers/mmintrin.h376
-rw-r--r--clang/lib/Headers/stdarg.h39
-rw-r--r--clang/lib/Headers/stdbool.h38
-rw-r--r--clang/lib/Headers/stddef.h38
-rw-r--r--clang/lib/Lex/HeaderMap.cpp241
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp425
-rw-r--r--clang/lib/Lex/Lexer.cpp1656
-rw-r--r--clang/lib/Lex/LiteralSupport.cpp772
-rw-r--r--clang/lib/Lex/MacroArgs.cpp225
-rw-r--r--clang/lib/Lex/MacroArgs.h109
-rw-r--r--clang/lib/Lex/MacroInfo.cpp70
-rw-r--r--clang/lib/Lex/Makefile28
-rw-r--r--clang/lib/Lex/PPCaching.cpp95
-rw-r--r--clang/lib/Lex/PPDirectives.cpp1161
-rw-r--r--clang/lib/Lex/PPExpressions.cpp711
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp330
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp535
-rw-r--r--clang/lib/Lex/Pragma.cpp420
-rw-r--r--clang/lib/Lex/Preprocessor.cpp759
-rw-r--r--clang/lib/Lex/ScratchBuffer.cpp72
-rw-r--r--clang/lib/Lex/TokenLexer.cpp488
-rwxr-xr-xclang/lib/Makefile14
-rw-r--r--clang/lib/Parse/AttributeList.cpp112
-rw-r--r--clang/lib/Parse/DeclSpec.cpp300
-rw-r--r--clang/lib/Parse/Makefile22
-rw-r--r--clang/lib/Parse/MinimalAction.cpp140
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp148
-rw-r--r--clang/lib/Parse/ParseDecl.cpp1650
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp630
-rw-r--r--clang/lib/Parse/ParseExpr.cpp1136
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp293
-rw-r--r--clang/lib/Parse/ParseInit.cpp239
-rw-r--r--clang/lib/Parse/ParseObjc.cpp1689
-rw-r--r--clang/lib/Parse/ParsePragma.cpp108
-rw-r--r--clang/lib/Parse/ParsePragma.h33
-rw-r--r--clang/lib/Parse/ParseStmt.cpp1228
-rw-r--r--clang/lib/Parse/ParseTentative.cpp877
-rw-r--r--clang/lib/Parse/Parser.cpp707
-rw-r--r--clang/lib/Rewrite/DeltaTree.cpp485
-rw-r--r--clang/lib/Rewrite/HTMLRewrite.cpp504
-rw-r--r--clang/lib/Rewrite/Makefile22
-rw-r--r--clang/lib/Rewrite/RewriteRope.cpp807
-rw-r--r--clang/lib/Rewrite/Rewriter.cpp227
-rw-r--r--clang/lib/Sema/CXXFieldCollector.h76
-rw-r--r--clang/lib/Sema/IdentifierResolver.cpp333
-rw-r--r--clang/lib/Sema/IdentifierResolver.h250
-rw-r--r--clang/lib/Sema/Makefile23
-rw-r--r--clang/lib/Sema/ParseAST.cpp76
-rw-r--r--clang/lib/Sema/Sema.cpp239
-rw-r--r--clang/lib/Sema/Sema.h1089
-rw-r--r--clang/lib/Sema/SemaChecking.cpp999
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2561
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp1185
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp617
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp1303
-rw-r--r--clang/lib/Sema/SemaExpr.cpp3116
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp237
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp579
-rw-r--r--clang/lib/Sema/SemaInit.cpp309
-rw-r--r--clang/lib/Sema/SemaStmt.cpp917
-rw-r--r--clang/lib/Sema/SemaType.cpp605
-rw-r--r--clang/lib/Sema/SemaUtil.h35
-rw-r--r--clang/test/Analysis/CFDate.m143
-rw-r--r--clang/test/Analysis/CFDateGC.m39
-rw-r--r--clang/test/Analysis/CFNumber.c32
-rw-r--r--clang/test/Analysis/CFRetainRelease_NSAssertionHandler.m64
-rw-r--r--clang/test/Analysis/CFString.c60
-rw-r--r--clang/test/Analysis/CheckNSError.m43
-rw-r--r--clang/test/Analysis/MissingDealloc_IBOutlet.m20
-rw-r--r--clang/test/Analysis/MissingDealloc_SEL.m30
-rw-r--r--clang/test/Analysis/NSPanel.m87
-rw-r--r--clang/test/Analysis/NSString.m181
-rw-r--r--clang/test/Analysis/NSWindow.m84
-rw-r--r--clang/test/Analysis/NoReturn.m78
-rw-r--r--clang/test/Analysis/ObjCRetSigs.m25
-rw-r--r--clang/test/Analysis/cfref_PR2519.c45
-rw-r--r--clang/test/Analysis/cfref_rdar6080742.c55
-rw-r--r--clang/test/Analysis/complex.c17
-rw-r--r--clang/test/Analysis/conditional-op-missing-lhs.c26
-rw-r--r--clang/test/Analysis/dead-stores.c123
-rw-r--r--clang/test/Analysis/dead-stores.m36
-rw-r--r--clang/test/Analysis/exercise-ps.c10
-rw-r--r--clang/test/Analysis/misc-ps.m11
-rw-r--r--clang/test/Analysis/no-exit-cfg.c18
-rw-r--r--clang/test/Analysis/null-deref-ps.c115
-rw-r--r--clang/test/Analysis/stack-addr-ps.c21
-rw-r--r--clang/test/Analysis/uninit-msg-expr.m56
-rw-r--r--clang/test/Analysis/uninit-ps-rdar6145427.m36
-rw-r--r--clang/test/Analysis/uninit-vals-ps.c43
-rw-r--r--clang/test/Analysis/uninit-vals.c44
-rw-r--r--clang/test/Analysis/uninit-vals.m24
-rw-r--r--clang/test/Analysis/unused-ivars.m10
-rw-r--r--clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c4
-rw-r--r--clang/test/CodeGen/2008-02-07-bitfield-bug.c11
-rw-r--r--clang/test/CodeGen/2008-02-08-bitfield-bug.c9
-rw-r--r--clang/test/CodeGen/2008-02-26-inline-asm-bug.c6
-rw-r--r--clang/test/CodeGen/2008-07-17-no-emit-on-error.c10
-rw-r--r--clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c5
-rw-r--r--clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c11
-rw-r--r--clang/test/CodeGen/2008-07-22-packed-bitfield-access.c10
-rw-r--r--clang/test/CodeGen/2008-07-29-override-alias-decl.c12
-rw-r--r--clang/test/CodeGen/2008-07-30-implicit-initialization.c28
-rw-r--r--clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c28
-rw-r--r--clang/test/CodeGen/2008-07-31-asm-labels.c25
-rw-r--r--clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c25
-rw-r--r--clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c6
-rw-r--r--clang/test/CodeGen/2008-08-19-cast-of-typedef.c10
-rw-r--r--clang/test/CodeGen/2008-08-25-incompatible-cond-expr.m10
-rw-r--r--clang/test/CodeGen/2008-09-22-bad-switch-type.c34
-rw-r--r--clang/test/CodeGen/OpaqueStruct.c12
-rw-r--r--clang/test/CodeGen/PR2001-bitfield-reload.c17
-rw-r--r--clang/test/CodeGen/PR2643-null-store-to-bitfield.c10
-rw-r--r--clang/test/CodeGen/PR2743-reference-missing-static.c16
-rw-r--r--clang/test/CodeGen/address-space-cast.c4
-rw-r--r--clang/test/CodeGen/address-space.c20
-rw-r--r--clang/test/CodeGen/align-local.c8
-rw-r--r--clang/test/CodeGen/array.c14
-rw-r--r--clang/test/CodeGen/atomic.c35
-rw-r--r--clang/test/CodeGen/attributes.c32
-rw-r--r--clang/test/CodeGen/bitfield-init.c12
-rw-r--r--clang/test/CodeGen/bitfield.c74
-rw-r--r--clang/test/CodeGen/bool-bitfield.c54
-rw-r--r--clang/test/CodeGen/bool-init.c4
-rw-r--r--clang/test/CodeGen/boolassign.c6
-rw-r--r--clang/test/CodeGen/builtin-count-zeros.c4
-rw-r--r--clang/test/CodeGen/builtin-memfns.c11
-rw-r--r--clang/test/CodeGen/builtin-stackaddress.c9
-rw-r--r--clang/test/CodeGen/builtinmemcpy.c3
-rw-r--r--clang/test/CodeGen/builtins-ffs_parity_popcount.c15
-rw-r--r--clang/test/CodeGen/builtins-powi.c29
-rw-r--r--clang/test/CodeGen/builtins-x86.c532
-rw-r--r--clang/test/CodeGen/builtins.c106
-rw-r--r--clang/test/CodeGen/builtinshufflevector.c5
-rw-r--r--clang/test/CodeGen/c-strings.c36
-rw-r--r--clang/test/CodeGen/cast.c6
-rw-r--r--clang/test/CodeGen/cfstring.c11
-rw-r--r--clang/test/CodeGen/cfstring2.c13
-rw-r--r--clang/test/CodeGen/complex.c53
-rw-r--r--clang/test/CodeGen/compound-literal.c12
-rw-r--r--clang/test/CodeGen/compound.c25
-rw-r--r--clang/test/CodeGen/conditional-gnu-ext.c6
-rw-r--r--clang/test/CodeGen/conditional.c44
-rw-r--r--clang/test/CodeGen/const-init.c15
-rw-r--r--clang/test/CodeGen/constant-comparison.c12
-rw-r--r--clang/test/CodeGen/constructor-attribute.c20
-rw-r--r--clang/test/CodeGen/cxx-condition.cpp9
-rw-r--r--clang/test/CodeGen/cxx-default-arg.cpp25
-rw-r--r--clang/test/CodeGen/cxx-value-init.cpp11
-rw-r--r--clang/test/CodeGen/dostmt.c70
-rw-r--r--clang/test/CodeGen/empty-union-init.c13
-rw-r--r--clang/test/CodeGen/enum.c18
-rw-r--r--clang/test/CodeGen/exprs.c41
-rw-r--r--clang/test/CodeGen/extern-block-var.c6
-rw-r--r--clang/test/CodeGen/func-decl-cleanup.c12
-rw-r--r--clang/test/CodeGen/func-return-member.c23
-rw-r--r--clang/test/CodeGen/function-attributes.c26
-rw-r--r--clang/test/CodeGen/functions.c17
-rw-r--r--clang/test/CodeGen/global-with-initialiser.c25
-rw-r--r--clang/test/CodeGen/globalinit.c52
-rw-r--r--clang/test/CodeGen/indirect-goto.c20
-rw-r--r--clang/test/CodeGen/init-with-member-expr.c21
-rw-r--r--clang/test/CodeGen/init.c23
-rw-r--r--clang/test/CodeGen/int-to-pointer.c6
-rw-r--r--clang/test/CodeGen/kr-func-promote.c5
-rw-r--r--clang/test/CodeGen/long-double-x86.c4
-rw-r--r--clang/test/CodeGen/mandel.c67
-rw-r--r--clang/test/CodeGen/merge-attrs.c13
-rw-r--r--clang/test/CodeGen/merge-statics.c13
-rw-r--r--clang/test/CodeGen/ocu-vector.c48
-rw-r--r--clang/test/CodeGen/opaque-pointer.c13
-rw-r--r--clang/test/CodeGen/pointer-arithmetic.c7
-rw-r--r--clang/test/CodeGen/pointer-cmp-type.c3
-rw-r--r--clang/test/CodeGen/pointer-to-int.c13
-rw-r--r--clang/test/CodeGen/rdr-6095112-alias-references-inline.c6
-rw-r--r--clang/test/CodeGen/rdr-6098585-default-after-caserange.c18
-rw-r--r--clang/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c20
-rw-r--r--clang/test/CodeGen/rdr-6098585-empty-case-range.c23
-rw-r--r--clang/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c15
-rw-r--r--clang/test/CodeGen/rdr-6098585-unsigned-caserange.c12
-rw-r--r--clang/test/CodeGen/rdr-6140807-alias-references-forward.c14
-rw-r--r--clang/test/CodeGen/shared-string-literals.c9
-rw-r--r--clang/test/CodeGen/statements.c13
-rw-r--r--clang/test/CodeGen/static-forward-decl-fun.c6
-rw-r--r--clang/test/CodeGen/static-forward-decl.c5
-rw-r--r--clang/test/CodeGen/static-local-union.c4
-rw-r--r--clang/test/CodeGen/staticinit.c20
-rw-r--r--clang/test/CodeGen/string-init.c8
-rw-r--r--clang/test/CodeGen/string-literal.c5
-rw-r--r--clang/test/CodeGen/struct-comma.c4
-rw-r--r--clang/test/CodeGen/struct-init.c12
-rw-r--r--clang/test/CodeGen/struct-x86-darwin.c25
-rw-r--r--clang/test/CodeGen/struct.c191
-rw-r--r--clang/test/CodeGen/switch.c87
-rw-r--r--clang/test/CodeGen/tentative-array.c4
-rw-r--r--clang/test/CodeGen/trunc-array-initializer.c3
-rw-r--r--clang/test/CodeGen/typedef-func.c16
-rw-r--r--clang/test/CodeGen/typedef.c8
-rw-r--r--clang/test/CodeGen/types.c34
-rw-r--r--clang/test/CodeGen/union-init.c31
-rw-r--r--clang/test/CodeGen/union.c41
-rw-r--r--clang/test/CodeGen/unwind-attr.c5
-rw-r--r--clang/test/CodeGen/var-align.c4
-rw-r--r--clang/test/CodeGen/vector.c11
-rw-r--r--clang/test/CodeGen/volatile.c88
-rw-r--r--clang/test/CodeGen/weak-global.c3
-rw-r--r--clang/test/CodeGen/whilestmt.c62
-rw-r--r--clang/test/CodeGen/writable-strings.c8
-rw-r--r--clang/test/CodeGen/x86-inline-asm.c15
-rw-r--r--clang/test/CodeGenObjC/constant-strings.m4
-rw-r--r--clang/test/CodeGenObjC/dot-syntax-1.m264
-rw-r--r--clang/test/CodeGenObjC/dot-syntax.m98
-rw-r--r--clang/test/CodeGenObjC/hidden.m19
-rw-r--r--clang/test/CodeGenObjC/link-errors.m39
-rw-r--r--clang/test/CodeGenObjC/message-arrays.m15
-rw-r--r--clang/test/CodeGenObjC/messages-2.m139
-rw-r--r--clang/test/CodeGenObjC/messages.m21
-rw-r--r--clang/test/CodeGenObjC/predefined-expr-in-method.m17
-rw-r--r--clang/test/CodeGenObjC/property.m52
-rw-r--r--clang/test/CodeGenObjC/runtime-fns.m28
-rw-r--r--clang/test/Coverage/ast-printing.c5
-rw-r--r--clang/test/Coverage/ast-printing.m5
-rw-r--r--clang/test/Coverage/c-language-features.inc139
-rw-r--r--clang/test/Coverage/codegen-gnu.m5
-rw-r--r--clang/test/Coverage/codegen-next.m5
-rw-r--r--clang/test/Coverage/codegen.c5
-rw-r--r--clang/test/Coverage/html-diagnostics.c15
-rw-r--r--clang/test/Coverage/html-print.c3
-rw-r--r--clang/test/Coverage/objc-language-features.inc67
-rw-r--r--clang/test/Coverage/parse-callbacks.c4
-rw-r--r--clang/test/Coverage/parse-callbacks.m4
-rw-r--r--clang/test/Coverage/serialize.c4
-rw-r--r--clang/test/Coverage/serialize.m4
-rw-r--r--clang/test/Coverage/targets.c18
-rw-r--r--clang/test/Coverage/verbose.c1
-rw-r--r--clang/test/Driver/env-include-paths.c27
-rw-r--r--clang/test/Driver/rewrite-macros.c18
-rw-r--r--clang/test/Lexer/11-27-2007-FloatLiterals.c7
-rw-r--r--clang/test/Lexer/badstring_in_if0.c8
-rw-r--r--clang/test/Lexer/block_cmt_end.c30
-rw-r--r--clang/test/Lexer/c90.c6
-rw-r--r--clang/test/Lexer/constants.c8
-rw-r--r--clang/test/Lexer/cxx0x_keyword.cpp2
-rw-r--r--clang/test/Lexer/cxx0x_keyword_as_cxx98.cpp2
-rw-r--r--clang/test/Lexer/digraph.c15
-rw-r--r--clang/test/Lexer/escape_newline.c7
-rw-r--r--clang/test/Lexer/multiple-include.c27
-rw-r--r--clang/test/Lexer/number.c9
-rw-r--r--clang/test/Lexer/numeric-literal-trash.c13
-rw-r--r--clang/test/Lexer/pragma-mark.c11
-rw-r--r--clang/test/Lexer/preprocess-compat.c3
-rw-r--r--clang/test/Lexer/rdr-6096838.c14
-rw-r--r--clang/test/Lexer/unknown-char.c2
-rw-r--r--clang/test/Makefile41
-rw-r--r--clang/test/Misc/diag-checker.c5
-rw-r--r--clang/test/Parser/CompoundStmtScope.c8
-rw-r--r--clang/test/Parser/argument_qualified.c5
-rw-r--r--clang/test/Parser/argument_redef.c6
-rw-r--r--clang/test/Parser/argument_scope.c6
-rw-r--r--clang/test/Parser/asm.c15
-rw-r--r--clang/test/Parser/attributes.c6
-rw-r--r--clang/test/Parser/bad-control.c9
-rw-r--r--clang/test/Parser/block-block-storageclass.c19
-rw-r--r--clang/test/Parser/block-pointer-decl.c26
-rw-r--r--clang/test/Parser/builtin_classify_type.c21
-rw-r--r--clang/test/Parser/builtin_types_compatible.c43
-rw-r--r--clang/test/Parser/c-namespace.c6
-rw-r--r--clang/test/Parser/char-literal-printing.c31
-rw-r--r--clang/test/Parser/check-objc2-syntax-1.m10
-rw-r--r--clang/test/Parser/check-syntax-1.m4
-rw-r--r--clang/test/Parser/check_cast.c12
-rw-r--r--clang/test/Parser/compound_literal.c5
-rw-r--r--clang/test/Parser/control-scope.c8
-rw-r--r--clang/test/Parser/cxx-bool.cpp4
-rw-r--r--clang/test/Parser/cxx-casting.cpp36
-rw-r--r--clang/test/Parser/cxx-class.cpp20
-rw-r--r--clang/test/Parser/cxx-condition.cpp11
-rw-r--r--clang/test/Parser/cxx-reference.cpp17
-rw-r--r--clang/test/Parser/cxx-typeof.cpp7
-rw-r--r--clang/test/Parser/cxx-variadic-func.cpp5
-rw-r--r--clang/test/Parser/declarators.c34
-rw-r--r--clang/test/Parser/encode.m8
-rw-r--r--clang/test/Parser/enhanced-proto-1.m17
-rw-r--r--clang/test/Parser/expressions.c39
-rw-r--r--clang/test/Parser/expressions.m6
-rw-r--r--clang/test/Parser/extension.c17
-rw-r--r--clang/test/Parser/function-decls.c10
-rw-r--r--clang/test/Parser/goto-ident.c6
-rw-r--r--clang/test/Parser/if-scope-c90.c8
-rw-r--r--clang/test/Parser/if-scope-c99.c8
-rw-r--r--clang/test/Parser/implicit-casts.c20
-rw-r--r--clang/test/Parser/method-prototype-1.m43
-rw-r--r--clang/test/Parser/namelookup-bug-1.c7
-rw-r--r--clang/test/Parser/namelookup-bug-2.c14
-rw-r--r--clang/test/Parser/objc-alias-printing.m18
-rw-r--r--clang/test/Parser/objc-category-neg-1.m8
-rw-r--r--clang/test/Parser/objc-forcollection-1.m43
-rw-r--r--clang/test/Parser/objc-forcollection-neg-2.m38
-rw-r--r--clang/test/Parser/objc-forcollection-neg.m37
-rw-r--r--clang/test/Parser/objc-foreach-error-1.m24
-rw-r--r--clang/test/Parser/objc-init.m26
-rw-r--r--clang/test/Parser/objc-messaging-1.m19
-rw-r--r--clang/test/Parser/objc-messaging-neg-1.m7
-rw-r--r--clang/test/Parser/objc-missing-impl.m2
-rw-r--r--clang/test/Parser/objc-quirks.m4
-rw-r--r--clang/test/Parser/objc-try-catch-1.m65
-rw-r--r--clang/test/Parser/objc-type-printing.m19
-rw-r--r--clang/test/Parser/ocu_vector_components.c28
-rw-r--r--clang/test/Parser/parmvardecl_conversion.c4
-rw-r--r--clang/test/Parser/pointer-arithmetic.c9
-rw-r--r--clang/test/Parser/pointer_promotion.c18
-rw-r--r--clang/test/Parser/pragma-pack.c32
-rw-r--r--clang/test/Parser/prefix-attributes.m8
-rw-r--r--clang/test/Parser/promote_types_in_proto.c9
-rw-r--r--clang/test/Parser/recovery-1.c16
-rw-r--r--clang/test/Parser/recovery-2.c8
-rw-r--r--clang/test/Parser/recovery-3.c9
-rw-r--r--clang/test/Parser/selector-1.m14
-rw-r--r--clang/test/Parser/statements.c49
-rw-r--r--clang/test/Parser/struct-recursion.c11
-rw-r--r--clang/test/Parser/traditional_arg_scope.c7
-rw-r--r--clang/test/Parser/typeof.c19
-rw-r--r--clang/test/Parser/types.c6
-rw-r--r--clang/test/Preprocessor/_Pragma-dependency.c7
-rw-r--r--clang/test/Preprocessor/_Pragma-location.c4
-rw-r--r--clang/test/Preprocessor/_Pragma-physloc.c6
-rw-r--r--clang/test/Preprocessor/_Pragma-poison.c8
-rw-r--r--clang/test/Preprocessor/_Pragma-syshdr.c4
-rw-r--r--clang/test/Preprocessor/_Pragma-syshdr2.c5
-rw-r--r--clang/test/Preprocessor/builtin_line.c4
-rw-r--r--clang/test/Preprocessor/c99-6_10_3_3_p4.c6
-rw-r--r--clang/test/Preprocessor/c99-6_10_3_4_p5.c29
-rw-r--r--clang/test/Preprocessor/c99-6_10_3_4_p6.c24
-rw-r--r--clang/test/Preprocessor/c99-6_10_3_4_p7.c9
-rw-r--r--clang/test/Preprocessor/c99-6_10_3_4_p9.c16
-rw-r--r--clang/test/Preprocessor/comment_save.c7
-rw-r--r--clang/test/Preprocessor/comment_save_if.c6
-rw-r--r--clang/test/Preprocessor/comment_save_macro.c8
-rw-r--r--clang/test/Preprocessor/cxx_and.cpp17
-rw-r--r--clang/test/Preprocessor/cxx_bitand.cpp16
-rw-r--r--clang/test/Preprocessor/cxx_bitor.cpp18
-rw-r--r--clang/test/Preprocessor/cxx_compl.cpp16
-rw-r--r--clang/test/Preprocessor/cxx_not.cpp15
-rw-r--r--clang/test/Preprocessor/cxx_not_eq.cpp16
-rw-r--r--clang/test/Preprocessor/cxx_oper_keyword.cpp7
-rw-r--r--clang/test/Preprocessor/cxx_oper_spelling.cpp11
-rw-r--r--clang/test/Preprocessor/cxx_or.cpp17
-rw-r--r--clang/test/Preprocessor/cxx_true.cpp13
-rw-r--r--clang/test/Preprocessor/cxx_xor.cpp18
-rw-r--r--clang/test/Preprocessor/disabled-cond-diags.c10
-rw-r--r--clang/test/Preprocessor/dumptokens_phyloc.c5
-rw-r--r--clang/test/Preprocessor/expr_comma.c10
-rw-r--r--clang/test/Preprocessor/expr_invalid_tok.c15
-rw-r--r--clang/test/Preprocessor/expr_liveness.c46
-rw-r--r--clang/test/Preprocessor/expr_usual_conversions.c13
-rw-r--r--clang/test/Preprocessor/extension-warning.c10
-rw-r--r--clang/test/Preprocessor/file_to_include.h3
-rw-r--r--clang/test/Preprocessor/function_macro_file.c5
-rw-r--r--clang/test/Preprocessor/function_macro_file.h3
-rw-r--r--clang/test/Preprocessor/hash_line.c8
-rw-r--r--clang/test/Preprocessor/hash_space.c6
-rw-r--r--clang/test/Preprocessor/header_lookup1.c2
-rw-r--r--clang/test/Preprocessor/if_warning.c12
-rw-r--r--clang/test/Preprocessor/ifdef-recover.c15
-rw-r--r--clang/test/Preprocessor/import_self.c7
-rw-r--r--clang/test/Preprocessor/includeexpand.c12
-rw-r--r--clang/test/Preprocessor/includeexpand2.c4
-rw-r--r--clang/test/Preprocessor/indent_macro.c6
-rw-r--r--clang/test/Preprocessor/macro_arg_keyword.c6
-rw-r--r--clang/test/Preprocessor/macro_defined.c6
-rw-r--r--clang/test/Preprocessor/macro_disable.c13
-rw-r--r--clang/test/Preprocessor/macro_disable2.c8
-rw-r--r--clang/test/Preprocessor/macro_disable3.c8
-rw-r--r--clang/test/Preprocessor/macro_disable4.c6
-rw-r--r--clang/test/Preprocessor/macro_expand.c7
-rw-r--r--clang/test/Preprocessor/macro_expandloc.c6
-rw-r--r--clang/test/Preprocessor/macro_expandloc2.c6
-rw-r--r--clang/test/Preprocessor/macro_fn_comma_swallow.c16
-rw-r--r--clang/test/Preprocessor/macro_fn_disable_expand.c11
-rw-r--r--clang/test/Preprocessor/macro_fn_lparen_scan.c27
-rw-r--r--clang/test/Preprocessor/macro_fn_lparen_scan2.c7
-rw-r--r--clang/test/Preprocessor/macro_fn_placemarker.c5
-rw-r--r--clang/test/Preprocessor/macro_fn_preexpand.c12
-rw-r--r--clang/test/Preprocessor/macro_fn_varargs_iso.c11
-rw-r--r--clang/test/Preprocessor/macro_fn_varargs_named.c10
-rw-r--r--clang/test/Preprocessor/macro_not_define.c9
-rw-r--r--clang/test/Preprocessor/macro_paste_bad.c5
-rw-r--r--clang/test/Preprocessor/macro_paste_bcpl_comment.c5
-rw-r--r--clang/test/Preprocessor/macro_paste_c_block_comment.c7
-rw-r--r--clang/test/Preprocessor/macro_paste_commaext.c13
-rw-r--r--clang/test/Preprocessor/macro_paste_empty.c13
-rw-r--r--clang/test/Preprocessor/macro_paste_hard.c17
-rw-r--r--clang/test/Preprocessor/macro_paste_hashhash.c7
-rw-r--r--clang/test/Preprocessor/macro_paste_mscomment.c20
-rw-r--r--clang/test/Preprocessor/macro_paste_none.c6
-rw-r--r--clang/test/Preprocessor/macro_paste_simple.c5
-rw-r--r--clang/test/Preprocessor/macro_paste_spacing.c7
-rw-r--r--clang/test/Preprocessor/macro_rescan.c9
-rw-r--r--clang/test/Preprocessor/macro_rescan2.c15
-rw-r--r--clang/test/Preprocessor/macro_rescan_varargs.c10
-rw-r--r--clang/test/Preprocessor/macro_rparen_scan.c8
-rw-r--r--clang/test/Preprocessor/macro_rparen_scan2.c8
-rw-r--r--clang/test/Preprocessor/macro_space.c5
-rw-r--r--clang/test/Preprocessor/mi_opt.c11
-rw-r--r--clang/test/Preprocessor/mi_opt.h4
-rw-r--r--clang/test/Preprocessor/output_paste_avoid.c18
-rw-r--r--clang/test/Preprocessor/paste_bad.c17
-rw-r--r--clang/test/Preprocessor/poison.c4
-rw-r--r--clang/test/Preprocessor/poison_expansion.c9
-rw-r--r--clang/test/Preprocessor/pr2086.c11
-rw-r--r--clang/test/Preprocessor/pr2086.h6
-rw-r--r--clang/test/Preprocessor/pragma_unknown.c6
-rw-r--r--clang/test/Preprocessor/print_line_track.c15
-rw-r--r--clang/test/Preprocessor/stringize_misc.c26
-rw-r--r--clang/test/Preprocessor/stringize_space.c4
-rw-r--r--clang/test/Preprocessor/stringize_space2.c6
-rw-r--r--clang/test/Preprocessor/undef-error.c5
-rw-r--r--clang/test/Rewriter/block-test.c27
-rw-r--r--clang/test/Rewriter/crash.m14
-rw-r--r--clang/test/Rewriter/id-test-3.m14
-rw-r--r--clang/test/Rewriter/ivar-encoding-1.m15
-rw-r--r--clang/test/Rewriter/ivar-encoding-2.m12
-rw-r--r--clang/test/Rewriter/metadata-test-1.m12
-rw-r--r--clang/test/Rewriter/metadata-test-2.m15
-rw-r--r--clang/test/Rewriter/method-encoding-1.m18
-rw-r--r--clang/test/Rewriter/objc-encoding-bug-1.m19
-rw-r--r--clang/test/Rewriter/objc-ivar-receiver-1.m24
-rw-r--r--clang/test/Rewriter/objc-string-concat-1.m14
-rw-r--r--clang/test/Rewriter/objc-super-test.m15
-rw-r--r--clang/test/Rewriter/objc-synchronized-1.m20
-rw-r--r--clang/test/Rewriter/protocol-rewrite-1.m48
-rw-r--r--clang/test/Rewriter/rewrite-api-bug.m11
-rw-r--r--clang/test/Rewriter/rewrite-foreach-1.m37
-rw-r--r--clang/test/Rewriter/rewrite-foreach-2.m34
-rw-r--r--clang/test/Rewriter/rewrite-foreach-3.m29
-rw-r--r--clang/test/Rewriter/rewrite-foreach-4.m32
-rw-r--r--clang/test/Rewriter/rewrite-foreach-5.m47
-rw-r--r--clang/test/Rewriter/rewrite-foreach-6.m13
-rw-r--r--clang/test/Rewriter/rewrite-nest.m27
-rw-r--r--clang/test/Rewriter/rewrite-protocol-type-1.m24
-rw-r--r--clang/test/Rewriter/rewrite-try-catch.m27
-rw-r--r--clang/test/Rewriter/static-type-protocol-1.m27
-rw-r--r--clang/test/Rewriter/undecl-objc-h.m29
-rw-r--r--clang/test/Rewriter/undeclared-method-1.m9
-rw-r--r--clang/test/Rewriter/undef-field-reference-1.m15
-rw-r--r--clang/test/Rewriter/va-method.m17
-rw-r--r--clang/test/Sema/PR2727.c8
-rw-r--r--clang/test/Sema/PR2728.c9
-rw-r--r--clang/test/Sema/address-constant.c10
-rw-r--r--clang/test/Sema/address_spaces.c19
-rw-r--r--clang/test/Sema/annotate.c7
-rw-r--r--clang/test/Sema/arg-duplicate.c14
-rw-r--r--clang/test/Sema/arg-scope-c99.c2
-rw-r--r--clang/test/Sema/arg-scope.c5
-rw-r--r--clang/test/Sema/array-constraint.c52
-rw-r--r--clang/test/Sema/array-declared-as-incorrect-type.c16
-rw-r--r--clang/test/Sema/array-init.c240
-rw-r--r--clang/test/Sema/asm.c35
-rw-r--r--clang/test/Sema/assign-null.c10
-rw-r--r--clang/test/Sema/assign.c15
-rw-r--r--clang/test/Sema/ast-print.c8
-rw-r--r--clang/test/Sema/attr-deprecated.c25
-rw-r--r--clang/test/Sema/attr-mode.c17
-rw-r--r--clang/test/Sema/bitfield-layout.c32
-rw-r--r--clang/test/Sema/block-args.c29
-rw-r--r--clang/test/Sema/block-as-object.m20
-rw-r--r--clang/test/Sema/block-byref-args.c18
-rw-r--r--clang/test/Sema/block-call.c55
-rw-r--r--clang/test/Sema/block-literal.c118
-rw-r--r--clang/test/Sema/block-misc.c64
-rw-r--r--clang/test/Sema/block-return.c85
-rw-r--r--clang/test/Sema/block-storageclass.c18
-rw-r--r--clang/test/Sema/builtin-object-size.c28
-rw-r--r--clang/test/Sema/builtin-prefetch.c13
-rw-r--r--clang/test/Sema/builtin-stackaddress.c16
-rw-r--r--clang/test/Sema/builtins.c42
-rw-r--r--clang/test/Sema/c89-2.c7
-rw-r--r--clang/test/Sema/c89.c61
-rw-r--r--clang/test/Sema/callingconv.c10
-rw-r--r--clang/test/Sema/carbon.c5
-rw-r--r--clang/test/Sema/cast.c8
-rw-r--r--clang/test/Sema/check-increment.c10
-rw-r--r--clang/test/Sema/compare.c17
-rw-r--r--clang/test/Sema/complex-int.c52
-rw-r--r--clang/test/Sema/compound-literal.c33
-rw-r--r--clang/test/Sema/conditional-expr.c42
-rw-r--r--clang/test/Sema/conditional.c15
-rw-r--r--clang/test/Sema/const-ptr-int-ptr-cast.c3
-rw-r--r--clang/test/Sema/constant-builtins.c23
-rw-r--r--clang/test/Sema/constructor-attribute.c15
-rw-r--r--clang/test/Sema/darwin-align-cast.c23
-rw-r--r--clang/test/Sema/decl-invalid.c11
-rw-r--r--clang/test/Sema/declspec.c23
-rw-r--r--clang/test/Sema/default.c8
-rw-r--r--clang/test/Sema/default1.c2
-rw-r--r--clang/test/Sema/deref.c43
-rw-r--r--clang/test/Sema/enum.c57
-rw-r--r--clang/test/Sema/expr-address-of.c91
-rw-r--r--clang/test/Sema/expr-comma-c89.c18
-rw-r--r--clang/test/Sema/expr-comma.c18
-rw-r--r--clang/test/Sema/exprs.c26
-rw-r--r--clang/test/Sema/floating-point-compare.c25
-rw-r--r--clang/test/Sema/for.c7
-rw-r--r--clang/test/Sema/format-attribute.c26
-rw-r--r--clang/test/Sema/format-strings.c81
-rw-r--r--clang/test/Sema/function-ptr.c11
-rw-r--r--clang/test/Sema/function.c31
-rw-r--r--clang/test/Sema/i-c-e1.c5
-rw-r--r--clang/test/Sema/i-c-e2.c16
-rw-r--r--clang/test/Sema/if-empty-body.c16
-rw-r--r--clang/test/Sema/illegal-types.c7
-rw-r--r--clang/test/Sema/implicit-cast.c8
-rw-r--r--clang/test/Sema/implicit-decl.c17
-rw-r--r--clang/test/Sema/implicit-def.c8
-rw-r--r--clang/test/Sema/implicit-int.c4
-rw-r--r--clang/test/Sema/incomplete-decl.c23
-rw-r--r--clang/test/Sema/init-struct-qualified.c12
-rw-r--r--clang/test/Sema/init.c69
-rw-r--r--clang/test/Sema/int-arith-convert.c12
-rw-r--r--clang/test/Sema/invalid-decl.c20
-rw-r--r--clang/test/Sema/invalid-struct-init.c26
-rw-r--r--clang/test/Sema/member-reference.c9
-rw-r--r--clang/test/Sema/merge-decls.c19
-rw-r--r--clang/test/Sema/ms-fuzzy-asm.c9
-rw-r--r--clang/test/Sema/nonnull.c8
-rw-r--r--clang/test/Sema/offsetof.c36
-rw-r--r--clang/test/Sema/pointer-addition.c14
-rw-r--r--clang/test/Sema/pointer-subtract-compat.c6
-rw-r--r--clang/test/Sema/predef.c12
-rw-r--r--clang/test/Sema/predefined-function.c40
-rw-r--r--clang/test/Sema/rdar6248119.m27
-rw-r--r--clang/test/Sema/recover-goto.c4
-rw-r--r--clang/test/Sema/redefinition.c5
-rw-r--r--clang/test/Sema/self-comparison.c25
-rw-r--r--clang/test/Sema/sentinel-attribute.c13
-rw-r--r--clang/test/Sema/shift.c6
-rw-r--r--clang/test/Sema/static-init.c7
-rw-r--r--clang/test/Sema/stmt_exprs.c22
-rw-r--r--clang/test/Sema/struct-compat.c17
-rw-r--r--clang/test/Sema/struct-packed-align.c103
-rw-r--r--clang/test/Sema/switch-duplicate-defaults.c10
-rw-r--r--clang/test/Sema/switch.c30
-rw-r--r--clang/test/Sema/tentative-decls.c43
-rw-r--r--clang/test/Sema/text-diag.c4
-rw-r--r--clang/test/Sema/transparent-union-pointer.c14
-rw-r--r--clang/test/Sema/typecheck-binop.c23
-rw-r--r--clang/test/Sema/typedef-prototype.c8
-rw-r--r--clang/test/Sema/typedef-redef.c13
-rw-r--r--clang/test/Sema/typedef-retain.c38
-rw-r--r--clang/test/Sema/typedef-variable-type.c3
-rw-r--r--clang/test/Sema/unnamed-bitfield-init.c6
-rw-r--r--clang/test/Sema/unused-expr.c42
-rw-r--r--clang/test/Sema/usual-float.c12
-rw-r--r--clang/test/Sema/va_arg_x86_64.c16
-rw-r--r--clang/test/Sema/varargs.c27
-rw-r--r--clang/test/Sema/vector-assign.c45
-rw-r--r--clang/test/Sema/vector-cast.c30
-rw-r--r--clang/test/Sema/vector-init.c5
-rw-r--r--clang/test/Sema/vla.c15
-rw-r--r--clang/test/Sema/void_arg.c26
-rw-r--r--clang/test/Sema/wchar_size.c3
-rw-r--r--clang/test/SemaCXX/bool.cpp7
-rw-r--r--clang/test/SemaCXX/carbon.cpp5
-rw-r--r--clang/test/SemaCXX/class-names.cpp52
-rw-r--r--clang/test/SemaCXX/class.cpp70
-rw-r--r--clang/test/SemaCXX/condition.cpp35
-rw-r--r--clang/test/SemaCXX/decl-expr-ambiguity.cpp42
-rw-r--r--clang/test/SemaCXX/default1.cpp17
-rw-r--r--clang/test/SemaCXX/default2.cpp38
-rw-r--r--clang/test/SemaCXX/direct-initializer.cpp8
-rw-r--r--clang/test/SemaCXX/do-while-scope.cpp8
-rw-r--r--clang/test/SemaCXX/inherit.cpp25
-rw-r--r--clang/test/SemaCXX/namespace.cpp57
-rw-r--r--clang/test/SemaCXX/references.cpp28
-rw-r--r--clang/test/SemaCXX/return-stack-addr.cpp113
-rw-r--r--clang/test/SemaCXX/static-initializers.cpp12
-rw-r--r--clang/test/SemaCXX/this.cpp6
-rw-r--r--clang/test/SemaCXX/type-convert-construct.cpp17
-rw-r--r--clang/test/SemaCXX/wchar_t.cpp9
-rw-r--r--clang/test/SemaObjC/DoubleMethod.m19
-rw-r--r--clang/test/SemaObjC/alias-test-1.m31
-rw-r--r--clang/test/SemaObjC/alias-test-2.m16
-rw-r--r--clang/test/SemaObjC/argument-checking.m25
-rw-r--r--clang/test/SemaObjC/at-defs.m29
-rw-r--r--clang/test/SemaObjC/bad-receiver-1.m9
-rw-r--r--clang/test/SemaObjC/category-1.m56
-rw-r--r--clang/test/SemaObjC/category-method-lookup.m31
-rw-r--r--clang/test/SemaObjC/check-dup-decl-methods-1.m38
-rw-r--r--clang/test/SemaObjC/check-dup-objc-decls-1.m28
-rw-r--r--clang/test/SemaObjC/class-conforming-protocol-1.m21
-rw-r--r--clang/test/SemaObjC/class-def-test-1.m26
-rw-r--r--clang/test/SemaObjC/class-impl-1.m33
-rw-r--r--clang/test/SemaObjC/class-proto-1.m36
-rw-r--r--clang/test/SemaObjC/cocoa.m5
-rw-r--r--clang/test/SemaObjC/compatible-protocol-qualified-types.m40
-rw-r--r--clang/test/SemaObjC/comptypes-1.m89
-rw-r--r--clang/test/SemaObjC/comptypes-2.m37
-rw-r--r--clang/test/SemaObjC/comptypes-3.m64
-rw-r--r--clang/test/SemaObjC/comptypes-4.m25
-rw-r--r--clang/test/SemaObjC/comptypes-5.m44
-rw-r--r--clang/test/SemaObjC/comptypes-6.m16
-rw-r--r--clang/test/SemaObjC/comptypes-7.m70
-rw-r--r--clang/test/SemaObjC/comptypes-8.m12
-rw-r--r--clang/test/SemaObjC/comptypes-9.m86
-rw-r--r--clang/test/SemaObjC/comptypes-a.m40
-rw-r--r--clang/test/SemaObjC/conditional-expr-2.m12
-rw-r--r--clang/test/SemaObjC/conditional-expr-3.m63
-rw-r--r--clang/test/SemaObjC/conditional-expr-4.m78
-rw-r--r--clang/test/SemaObjC/conditional-expr.m44
-rw-r--r--clang/test/SemaObjC/conflicting-ivar-test-1.m86
-rw-r--r--clang/test/SemaObjC/const-id.m8
-rw-r--r--clang/test/SemaObjC/enhanced-proto-2.m21
-rw-r--r--clang/test/SemaObjC/foreach-1.m10
-rw-r--r--clang/test/SemaObjC/format-strings-objc.m43
-rw-r--r--clang/test/SemaObjC/forward-class-1.m24
-rw-r--r--clang/test/SemaObjC/gcc-cast-ext.m24
-rw-r--r--clang/test/SemaObjC/id_builtin.m10
-rw-r--r--clang/test/SemaObjC/incompatible-protocol-qualified-types.m40
-rw-r--r--clang/test/SemaObjC/interface-1.m27
-rw-r--r--clang/test/SemaObjC/interface-layout.m27
-rw-r--r--clang/test/SemaObjC/invalid-code.m7
-rw-r--r--clang/test/SemaObjC/invalid-objc-decls-1.m29
-rw-r--r--clang/test/SemaObjC/ivar-lookup.m18
-rw-r--r--clang/test/SemaObjC/ivar-sem-check-1.m19
-rw-r--r--clang/test/SemaObjC/legacy-implementation-1.m11
-rw-r--r--clang/test/SemaObjC/message.m70
-rw-r--r--clang/test/SemaObjC/method-attributes.m8
-rw-r--r--clang/test/SemaObjC/method-def-1.m21
-rw-r--r--clang/test/SemaObjC/method-def-2.m19
-rw-r--r--clang/test/SemaObjC/method-encoding-2.m12
-rw-r--r--clang/test/SemaObjC/method-lookup-2.m40
-rw-r--r--clang/test/SemaObjC/method-lookup-3.m52
-rw-r--r--clang/test/SemaObjC/method-lookup.m34
-rw-r--r--clang/test/SemaObjC/method-not-defined.m13
-rw-r--r--clang/test/SemaObjC/method-undef-category-warn-1.m32
-rw-r--r--clang/test/SemaObjC/method-undefined-warn-1.m42
-rw-r--r--clang/test/SemaObjC/missing-method-context.m4
-rw-r--r--clang/test/SemaObjC/objc-gc-attr.m8
-rw-r--r--clang/test/SemaObjC/property-1.m47
-rw-r--r--clang/test/SemaObjC/property-10.m18
-rw-r--r--clang/test/SemaObjC/property-2.m63
-rw-r--r--clang/test/SemaObjC/property-3.m14
-rw-r--r--clang/test/SemaObjC/property-4.m30
-rw-r--r--clang/test/SemaObjC/property-5.m34
-rw-r--r--clang/test/SemaObjC/property-6.m69
-rw-r--r--clang/test/SemaObjC/property-7.m34
-rw-r--r--clang/test/SemaObjC/property-8.m74
-rw-r--r--clang/test/SemaObjC/property-9-impl-method.m63
-rw-r--r--clang/test/SemaObjC/props-on-prots.m65
-rw-r--r--clang/test/SemaObjC/protocol-archane.m24
-rw-r--r--clang/test/SemaObjC/protocol-expr-1.m15
-rw-r--r--clang/test/SemaObjC/protocol-expr-neg-1.m19
-rw-r--r--clang/test/SemaObjC/protocol-id-test-1.m16
-rw-r--r--clang/test/SemaObjC/protocol-id-test-2.m14
-rw-r--r--clang/test/SemaObjC/protocol-id-test-3.m94
-rw-r--r--clang/test/SemaObjC/protocol-implementation-inherited.m56
-rw-r--r--clang/test/SemaObjC/protocol-test-1.m20
-rw-r--r--clang/test/SemaObjC/protocol-test-2.m31
-rw-r--r--clang/test/SemaObjC/rdr-6211479-array-property.m9
-rw-r--r--clang/test/SemaObjC/selector-1.m14
-rw-r--r--clang/test/SemaObjC/selector-overload.m47
-rw-r--r--clang/test/SemaObjC/static-ivar-ref-1.m16
-rw-r--r--clang/test/SemaObjC/string.m15
-rw-r--r--clang/test/SemaObjC/synchronized.m75
-rw-r--r--clang/test/SemaObjC/try-catch.m37
-rw-r--r--clang/test/SemaObjC/typedef-class.m78
-rw-r--r--clang/test/SemaObjC/undef-protocol-methods-1.m42
-rw-r--r--clang/test/SemaObjC/undef-superclass-1.m26
-rw-r--r--clang/test/SemaObjC/undefined-protocol-type-1.m9
-rw-r--r--clang/test/SemaObjC/unused.m18
-rw-r--r--clang/test/SemaObjC/va-method-1.m17
-rw-r--r--clang/test/SemaObjCXX/cocoa.mm5
-rw-r--r--clang/test/SemaObjCXX/reserved-keyword-selectors.mm35
-rw-r--r--clang/test/Serialization/complex.c48
-rw-r--r--clang/test/Serialization/stmt_exprs.c12
-rwxr-xr-xclang/test/TestRunner.sh104
-rw-r--r--clang/tools/scan-view/Reporter.py244
-rw-r--r--clang/tools/scan-view/Resources/FileRadar.scptbin17054 -> 0 bytes
-rw-r--r--clang/tools/scan-view/Resources/GetRadarVersion.scpt0
-rw-r--r--clang/tools/scan-view/Resources/bugcatcher.icobin318 -> 0 bytes
-rw-r--r--clang/tools/scan-view/ScanView.py770
-rwxr-xr-xclang/tools/scan-view/scan-view131
-rw-r--r--clang/tools/scan-view/startfile.py203
-rwxr-xr-xclang/utils/CheckBuiltinMacros.sh23
-rwxr-xr-xclang/utils/FindSpecRefs885
-rwxr-xr-xclang/utils/ccc378
-rwxr-xr-xclang/utils/ccc-analyzer440
-rwxr-xr-xclang/utils/scan-build1101
-rw-r--r--clang/utils/scanview.css62
-rw-r--r--clang/utils/sorttable.js493
-rwxr-xr-xclang/utils/ubiviz74
-rw-r--r--clang/win32/clangAST/clangAST.vcproj327
-rw-r--r--clang/win32/clangAnalysis/clangAnalysis.vcproj347
-rw-r--r--clang/win32/clangBasic/clangBasic.vcproj236
-rw-r--r--clang/win32/clangCodeGen/clangCodeGen.vcproj271
-rw-r--r--clang/win32/clangDriver/clangDriver.vcproj256
-rw-r--r--clang/win32/clangLex/clangLex.vcproj275
-rw-r--r--clang/win32/clangLibDriver/clangLibDriver.vcproj193
-rw-r--r--clang/win32/clangParse/clangParse.vcproj243
-rw-r--r--clang/win32/clangRewrite/clangRewrite.vcproj187
-rw-r--r--clang/win32/clangSema/clangSema.vcproj239
-rw-r--r--clang/www/CheckerNotes.html9
-rw-r--r--clang/www/StaticAnalysis.html156
-rw-r--r--clang/www/StaticAnalysisUsage.html274
-rw-r--r--clang/www/carbon-compile.pngbin23702 -> 0 bytes
-rw-r--r--clang/www/clang_video-05-25-2007.html27
-rw-r--r--clang/www/clang_video-07-25-2007.html30
-rw-r--r--clang/www/comparison.html196
-rw-r--r--clang/www/content.css23
-rw-r--r--clang/www/cxx_status.html84
-rw-r--r--clang/www/demo/DemoInfo.html83
-rw-r--r--clang/www/demo/cathead.pngbin21602 -> 0 bytes
-rw-r--r--clang/www/demo/index.cgi461
-rw-r--r--clang/www/demo/syntax.css4
-rw-r--r--clang/www/demo/what is this directory.txt15
-rw-r--r--clang/www/distclang_status.html30
-rw-r--r--clang/www/feature-compile1.pngbin91247 -> 0 bytes
-rw-r--r--clang/www/feature-compile2.pngbin140963 -> 0 bytes
-rw-r--r--clang/www/feature-diagnostics1.pngbin156796 -> 0 bytes
-rw-r--r--clang/www/feature-memory1.pngbin92680 -> 0 bytes
-rw-r--r--clang/www/features.html420
-rw-r--r--clang/www/get_involved.html164
-rw-r--r--clang/www/get_started.html231
-rw-r--r--clang/www/index.html120
-rw-r--r--clang/www/latest_checker.html.incl1
-rw-r--r--clang/www/menu.css39
-rw-r--r--clang/www/menu.html.incl38
958 files changed, 0 insertions, 145802 deletions
diff --git a/clang/Driver/ASTConsumers.cpp b/clang/Driver/ASTConsumers.cpp
deleted file mode 100644
index 24335cfae039..000000000000
--- a/clang/Driver/ASTConsumers.cpp
+++ /dev/null
@@ -1,734 +0,0 @@
-//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// AST Consumer Implementations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTConsumers.h"
-#include "clang/Driver/HTMLDiagnostics.h"
-#include "clang/AST/TranslationUnit.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "llvm/Module.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/OwningPtr.h"
-#include <fstream>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-/// DeclPrinter - Utility class for printing top-level decls.
-
-namespace {
- class DeclPrinter {
- public:
- llvm::raw_ostream& Out;
-
- DeclPrinter(llvm::raw_ostream* out) : Out(out ? *out : llvm::errs()) {}
- DeclPrinter() : Out(llvm::errs()) {}
- virtual ~DeclPrinter();
-
- void PrintDecl(Decl *D);
- void PrintFunctionDeclStart(FunctionDecl *FD);
- void PrintTypeDefDecl(TypedefDecl *TD);
- void PrintLinkageSpec(LinkageSpecDecl *LS);
- void PrintObjCMethodDecl(ObjCMethodDecl *OMD);
- void PrintObjCImplementationDecl(ObjCImplementationDecl *OID);
- void PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID);
- void PrintObjCProtocolDecl(ObjCProtocolDecl *PID);
- void PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID);
- void PrintObjCCategoryDecl(ObjCCategoryDecl *PID);
- void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID);
- void PrintObjCPropertyDecl(ObjCPropertyDecl *PD);
- void PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID);
- };
-} // end anonymous namespace
-
-DeclPrinter::~DeclPrinter() {
- Out.flush();
-}
-
-void DeclPrinter:: PrintDecl(Decl *D) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- PrintFunctionDeclStart(FD);
-
- if (FD->getBody()) {
- Out << ' ';
- FD->getBody()->printPretty(Out);
- Out << '\n';
- }
- } else if (isa<ObjCMethodDecl>(D)) {
- // Do nothing, methods definitions are printed in
- // PrintObjCImplementationDecl.
- } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
- PrintTypeDefDecl(TD);
- } else if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
- PrintObjCInterfaceDecl(OID);
- } else if (ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(D)) {
- PrintObjCProtocolDecl(PID);
- } else if (ObjCForwardProtocolDecl *OFPD =
- dyn_cast<ObjCForwardProtocolDecl>(D)) {
- Out << "@protocol ";
- for (unsigned i = 0, e = OFPD->getNumForwardDecls(); i != e; ++i) {
- const ObjCProtocolDecl *D = OFPD->getForwardProtocolDecl(i);
- if (i) Out << ", ";
- Out << D->getName();
- }
- Out << ";\n";
- } else if (ObjCImplementationDecl *OID =
- dyn_cast<ObjCImplementationDecl>(D)) {
- PrintObjCImplementationDecl(OID);
- } else if (ObjCCategoryImplDecl *OID =
- dyn_cast<ObjCCategoryImplDecl>(D)) {
- PrintObjCCategoryImplDecl(OID);
- } else if (ObjCCategoryDecl *OID =
- dyn_cast<ObjCCategoryDecl>(D)) {
- PrintObjCCategoryDecl(OID);
- } else if (ObjCCompatibleAliasDecl *OID =
- dyn_cast<ObjCCompatibleAliasDecl>(D)) {
- PrintObjCCompatibleAliasDecl(OID);
- } else if (ObjCClassDecl *OFCD = dyn_cast<ObjCClassDecl>(D)) {
- Out << "@class ";
- ObjCInterfaceDecl **ForwardDecls = OFCD->getForwardDecls();
- for (unsigned i = 0, e = OFCD->getNumForwardDecls(); i != e; ++i) {
- const ObjCInterfaceDecl *D = ForwardDecls[i];
- if (i) Out << ", ";
- Out << D->getName();
- }
- Out << ";\n";
- } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- Out << "Read top-level tag decl: '" << TD->getName() << "'\n";
- } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
- Out << "Read top-level variable decl: '" << SD->getName() << "'\n";
- } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
- PrintLinkageSpec(LSD);
- } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) {
- Out << "asm(";
- AD->getAsmString()->printPretty(Out);
- Out << ")\n";
- } else {
- assert(0 && "Unknown decl type!");
- }
-}
-
-void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
- bool HasBody = FD->getBody();
-
- Out << '\n';
-
- switch (FD->getStorageClass()) {
- default: assert(0 && "Unknown storage class");
- case FunctionDecl::None: break;
- case FunctionDecl::Extern: Out << "extern "; break;
- case FunctionDecl::Static: Out << "static "; break;
- case FunctionDecl::PrivateExtern: Out << "__private_extern__ "; break;
- }
-
- if (FD->isInline())
- Out << "inline ";
-
- std::string Proto = FD->getName();
- const FunctionType *AFT = FD->getType()->getAsFunctionType();
-
- if (const FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
- Proto += "(";
- for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
- if (i) Proto += ", ";
- std::string ParamStr;
- if (HasBody) ParamStr = FD->getParamDecl(i)->getName();
-
- FT->getArgType(i).getAsStringInternal(ParamStr);
- Proto += ParamStr;
- }
-
- if (FT->isVariadic()) {
- if (FD->getNumParams()) Proto += ", ";
- Proto += "...";
- }
- Proto += ")";
- } else {
- assert(isa<FunctionTypeNoProto>(AFT));
- Proto += "()";
- }
-
- AFT->getResultType().getAsStringInternal(Proto);
- Out << Proto;
-
- if (!FD->getBody())
- Out << ";\n";
- // Doesn't print the body.
-}
-
-void DeclPrinter::PrintTypeDefDecl(TypedefDecl *TD) {
- std::string S = TD->getName();
- TD->getUnderlyingType().getAsStringInternal(S);
- Out << "typedef " << S << ";\n";
-}
-
-void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
- const char *l;
- if (LS->getLanguage() == LinkageSpecDecl::lang_c)
- l = "C";
- else {
- assert(LS->getLanguage() == LinkageSpecDecl::lang_cxx &&
- "unknown language in linkage specification");
- l = "C++";
- }
- Out << "extern \"" << l << "\" { ";
- PrintDecl(LS->getDecl());
- Out << "}\n";
-}
-
-void DeclPrinter::PrintObjCMethodDecl(ObjCMethodDecl *OMD) {
- if (OMD->isInstance())
- Out << "\n- ";
- else
- Out << "\n+ ";
- if (!OMD->getResultType().isNull())
- Out << '(' << OMD->getResultType().getAsString() << ")";
-
- std::string name = OMD->getSelector().getName();
- std::string::size_type pos, lastPos = 0;
- for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i) {
- ParmVarDecl *PDecl = OMD->getParamDecl(i);
- // FIXME: selector is missing here!
- pos = name.find_first_of(":", lastPos);
- Out << " " << name.substr(lastPos, pos - lastPos);
- Out << ":(" << PDecl->getType().getAsString() << ")" << PDecl->getName();
- lastPos = pos + 1;
- }
-
- if (OMD->getNumParams() == 0)
- Out << " " << name;
-
- if (OMD->isVariadic())
- Out << ", ...";
-
- Out << ";";
-}
-
-void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
- std::string I = OID->getName();
- ObjCInterfaceDecl *SID = OID->getSuperClass();
-
- if (SID)
- Out << "@implementation " << I << " : " << SID->getName();
- else
- Out << "@implementation " << I;
-
- for (ObjCImplementationDecl::instmeth_iterator I = OID->instmeth_begin(),
- E = OID->instmeth_end(); I != E; ++I) {
- ObjCMethodDecl *OMD = *I;
- PrintObjCMethodDecl(OMD);
- if (OMD->getBody()) {
- Out << ' ';
- OMD->getBody()->printPretty(Out);
- Out << '\n';
- }
- }
-
- for (ObjCImplementationDecl::classmeth_iterator I = OID->classmeth_begin(),
- E = OID->classmeth_end(); I != E; ++I) {
- ObjCMethodDecl *OMD = *I;
- PrintObjCMethodDecl(OMD);
- if (OMD->getBody()) {
- Out << ' ';
- OMD->getBody()->printPretty(Out);
- Out << '\n';
- }
- }
-
- for (ObjCImplementationDecl::propimpl_iterator I = OID->propimpl_begin(),
- E = OID->propimpl_end(); I != E; ++I)
- PrintObjCPropertyImplDecl(*I);
-
- Out << "@end\n";
-}
-
-
-void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
- std::string I = OID->getName();
- ObjCInterfaceDecl *SID = OID->getSuperClass();
-
- if (SID)
- Out << "@interface " << I << " : " << SID->getName();
- else
- Out << "@interface " << I;
-
- // Protocols?
- const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
- if (!Protocols.empty()) {
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end(); I != E; ++I)
- Out << (I == Protocols.begin() ? '<' : ',') << (*I)->getName();
- }
-
- if (!Protocols.empty())
- Out << ">";
- Out << '\n';
-
- if (OID->ivar_size() > 0) {
- Out << '{';
- for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
- E = OID->ivar_end(); I != E; ++I) {
- Out << '\t' << (*I)->getType().getAsString()
- << ' ' << (*I)->getName() << ";\n";
- }
- Out << "}\n";
- }
-
- for (ObjCInterfaceDecl::classprop_iterator I = OID->classprop_begin(),
- E = OID->classprop_end(); I != E; ++I)
- PrintObjCPropertyDecl(*I);
- bool eol_needed = false;
- for (ObjCInterfaceDecl::classmeth_iterator I = OID->classmeth_begin(),
- E = OID->classmeth_end(); I != E; ++I)
- eol_needed = true, PrintObjCMethodDecl(*I);
-
- for (ObjCInterfaceDecl::instmeth_iterator I = OID->instmeth_begin(),
- E = OID->instmeth_end(); I != E; ++I)
- eol_needed = true, PrintObjCMethodDecl(*I);
-
- Out << (eol_needed ? "\n@end\n" : "@end\n");
- // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCProtocolDecl(ObjCProtocolDecl *PID) {
- Out << "@protocol " << PID->getName() << '\n';
-
- for (ObjCProtocolDecl::classprop_iterator I = PID->classprop_begin(),
- E = PID->classprop_end(); I != E; ++I)
- PrintObjCPropertyDecl(*I);
- Out << "@end\n";
- // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
- Out << "@implementation "
- << PID->getClassInterface()->getName()
- << '(' << PID->getName() << ");\n";
- for (ObjCCategoryImplDecl::propimpl_iterator I = PID->propimpl_begin(),
- E = PID->propimpl_end(); I != E; ++I)
- PrintObjCPropertyImplDecl(*I);
- Out << "@end\n";
- // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCCategoryDecl(ObjCCategoryDecl *PID) {
- Out << "@interface "
- << PID->getClassInterface()->getName()
- << '(' << PID->getName() << ");\n";
- // Output property declarations.
- for (ObjCCategoryDecl::classprop_iterator I = PID->classprop_begin(),
- E = PID->classprop_end(); I != E; ++I)
- PrintObjCPropertyDecl(*I);
- Out << "@end\n";
-
- // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
- Out << "@compatibility_alias " << AID->getName()
- << ' ' << AID->getClassInterface()->getName() << ";\n";
-}
-
-/// PrintObjCPropertyDecl - print a property declaration.
-///
-void DeclPrinter::PrintObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
- if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
- Out << "@required\n";
- else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
- Out << "@optional\n";
-
- Out << "@property";
- if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
- bool first = true;
- Out << " (";
- if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_readonly) {
- Out << (first ? ' ' : ',') << "readonly";
- first = false;
- }
-
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
- Out << (first ? ' ' : ',') << "getter = "
- << PDecl->getGetterName().getName();
- first = false;
- }
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
- Out << (first ? ' ' : ',') << "setter = "
- << PDecl->getSetterName().getName();
- first = false;
- }
-
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
- Out << (first ? ' ' : ',') << "assign";
- first = false;
- }
-
- if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_readwrite) {
- Out << (first ? ' ' : ',') << "readwrite";
- first = false;
- }
-
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
- Out << (first ? ' ' : ',') << "retain";
- first = false;
- }
-
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
- Out << (first ? ' ' : ',') << "copy";
- first = false;
- }
-
- if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_nonatomic) {
- Out << (first ? ' ' : ',') << "nonatomic";
- first = false;
- }
- Out << " )";
- }
- Out << ' ' << PDecl->getType().getAsString()
- << ' ' << PDecl->getName();
-
- Out << ";\n";
-}
-
-/// PrintObjCPropertyImplDecl - Print an objective-c property implementation
-/// declaration syntax.
-///
-void DeclPrinter::PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
- if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
- Out << "\n@synthesize ";
- else
- Out << "\n@dynamic ";
- Out << PID->getPropertyDecl()->getName();
- if (PID->getPropertyIvarDecl())
- Out << "=" << PID->getPropertyIvarDecl()->getName();
- Out << ";\n";
-}
-//===----------------------------------------------------------------------===//
-/// ASTPrinter - Pretty-printer of ASTs
-
-namespace {
- class ASTPrinter : public ASTConsumer, public DeclPrinter {
- public:
- ASTPrinter(llvm::raw_ostream* o = NULL) : DeclPrinter(o) {}
-
- virtual void HandleTopLevelDecl(Decl *D) {
- PrintDecl(D);
- }
- };
-}
-
-ASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) {
- return new ASTPrinter(out);
-}
-
-//===----------------------------------------------------------------------===//
-/// ASTDumper - Low-level dumper of ASTs
-
-namespace {
- class ASTDumper : public ASTConsumer, public DeclPrinter {
- SourceManager *SM;
- public:
- ASTDumper() : DeclPrinter() {}
-
- void Initialize(ASTContext &Context) {
- SM = &Context.getSourceManager();
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- PrintFunctionDeclStart(FD);
-
- if (FD->getBody()) {
- Out << '\n';
- // FIXME: convert dumper to use std::ostream?
- FD->getBody()->dumpAll(*SM);
- Out << '\n';
- }
- } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
- PrintTypeDefDecl(TD);
- } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
- Out << "Read top-level variable decl: '" << SD->getName() << "'\n";
- } else if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
- Out << "Read objc interface '" << OID->getName() << "'\n";
- } else if (ObjCProtocolDecl *OPD = dyn_cast<ObjCProtocolDecl>(D)) {
- Out << "Read objc protocol '" << OPD->getName() << "'\n";
- } else if (ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(D)) {
- Out << "Read objc category '" << OCD->getName() << "'\n";
- } else if (isa<ObjCForwardProtocolDecl>(D)) {
- Out << "Read objc fwd protocol decl\n";
- } else if (isa<ObjCClassDecl>(D)) {
- Out << "Read objc fwd class decl\n";
- } else if (isa<FileScopeAsmDecl>(D)) {
- Out << "Read file scope asm decl\n";
- } else if (ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
- Out << "Read objc method decl: '" << MD->getSelector().getName()
- << "'\n";
- if (MD->getBody()) {
- // FIXME: convert dumper to use std::ostream?
- MD->getBody()->dumpAll(*SM);
- Out << '\n';
- }
- } else if (isa<ObjCImplementationDecl>(D)) {
- Out << "Read objc implementation decl\n";
- } else if (isa<ObjCCategoryImplDecl>(D)) {
- Out << "Read objc category implementation decl\n";
- }
- else {
- assert(0 && "Unknown decl type!");
- }
- }
- };
-}
-
-ASTConsumer *clang::CreateASTDumper() { return new ASTDumper(); }
-
-//===----------------------------------------------------------------------===//
-/// ASTViewer - AST Visualization
-
-namespace {
- class ASTViewer : public ASTConsumer {
- SourceManager *SM;
- public:
- void Initialize(ASTContext &Context) {
- SM = &Context.getSourceManager();
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- DeclPrinter().PrintFunctionDeclStart(FD);
-
- if (FD->getBody()) {
- llvm::cerr << '\n';
- FD->getBody()->viewAST();
- llvm::cerr << '\n';
- }
- }
- else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- DeclPrinter().PrintObjCMethodDecl(MD);
-
- if (MD->getBody()) {
- llvm::cerr << '\n';
- MD->getBody()->viewAST();
- llvm::cerr << '\n';
- }
- }
- }
- };
-}
-
-ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
-
-//===----------------------------------------------------------------------===//
-// AST Serializer
-
-namespace {
-
-class ASTSerializer : public ASTConsumer {
-protected:
- Diagnostic& Diags;
-
-public:
- ASTSerializer(Diagnostic& diags) : Diags(diags) {}
-};
-
-class SingleFileSerializer : public ASTSerializer {
- const llvm::sys::Path FName;
-public:
- SingleFileSerializer(const llvm::sys::Path& F, Diagnostic& diags)
- : ASTSerializer(diags), FName(F) {}
-
- virtual void HandleTranslationUnit(TranslationUnit& TU) {
- if (Diags.hasErrorOccurred())
- return;
- EmitASTBitcodeFile(&TU, FName);
- }
-};
-
-class BuildSerializer : public ASTSerializer {
- llvm::sys::Path EmitDir;
-public:
- BuildSerializer(const llvm::sys::Path& dir, Diagnostic& diags)
- : ASTSerializer(diags), EmitDir(dir) {}
-
- virtual void HandleTranslationUnit(TranslationUnit& TU) {
- if (Diags.hasErrorOccurred())
- return;
-
- SourceManager& SourceMgr = TU.getContext().getSourceManager();
- unsigned ID = SourceMgr.getMainFileID();
- assert (ID && "MainFileID not set!");
- const FileEntry* FE = SourceMgr.getFileEntryForID(ID);
- assert (FE && "No FileEntry for main file.");
-
- // FIXME: This is not portable to Windows.
- // FIXME: This logic should probably be moved elsewhere later.
-
- llvm::sys::Path FName(EmitDir);
-
- std::vector<char> buf;
- buf.reserve(strlen(FE->getName())+100);
-
- sprintf(&buf[0], "dev_%llx", (uint64_t) FE->getDevice());
- FName.appendComponent(&buf[0]);
- FName.createDirectoryOnDisk(true);
- if (!FName.canWrite() || !FName.isDirectory()) {
- assert (false && "Could not create 'device' serialization directory.");
- return;
- }
-
- sprintf(&buf[0], "%s-%llX.ast", FE->getName(), (uint64_t) FE->getInode());
- FName.appendComponent(&buf[0]);
- EmitASTBitcodeFile(&TU, FName);
-
- // Now emit the sources.
-
- }
-};
-
-
-} // end anonymous namespace
-
-
-ASTConsumer* clang::CreateASTSerializer(const std::string& InFile,
- const std::string& OutputFile,
- Diagnostic &Diags) {
-
- if (OutputFile.size()) {
- if (InFile == "-") {
- llvm::cerr <<
- "error: Cannot use --serialize with -o for source read from STDIN.\n";
- return NULL;
- }
-
- // The user specified an AST-emission directory. Determine if the path
- // is absolute.
- llvm::sys::Path EmitDir(OutputFile);
-
- if (!EmitDir.isAbsolute()) {
- llvm::cerr <<
- "error: Output directory for --serialize must be an absolute path.\n";
-
- return NULL;
- }
-
- // Create the directory if it does not exist.
- EmitDir.createDirectoryOnDisk(true);
- if (!EmitDir.canWrite() || !EmitDir.isDirectory()) {
- llvm::cerr <<
- "error: Could not create output directory for --serialize.\n";
-
- return NULL;
- }
-
- // FIXME: We should probably only allow using BuildSerializer when
- // the ASTs come from parsed source files, and not from .ast files.
- return new BuildSerializer(EmitDir, Diags);
- }
-
- // The user did not specify an output directory for serialized ASTs.
- // Serialize the translation to a single file whose name is the same
- // as the input file with the ".ast" extension appended.
-
- llvm::sys::Path FName(InFile.c_str());
- FName.appendSuffix("ast");
- return new SingleFileSerializer(FName, Diags);
-}
-
-class LLVMCodeGenWriter : public ASTConsumer {
- llvm::OwningPtr<CodeGenerator> Gen;
- const std::string &InFile;
- const std::string &OutputFile;
- bool EmitBitcode;
-public:
-
- LLVMCodeGenWriter(bool EmitBC, Diagnostic &Diags, const LangOptions &Features,
- const std::string& infile, const std::string& outfile,
- bool GenerateDebugInfo)
- : Gen(CreateLLVMCodeGen(Diags, Features, infile, GenerateDebugInfo)),
- InFile(infile), OutputFile(outfile), EmitBitcode(EmitBC) {}
-
- virtual void Initialize(ASTContext &Context) {
- Gen->Initialize(Context);
- }
-
- virtual void InitializeTU(TranslationUnit& TU) {
- Gen->InitializeTU(TU);
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- Gen->HandleTopLevelDecl(D);
- }
-
- virtual void HandleTranslationUnit(TranslationUnit& TU) {
- Gen->HandleTranslationUnit(TU);
- }
-
- virtual void HandleTagDeclDefinition(TagDecl *D) {
- Gen->HandleTagDeclDefinition(D);
- }
-
- virtual ~LLVMCodeGenWriter() {
- llvm::OwningPtr<llvm::Module> CodeGenModule(Gen->ReleaseModule());
-
- if (!CodeGenModule)
- return;
-
- std::ostream *Out;
-
- if (OutputFile == "-") {
- Out = llvm::cout.stream();
- } else if (!OutputFile.empty()) {
- Out = new std::ofstream(OutputFile.c_str(),
- std::ios_base::binary|std::ios_base::out);
- } else if (InFile == "-") {
- Out = llvm::cout.stream();
- } else {
- llvm::sys::Path Path(InFile);
- Path.eraseSuffix();
- if (!EmitBitcode)
- Path.appendSuffix("ll");
- else
- Path.appendSuffix("bc");
-
- Out = new std::ofstream(Path.toString().c_str(),
- std::ios_base::binary|std::ios_base::out);
- }
-
- if (!EmitBitcode)
- *Out << *CodeGenModule.get();
- else
- llvm::WriteBitcodeToFile(CodeGenModule.get(), *Out);
-
- if (Out != llvm::cout.stream())
- delete Out;
- }
-};
-
-ASTConsumer *clang::CreateLLVMCodeGenWriter(bool EmitBC, Diagnostic &Diags,
- const LangOptions &Features,
- const std::string& InFile,
- const std::string& OutFile,
- bool GenerateDebugInfo) {
-
- return new LLVMCodeGenWriter(EmitBC, Diags, Features, InFile, OutFile,
- GenerateDebugInfo);
-}
diff --git a/clang/Driver/ASTConsumers.h b/clang/Driver/ASTConsumers.h
deleted file mode 100644
index c1bf2300cebc..000000000000
--- a/clang/Driver/ASTConsumers.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// AST Consumers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DRIVER_ASTCONSUMERS_H
-#define DRIVER_ASTCONSUMERS_H
-
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-#include <iosfwd>
-
-namespace llvm {
- class Module;
- namespace sys { class Path; }
-}
-namespace clang {
-
-class ASTConsumer;
-class Diagnostic;
-class FileManager;
-struct LangOptions;
-class Preprocessor;
-class PreprocessorFactory;
-
-ASTConsumer *CreateASTPrinter(llvm::raw_ostream* OS = NULL);
-
-ASTConsumer *CreateASTDumper();
-
-ASTConsumer *CreateASTViewer();
-
-ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
- const std::string& OutFile,
- Diagnostic &Diags,
- const LangOptions &LOpts);
-
-ASTConsumer *CreateLLVMCodeGenWriter(bool EmitBC, Diagnostic &Diags,
- const LangOptions &Features,
- const std::string& InFile,
- const std::string& OutFile,
- bool GenerateDebugInfo);
-
-ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D,
- Preprocessor *PP, PreprocessorFactory* PPF);
-
-ASTConsumer *CreateSerializationTest(Diagnostic &Diags,
- FileManager& FMgr);
-
-ASTConsumer *CreateASTSerializer(const std::string& InFile,
- const std::string& EmitDir,
- Diagnostic &Diags);
-
-ASTConsumer *CreateBlockRewriter(const std::string& InFile,
- const std::string& OutFile,
- Diagnostic &Diags,
- const LangOptions &LangOpts);
-} // end clang namespace
-
-#include "AnalysisConsumer.h"
-
-#endif
diff --git a/clang/Driver/Analyses.def b/clang/Driver/Analyses.def
deleted file mode 100644
index 841f0c1da1ec..000000000000
--- a/clang/Driver/Analyses.def
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- Analyses.def - Metadata about Static Analyses -----------*- 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 set of static analyses used by AnalysisConsumer.
-//
-//===----------------------------------------------------------------------===//
-
-ANALYSIS(CFGDump, "cfg-dump",
- "Display Control-Flow Graphs", Code)
-
-ANALYSIS(CFGView, "cfg-view",
- "View Control-Flow Graphs using GraphViz", Code)
-
-ANALYSIS(DisplayLiveVariables, "dump-live-variables",
- "Print results of live variable analysis", Code)
-
-ANALYSIS(WarnDeadStores, "warn-dead-stores",
- "Warn about stores to dead variables", Code)
-
-ANALYSIS(WarnUninitVals, "warn-uninit-values",
- "Warn about uses of uninitialized variables", Code)
-
-ANALYSIS(WarnObjCMethSigs, "warn-objc-methodsigs",
- "Warn about Objective-C method signatures with type incompatibilities",
- ObjCImplementation)
-
-ANALYSIS(WarnObjCDealloc, "warn-objc-missing-dealloc",
- "Warn about Objective-C classes that lack a correct implementation of -dealloc",
- ObjCImplementation)
-
-ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars",
- "Warn about private ivars that are never used", ObjCImplementation)
-
-ANALYSIS(CheckerSimple, "checker-simple",
- "Perform simple path-sensitive checks.", Code)
-
-ANALYSIS(CheckerCFRef, "checker-cfref",
- "Run the [Core] Foundation reference count checker", Code)
-
-#undef ANALYSIS
diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp
deleted file mode 100644
index e22178b73eb5..000000000000
--- a/clang/Driver/AnalysisConsumer.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-//===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// "Meta" ASTConsumer for running different source analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTConsumers.h"
-#include "clang/Driver/HTMLDiagnostics.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "clang/AST/CFG.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/AST/TranslationUnit.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
-#include <vector>
-
-using namespace clang;
-
-static ExplodedNodeImpl::Auditor* CreateUbiViz();
-
-//===----------------------------------------------------------------------===//
-// Basic type definitions.
-//===----------------------------------------------------------------------===//
-
-namespace {
- class AnalysisManager;
- typedef void (*CodeAction)(AnalysisManager& Mgr);
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// AnalysisConsumer declaration.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
- class VISIBILITY_HIDDEN AnalysisConsumer : public ASTConsumer {
- typedef std::vector<CodeAction> Actions;
- Actions FunctionActions;
- Actions ObjCMethodActions;
- Actions ObjCImplementationActions;
-
- public:
- const bool VisGraphviz;
- const bool VisUbigraph;
- const bool TrimGraph;
- const LangOptions& LOpts;
- Diagnostic &Diags;
- ASTContext* Ctx;
- Preprocessor* PP;
- PreprocessorFactory* PPF;
- const std::string HTMLDir;
- const std::string FName;
- llvm::OwningPtr<PathDiagnosticClient> PD;
- bool AnalyzeAll;
-
- AnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
- PreprocessorFactory* ppf,
- const LangOptions& lopts,
- const std::string& fname,
- const std::string& htmldir,
- bool visgraphviz, bool visubi, bool trim, bool analyzeAll)
- : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim),
- LOpts(lopts), Diags(diags),
- Ctx(0), PP(pp), PPF(ppf),
- HTMLDir(htmldir),
- FName(fname),
- AnalyzeAll(analyzeAll) {}
-
- void addCodeAction(CodeAction action) {
- FunctionActions.push_back(action);
- ObjCMethodActions.push_back(action);
- }
-
- void addObjCImplementationAction(CodeAction action) {
- ObjCImplementationActions.push_back(action);
- }
-
- virtual void Initialize(ASTContext &Context) {
- Ctx = &Context;
- }
-
- virtual void HandleTopLevelDecl(Decl *D);
- virtual void HandleTranslationUnit(TranslationUnit &TU);
-
- void HandleCode(Decl* D, Stmt* Body, Actions actions);
- };
-
-
- class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData {
- Decl* D;
- Stmt* Body;
- AnalysisConsumer& C;
- bool DisplayedFunction;
-
- llvm::OwningPtr<CFG> cfg;
- llvm::OwningPtr<LiveVariables> liveness;
- llvm::OwningPtr<ParentMap> PM;
-
- public:
- AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b)
- : D(d), Body(b), C(c), DisplayedFunction(false) {}
-
-
- Decl* getCodeDecl() const { return D; }
- Stmt* getBody() const { return Body; }
-
- virtual CFG* getCFG() {
- if (!cfg) cfg.reset(CFG::buildCFG(getBody()));
- return cfg.get();
- }
-
- virtual ParentMap& getParentMap() {
- if (!PM)
- PM.reset(new ParentMap(getBody()));
- return *PM.get();
- }
-
- virtual ASTContext& getContext() {
- return *C.Ctx;
- }
-
- virtual SourceManager& getSourceManager() {
- return getContext().getSourceManager();
- }
-
- virtual Diagnostic& getDiagnostic() {
- return C.Diags;
- }
-
- const LangOptions& getLangOptions() const {
- return C.LOpts;
- }
-
- virtual PathDiagnosticClient* getPathDiagnosticClient() {
- if (C.PD.get() == 0 && !C.HTMLDir.empty())
- C.PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF));
-
- return C.PD.get();
- }
-
- virtual LiveVariables* getLiveVariables() {
- if (!liveness) {
- CFG* c = getCFG();
- if (!c) return 0;
-
- liveness.reset(new LiveVariables(*c));
- liveness->runOnCFG(*c);
- liveness->runOnAllBlocks(*c, 0, true);
- }
-
- return liveness.get();
- }
-
- bool shouldVisualizeGraphviz() const {
- return C.VisGraphviz;
- }
-
- bool shouldVisualizeUbigraph() const {
- return C.VisUbigraph;
- }
-
- bool shouldVisualize() const {
- return C.VisGraphviz || C.VisUbigraph;
- }
-
- bool shouldTrimGraph() const {
- return C.TrimGraph;
- }
-
- void DisplayFunction() {
-
- if (DisplayedFunction)
- return;
-
- DisplayedFunction = true;
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(getCodeDecl())) {
- llvm::cout << "ANALYZE: "
- << getContext().getSourceManager().getSourceName(FD->getLocation())
- << ' '
- << FD->getIdentifier()->getName()
- << '\n';
- }
- else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(getCodeDecl())) {
- llvm::cout << "ANALYZE (ObjC Method): "
- << getContext().getSourceManager().getSourceName(MD->getLocation())
- << " '"
- << MD->getSelector().getName() << "'\n";
- }
- }
- };
-
-} // end anonymous namespace
-
-namespace llvm {
- template <> struct FoldingSetTrait<CodeAction> {
- static inline void Profile(CodeAction X, FoldingSetNodeID& ID) {
- ID.AddPointer(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(X)));
- }
- };
-}
-
-//===----------------------------------------------------------------------===//
-// AnalysisConsumer implementation.
-//===----------------------------------------------------------------------===//
-
-void AnalysisConsumer::HandleTopLevelDecl(Decl *D) {
- switch (D->getKind()) {
- case Decl::Function: {
- FunctionDecl* FD = cast<FunctionDecl>(D);
-
- if (FName.size() > 0 && FName != FD->getIdentifier()->getName())
- break;
-
- Stmt* Body = FD->getBody();
- if (Body) HandleCode(FD, Body, FunctionActions);
- break;
- }
-
- case Decl::ObjCMethod: {
- ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
-
- if (FName.size() > 0 && FName != MD->getSelector().getName())
- return;
-
- Stmt* Body = MD->getBody();
- if (Body) HandleCode(MD, Body, ObjCMethodActions);
- break;
- }
-
- default:
- break;
- }
-}
-
-void AnalysisConsumer::HandleTranslationUnit(TranslationUnit& TU) {
-
- if (ObjCImplementationActions.empty())
- return;
-
- for (TranslationUnit::iterator I = TU.begin(), E = TU.end(); I!=E; ++I) {
-
- if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
- HandleCode(ID, 0, ObjCImplementationActions);
- }
-}
-
-void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) {
-
- // Don't run the actions if an error has occured with parsing the file.
- if (Diags.hasErrorOccurred())
- return;
-
- SourceLocation Loc = D->getLocation();
-
- // Only run actions on declarations defined in actual source.
- if (!Loc.isFileID())
- return;
-
- // Don't run the actions on declarations in header files unless
- // otherwise specified.
- if (!AnalyzeAll && !Ctx->getSourceManager().isFromMainFile(Loc))
- return;
-
- // Create an AnalysisManager that will manage the state for analyzing
- // this method/function.
- AnalysisManager mgr(*this, D, Body);
-
- // Dispatch on the actions.
- for (Actions::iterator I = actions.begin(),
- E = actions.end(); I != E; ++I)
- (*I)(mgr);
-}
-
-//===----------------------------------------------------------------------===//
-// Analyses
-//===----------------------------------------------------------------------===//
-
-static void ActionWarnDeadStores(AnalysisManager& mgr) {
- if (LiveVariables* L = mgr.getLiveVariables()) {
- BugReporter BR(mgr);
- CheckDeadStores(*L, BR);
- }
-}
-
-static void ActionWarnUninitVals(AnalysisManager& mgr) {
- if (CFG* c = mgr.getCFG())
- CheckUninitializedValues(*c, mgr.getContext(), mgr.getDiagnostic());
-}
-
-
-static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf,
- bool StandardWarnings = true) {
-
-
- llvm::OwningPtr<GRTransferFuncs> TF(tf);
-
- // Construct the analysis engine.
- LiveVariables* L = mgr.getLiveVariables();
- if (!L) return;
-
- // Display progress.
- mgr.DisplayFunction();
-
- GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L);
- Eng.setTransferFunctions(tf);
-
- if (StandardWarnings) {
- Eng.RegisterInternalChecks();
- RegisterAppleChecks(Eng);
- }
-
- // Set the graph auditor.
- llvm::OwningPtr<ExplodedNodeImpl::Auditor> Auditor;
- if (mgr.shouldVisualizeUbigraph()) {
- Auditor.reset(CreateUbiViz());
- ExplodedNodeImpl::SetAuditor(Auditor.get());
- }
-
- // Execute the worklist algorithm.
- Eng.ExecuteWorkList();
-
- // Release the auditor (if any) so that it doesn't monitor the graph
- // created BugReporter.
- ExplodedNodeImpl::SetAuditor(0);
-
- // Display warnings.
- Eng.EmitWarnings(mgr);
-
- // Visualize the exploded graph.
- if (mgr.shouldVisualizeGraphviz())
- Eng.ViewGraph(mgr.shouldTrimGraph());
-}
-
-static void ActionCheckerCFRefAux(AnalysisManager& mgr, bool GCEnabled,
- bool StandardWarnings) {
-
- GRTransferFuncs* TF = MakeCFRefCountTF(mgr.getContext(),
- GCEnabled,
- mgr.getLangOptions());
-
- ActionGRExprEngine(mgr, TF, StandardWarnings);
-}
-
-static void ActionCheckerCFRef(AnalysisManager& mgr) {
-
- switch (mgr.getLangOptions().getGCMode()) {
- default:
- assert (false && "Invalid GC mode.");
- case LangOptions::NonGC:
- ActionCheckerCFRefAux(mgr, false, true);
- break;
-
- case LangOptions::GCOnly:
- ActionCheckerCFRefAux(mgr, true, true);
- break;
-
- case LangOptions::HybridGC:
- ActionCheckerCFRefAux(mgr, false, true);
- ActionCheckerCFRefAux(mgr, true, false);
- break;
- }
-}
-
-static void ActionCheckerSimple(AnalysisManager& mgr) {
- ActionGRExprEngine(mgr, MakeGRSimpleValsTF());
-}
-
-static void ActionDisplayLiveVariables(AnalysisManager& mgr) {
- if (LiveVariables* L = mgr.getLiveVariables()) {
- mgr.DisplayFunction();
- L->dumpBlockLiveness(mgr.getSourceManager());
- }
-}
-
-static void ActionCFGDump(AnalysisManager& mgr) {
- if (CFG* c = mgr.getCFG()) {
- mgr.DisplayFunction();
- c->dump();
- }
-}
-
-static void ActionCFGView(AnalysisManager& mgr) {
- if (CFG* c = mgr.getCFG()) {
- mgr.DisplayFunction();
- c->viewCFG();
- }
-}
-
-static void ActionWarnObjCDealloc(AnalysisManager& mgr) {
- if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
- return;
-
- BugReporter BR(mgr);
-
- CheckObjCDealloc(cast<ObjCImplementationDecl>(mgr.getCodeDecl()),
- mgr.getLangOptions(), BR);
-}
-
-static void ActionWarnObjCUnusedIvars(AnalysisManager& mgr) {
- BugReporter BR(mgr);
- CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(mgr.getCodeDecl()), BR);
-}
-
-static void ActionWarnObjCMethSigs(AnalysisManager& mgr) {
- BugReporter BR(mgr);
-
- CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(mgr.getCodeDecl()),
- BR);
-}
-
-//===----------------------------------------------------------------------===//
-// AnalysisConsumer creation.
-//===----------------------------------------------------------------------===//
-
-ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
- Diagnostic &diags, Preprocessor* pp,
- PreprocessorFactory* ppf,
- const LangOptions& lopts,
- const std::string& fname,
- const std::string& htmldir,
- bool VisGraphviz, bool VisUbi,
- bool trim,
- bool analyzeAll) {
-
- llvm::OwningPtr<AnalysisConsumer>
- C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir,
- VisGraphviz, VisUbi, trim, analyzeAll));
-
- for ( ; Beg != End ; ++Beg)
- switch (*Beg) {
-#define ANALYSIS(NAME, CMD, DESC, SCOPE)\
- case NAME:\
- C->add ## SCOPE ## Action(&Action ## NAME);\
- break;
-#include "Analyses.def"
- default: break;
- }
-
- return C.take();
-}
-
-//===----------------------------------------------------------------------===//
-// Ubigraph Visualization. FIXME: Move to separate file.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class UbigraphViz : public ExplodedNodeImpl::Auditor {
- llvm::OwningPtr<llvm::raw_ostream> Out;
- llvm::sys::Path Dir, Filename;
- unsigned Cntr;
-
- typedef llvm::DenseMap<void*,unsigned> VMap;
- VMap M;
-
-public:
- UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
- llvm::sys::Path& filename);
-
- ~UbigraphViz();
-
- virtual void AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst);
-};
-
-} // end anonymous namespace
-
-static ExplodedNodeImpl::Auditor* CreateUbiViz() {
- std::string ErrMsg;
-
- llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
- if (!ErrMsg.empty())
- return 0;
-
- llvm::sys::Path Filename = Dir;
- Filename.appendComponent("llvm_ubi");
- Filename.makeUnique(true,&ErrMsg);
-
- if (!ErrMsg.empty())
- return 0;
-
- llvm::cerr << "Writing '" << Filename << "'.\n";
-
- llvm::OwningPtr<llvm::raw_fd_ostream> Stream;
- std::string filename = Filename.toString();
- Stream.reset(new llvm::raw_fd_ostream(filename.c_str(), ErrMsg));
-
- if (!ErrMsg.empty())
- return 0;
-
- return new UbigraphViz(Stream.take(), Dir, Filename);
-}
-
-void UbigraphViz::AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst) {
-
- assert (Src != Dst && "Self-edges are not allowed.");
-
- // Lookup the Src. If it is a new node, it's a root.
- VMap::iterator SrcI= M.find(Src);
- unsigned SrcID;
-
- if (SrcI == M.end()) {
- M[Src] = SrcID = Cntr++;
- *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
- }
- else
- SrcID = SrcI->second;
-
- // Lookup the Dst.
- VMap::iterator DstI= M.find(Dst);
- unsigned DstID;
-
- if (DstI == M.end()) {
- M[Dst] = DstID = Cntr++;
- *Out << "('vertex', " << DstID << ")\n";
- }
- else {
- // We have hit DstID before. Change its style to reflect a cache hit.
- DstID = DstI->second;
- *Out << "('change_vertex_style', " << DstID << ", 1)\n";
- }
-
- // Add the edge.
- *Out << "('edge', " << SrcID << ", " << DstID
- << ", ('arrow','true'), ('oriented', 'true'))\n";
-}
-
-UbigraphViz::UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
- llvm::sys::Path& filename)
- : Out(out), Dir(dir), Filename(filename), Cntr(0) {
-
- *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
- *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
- " ('size', '1.5'))\n";
-}
-
-UbigraphViz::~UbigraphViz() {
- Out.reset(0);
- llvm::cerr << "Running 'ubiviz' program... ";
- std::string ErrMsg;
- llvm::sys::Path Ubiviz = llvm::sys::Program::FindProgramByName("ubiviz");
- std::vector<const char*> args;
- args.push_back(Ubiviz.c_str());
- args.push_back(Filename.c_str());
- args.push_back(0);
-
- if (llvm::sys::Program::ExecuteAndWait(Ubiviz, &args[0],0,0,0,0,&ErrMsg)) {
- llvm::cerr << "Error viewing graph: " << ErrMsg << "\n";
- }
-
- // Delete the directory.
- Dir.eraseFromDisk(true);
-}
diff --git a/clang/Driver/AnalysisConsumer.h b/clang/Driver/AnalysisConsumer.h
deleted file mode 100644
index daec6f3441ba..000000000000
--- a/clang/Driver/AnalysisConsumer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// "Meta" ASTConsumer for running different source analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DRIVER_ANALYSISCONSUMER_H
-#define DRIVER_ANALYSISCONSUMER_H
-
-namespace clang {
-
-enum Analyses {
-#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
-#include "Analyses.def"
-NumAnalyses
-};
-
-ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
- Diagnostic &diags, Preprocessor* pp,
- PreprocessorFactory* ppf,
- const LangOptions& lopts,
- const std::string& fname,
- const std::string& htmldir,
- bool VisualizeGraphViz,
- bool VisualizeUbi,
- bool VizTrimGraph,
- bool AnalyzeAll);
-} // end clang namespace
-
-#endif
diff --git a/clang/Driver/DiagChecker.cpp b/clang/Driver/DiagChecker.cpp
deleted file mode 100644
index 6f7ea0b739b3..000000000000
--- a/clang/Driver/DiagChecker.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-//===--- DiagChecker.cpp - Diagnostic Checking Functions ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Process the input files and check that the diagnostic messages are expected.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang.h"
-#include "ASTConsumers.h"
-#include "clang/Driver/TextDiagnosticBuffer.h"
-#include "clang/Sema/ParseAST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
-using namespace clang;
-
-typedef TextDiagnosticBuffer::DiagList DiagList;
-typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
-
-// 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.
-
-static const char * const ExpectedErrStr = "expected-error";
-static const char * const ExpectedWarnStr = "expected-warning";
-static const char * const ExpectedNoteStr = "expected-note";
-
-/// FindDiagnostics - Go through the comment and see if it indicates expected
-/// diagnostics. If so, then put them in a diagnostic list.
-///
-static void FindDiagnostics(const std::string &Comment,
- DiagList &ExpectedDiags,
- SourceManager &SourceMgr,
- SourceLocation Pos,
- const char * const ExpectedStr) {
- // Find all expected diagnostics
- typedef std::string::size_type size_type;
- size_type ColNo = 0;
-
- for (;;) {
- ColNo = Comment.find(ExpectedStr, ColNo);
- if (ColNo == std::string::npos) break;
-
- size_type OpenDiag = Comment.find("{{", ColNo);
-
- if (OpenDiag == std::string::npos) {
- fprintf(stderr,
- "oops:%d: Cannot find beginning of expected error string\n",
- SourceMgr.getLogicalLineNumber(Pos));
- break;
- }
-
- OpenDiag += 2;
- size_type CloseDiag = Comment.find("}}", OpenDiag);
-
- if (CloseDiag == std::string::npos) {
- fprintf(stderr,
- "oops:%d: Cannot find end of expected error string\n",
- SourceMgr.getLogicalLineNumber(Pos));
- break;
- }
-
- std::string Msg(Comment.substr(OpenDiag, CloseDiag - OpenDiag));
- ExpectedDiags.push_back(std::make_pair(Pos, Msg));
- ColNo = CloseDiag + 2;
- }
-}
-
-/// FindExpectedDiags - Lex the main source file to find all of the
-// expected errors and warnings.
-static void FindExpectedDiags(Preprocessor &PP,
- DiagList &ExpectedErrors,
- DiagList &ExpectedWarnings,
- DiagList &ExpectedNotes) {
- // Return comments as tokens, this is how we find expected diagnostics.
- PP.SetCommentRetentionState(true, true);
-
- // Enter the cave.
- PP.EnterMainSourceFile();
-
- // Turn off all warnings from relexing or preprocessing.
- PP.getDiagnostics().setWarnOnExtensions(false);
- PP.getDiagnostics().setErrorOnExtensions(false);
- for (unsigned i = 0; i != diag::NUM_BUILTIN_DIAGNOSTICS; ++i)
- if (PP.getDiagnostics().isBuiltinNoteWarningOrExtension((diag::kind)i))
- PP.getDiagnostics().setDiagnosticMapping((diag::kind)i, diag::MAP_IGNORE);
-
- Token Tok;
- do {
- PP.Lex(Tok);
-
- if (Tok.is(tok::comment)) {
- std::string Comment = PP.getSpelling(Tok);
-
- // Find all expected errors
- FindDiagnostics(Comment, ExpectedErrors,PP.getSourceManager(),
- Tok.getLocation(), ExpectedErrStr);
-
- // Find all expected warnings
- FindDiagnostics(Comment, ExpectedWarnings, PP.getSourceManager(),
- Tok.getLocation(), ExpectedWarnStr);
-
- // Find all expected notes
- FindDiagnostics(Comment, ExpectedNotes, PP.getSourceManager(),
- Tok.getLocation(), ExpectedNoteStr);
- }
- } while (Tok.isNot(tok::eof));
-
- PP.SetCommentRetentionState(false, false);
-}
-
-/// PrintProblem - This takes a diagnostic map of the delta between expected and
-/// seen diagnostics. If there's anything in it, then something unexpected
-/// happened. Print the map out in a nice format and return "true". If the map
-/// is empty and we're not going to print things, then return "false".
-///
-static bool PrintProblem(SourceManager &SourceMgr,
- const_diag_iterator diag_begin,
- const_diag_iterator diag_end,
- const char *Msg) {
- if (diag_begin == diag_end) return false;
-
- fprintf(stderr, "%s\n", Msg);
-
- for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I)
- fprintf(stderr, " Line %d: %s\n",
- SourceMgr.getLogicalLineNumber(I->first),
- I->second.c_str());
-
- return true;
-}
-
-/// CompareDiagLists - Compare two diangnostic lists and return the difference
-/// between them.
-///
-static bool CompareDiagLists(SourceManager &SourceMgr,
- const_diag_iterator d1_begin,
- const_diag_iterator d1_end,
- const_diag_iterator d2_begin,
- const_diag_iterator d2_end,
- const char *Msg) {
- DiagList DiffList;
-
- for (const_diag_iterator I = d1_begin, E = d1_end; I != E; ++I) {
- unsigned LineNo1 = SourceMgr.getLogicalLineNumber(I->first);
- const std::string &Diag1 = I->second;
- bool Found = false;
-
- for (const_diag_iterator II = d2_begin, IE = d2_end; II != IE; ++II) {
- unsigned LineNo2 = SourceMgr.getLogicalLineNumber(II->first);
- if (LineNo1 != LineNo2) continue;
-
- const std::string &Diag2 = II->second;
- if (Diag2.find(Diag1) != std::string::npos ||
- Diag1.find(Diag2) != std::string::npos) {
- Found = true;
- break;
- }
- }
-
- if (!Found)
- DiffList.push_back(std::make_pair(I->first, Diag1));
- }
-
- return PrintProblem(SourceMgr, DiffList.begin(), DiffList.end(), Msg);
-}
-
-/// CheckResults - This compares the expected results to those that
-/// were actually reported. It emits any discrepencies. Return "true" if there
-/// were problems. Return "false" otherwise.
-///
-static bool CheckResults(Preprocessor &PP,
- const DiagList &ExpectedErrors,
- const DiagList &ExpectedWarnings,
- const DiagList &ExpectedNotes) {
- const DiagnosticClient *DiagClient = PP.getDiagnostics().getClient();
- assert(DiagClient != 0 &&
- "DiagChecker requires a valid TextDiagnosticBuffer");
- const TextDiagnosticBuffer &Diags =
- static_cast<const TextDiagnosticBuffer&>(*DiagClient);
- SourceManager &SourceMgr = PP.getSourceManager();
-
- // We want to capture the delta between what was expected and what was
- // seen.
- //
- // Expected \ Seen - set expected but not seen
- // Seen \ Expected - set seen but not expected
- bool HadProblem = false;
-
- // See if there were errors that were expected but not seen.
- HadProblem |= CompareDiagLists(SourceMgr,
- ExpectedErrors.begin(), ExpectedErrors.end(),
- Diags.err_begin(), Diags.err_end(),
- "Errors expected but not seen:");
-
- // See if there were errors that were seen but not expected.
- HadProblem |= CompareDiagLists(SourceMgr,
- Diags.err_begin(), Diags.err_end(),
- ExpectedErrors.begin(), ExpectedErrors.end(),
- "Errors seen but not expected:");
-
- // See if there were warnings that were expected but not seen.
- HadProblem |= CompareDiagLists(SourceMgr,
- ExpectedWarnings.begin(),
- ExpectedWarnings.end(),
- Diags.warn_begin(), Diags.warn_end(),
- "Warnings expected but not seen:");
-
- // See if there were warnings that were seen but not expected.
- HadProblem |= CompareDiagLists(SourceMgr,
- Diags.warn_begin(), Diags.warn_end(),
- ExpectedWarnings.begin(),
- ExpectedWarnings.end(),
- "Warnings seen but not expected:");
-
- // See if there were notes that were expected but not seen.
- HadProblem |= CompareDiagLists(SourceMgr,
- ExpectedNotes.begin(),
- ExpectedNotes.end(),
- Diags.note_begin(), Diags.note_end(),
- "Notes expected but not seen:");
-
- // See if there were notes that were seen but not expected.
- HadProblem |= CompareDiagLists(SourceMgr,
- Diags.note_begin(), Diags.note_end(),
- ExpectedNotes.begin(),
- ExpectedNotes.end(),
- "Notes seen but not expected:");
-
- return HadProblem;
-}
-
-
-/// CheckASTConsumer - Implement diagnostic checking for AST consumers.
-bool clang::CheckASTConsumer(Preprocessor &PP, ASTConsumer* C) {
-
- // Parse the AST and run the consumer, ultimately deleting C.
- ParseAST(PP, C);
- return CheckDiagnostics(PP);
-}
-
-/// CheckDiagnostics - Gather the expected diagnostics and check them.
-bool clang::CheckDiagnostics(Preprocessor &PP) {
- // Gather the set of expected diagnostics.
- DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes;
- FindExpectedDiags(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes);
-
- // Check that the expected diagnostics occurred.
- return CheckResults(PP, ExpectedErrors, ExpectedWarnings, ExpectedNotes);
-}
diff --git a/clang/Driver/HTMLPrint.cpp b/clang/Driver/HTMLPrint.cpp
deleted file mode 100644
index 0956c2bca581..000000000000
--- a/clang/Driver/HTMLPrint.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Pretty-printing of source code to HTML.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTConsumers.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Decl.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/Rewrite/HTMLRewrite.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/AST/ASTContext.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Functional HTML pretty-printing.
-//===----------------------------------------------------------------------===//
-
-namespace {
- class HTMLPrinter : public ASTConsumer {
- Rewriter R;
- std::string OutFilename;
- Diagnostic &Diags;
- Preprocessor *PP;
- PreprocessorFactory *PPF;
- public:
- HTMLPrinter(const std::string &OutFile, Diagnostic &D, Preprocessor *pp,
- PreprocessorFactory* ppf)
- : OutFilename(OutFile), Diags(D), PP(pp), PPF(ppf) {}
- virtual ~HTMLPrinter();
-
- void Initialize(ASTContext &context);
- };
-}
-
-ASTConsumer* clang::CreateHTMLPrinter(const std::string &OutFile,
- Diagnostic &D, Preprocessor *PP,
- PreprocessorFactory* PPF) {
-
- return new HTMLPrinter(OutFile, D, PP, PPF);
-}
-
-void HTMLPrinter::Initialize(ASTContext &context) {
- R.setSourceMgr(context.getSourceManager());
-}
-
-HTMLPrinter::~HTMLPrinter() {
- if (Diags.hasErrorOccurred())
- return;
-
- // Format the file.
- unsigned FileID = R.getSourceMgr().getMainFileID();
- const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FileID);
-
- html::AddLineNumbers(R, FileID);
- html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName());
-
- // If we have a preprocessor, relex the file and syntax highlight.
- // We might not have a preprocessor if we come from a deserialized AST file,
- // for example.
-
- if (PP) html::SyntaxHighlight(R, FileID, *PP);
- if (PPF) html::HighlightMacros(R, FileID, *PP);
- html::EscapeText(R, FileID, false, true);
-
- // Open the output.
- FILE *OutputFILE;
- if (OutFilename.empty() || OutFilename == "-")
- OutputFILE = stdout;
- else {
- OutputFILE = fopen(OutFilename.c_str(), "w+");
- if (OutputFILE == 0) {
- fprintf(stderr, "Error opening output file '%s'.\n", OutFilename.c_str());
- exit(1);
- }
- }
-
- // Emit the HTML.
- const RewriteBuffer &RewriteBuf = R.getEditBuffer(FileID);
- char *Buffer = (char*)malloc(RewriteBuf.size());
- std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
- fwrite(Buffer, 1, RewriteBuf.size(), OutputFILE);
- free(Buffer);
-
- if (OutputFILE != stdout) fclose(OutputFILE);
-}
diff --git a/clang/Driver/Makefile b/clang/Driver/Makefile
deleted file mode 100644
index 3b0dae498467..000000000000
--- a/clang/Driver/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-LEVEL = ../../..
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../include
-CXXFLAGS = -fno-rtti
-
-TOOLNAME = clang
-USEDLIBS = clangCodeGen.a clangAnalysis.a clangRewrite.a clangSema.a \
- clangDriver.a clangAST.a clangParse.a clangLex.a clangBasic.a \
- LLVMCore.a LLVMSupport.a LLVMSystem.a \
- LLVMBitWriter.a LLVMBitReader.a LLVMCodeGen.a LLVMAnalysis.a \
- LLVMTarget.a
-
-include $(LEVEL)/Makefile.common
diff --git a/clang/Driver/PrintParserCallbacks.cpp b/clang/Driver/PrintParserCallbacks.cpp
deleted file mode 100644
index b616268376f9..000000000000
--- a/clang/Driver/PrintParserCallbacks.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-//===--- PrintParserActions.cpp - Implement -parse-print-callbacks mode ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This code simply runs the preprocessor on the input file and prints out the
-// result. This is the traditional behavior of the -E option.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang.h"
-#include "clang/Parse/Action.h"
-#include "clang/Parse/DeclSpec.h"
-#include "llvm/Support/Streams.h"
-using namespace clang;
-
-namespace {
- class ParserPrintActions : public MinimalAction {
-
- public:
- ParserPrintActions(IdentifierTable &IT) : MinimalAction(IT) {}
-
- // Printing Functions which also must call MinimalAction
-
- /// ActOnDeclarator - This callback is invoked when a declarator is parsed
- /// and 'Init' specifies the initializer if any. This is for things like:
- /// "int X = 4" or "typedef int foo".
- virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D,
- DeclTy *LastInGroup) {
- llvm::cout << __FUNCTION__ << " ";
- if (IdentifierInfo *II = D.getIdentifier()) {
- llvm::cout << "'" << II->getName() << "'";
- } else {
- llvm::cout << "<anon>";
- }
- llvm::cout << "\n";
-
- // Pass up to EmptyActions so that the symbol table is maintained right.
- return MinimalAction::ActOnDeclarator(S, D, LastInGroup);
- }
- /// ActOnPopScope - This callback is called immediately before the specified
- /// scope is popped and deleted.
- virtual void ActOnPopScope(SourceLocation Loc, Scope *S) {
- llvm::cout << __FUNCTION__ << "\n";
- return MinimalAction::ActOnPopScope(Loc, S);
- }
-
- /// ActOnTranslationUnitScope - This callback is called once, immediately
- /// after creating the translation unit scope (in Parser::Initialize).
- virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
- llvm::cout << __FUNCTION__ << "\n";
- MinimalAction::ActOnTranslationUnitScope(Loc, S);
- }
-
-
- Action::DeclTy *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtocols,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
- llvm::cout << __FUNCTION__ << "\n";
- return MinimalAction::ActOnStartClassInterface(AtInterfaceLoc,
- ClassName, ClassLoc,
- SuperName, SuperLoc,
- ProtoRefs, NumProtocols,
- EndProtoLoc, AttrList);
- }
-
- /// ActOnForwardClassDeclaration -
- /// Scope will always be top level file scope.
- Action::DeclTy *ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
- IdentifierInfo **IdentList,
- unsigned NumElts) {
- llvm::cout << __FUNCTION__ << "\n";
- return MinimalAction::ActOnForwardClassDeclaration(AtClassLoc, IdentList,
- NumElts);
- }
-
- // Pure Printing
-
- /// ActOnParamDeclarator - This callback is invoked when a parameter
- /// declarator is parsed. This callback only occurs for functions
- /// with prototypes. S is the function prototype scope for the
- /// parameters (C++ [basic.scope.proto]).
- virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D) {
- llvm::cout << __FUNCTION__ << " ";
- if (IdentifierInfo *II = D.getIdentifier()) {
- llvm::cout << "'" << II->getName() << "'";
- } else {
- llvm::cout << "<anon>";
- }
- llvm::cout << "\n";
- return 0;
- }
-
- /// AddInitializerToDecl - This action is called immediately after
- /// ParseDeclarator (when an initializer is present). The code is factored
- /// this way to make sure we are able to handle the following:
- /// void func() { int xx = xx; }
- /// This allows ActOnDeclarator to register "xx" prior to parsing the
- /// initializer. The declaration above should still result in a warning,
- /// since the reference to "xx" is uninitialized.
- virtual void AddInitializerToDecl(DeclTy *Dcl, ExprTy *Init) {
- llvm::cout << __FUNCTION__ << "\n";
- }
-
- /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
- /// gives the actions implementation a chance to process the group as a whole.
- virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// ActOnStartOfFunctionDef - This is called at the start of a function
- /// definition, instead of calling ActOnDeclarator. The Declarator includes
- /// information about formal arguments that are part of this function.
- virtual DeclTy *ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// ActOnStartOfFunctionDef - This is called at the start of a function
- /// definition, after the FunctionDecl has already been created.
- virtual DeclTy *ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual void ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
- llvm::cout << __FUNCTION__ << "\n";
- }
-
- /// ActOnFunctionDefBody - This is called when a function body has completed
- /// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
- virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprTy *AsmString) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
- /// no declarator (e.g. "struct foo;") is parsed.
- virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
- SourceLocation RBrace, const char *Lang,
- unsigned StrSize, DeclTy *D) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- //===--------------------------------------------------------------------===//
- // Type Parsing Callbacks.
- //===--------------------------------------------------------------------===//
-
- virtual TypeResult ActOnTypeName(Scope *S, Declarator &D) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK,
- SourceLocation KWLoc, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr) {
- // TagType is an instance of DeclSpec::TST, indicating what kind of tag this
- // is (struct/union/enum/class).
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// Act on @defs() element found when parsing a structure. ClassName is the
- /// name of the referenced class.
- virtual void ActOnDefs(Scope *S, SourceLocation DeclStart,
- IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclTy*> &Decls) {
- llvm::cout << __FUNCTION__ << "\n";
- }
-
- virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth,
- tok::ObjCKeywordKind visibility) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *TagDecl,
- DeclTy **Fields, unsigned NumFields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *AttrList) {
- llvm::cout << __FUNCTION__ << "\n";
- }
-
- virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
- DeclTy *LastEnumConstant,
- SourceLocation IdLoc, IdentifierInfo *Id,
- SourceLocation EqualLoc, ExprTy *Val) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
- DeclTy **Elements, unsigned NumElements) {
- llvm::cout << __FUNCTION__ << "\n";
- }
-
- //===--------------------------------------------------------------------===//
- // Statement Parsing Callbacks.
- //===--------------------------------------------------------------------===//
-
- virtual StmtResult ActOnNullStmt(SourceLocation SemiLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
- StmtTy **Elts, unsigned NumElts,
- bool isStmtExpr) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
- SourceLocation EndLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnExprStmt(ExprTy *Expr) {
- llvm::cout << __FUNCTION__ << "\n";
- return StmtResult(Expr);
- }
-
- /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
- /// which can specify an RHS value.
- virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
- SourceLocation DotDotDotLoc, ExprTy *RHSVal,
- SourceLocation ColonLoc, StmtTy *SubStmt) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc, StmtTy *SubStmt,
- Scope *CurScope){
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, StmtTy *SubStmt) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
- StmtTy *ThenVal, SourceLocation ElseLoc,
- StmtTy *ElseVal) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
- StmtTy *Switch, ExprTy *Body) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
- StmtTy *Body) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnDoStmt(SourceLocation DoLoc, StmtTy *Body,
- SourceLocation WhileLoc, ExprTy *Cond) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnForStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- StmtTy *First, ExprTy *Second, ExprTy *Third,
- SourceLocation RParenLoc, StmtTy *Body) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
- SourceLocation LParenLoc,
- StmtTy *First, ExprTy *Second,
- SourceLocation RParenLoc, StmtTy *Body) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
- SourceLocation LabelLoc,
- IdentifierInfo *LabelII) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
- SourceLocation StarLoc,
- ExprTy *DestExp) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
- Scope *CurScope) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
- ExprTy *RetValExp) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
- bool IsSimple,
- bool IsVolatile,
- unsigned NumOutputs,
- unsigned NumInputs,
- std::string *Names,
- ExprTy **Constraints,
- ExprTy **Exprs,
- ExprTy *AsmString,
- unsigned NumClobbers,
- ExprTy **Clobbers,
- SourceLocation RParenLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- // Objective-c statements
- virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
- SourceLocation RParen, StmtTy *Parm,
- StmtTy *Body, StmtTy *CatchList) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
- StmtTy *Body) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtTy *Try,
- StmtTy *Catch, StmtTy *Finally) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
- StmtTy *Throw) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
- ExprTy *SynchExpr,
- StmtTy *SynchBody) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- //===--------------------------------------------------------------------===//
- // Expression Parsing Callbacks.
- //===--------------------------------------------------------------------===//
-
- // Primary Expressions.
-
- /// ActOnIdentifierExpr - Parse an identifier in expression context.
- /// 'HasTrailingLParen' indicates whether or not the identifier has a '('
- /// token immediately after it.
- virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
- IdentifierInfo &II,
- bool HasTrailingLParen) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc,
- tok::TokenKind Kind) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnCharacterConstant(const Token &) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnNumericConstant(const Token &) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// ActOnStringLiteral - The specified tokens were lexed as pasted string
- /// fragments (e.g. "foo" "bar" L"baz").
- virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
- ExprTy *Val) {
- llvm::cout << __FUNCTION__ << "\n";
- return Val; // Default impl returns operand.
- }
-
- // Postfix Expressions.
- virtual ExprResult ActOnPostfixUnaryOp(SourceLocation OpLoc,
- tok::TokenKind Kind, ExprTy *Input) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual ExprResult ActOnArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
- ExprTy *Idx, SourceLocation RLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation MemberLoc,
- IdentifierInfo &Member) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
- /// This provides the location of the left/right parens and a list of comma
- /// locations. There are guaranteed to be one fewer commas than arguments,
- /// unless there are zero arguments.
- virtual ExprResult ActOnCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
- ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- // Unary Operators. 'Tok' is the token for the operator.
- virtual ExprResult ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
- ExprTy *Input) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual ExprResult
- ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
- SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnCompoundLiteral(SourceLocation LParen, TypeTy *Ty,
- SourceLocation RParen, ExprTy *Op) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual ExprResult ActOnInitList(SourceLocation LParenLoc,
- ExprTy **InitList, unsigned NumInit,
- SourceLocation RParenLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- virtual ExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprTy *Op) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
- ExprTy *LHS, ExprTy *RHS) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
- /// in the case of a the GNU conditional expr extension.
- virtual ExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
- SourceLocation ColonLoc,
- ExprTy *Cond, ExprTy *LHS, ExprTy *RHS){
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- //===---------------------- GNU Extension Expressions -------------------===//
-
- virtual ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
- IdentifierInfo *LabelII) { // "&&foo"
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
- SourceLocation RPLoc) { // "({..})"
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- virtual ExprResult ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
- SourceLocation TypeLoc, TypeTy *Arg1,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RParenLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
- // __builtin_types_compatible_p(type1, type2)
- virtual ExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1, TypeTy *arg2,
- SourceLocation RPLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- // __builtin_choose_expr(constExpr, expr1, expr2)
- virtual ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
- ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
- SourceLocation RPLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- // __builtin_overload(...)
- virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation BuiltinLoc,
- SourceLocation RPLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
-
-
- // __builtin_va_arg(expr, type)
- virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
- ExprTy *expr, TypeTy *type,
- SourceLocation RPLoc) {
- llvm::cout << __FUNCTION__ << "\n";
- return 0;
- }
- };
-}
-
-MinimalAction *clang::CreatePrintParserActionsAction(IdentifierTable &IT) {
- return new ParserPrintActions(IT);
-}
diff --git a/clang/Driver/PrintPreprocessedOutput.cpp b/clang/Driver/PrintPreprocessedOutput.cpp
deleted file mode 100644
index 570b36b6942f..000000000000
--- a/clang/Driver/PrintPreprocessedOutput.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This code simply runs the preprocessor on the input file and prints out the
-// result. This is the traditional behavior of the -E option.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/Pragma.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/System/Path.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Config/config.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Preprocessed token printer
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<bool>
-DisableLineMarkers("P", llvm::cl::desc("Disable linemarker output in -E mode"));
-static llvm::cl::opt<bool>
-EnableCommentOutput("C", llvm::cl::desc("Enable comment output in -E mode"));
-static llvm::cl::opt<bool>
-EnableMacroCommentOutput("CC",
- llvm::cl::desc("Enable comment output in -E mode, "
- "even from macro expansions"));
-
-namespace {
-class PrintPPOutputPPCallbacks : public PPCallbacks {
- Preprocessor &PP;
-public:
- llvm::raw_ostream &OS;
-private:
- unsigned CurLine;
- bool EmittedTokensOnThisLine;
- SrcMgr::Characteristic_t FileType;
- llvm::SmallString<512> CurFilename;
- bool Initialized;
-public:
- PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os)
- : PP(pp), OS(os) {
- CurLine = 0;
- CurFilename += "<uninit>";
- EmittedTokensOnThisLine = false;
- FileType = SrcMgr::C_User;
- Initialized = false;
- }
-
- void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
- bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
-
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::Characteristic_t FileType);
- virtual void Ident(SourceLocation Loc, const std::string &str);
-
-
- bool HandleFirstTokOnLine(Token &Tok);
- bool MoveToLine(SourceLocation Loc);
- bool AvoidConcat(const Token &PrevTok, const Token &Tok);
- void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
-};
-} // end anonymous namespace
-
-void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
- const char *Extra,
- unsigned ExtraLen) {
- if (EmittedTokensOnThisLine) {
- OS << '\n';
- EmittedTokensOnThisLine = false;
- }
-
- OS << '#' << ' ' << LineNo << ' ' << '"';
- OS.write(&CurFilename[0], CurFilename.size());
- OS << '"';
-
- if (ExtraLen)
- OS.write(Extra, ExtraLen);
-
- if (FileType == SrcMgr::C_System)
- OS.write(" 3", 2);
- else if (FileType == SrcMgr::C_ExternCSystem)
- OS.write(" 3 4", 4);
- OS << '\n';
-}
-
-/// MoveToLine - Move the output to the source line specified by the location
-/// object. We can do this by emitting some number of \n's, or be emitting a
-/// #line directive. This returns false if already at the specified line, true
-/// if some newlines were emitted.
-bool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) {
- unsigned LineNo = PP.getSourceManager().getLogicalLineNumber(Loc);
-
- if (DisableLineMarkers) {
- if (LineNo == CurLine) return false;
-
- CurLine = LineNo;
-
- if (!EmittedTokensOnThisLine)
- return true;
-
- OS << '\n';
- EmittedTokensOnThisLine = false;
- return true;
- }
-
- // If this line is "close enough" to the original line, just print newlines,
- // otherwise print a #line directive.
- if (LineNo-CurLine <= 8) {
- if (LineNo-CurLine == 1)
- OS << '\n';
- else if (LineNo == CurLine)
- return false; // Phys line moved, but logical line didn't.
- else {
- const char *NewLines = "\n\n\n\n\n\n\n\n";
- OS.write(NewLines, LineNo-CurLine);
- }
- } else {
- WriteLineInfo(LineNo, 0, 0);
- }
-
- CurLine = LineNo;
- return true;
-}
-
-
-/// FileChanged - Whenever the preprocessor enters or exits a #include file
-/// it invokes this handler. Update our conception of the current source
-/// position.
-void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
- FileChangeReason Reason,
- SrcMgr::Characteristic_t NewFileType) {
- // Unless we are exiting a #include, make sure to skip ahead to the line the
- // #include directive was at.
- SourceManager &SourceMgr = PP.getSourceManager();
- if (Reason == PPCallbacks::EnterFile) {
- MoveToLine(SourceMgr.getIncludeLoc(Loc));
- } else if (Reason == PPCallbacks::SystemHeaderPragma) {
- MoveToLine(Loc);
-
- // TODO GCC emits the # directive for this directive on the line AFTER the
- // directive and emits a bunch of spaces that aren't needed. Emulate this
- // strange behavior.
- }
-
- Loc = SourceMgr.getLogicalLoc(Loc);
- CurLine = SourceMgr.getLineNumber(Loc);
-
- if (DisableLineMarkers) return;
-
- CurFilename.clear();
- CurFilename += SourceMgr.getSourceName(Loc);
- Lexer::Stringify(CurFilename);
- FileType = NewFileType;
-
- if (!Initialized) {
- WriteLineInfo(CurLine);
- Initialized = true;
- }
-
- switch (Reason) {
- case PPCallbacks::EnterFile:
- WriteLineInfo(CurLine, " 1", 2);
- break;
- case PPCallbacks::ExitFile:
- WriteLineInfo(CurLine, " 2", 2);
- break;
- case PPCallbacks::SystemHeaderPragma:
- case PPCallbacks::RenameFile:
- WriteLineInfo(CurLine);
- break;
- }
-}
-
-/// HandleIdent - Handle #ident directives when read by the preprocessor.
-///
-void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
- MoveToLine(Loc);
-
- OS.write("#ident ", strlen("#ident "));
- OS.write(&S[0], S.size());
- EmittedTokensOnThisLine = true;
-}
-
-/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
-/// is called for the first token on each new line. If this really is the start
-/// of a new logical line, handle it and return true, otherwise return false.
-/// This may not be the start of a logical line because the "start of line"
-/// marker is set for physical lines, not logical ones.
-bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
- // Figure out what line we went to and insert the appropriate number of
- // newline characters.
- if (!MoveToLine(Tok.getLocation()))
- return false;
-
- // Print out space characters so that the first token on a line is
- // indented for easy reading.
- const SourceManager &SourceMgr = PP.getSourceManager();
- unsigned ColNo = SourceMgr.getLogicalColumnNumber(Tok.getLocation());
-
- // This hack prevents stuff like:
- // #define HASH #
- // HASH define foo bar
- // From having the # character end up at column 1, which makes it so it
- // is not handled as a #define next time through the preprocessor if in
- // -fpreprocessed mode.
- if (ColNo <= 1 && Tok.is(tok::hash))
- OS << ' ';
-
- // Otherwise, indent the appropriate number of spaces.
- for (; ColNo > 1; --ColNo)
- OS << ' ';
-
- return true;
-}
-
-namespace {
-struct UnknownPragmaHandler : public PragmaHandler {
- const char *Prefix;
- PrintPPOutputPPCallbacks *Callbacks;
-
- UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
- : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
- virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) {
- // Figure out what line we went to and insert the appropriate number of
- // newline characters.
- Callbacks->MoveToLine(PragmaTok.getLocation());
- Callbacks->OS.write(Prefix, strlen(Prefix));
-
- // Read and print all of the pragma tokens.
- while (PragmaTok.isNot(tok::eom)) {
- if (PragmaTok.hasLeadingSpace())
- Callbacks->OS << ' ';
- std::string TokSpell = PP.getSpelling(PragmaTok);
- Callbacks->OS.write(&TokSpell[0], TokSpell.size());
- PP.LexUnexpandedToken(PragmaTok);
- }
- Callbacks->OS << '\n';
- }
-};
-} // end anonymous namespace
-
-
-enum AvoidConcatInfo {
- /// By default, a token never needs to avoid concatenation. Most tokens (e.g.
- /// ',', ')', etc) don't cause a problem when concatenated.
- aci_never_avoid_concat = 0,
-
- /// aci_custom_firstchar - AvoidConcat contains custom code to handle this
- /// token's requirements, and it needs to know the first character of the
- /// token.
- aci_custom_firstchar = 1,
-
- /// aci_custom - AvoidConcat contains custom code to handle this token's
- /// requirements, but it doesn't need to know the first character of the
- /// token.
- aci_custom = 2,
-
- /// aci_avoid_equal - Many tokens cannot be safely followed by an '='
- /// character. For example, "<<" turns into "<<=" when followed by an =.
- aci_avoid_equal = 4
-};
-
-/// This array contains information for each token on what action to take when
-/// avoiding concatenation of tokens in the AvoidConcat method.
-static char TokenInfo[tok::NUM_TOKENS];
-
-/// InitAvoidConcatTokenInfo - Tokens that must avoid concatenation should be
-/// marked by this function.
-static void InitAvoidConcatTokenInfo() {
- // These tokens have custom code in AvoidConcat.
- TokenInfo[tok::identifier ] |= aci_custom;
- TokenInfo[tok::numeric_constant] |= aci_custom_firstchar;
- TokenInfo[tok::period ] |= aci_custom_firstchar;
- TokenInfo[tok::amp ] |= aci_custom_firstchar;
- TokenInfo[tok::plus ] |= aci_custom_firstchar;
- TokenInfo[tok::minus ] |= aci_custom_firstchar;
- TokenInfo[tok::slash ] |= aci_custom_firstchar;
- TokenInfo[tok::less ] |= aci_custom_firstchar;
- TokenInfo[tok::greater ] |= aci_custom_firstchar;
- TokenInfo[tok::pipe ] |= aci_custom_firstchar;
- TokenInfo[tok::percent ] |= aci_custom_firstchar;
- TokenInfo[tok::colon ] |= aci_custom_firstchar;
- TokenInfo[tok::hash ] |= aci_custom_firstchar;
- TokenInfo[tok::arrow ] |= aci_custom_firstchar;
-
- // These tokens change behavior if followed by an '='.
- TokenInfo[tok::amp ] |= aci_avoid_equal; // &=
- TokenInfo[tok::plus ] |= aci_avoid_equal; // +=
- TokenInfo[tok::minus ] |= aci_avoid_equal; // -=
- TokenInfo[tok::slash ] |= aci_avoid_equal; // /=
- TokenInfo[tok::less ] |= aci_avoid_equal; // <=
- TokenInfo[tok::greater ] |= aci_avoid_equal; // >=
- TokenInfo[tok::pipe ] |= aci_avoid_equal; // |=
- TokenInfo[tok::percent ] |= aci_avoid_equal; // %=
- TokenInfo[tok::star ] |= aci_avoid_equal; // *=
- TokenInfo[tok::exclaim ] |= aci_avoid_equal; // !=
- TokenInfo[tok::lessless ] |= aci_avoid_equal; // <<=
- TokenInfo[tok::greaterequal] |= aci_avoid_equal; // >>=
- TokenInfo[tok::caret ] |= aci_avoid_equal; // ^=
- TokenInfo[tok::equal ] |= aci_avoid_equal; // ==
-}
-
-/// StartsWithL - Return true if the spelling of this token starts with 'L'.
-static bool StartsWithL(const Token &Tok, Preprocessor &PP) {
- if (!Tok.needsCleaning()) {
- SourceManager &SrcMgr = PP.getSourceManager();
- return *SrcMgr.getCharacterData(SrcMgr.getPhysicalLoc(Tok.getLocation()))
- == 'L';
- }
-
- if (Tok.getLength() < 256) {
- char Buffer[256];
- const char *TokPtr = Buffer;
- PP.getSpelling(Tok, TokPtr);
- return TokPtr[0] == 'L';
- }
-
- return PP.getSpelling(Tok)[0] == 'L';
-}
-
-/// IsIdentifierL - Return true if the spelling of this token is literally 'L'.
-static bool IsIdentifierL(const Token &Tok, Preprocessor &PP) {
- if (!Tok.needsCleaning()) {
- if (Tok.getLength() != 1)
- return false;
- SourceManager &SrcMgr = PP.getSourceManager();
- return *SrcMgr.getCharacterData(SrcMgr.getPhysicalLoc(Tok.getLocation()))
- == 'L';
- }
-
- if (Tok.getLength() < 256) {
- char Buffer[256];
- const char *TokPtr = Buffer;
- if (PP.getSpelling(Tok, TokPtr) != 1)
- return false;
- return TokPtr[0] == 'L';
- }
-
- return PP.getSpelling(Tok) == "L";
-}
-
-
-/// AvoidConcat - If printing PrevTok immediately followed by Tok would cause
-/// the two individual tokens to be lexed as a single token, return true (which
-/// causes a space to be printed between them). This allows the output of -E
-/// mode to be lexed to the same token stream as lexing the input directly
-/// would.
-///
-/// This code must conservatively return true if it doesn't want to be 100%
-/// accurate. This will cause the output to include extra space characters, but
-/// the resulting output won't have incorrect concatenations going on. Examples
-/// include "..", which we print with a space between, because we don't want to
-/// track enough to tell "x.." from "...".
-bool PrintPPOutputPPCallbacks::AvoidConcat(const Token &PrevTok,
- const Token &Tok) {
- char Buffer[256];
-
- tok::TokenKind PrevKind = PrevTok.getKind();
- if (PrevTok.getIdentifierInfo()) // Language keyword or named operator.
- PrevKind = tok::identifier;
-
- // Look up information on when we should avoid concatenation with prevtok.
- unsigned ConcatInfo = TokenInfo[PrevKind];
-
- // If prevtok never causes a problem for anything after it, return quickly.
- if (ConcatInfo == 0) return false;
-
- if (ConcatInfo & aci_avoid_equal) {
- // If the next token is '=' or '==', avoid concatenation.
- if (Tok.is(tok::equal) || Tok.is(tok::equalequal))
- return true;
- ConcatInfo &= ~aci_avoid_equal;
- }
-
- if (ConcatInfo == 0) return false;
-
-
-
- // Basic algorithm: we look at the first character of the second token, and
- // determine whether it, if appended to the first token, would form (or would
- // contribute) to a larger token if concatenated.
- char FirstChar = 0;
- if (ConcatInfo & aci_custom) {
- // If the token does not need to know the first character, don't get it.
- } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
- // Avoid spelling identifiers, the most common form of token.
- FirstChar = II->getName()[0];
- } else if (!Tok.needsCleaning()) {
- SourceManager &SrcMgr = PP.getSourceManager();
- FirstChar =
- *SrcMgr.getCharacterData(SrcMgr.getPhysicalLoc(Tok.getLocation()));
- } else if (Tok.getLength() < 256) {
- const char *TokPtr = Buffer;
- PP.getSpelling(Tok, TokPtr);
- FirstChar = TokPtr[0];
- } else {
- FirstChar = PP.getSpelling(Tok)[0];
- }
-
- switch (PrevKind) {
- default: assert(0 && "InitAvoidConcatTokenInfo built wrong");
- case tok::identifier: // id+id or id+number or id+L"foo".
- if (Tok.is(tok::numeric_constant) || Tok.getIdentifierInfo() ||
- Tok.is(tok::wide_string_literal) /* ||
- Tok.is(tok::wide_char_literal)*/)
- return true;
-
- // If this isn't identifier + string, we're done.
- if (Tok.isNot(tok::char_constant) && Tok.isNot(tok::string_literal))
- return false;
-
- // FIXME: need a wide_char_constant!
-
- // If the string was a wide string L"foo" or wide char L'f', it would concat
- // with the previous identifier into fooL"bar". Avoid this.
- if (StartsWithL(Tok, PP))
- return true;
-
- // Otherwise, this is a narrow character or string. If the *identifier* is
- // a literal 'L', avoid pasting L "foo" -> L"foo".
- return IsIdentifierL(PrevTok, PP);
- case tok::numeric_constant:
- return isalnum(FirstChar) || Tok.is(tok::numeric_constant) ||
- FirstChar == '+' || FirstChar == '-' || FirstChar == '.';
- case tok::period: // ..., .*, .1234
- return FirstChar == '.' || FirstChar == '*' || isdigit(FirstChar);
- case tok::amp: // &&
- return FirstChar == '&';
- case tok::plus: // ++
- return FirstChar == '+';
- case tok::minus: // --, ->, ->*
- return FirstChar == '-' || FirstChar == '>';
- case tok::slash: //, /*, //
- return FirstChar == '*' || FirstChar == '/';
- case tok::less: // <<, <<=, <:, <%
- return FirstChar == '<' || FirstChar == ':' || FirstChar == '%';
- case tok::greater: // >>, >>=
- return FirstChar == '>';
- case tok::pipe: // ||
- return FirstChar == '|';
- case tok::percent: // %>, %:
- return FirstChar == '>' || FirstChar == ':';
- case tok::colon: // ::, :>
- return FirstChar == ':' || FirstChar == '>';
- case tok::hash: // ##, #@, %:%:
- return FirstChar == '#' || FirstChar == '@' || FirstChar == '%';
- case tok::arrow: // ->*
- return FirstChar == '*';
- }
-}
-
-/// DoPrintPreprocessedInput - This implements -E mode.
-///
-void clang::DoPrintPreprocessedInput(Preprocessor &PP,
- const std::string &OutFile) {
- // Inform the preprocessor whether we want it to retain comments or not, due
- // to -C or -CC.
- PP.SetCommentRetentionState(EnableCommentOutput, EnableMacroCommentOutput);
- InitAvoidConcatTokenInfo();
-
-
- // Open the output buffer.
- std::string Err;
- llvm::raw_fd_ostream OS(OutFile.empty() ? "-" : OutFile.c_str(), Err);
- if (!Err.empty()) {
- fprintf(stderr, "%s\n", Err.c_str());
- exit(1);
- }
-
- OS.SetBufferSize(64*1024);
-
-
- Token Tok, PrevTok;
- char Buffer[256];
- PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(PP, OS);
- PP.setPPCallbacks(Callbacks);
-
- PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
- PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",Callbacks));
-
- // After we have configured the preprocessor, enter the main file.
-
- // Start parsing the specified input file.
- PP.EnterMainSourceFile();
-
- // Consume all of the tokens that come from the predefines buffer. Those
- // should not be emitted into the output and are guaranteed to be at the
- // start.
- const SourceManager &SourceMgr = PP.getSourceManager();
- do PP.Lex(Tok);
- while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
- !strcmp(SourceMgr.getSourceName(Tok.getLocation()), "<predefines>"));
-
- while (1) {
-
- // If this token is at the start of a line, emit newlines if needed.
- if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
- // done.
- } else if (Tok.hasLeadingSpace() ||
- // If we haven't emitted a token on this line yet, PrevTok isn't
- // useful to look at and no concatenation could happen anyway.
- (Callbacks->hasEmittedTokensOnThisLine() &&
- // Don't print "-" next to "-", it would form "--".
- Callbacks->AvoidConcat(PrevTok, Tok))) {
- OS << ' ';
- }
-
- if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
- const char *Str = II->getName();
- unsigned Len = Tok.needsCleaning() ? strlen(Str) : Tok.getLength();
- OS.write(Str, Len);
- } else if (Tok.getLength() < 256) {
- const char *TokPtr = Buffer;
- unsigned Len = PP.getSpelling(Tok, TokPtr);
- OS.write(TokPtr, Len);
- } else {
- std::string S = PP.getSpelling(Tok);
- OS.write(&S[0], S.size());
- }
- Callbacks->SetEmittedTokensOnThisLine();
-
- if (Tok.is(tok::eof)) break;
-
- PrevTok = Tok;
- PP.Lex(Tok);
- }
- OS << '\n';
-
- // Flush the ostream.
- OS.flush();
-
- // If an error occurred, remove the output file.
- if (PP.getDiagnostics().hasErrorOccurred() && !OutFile.empty())
- llvm::sys::Path(OutFile).eraseFromDisk();
-}
-
diff --git a/clang/Driver/RewriteBlocks.cpp b/clang/Driver/RewriteBlocks.cpp
deleted file mode 100644
index 83bc4280c89e..000000000000
--- a/clang/Driver/RewriteBlocks.cpp
+++ /dev/null
@@ -1,1114 +0,0 @@
-//===--- RewriteBlocks.cpp ----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Hacks and fun related to the closure rewriter.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTConsumers.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include <sstream>
-
-using namespace clang;
-using llvm::utostr;
-
-namespace {
-
-class RewriteBlocks : public ASTConsumer {
- Rewriter Rewrite;
- Diagnostic &Diags;
- const LangOptions &LangOpts;
- unsigned RewriteFailedDiag;
-
- ASTContext *Context;
- SourceManager *SM;
- unsigned MainFileID;
- const char *MainFileStart, *MainFileEnd;
-
- // Block expressions.
- llvm::SmallVector<BlockExpr *, 32> Blocks;
- llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
- llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
-
- // Block related declarations.
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
- llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
-
- llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
-
- // The function/method we are rewriting.
- FunctionDecl *CurFunctionDef;
- ObjCMethodDecl *CurMethodDef;
-
- bool IsHeader;
- std::string InFileName;
- std::string OutFileName;
-
- std::string Preamble;
-public:
- RewriteBlocks(std::string inFile, std::string outFile, Diagnostic &D,
- const LangOptions &LOpts);
- ~RewriteBlocks() {
- // Get the buffer corresponding to MainFileID.
- // If we haven't changed it, then we are done.
- if (const RewriteBuffer *RewriteBuf =
- Rewrite.getRewriteBufferFor(MainFileID)) {
- std::string S(RewriteBuf->begin(), RewriteBuf->end());
- printf("%s\n", S.c_str());
- } else {
- printf("No changes\n");
- }
- }
-
- void Initialize(ASTContext &context);
-
- void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen);
- void ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength);
-
- // Top Level Driver code.
- virtual void HandleTopLevelDecl(Decl *D);
- void HandleDeclInMainFile(Decl *D);
-
- // Top level
- Stmt *RewriteFunctionBody(Stmt *S);
- void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
- void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
-
- // Block specific rewrite rules.
- std::string SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD=0);
-
- void RewriteBlockCall(CallExpr *Exp);
- void RewriteBlockPointerDecl(NamedDecl *VD);
- void RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
- void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
-
- std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
- const char *funcName, std::string Tag);
- std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
- const char *funcName, std::string Tag);
- std::string SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
- bool hasCopyDisposeHelpers);
- std::string SynthesizeBlockCall(CallExpr *Exp);
- void SynthesizeBlockLiterals(SourceLocation FunLocStart,
- const char *FunName);
-
- void CollectBlockDeclRefInfo(BlockExpr *Exp);
- void GetBlockCallExprs(Stmt *S);
- void GetBlockDeclRefExprs(Stmt *S);
-
- // We avoid calling Type::isBlockPointerType(), since it operates on the
- // canonical type. We only care if the top-level type is a closure pointer.
- bool isBlockPointerType(QualType T) { return isa<BlockPointerType>(T); }
-
- // FIXME: This predicate seems like it would be useful to add to ASTContext.
- bool isObjCType(QualType T) {
- if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
- return false;
-
- QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
-
- if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
- OCT == Context->getCanonicalType(Context->getObjCClassType()))
- return true;
-
- if (const PointerType *PT = OCT->getAsPointerType()) {
- if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
- isa<ObjCQualifiedIdType>(PT->getPointeeType()))
- return true;
- }
- return false;
- }
- // ObjC rewrite methods.
- void RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl);
- void RewriteCategoryDecl(ObjCCategoryDecl *CatDecl);
- void RewriteProtocolDecl(ObjCProtocolDecl *PDecl);
- void RewriteMethodDecl(ObjCMethodDecl *MDecl);
-
- bool BlockPointerTypeTakesAnyBlockArguments(QualType QT);
- void GetExtentOfArgList(const char *Name, const char *&LParen, const char *&RParen);
-};
-
-}
-
-static bool IsHeaderFile(const std::string &Filename) {
- std::string::size_type DotPos = Filename.rfind('.');
-
- if (DotPos == std::string::npos) {
- // no file extension
- return false;
- }
-
- std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
- // C header: .h
- // C++ header: .hh or .H;
- return Ext == "h" || Ext == "hh" || Ext == "H";
-}
-
-RewriteBlocks::RewriteBlocks(std::string inFile, std::string outFile,
- Diagnostic &D, const LangOptions &LOpts) :
- Diags(D), LangOpts(LOpts) {
- IsHeader = IsHeaderFile(inFile);
- InFileName = inFile;
- OutFileName = outFile;
- CurFunctionDef = 0;
- CurMethodDef = 0;
- RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning,
- "rewriting failed");
-}
-
-ASTConsumer *clang::CreateBlockRewriter(const std::string& InFile,
- const std::string& OutFile,
- Diagnostic &Diags,
- const LangOptions &LangOpts) {
- return new RewriteBlocks(InFile, OutFile, Diags, LangOpts);
-}
-
-void RewriteBlocks::Initialize(ASTContext &context) {
- Context = &context;
- SM = &Context->getSourceManager();
-
- // Get the ID and start/end of the main file.
- MainFileID = SM->getMainFileID();
- const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
- MainFileStart = MainBuf->getBufferStart();
- MainFileEnd = MainBuf->getBufferEnd();
-
- Rewrite.setSourceMgr(Context->getSourceManager());
-
- if (IsHeader)
- Preamble = "#pragma once\n";
- Preamble += "#ifndef BLOCK_IMPL\n";
- Preamble += "#define BLOCK_IMPL\n";
- Preamble += "struct __block_impl {\n";
- Preamble += " void *isa;\n";
- Preamble += " int Flags;\n";
- Preamble += " int Size;\n";
- Preamble += " void *FuncPtr;\n";
- Preamble += "};\n";
- Preamble += "enum {\n";
- Preamble += " BLOCK_HAS_COPY_DISPOSE = (1<<25),\n";
- Preamble += " BLOCK_IS_GLOBAL = (1<<28)\n";
- Preamble += "};\n";
- if (LangOpts.Microsoft)
- Preamble += "#define __OBJC_RW_EXTERN extern \"C\" __declspec(dllimport)\n";
- else
- Preamble += "#define __OBJC_RW_EXTERN extern\n";
- Preamble += "// Runtime copy/destroy helper functions\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_copy_assign(void *, void *);\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_byref_assign_copy(void *, void *);\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_destroy(void *);\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_byref_release(void *);\n";
- Preamble += "__OBJC_RW_EXTERN void *_NSConcreteGlobalBlock;\n";
- Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n";
- Preamble += "#endif\n";
-
- InsertText(SourceLocation::getFileLoc(MainFileID, 0),
- Preamble.c_str(), Preamble.size());
-}
-
-void RewriteBlocks::InsertText(SourceLocation Loc, const char *StrData,
- unsigned StrLen)
-{
- if (!Rewrite.InsertText(Loc, StrData, StrLen))
- return;
- Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
-}
-
-void RewriteBlocks::ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
- if (!Rewrite.ReplaceText(Start, OrigLength, NewStr, NewLength))
- return;
- Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
-}
-
-void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl *Method) {
- bool haveBlockPtrs = false;
- for (ObjCMethodDecl::param_iterator I = Method->param_begin(),
- E = Method->param_end(); I != E; ++I)
- if (isBlockPointerType((*I)->getType()))
- haveBlockPtrs = true;
-
- if (!haveBlockPtrs)
- return;
-
- // Do a fuzzy rewrite.
- // We have 1 or more arguments that have closure pointers.
- SourceLocation Loc = Method->getLocStart();
- SourceLocation LocEnd = Method->getLocEnd();
- const char *startBuf = SM->getCharacterData(Loc);
- const char *endBuf = SM->getCharacterData(LocEnd);
-
- const char *methodPtr = startBuf;
- std::string Tag = "struct __block_impl *";
-
- while (*methodPtr++ && (methodPtr != endBuf)) {
- switch (*methodPtr) {
- case ':':
- methodPtr++;
- if (*methodPtr == '(') {
- const char *scanType = ++methodPtr;
- bool foundBlockPointer = false;
- unsigned parenCount = 1;
-
- while (parenCount) {
- switch (*scanType) {
- case '(':
- parenCount++;
- break;
- case ')':
- parenCount--;
- break;
- case '^':
- foundBlockPointer = true;
- break;
- }
- scanType++;
- }
- if (foundBlockPointer) {
- // advance the location to startArgList.
- Loc = Loc.getFileLocWithOffset(methodPtr-startBuf);
- assert((Loc.isValid()) && "Invalid Loc");
- ReplaceText(Loc, scanType-methodPtr-1, Tag.c_str(), Tag.size());
-
- // Advance startBuf. Since the underlying buffer has changed,
- // it's very important to advance startBuf (so we can correctly
- // compute a relative Loc the next time around).
- startBuf = methodPtr;
- }
- // Advance the method ptr to the end of the type.
- methodPtr = scanType;
- }
- break;
- }
- }
- return;
-}
-
-void RewriteBlocks::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
- for (ObjCInterfaceDecl::instmeth_iterator I = ClassDecl->instmeth_begin(),
- E = ClassDecl->instmeth_end(); I != E; ++I)
- RewriteMethodDecl(*I);
- for (ObjCInterfaceDecl::classmeth_iterator I = ClassDecl->classmeth_begin(),
- E = ClassDecl->classmeth_end(); I != E; ++I)
- RewriteMethodDecl(*I);
-}
-
-void RewriteBlocks::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
- for (ObjCCategoryDecl::instmeth_iterator I = CatDecl->instmeth_begin(),
- E = CatDecl->instmeth_end(); I != E; ++I)
- RewriteMethodDecl(*I);
- for (ObjCCategoryDecl::classmeth_iterator I = CatDecl->classmeth_begin(),
- E = CatDecl->classmeth_end(); I != E; ++I)
- RewriteMethodDecl(*I);
-}
-
-void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
- E = PDecl->instmeth_end(); I != E; ++I)
- RewriteMethodDecl(*I);
- for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
- E = PDecl->classmeth_end(); I != E; ++I)
- RewriteMethodDecl(*I);
-}
-
-//===----------------------------------------------------------------------===//
-// Top Level Driver Code
-//===----------------------------------------------------------------------===//
-
-void RewriteBlocks::HandleTopLevelDecl(Decl *D) {
- // Two cases: either the decl could be in the main file, or it could be in a
- // #included file. If the former, rewrite it now. If the later, check to see
- // if we rewrote the #include/#import.
- SourceLocation Loc = D->getLocation();
- Loc = SM->getLogicalLoc(Loc);
-
- // If this is for a builtin, ignore it.
- if (Loc.isInvalid()) return;
-
- if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D))
- RewriteInterfaceDecl(MD);
- else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D))
- RewriteCategoryDecl(CD);
- else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
- RewriteProtocolDecl(PD);
-
- // If we have a decl in the main file, see if we should rewrite it.
- if (SM->getDecomposedFileLoc(Loc).first == MainFileID)
- HandleDeclInMainFile(D);
- return;
-}
-
-std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,
- const char *funcName,
- std::string Tag) {
- const FunctionType *AFT = CE->getFunctionType();
- QualType RT = AFT->getResultType();
- std::string StructRef = "struct " + Tag;
- std::string S = "static " + RT.getAsString() + " __" +
- funcName + "_" + "block_func_" + utostr(i);
-
- if (isa<FunctionTypeNoProto>(AFT)) {
- S += "()";
- } else if (CE->arg_empty()) {
- S += "(" + StructRef + " *__cself)";
- } else {
- const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
- assert(FT && "SynthesizeBlockFunc: No function proto");
- S += '(';
- // first add the implicit argument.
- S += StructRef + " *__cself, ";
- std::string ParamStr;
- for (BlockExpr::arg_iterator AI = CE->arg_begin(),
- E = CE->arg_end(); AI != E; ++AI) {
- if (AI != CE->arg_begin()) S += ", ";
- ParamStr = (*AI)->getName();
- (*AI)->getType().getAsStringInternal(ParamStr);
- S += ParamStr;
- }
- if (FT->isVariadic()) {
- if (!CE->arg_empty()) S += ", ";
- S += "...";
- }
- S += ')';
- }
- S += " {\n";
-
- // Create local declarations to avoid rewriting all closure decl ref exprs.
- // First, emit a declaration for all "by ref" decls.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- S += " ";
- std::string Name = (*I)->getName();
- Context->getPointerType((*I)->getType()).getAsStringInternal(Name);
- S += Name + " = __cself->" + (*I)->getName() + "; // bound by ref\n";
- }
- // Next, emit a declaration for all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- S += " ";
- std::string Name = (*I)->getName();
- // Handle nested closure invocation. For example:
- //
- // void (^myImportedClosure)(void);
- // myImportedClosure = ^(void) { setGlobalInt(x + y); };
- //
- // void (^anotherClosure)(void);
- // anotherClosure = ^(void) {
- // myImportedClosure(); // import and invoke the closure
- // };
- //
- if (isBlockPointerType((*I)->getType()))
- S += "struct __block_impl *";
- else
- (*I)->getType().getAsStringInternal(Name);
- S += Name + " = __cself->" + (*I)->getName() + "; // bound by copy\n";
- }
- std::string RewrittenStr = RewrittenBlockExprs[CE];
- const char *cstr = RewrittenStr.c_str();
- while (*cstr++ != '{') ;
- S += cstr;
- S += "\n";
- return S;
-}
-
-std::string RewriteBlocks::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
- const char *funcName,
- std::string Tag) {
- std::string StructRef = "struct " + Tag;
- std::string S = "static void __";
-
- S += funcName;
- S += "_block_copy_" + utostr(i);
- S += "(" + StructRef;
- S += "*dst, " + StructRef;
- S += "*src) {";
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
- E = ImportedBlockDecls.end(); I != E; ++I) {
- S += "_Block_copy_assign(&dst->";
- S += (*I)->getName();
- S += ", src->";
- S += (*I)->getName();
- S += ");}";
- }
- S += "\nstatic void __";
- S += funcName;
- S += "_block_dispose_" + utostr(i);
- S += "(" + StructRef;
- S += "*src) {";
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
- E = ImportedBlockDecls.end(); I != E; ++I) {
- S += "_Block_destroy(src->";
- S += (*I)->getName();
- S += ");";
- }
- S += "}\n";
- return S;
-}
-
-std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
- bool hasCopyDisposeHelpers) {
- std::string S = "struct " + Tag;
- std::string Constructor = " " + Tag;
-
- S += " {\n struct __block_impl impl;\n";
-
- if (hasCopyDisposeHelpers)
- S += " void *copy;\n void *dispose;\n";
-
- Constructor += "(void *fp";
-
- if (hasCopyDisposeHelpers)
- Constructor += ", void *copyHelp, void *disposeHelp";
-
- if (BlockDeclRefs.size()) {
- // Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- S += " ";
- std::string FieldName = (*I)->getName();
- std::string ArgName = "_" + FieldName;
- // Handle nested closure invocation. For example:
- //
- // void (^myImportedBlock)(void);
- // myImportedBlock = ^(void) { setGlobalInt(x + y); };
- //
- // void (^anotherBlock)(void);
- // anotherBlock = ^(void) {
- // myImportedBlock(); // import and invoke the closure
- // };
- //
- if (isBlockPointerType((*I)->getType())) {
- S += "struct __block_impl *";
- Constructor += ", void *" + ArgName;
- } else {
- (*I)->getType().getAsStringInternal(FieldName);
- (*I)->getType().getAsStringInternal(ArgName);
- Constructor += ", " + ArgName;
- }
- S += FieldName + ";\n";
- }
- // Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- S += " ";
- std::string FieldName = (*I)->getName();
- std::string ArgName = "_" + FieldName;
- // Handle nested closure invocation. For example:
- //
- // void (^myImportedBlock)(void);
- // myImportedBlock = ^(void) { setGlobalInt(x + y); };
- //
- // void (^anotherBlock)(void);
- // anotherBlock = ^(void) {
- // myImportedBlock(); // import and invoke the closure
- // };
- //
- if (isBlockPointerType((*I)->getType())) {
- S += "struct __block_impl *";
- Constructor += ", void *" + ArgName;
- } else {
- Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName);
- Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName);
- Constructor += ", " + ArgName;
- }
- S += FieldName + "; // by ref\n";
- }
- // Finish writing the constructor.
- // FIXME: handle NSConcreteGlobalBlock.
- Constructor += ", int flags=0) {\n";
- Constructor += " impl.isa = 0/*&_NSConcreteStackBlock*/;\n impl.Size = sizeof(";
- Constructor += Tag + ");\n impl.Flags = flags;\n impl.FuncPtr = fp;\n";
-
- if (hasCopyDisposeHelpers)
- Constructor += " copy = copyHelp;\n dispose = disposeHelp;\n";
-
- // Initialize all "by copy" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- std::string Name = (*I)->getName();
- Constructor += " ";
- if (isBlockPointerType((*I)->getType()))
- Constructor += Name + " = (struct __block_impl *)_";
- else
- Constructor += Name + " = _";
- Constructor += Name + ";\n";
- }
- // Initialize all "by ref" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- std::string Name = (*I)->getName();
- Constructor += " ";
- if (isBlockPointerType((*I)->getType()))
- Constructor += Name + " = (struct __block_impl *)_";
- else
- Constructor += Name + " = _";
- Constructor += Name + ";\n";
- }
- } else {
- // Finish writing the constructor.
- // FIXME: handle NSConcreteGlobalBlock.
- Constructor += ", int flags=0) {\n";
- Constructor += " impl.isa = 0/*&_NSConcreteStackBlock*/;\n impl.Size = sizeof(";
- Constructor += Tag + ");\n impl.Flags = flags;\n impl.FuncPtr = fp;\n";
- if (hasCopyDisposeHelpers)
- Constructor += " copy = copyHelp;\n dispose = disposeHelp;\n";
- }
- Constructor += " ";
- Constructor += "}\n";
- S += Constructor;
- S += "};\n";
- return S;
-}
-
-void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart,
- const char *FunName) {
- // Insert closures that were part of the function.
- for (unsigned i = 0; i < Blocks.size(); i++) {
-
- CollectBlockDeclRefInfo(Blocks[i]);
-
- std::string Tag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
-
- std::string CI = SynthesizeBlockImpl(Blocks[i], Tag,
- ImportedBlockDecls.size() > 0);
-
- InsertText(FunLocStart, CI.c_str(), CI.size());
-
- std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, Tag);
-
- InsertText(FunLocStart, CF.c_str(), CF.size());
-
- if (ImportedBlockDecls.size()) {
- std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, Tag);
- InsertText(FunLocStart, HF.c_str(), HF.size());
- }
-
- BlockDeclRefs.clear();
- BlockByRefDecls.clear();
- BlockByCopyDecls.clear();
- BlockCallExprs.clear();
- ImportedBlockDecls.clear();
- }
- Blocks.clear();
- RewrittenBlockExprs.clear();
-}
-
-void RewriteBlocks::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
- SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
- const char *FuncName = FD->getName();
-
- SynthesizeBlockLiterals(FunLocStart, FuncName);
-}
-
-void RewriteBlocks::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
- SourceLocation FunLocStart = MD->getLocStart();
- std::string FuncName = std::string(MD->getSelector().getName());
- // Convert colons to underscores.
- std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
-
- SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
-}
-
-
-void RewriteBlocks::GetBlockDeclRefExprs(Stmt *S) {
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI)
- GetBlockDeclRefExprs(*CI);
-
- // Handle specific things.
- if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S))
- // FIXME: Handle enums.
- if (!isa<FunctionDecl>(CDRE->getDecl()))
- BlockDeclRefs.push_back(CDRE);
- return;
-}
-
-void RewriteBlocks::GetBlockCallExprs(Stmt *S) {
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI)
- GetBlockCallExprs(*CI);
-
- if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
- if (CE->getCallee()->getType()->isBlockPointerType()) {
- BlockCallExprs[dyn_cast<BlockDeclRefExpr>(CE->getCallee())] = CE;
- }
- }
- return;
-}
-
-std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
- // Navigate to relevant type information.
- const char *closureName = 0;
- const BlockPointerType *CPT = 0;
-
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
- closureName = DRE->getDecl()->getName();
- CPT = DRE->getType()->getAsBlockPointerType();
- } else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
- closureName = CDRE->getDecl()->getName();
- CPT = CDRE->getType()->getAsBlockPointerType();
- } else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
- closureName = MExpr->getMemberDecl()->getName();
- CPT = MExpr->getType()->getAsBlockPointerType();
- } else {
- assert(1 && "RewriteBlockClass: Bad type");
- }
- assert(CPT && "RewriteBlockClass: Bad type");
- const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
- assert(FT && "RewriteBlockClass: Bad type");
- const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FT);
- // FTP will be null for closures that don't take arguments.
-
- // Build a closure call - start with a paren expr to enforce precedence.
- std::string BlockCall = "(";
-
- // Synthesize the cast.
- BlockCall += "(" + Exp->getType().getAsString() + "(*)";
- BlockCall += "(struct __block_impl *";
- if (FTP) {
- for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),
- E = FTP->arg_type_end(); I && (I != E); ++I)
- BlockCall += ", " + (*I).getAsString();
- }
- BlockCall += "))"; // close the argument list and paren expression.
-
- // Invoke the closure. We need to cast it since the declaration type is
- // bogus (it's a function pointer type)
- BlockCall += "((struct __block_impl *)";
- std::string closureExprBufStr;
- llvm::raw_string_ostream closureExprBuf(closureExprBufStr);
- Exp->getCallee()->printPretty(closureExprBuf);
- BlockCall += closureExprBuf.str();
- BlockCall += ")->FuncPtr)";
-
- // Add the arguments.
- BlockCall += "((struct __block_impl *)";
- BlockCall += closureExprBuf.str();
- for (CallExpr::arg_iterator I = Exp->arg_begin(),
- E = Exp->arg_end(); I != E; ++I) {
- std::string syncExprBufS;
- llvm::raw_string_ostream Buf(syncExprBufS);
- (*I)->printPretty(Buf);
- BlockCall += ", " + Buf.str();
- }
- return BlockCall;
-}
-
-void RewriteBlocks::RewriteBlockCall(CallExpr *Exp) {
- std::string BlockCall = SynthesizeBlockCall(Exp);
-
- const char *startBuf = SM->getCharacterData(Exp->getLocStart());
- const char *endBuf = SM->getCharacterData(Exp->getLocEnd());
-
- ReplaceText(Exp->getLocStart(), endBuf-startBuf,
- BlockCall.c_str(), BlockCall.size());
-}
-
-void RewriteBlocks::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
- // FIXME: Add more elaborate code generation required by the ABI.
- InsertText(BDRE->getLocStart(), "*", 1);
-}
-
-void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
- SourceLocation DeclLoc = FD->getLocation();
- unsigned parenCount = 0, nArgs = 0;
-
- // We have 1 or more arguments that have closure pointers.
- const char *startBuf = SM->getCharacterData(DeclLoc);
- const char *startArgList = strchr(startBuf, '(');
-
- assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
-
- parenCount++;
- // advance the location to startArgList.
- DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf+1);
- assert((DeclLoc.isValid()) && "Invalid DeclLoc");
-
- const char *topLevelCommaCursor = 0;
- const char *argPtr = startArgList;
- bool scannedBlockDecl = false;
- std::string Tag = "struct __block_impl *";
-
- while (*argPtr++ && parenCount) {
- switch (*argPtr) {
- case '^':
- scannedBlockDecl = true;
- break;
- case '(':
- parenCount++;
- break;
- case ')':
- parenCount--;
- if (parenCount == 0) {
- if (scannedBlockDecl) {
- // If we are rewriting a definition, don't forget the arg name.
- if (FD->getBody())
- Tag += FD->getParamDecl(nArgs)->getName();
- // The last argument is a closure pointer decl, rewrite it!
- if (topLevelCommaCursor)
- ReplaceText(DeclLoc, argPtr-topLevelCommaCursor-2, Tag.c_str(), Tag.size());
- else
- ReplaceText(DeclLoc, argPtr-startArgList-1, Tag.c_str(), Tag.size());
- scannedBlockDecl = false; // reset.
- }
- nArgs++;
- }
- break;
- case ',':
- if (parenCount == 1) {
- // Make sure the function takes more than one argument.
- assert((FD->getNumParams() > 1) && "Rewriter fuzzy parser confused");
- if (scannedBlockDecl) {
- // If we are rewriting a definition, don't forget the arg name.
- if (FD->getBody())
- Tag += FD->getParamDecl(nArgs)->getName();
- // The current argument is a closure pointer decl, rewrite it!
- if (topLevelCommaCursor)
- ReplaceText(DeclLoc, argPtr-topLevelCommaCursor-1, Tag.c_str(), Tag.size());
- else
- ReplaceText(DeclLoc, argPtr-startArgList-1, Tag.c_str(), Tag.size());
- scannedBlockDecl = false;
- }
- nArgs++;
- // advance the location to topLevelCommaCursor.
- if (topLevelCommaCursor)
- DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-topLevelCommaCursor);
- else
- DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList+1);
- topLevelCommaCursor = argPtr;
- assert((DeclLoc.isValid()) && "Invalid DeclLoc");
- }
- break;
- }
- }
- return;
-}
-
-bool RewriteBlocks::BlockPointerTypeTakesAnyBlockArguments(QualType QT) {
- const BlockPointerType *BPT = QT->getAsBlockPointerType();
- assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
- const FunctionTypeProto *FTP = BPT->getPointeeType()->getAsFunctionTypeProto();
- if (FTP) {
- for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),
- E = FTP->arg_type_end(); I != E; ++I)
- if (isBlockPointerType(*I))
- return true;
- }
- return false;
-}
-
-void RewriteBlocks::GetExtentOfArgList(const char *Name,
- const char *&LParen, const char *&RParen) {
- const char *argPtr = strchr(Name, '(');
- assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
-
- LParen = argPtr; // output the start.
- argPtr++; // skip past the left paren.
- unsigned parenCount = 1;
-
- while (*argPtr && parenCount) {
- switch (*argPtr) {
- case '(': parenCount++; break;
- case ')': parenCount--; break;
- default: break;
- }
- if (parenCount) argPtr++;
- }
- assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
- RParen = argPtr; // output the end
-}
-
-void RewriteBlocks::RewriteBlockPointerDecl(NamedDecl *ND) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
- RewriteBlockPointerFunctionArgs(FD);
- return;
- }
- // Handle Variables and Typedefs.
- SourceLocation DeclLoc = ND->getLocation();
- QualType DeclT;
- if (VarDecl *VD = dyn_cast<VarDecl>(ND))
- DeclT = VD->getType();
- else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
- DeclT = TDD->getUnderlyingType();
- else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
- DeclT = FD->getType();
- else
- assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
-
- const char *startBuf = SM->getCharacterData(DeclLoc);
- const char *endBuf = startBuf;
- // scan backward (from the decl location) for the end of the previous decl.
- while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
- startBuf--;
- assert((*startBuf == '^') &&
- "RewriteBlockPointerDecl() scan error: no caret");
- // Replace the '^' with '*', computing a negative offset.
- DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
- ReplaceText(DeclLoc, 1, "*", 1);
-
- if (BlockPointerTypeTakesAnyBlockArguments(DeclT)) {
- // Replace the '^' with '*' for arguments.
- DeclLoc = ND->getLocation();
- startBuf = SM->getCharacterData(DeclLoc);
- const char *argListBegin, *argListEnd;
- GetExtentOfArgList(startBuf, argListBegin, argListEnd);
- while (argListBegin < argListEnd) {
- if (*argListBegin == '^') {
- SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
- ReplaceText(CaretLoc, 1, "*", 1);
- }
- argListBegin++;
- }
- }
- return;
-}
-
-void RewriteBlocks::CollectBlockDeclRefInfo(BlockExpr *Exp) {
- // Add initializers for any closure decl refs.
- GetBlockDeclRefExprs(Exp);
- if (BlockDeclRefs.size()) {
- // Unique all "by copy" declarations.
- for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (!BlockDeclRefs[i]->isByRef())
- BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
- // Unique all "by ref" declarations.
- for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (BlockDeclRefs[i]->isByRef()) {
- BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
- }
- // Find any imported blocks...they will need special attention.
- for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (isBlockPointerType(BlockDeclRefs[i]->getType())) {
- GetBlockCallExprs(Blocks[i]);
- ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
- }
- }
-}
-
-std::string RewriteBlocks::SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD) {
- Blocks.push_back(Exp);
-
- CollectBlockDeclRefInfo(Exp);
- std::string FuncName;
-
- if (CurFunctionDef)
- FuncName = std::string(CurFunctionDef->getName());
- else if (CurMethodDef) {
- FuncName = std::string(CurMethodDef->getSelector().getName());
- // Convert colons to underscores.
- std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
- } else if (VD)
- FuncName = std::string(VD->getName());
-
- std::string BlockNumber = utostr(Blocks.size()-1);
-
- std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
- std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
-
- std::string FunkTypeStr;
-
- // Get a pointer to the function type so we can cast appropriately.
- Context->getPointerType(QualType(Exp->getFunctionType(),0)).getAsStringInternal(FunkTypeStr);
-
- // Rewrite the closure block with a compound literal. The first cast is
- // to prevent warnings from the C compiler.
- std::string Init = "(" + FunkTypeStr;
-
- Init += ")&" + Tag;
-
- // Initialize the block function.
- Init += "((void*)" + Func;
-
- if (ImportedBlockDecls.size()) {
- std::string Buf = "__" + FuncName + "_block_copy_" + BlockNumber;
- Init += ",(void*)" + Buf;
- Buf = "__" + FuncName + "_block_dispose_" + BlockNumber;
- Init += ",(void*)" + Buf;
- }
- // Add initializers for any closure decl refs.
- if (BlockDeclRefs.size()) {
- // Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- Init += ",";
- if (isObjCType((*I)->getType())) {
- Init += "[[";
- Init += (*I)->getName();
- Init += " retain] autorelease]";
- } else if (isBlockPointerType((*I)->getType())) {
- Init += "(void *)";
- Init += (*I)->getName();
- } else {
- Init += (*I)->getName();
- }
- }
- // Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- Init += ",&";
- Init += (*I)->getName();
- }
- }
- Init += ")";
- BlockDeclRefs.clear();
- BlockByRefDecls.clear();
- BlockByCopyDecls.clear();
- ImportedBlockDecls.clear();
-
- return Init;
-}
-
-//===----------------------------------------------------------------------===//
-// Function Body / Expression rewriting
-//===----------------------------------------------------------------------===//
-
-Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
- // Start by rewriting all children.
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
- Stmt *newStmt = RewriteFunctionBody(*CI);
- if (newStmt)
- *CI = newStmt;
-
- // We've just rewritten the block body in place.
- // Now we snarf the rewritten text and stash it away for later use.
- std::string S = Rewrite.getRewritenText(CBE->getSourceRange());
- RewrittenBlockExprs[CBE] = S;
- std::string Init = SynthesizeBlockInitExpr(CBE);
- // Do the rewrite, using S.size() which contains the rewritten size.
- ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
- } else {
- Stmt *newStmt = RewriteFunctionBody(*CI);
- if (newStmt)
- *CI = newStmt;
- }
- }
- // Handle specific things.
- if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
- if (CE->getCallee()->getType()->isBlockPointerType())
- RewriteBlockCall(CE);
- }
- if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
- for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
- DI != DE; ++DI) {
-
- ScopedDecl *SD = *DI;
- if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
- if (isBlockPointerType(ND->getType()))
- RewriteBlockPointerDecl(ND);
- }
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
- if (isBlockPointerType(TD->getUnderlyingType()))
- RewriteBlockPointerDecl(TD);
- }
- }
- }
- // Handle specific things.
- if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- if (BDRE->isByRef())
- RewriteBlockDeclRefExpr(BDRE);
- }
- // Return this stmt unmodified.
- return S;
-}
-
-/// HandleDeclInMainFile - This is called for each top-level decl defined in the
-/// main file of the input.
-void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-
- // Since function prototypes don't have ParmDecl's, we check the function
- // prototype. This enables us to rewrite function declarations and
- // definitions using the same code.
- QualType funcType = FD->getType();
-
- if (FunctionTypeProto *fproto = dyn_cast<FunctionTypeProto>(funcType)) {
- for (FunctionTypeProto::arg_type_iterator I = fproto->arg_type_begin(),
- E = fproto->arg_type_end(); I && (I != E); ++I)
- if (isBlockPointerType(*I)) {
- // All the args are checked/rewritten. Don't call twice!
- RewriteBlockPointerDecl(FD);
- break;
- }
- }
- if (Stmt *Body = FD->getBody()) {
- CurFunctionDef = FD;
- FD->setBody(RewriteFunctionBody(Body));
- // This synthesizes and inserts the block "impl" struct, invoke function,
- // and any copy/dispose helper functions.
- InsertBlockLiteralsWithinFunction(FD);
- CurFunctionDef = 0;
- }
- return;
- }
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- RewriteMethodDecl(MD);
- if (Stmt *Body = MD->getBody()) {
- CurMethodDef = MD;
- RewriteFunctionBody(Body);
- InsertBlockLiteralsWithinMethod(MD);
- CurMethodDef = 0;
- }
- }
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (isBlockPointerType(VD->getType())) {
- RewriteBlockPointerDecl(VD);
- if (VD->getInit()) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(VD->getInit())) {
- RewriteFunctionBody(VD->getInit());
-
- // We've just rewritten the block body in place.
- // Now we snarf the rewritten text and stash it away for later use.
- std::string S = Rewrite.getRewritenText(CBE->getSourceRange());
- RewrittenBlockExprs[CBE] = S;
- std::string Init = SynthesizeBlockInitExpr(CBE, VD);
- // Do the rewrite, using S.size() which contains the rewritten size.
- ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
- SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
- }
- }
- }
- return;
- }
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
- if (isBlockPointerType(TD->getUnderlyingType()))
- RewriteBlockPointerDecl(TD);
- return;
- }
- if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
- if (RD->isDefinition()) {
- for (RecordDecl::field_const_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- FieldDecl *FD = *i;
- if (isBlockPointerType(FD->getType()))
- RewriteBlockPointerDecl(FD);
- }
- }
- return;
- }
-}
diff --git a/clang/Driver/RewriteMacros.cpp b/clang/Driver/RewriteMacros.cpp
deleted file mode 100644
index 5106367839c5..000000000000
--- a/clang/Driver/RewriteMacros.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This code rewrites macro invocations into their expansions. This gives you
-// a macro expanded file that retains comments and #includes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/ADT/OwningPtr.h"
-using namespace clang;
-
-/// isSameToken - Return true if the two specified tokens start have the same
-/// content.
-static bool isSameToken(Token &RawTok, Token &PPTok) {
- // If two tokens have the same kind and the same identifier info, they are
- // obviously the same.
- if (PPTok.getKind() == RawTok.getKind() &&
- PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
- return true;
-
- // Otherwise, if they are different but have the same identifier info, they
- // are also considered to be the same. This allows keywords and raw lexed
- // identifiers with the same name to be treated the same.
- if (PPTok.getIdentifierInfo() &&
- PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
- return true;
-
- return false;
-}
-
-
-/// GetNextRawTok - Return the next raw token in the stream, skipping over
-/// comments if ReturnComment is false.
-static const Token &GetNextRawTok(const std::vector<Token> &RawTokens,
- unsigned &CurTok, bool ReturnComment) {
- assert(CurTok < RawTokens.size() && "Overran eof!");
-
- // If the client doesn't want comments and we have one, skip it.
- if (!ReturnComment && RawTokens[CurTok].is(tok::comment))
- ++CurTok;
-
- return RawTokens[CurTok++];
-}
-
-
-/// LexRawTokensFromMainFile - Lets all the raw tokens from the main file into
-/// the specified vector.
-static void LexRawTokensFromMainFile(Preprocessor &PP,
- std::vector<Token> &RawTokens) {
- SourceManager &SM = PP.getSourceManager();
- std::pair<const char*,const char*> File =SM.getBufferData(SM.getMainFileID());
-
- // Create a lexer to lex all the tokens of the main file in raw mode. Even
- // though it is in raw mode, it will not return comments.
- Lexer RawLex(SourceLocation::getFileLoc(SM.getMainFileID(), 0),
- PP.getLangOptions(), File.first, File.second);
-
- // Switch on comment lexing because we really do want them.
- RawLex.SetCommentRetentionState(true);
-
- Token RawTok;
- do {
- RawLex.LexRawToken(RawTok);
-
- // If we have an identifier with no identifier info for our raw token, look
- // up the indentifier info. This is important for equality comparison of
- // identifier tokens.
- if (RawTok.is(tok::identifier) && !RawTok.getIdentifierInfo())
- RawTok.setIdentifierInfo(PP.LookUpIdentifierInfo(RawTok));
-
- RawTokens.push_back(RawTok);
- } while (RawTok.isNot(tok::eof));
-}
-
-
-/// RewriteMacrosInInput - Implement -rewrite-macros mode.
-void clang::RewriteMacrosInInput(Preprocessor &PP,const std::string &InFileName,
- const std::string &OutFileName) {
- SourceManager &SM = PP.getSourceManager();
-
- Rewriter Rewrite;
- Rewrite.setSourceMgr(SM);
- RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());
-
- std::vector<Token> RawTokens;
- LexRawTokensFromMainFile(PP, RawTokens);
- unsigned CurRawTok = 0;
- Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
-
-
- // Get the first preprocessing token.
- PP.EnterMainSourceFile();
- Token PPTok;
- PP.Lex(PPTok);
-
- // Preprocess the input file in parallel with raw lexing the main file. Ignore
- // all tokens that are preprocessed from a file other than the main file (e.g.
- // a header). If we see tokens that are in the preprocessed file but not the
- // lexed file, we have a macro expansion. If we see tokens in the lexed file
- // that aren't in the preprocessed view, we have macros that expand to no
- // tokens, or macro arguments etc.
- while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) {
- SourceLocation PPLoc = SM.getLogicalLoc(PPTok.getLocation());
-
- // If PPTok is from a different source file, ignore it.
- if (!SM.isFromMainFile(PPLoc)) {
- PP.Lex(PPTok);
- continue;
- }
-
- // If the raw file hits a preprocessor directive, they will be extra tokens
- // in the raw file that don't exist in the preprocsesed file. However, we
- // choose to preserve them in the output file and otherwise handle them
- // specially.
- if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
- // If this is a #warning directive or #pragma mark (GNU extensions),
- // comment the line out.
- if (RawTokens[CurRawTok].is(tok::identifier)) {
- const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo();
- if (!strcmp(II->getName(), "warning")) {
- // Comment out #warning.
- RB.InsertTextAfter(SM.getFullFilePos(RawTok.getLocation()), "//", 2);
- } else if (!strcmp(II->getName(), "pragma") &&
- RawTokens[CurRawTok+1].is(tok::identifier) &&
- !strcmp(RawTokens[CurRawTok+1].getIdentifierInfo()->getName(),
- "mark")){
- // Comment out #pragma mark.
- RB.InsertTextAfter(SM.getFullFilePos(RawTok.getLocation()), "//", 2);
- }
- }
-
- // Otherwise, if this is a #include or some other directive, just leave it
- // in the file by skipping over the line.
- RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
- while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
- RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
- continue;
- }
-
- // Okay, both tokens are from the same file. Get their offsets from the
- // start of the file.
- unsigned PPOffs = SM.getFullFilePos(PPLoc);
- unsigned RawOffs = SM.getFullFilePos(RawTok.getLocation());
-
- // If the offsets are the same and the token kind is the same, ignore them.
- if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) {
- RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
- PP.Lex(PPTok);
- continue;
- }
-
- // If the PP token is farther along than the raw token, something was
- // deleted. Comment out the raw token.
- if (RawOffs <= PPOffs) {
- // Comment out a whole run of tokens instead of bracketing each one with
- // comments. Add a leading space if RawTok didn't have one.
- bool HasSpace = RawTok.hasLeadingSpace();
- RB.InsertTextAfter(RawOffs, " /*"+HasSpace, 2+!HasSpace);
- unsigned EndPos;
-
- do {
- EndPos = RawOffs+RawTok.getLength();
-
- RawTok = GetNextRawTok(RawTokens, CurRawTok, true);
- RawOffs = SM.getFullFilePos(RawTok.getLocation());
-
- if (RawTok.is(tok::comment)) {
- // Skip past the comment.
- RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
- break;
- }
-
- } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
- (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));
-
- RB.InsertTextBefore(EndPos, "*/", 2);
- continue;
- }
-
- // Otherwise, there was a replacement an expansion. Insert the new token
- // in the output buffer. Insert the whole run of new tokens at once to get
- // them in the right order.
- unsigned InsertPos = PPOffs;
- std::string Expansion;
- while (PPOffs < RawOffs) {
- Expansion += ' ' + PP.getSpelling(PPTok);
- PP.Lex(PPTok);
- PPLoc = SM.getLogicalLoc(PPTok.getLocation());
- PPOffs = SM.getFullFilePos(PPLoc);
- }
- Expansion += ' ';
- RB.InsertTextBefore(InsertPos, &Expansion[0], Expansion.size());
- }
-
- // Create the output file.
- llvm::OwningPtr<llvm::raw_ostream> OwnedStream;
- llvm::raw_ostream *OutFile;
- if (OutFileName == "-") {
- OutFile = &llvm::outs();
- } else if (!OutFileName.empty()) {
- std::string Err;
- OutFile = new llvm::raw_fd_ostream(OutFileName.c_str(), Err);
- OwnedStream.reset(OutFile);
- } else if (InFileName == "-") {
- OutFile = &llvm::outs();
- } else {
- llvm::sys::Path Path(InFileName);
- Path.eraseSuffix();
- Path.appendSuffix("cpp");
- std::string Err;
- OutFile = new llvm::raw_fd_ostream(Path.toString().c_str(), Err);
- OwnedStream.reset(OutFile);
- }
-
- // Get the buffer corresponding to MainFileID. If we haven't changed it, then
- // we are done.
- if (const RewriteBuffer *RewriteBuf =
- Rewrite.getRewriteBufferFor(SM.getMainFileID())) {
- //printf("Changed:\n");
- *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
- } else {
- fprintf(stderr, "No changes\n");
- }
- OutFile->flush();
-}
diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp
deleted file mode 100644
index 316c1761eabe..000000000000
--- a/clang/Driver/RewriteObjC.cpp
+++ /dev/null
@@ -1,3236 +0,0 @@
-//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Hacks and fun related to the code rewriter.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTConsumers.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/TranslationUnit.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Lex/Lexer.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-using namespace clang;
-using llvm::utostr;
-
-static llvm::cl::opt<bool>
-SilenceRewriteMacroWarning("Wno-rewrite-macros", llvm::cl::init(false),
- llvm::cl::desc("Silence ObjC rewriting warnings"));
-
-namespace {
- class RewriteObjC : public ASTConsumer {
- Rewriter Rewrite;
- Diagnostic &Diags;
- const LangOptions &LangOpts;
- unsigned RewriteFailedDiag;
-
- ASTContext *Context;
- SourceManager *SM;
- TranslationUnitDecl *TUDecl;
- unsigned MainFileID;
- const char *MainFileStart, *MainFileEnd;
- SourceLocation LastIncLoc;
-
- llvm::SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
- llvm::SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
- llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
- llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
- llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
- llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
- llvm::SmallVector<Stmt *, 32> Stmts;
- llvm::SmallVector<int, 8> ObjCBcLabelNo;
- llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
-
- unsigned NumObjCStringLiterals;
-
- FunctionDecl *MsgSendFunctionDecl;
- FunctionDecl *MsgSendSuperFunctionDecl;
- FunctionDecl *MsgSendStretFunctionDecl;
- FunctionDecl *MsgSendSuperStretFunctionDecl;
- FunctionDecl *MsgSendFpretFunctionDecl;
- FunctionDecl *GetClassFunctionDecl;
- FunctionDecl *GetMetaClassFunctionDecl;
- FunctionDecl *SelGetUidFunctionDecl;
- FunctionDecl *CFStringFunctionDecl;
- FunctionDecl *GetProtocolFunctionDecl;
- FunctionDecl *SuperContructorFunctionDecl;
-
- // ObjC string constant support.
- VarDecl *ConstantStringClassReference;
- RecordDecl *NSStringRecord;
-
- // ObjC foreach break/continue generation support.
- int BcLabelCount;
-
- // Needed for super.
- ObjCMethodDecl *CurMethodDecl;
- RecordDecl *SuperStructDecl;
- RecordDecl *ConstantStringDecl;
-
- // Needed for header files being rewritten
- bool IsHeader;
-
- std::string InFileName;
- std::string OutFileName;
-
- std::string Preamble;
-
- static const int OBJC_ABI_VERSION =7 ;
- public:
- virtual void Initialize(ASTContext &context);
-
- virtual void InitializeTU(TranslationUnit &TU) {
- TU.SetOwnsDecls(false);
- Initialize(TU.getContext());
- }
-
-
- // Top Level Driver code.
- virtual void HandleTopLevelDecl(Decl *D);
- void HandleDeclInMainFile(Decl *D);
- RewriteObjC(std::string inFile, std::string outFile,
- Diagnostic &D, const LangOptions &LOpts);
-
- ~RewriteObjC() {}
-
- virtual void HandleTranslationUnit(TranslationUnit& TU);
-
- void ReplaceStmt(Stmt *Old, Stmt *New) {
- // If replacement succeeded or warning disabled return with no warning.
- if (!Rewrite.ReplaceStmt(Old, New) || SilenceRewriteMacroWarning)
- return;
-
- SourceRange Range = Old->getSourceRange();
- Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag,
- 0, 0, &Range, 1);
- }
-
- void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen,
- bool InsertAfter = true) {
- // If insertion succeeded or warning disabled return with no warning.
- if (!Rewrite.InsertText(Loc, StrData, StrLen, InsertAfter) ||
- SilenceRewriteMacroWarning)
- return;
-
- Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
- }
-
- void RemoveText(SourceLocation Loc, unsigned StrLen) {
- // If removal succeeded or warning disabled return with no warning.
- if (!Rewrite.RemoveText(Loc, StrLen) || SilenceRewriteMacroWarning)
- return;
-
- Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
- }
-
- void ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
- // If removal succeeded or warning disabled return with no warning.
- if (!Rewrite.ReplaceText(Start, OrigLength, NewStr, NewLength) ||
- SilenceRewriteMacroWarning)
- return;
-
- Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
- }
-
- // Syntactic Rewriting.
- void RewritePrologue(SourceLocation Loc);
- void RewriteInclude();
- void RewriteTabs();
- void RewriteForwardClassDecl(ObjCClassDecl *Dcl);
- void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
- void RewriteImplementationDecl(NamedDecl *Dcl);
- void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr);
- void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
- void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
- void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl);
- void RewriteMethodDeclaration(ObjCMethodDecl *Method);
- void RewriteProperties(unsigned nProperties, ObjCPropertyDecl **Properties);
- void RewriteFunctionDecl(FunctionDecl *FD);
- void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
- void RewriteObjCQualifiedInterfaceTypes(Expr *E);
- bool needToScanForQualifiers(QualType T);
- ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
- QualType getSuperStructType();
- QualType getConstantStringStructType();
- bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
-
- // Expression Rewriting.
- Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
- Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
- Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart);
- Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
- Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
- Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
- Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
- Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
- Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
- Stmt *RewriteObjCCatchStmt(ObjCAtCatchStmt *S);
- Stmt *RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S);
- Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
- Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
- SourceLocation OrigEnd);
- CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
- Expr **args, unsigned nargs);
- Stmt *SynthMessageExpr(ObjCMessageExpr *Exp);
- Stmt *RewriteBreakStmt(BreakStmt *S);
- Stmt *RewriteContinueStmt(ContinueStmt *S);
- void SynthCountByEnumWithState(std::string &buf);
-
- void SynthMsgSendFunctionDecl();
- void SynthMsgSendSuperFunctionDecl();
- void SynthMsgSendStretFunctionDecl();
- void SynthMsgSendFpretFunctionDecl();
- void SynthMsgSendSuperStretFunctionDecl();
- void SynthGetClassFunctionDecl();
- void SynthGetMetaClassFunctionDecl();
- void SynthSelGetUidFunctionDecl();
- void SynthGetProtocolFunctionDecl();
- void SynthSuperContructorFunctionDecl();
-
- // Metadata emission.
- void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
- std::string &Result);
-
- void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
- std::string &Result);
-
- typedef ObjCCategoryImplDecl::instmeth_iterator instmeth_iterator;
- void RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
- instmeth_iterator MethodEnd,
- bool IsInstanceMethod,
- const char *prefix,
- const char *ClassName,
- std::string &Result);
-
- void RewriteObjCProtocolsMetaData(const ObjCList<ObjCProtocolDecl>
- &Protocols,
- const char *prefix,
- const char *ClassName,
- std::string &Result);
- void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
- std::string &Result);
- void SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl,
- ObjCIvarDecl *ivar,
- std::string &Result);
- void RewriteImplementations(std::string &Result);
- };
-}
-
-static bool IsHeaderFile(const std::string &Filename) {
- std::string::size_type DotPos = Filename.rfind('.');
-
- if (DotPos == std::string::npos) {
- // no file extension
- return false;
- }
-
- std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
- // C header: .h
- // C++ header: .hh or .H;
- return Ext == "h" || Ext == "hh" || Ext == "H";
-}
-
-RewriteObjC::RewriteObjC(std::string inFile, std::string outFile,
- Diagnostic &D, const LangOptions &LOpts)
- : Diags(D), LangOpts(LOpts) {
- IsHeader = IsHeaderFile(inFile);
- InFileName = inFile;
- OutFileName = outFile;
- RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning,
- "rewriting sub-expression within a macro (may not be correct)");
-}
-
-ASTConsumer *clang::CreateCodeRewriterTest(const std::string& InFile,
- const std::string& OutFile,
- Diagnostic &Diags,
- const LangOptions &LOpts) {
- return new RewriteObjC(InFile, OutFile, Diags, LOpts);
-}
-
-void RewriteObjC::Initialize(ASTContext &context) {
- Context = &context;
- SM = &Context->getSourceManager();
- TUDecl = Context->getTranslationUnitDecl();
- MsgSendFunctionDecl = 0;
- MsgSendSuperFunctionDecl = 0;
- MsgSendStretFunctionDecl = 0;
- MsgSendSuperStretFunctionDecl = 0;
- MsgSendFpretFunctionDecl = 0;
- GetClassFunctionDecl = 0;
- GetMetaClassFunctionDecl = 0;
- SelGetUidFunctionDecl = 0;
- CFStringFunctionDecl = 0;
- GetProtocolFunctionDecl = 0;
- ConstantStringClassReference = 0;
- NSStringRecord = 0;
- CurMethodDecl = 0;
- SuperStructDecl = 0;
- ConstantStringDecl = 0;
- BcLabelCount = 0;
- SuperContructorFunctionDecl = 0;
- NumObjCStringLiterals = 0;
-
- // Get the ID and start/end of the main file.
- MainFileID = SM->getMainFileID();
- const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
- MainFileStart = MainBuf->getBufferStart();
- MainFileEnd = MainBuf->getBufferEnd();
-
- Rewrite.setSourceMgr(Context->getSourceManager());
-
- // declaring objc_selector outside the parameter list removes a silly
- // scope related warning...
- if (IsHeader)
- Preamble = "#pragma once\n";
- Preamble += "struct objc_selector; struct objc_class;\n";
- Preamble += "#ifndef OBJC_SUPER\n";
- Preamble += "struct objc_super { struct objc_object *object; ";
- Preamble += "struct objc_object *superClass; ";
- if (LangOpts.Microsoft) {
- // Add a constructor for creating temporary objects.
- Preamble += "objc_super(struct objc_object *o, struct objc_object *s) : ";
- Preamble += "object(o), superClass(s) {} ";
- }
- Preamble += "};\n";
- Preamble += "#define OBJC_SUPER\n";
- Preamble += "#endif\n";
- Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
- Preamble += "typedef struct objc_object Protocol;\n";
- Preamble += "#define _REWRITER_typedef_Protocol\n";
- Preamble += "#endif\n";
- if (LangOpts.Microsoft)
- Preamble += "#define __OBJC_RW_EXTERN extern \"C\" __declspec(dllimport)\n";
- else
- Preamble += "#define __OBJC_RW_EXTERN extern\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_msgSend";
- Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_msgSendSuper";
- Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_msgSend_stret";
- Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_msgSendSuper_stret";
- Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
- Preamble += "__OBJC_RW_EXTERN double objc_msgSend_fpret";
- Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_getClass";
- Preamble += "(const char *);\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_getMetaClass";
- Preamble += "(const char *);\n";
- Preamble += "__OBJC_RW_EXTERN void objc_exception_throw(struct objc_object *);\n";
- Preamble += "__OBJC_RW_EXTERN void objc_exception_try_enter(void *);\n";
- Preamble += "__OBJC_RW_EXTERN void objc_exception_try_exit(void *);\n";
- Preamble += "__OBJC_RW_EXTERN struct objc_object *objc_exception_extract(void *);\n";
- Preamble += "__OBJC_RW_EXTERN int objc_exception_match";
- Preamble += "(struct objc_class *, struct objc_object *);\n";
- // @synchronized hooks.
- Preamble += "__OBJC_RW_EXTERN void objc_sync_enter(struct objc_object *);\n";
- Preamble += "__OBJC_RW_EXTERN void objc_sync_exit(struct objc_object *);\n";
- Preamble += "__OBJC_RW_EXTERN Protocol *objc_getProtocol(const char *);\n";
- Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
- Preamble += "struct __objcFastEnumerationState {\n\t";
- Preamble += "unsigned long state;\n\t";
- Preamble += "void **itemsPtr;\n\t";
- Preamble += "unsigned long *mutationsPtr;\n\t";
- Preamble += "unsigned long extra[5];\n};\n";
- Preamble += "__OBJC_RW_EXTERN void objc_enumerationMutation(struct objc_object *);\n";
- Preamble += "#define __FASTENUMERATIONSTATE\n";
- Preamble += "#endif\n";
- Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
- Preamble += "struct __NSConstantStringImpl {\n";
- Preamble += " int *isa;\n";
- Preamble += " int flags;\n";
- Preamble += " char *str;\n";
- Preamble += " long length;\n";
- Preamble += "};\n";
- Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
- Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
- Preamble += "#else\n";
- Preamble += "__OBJC_RW_EXTERN int __CFConstantStringClassReference[];\n";
- Preamble += "#endif\n";
- Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
- Preamble += "#endif\n";
- if (LangOpts.Microsoft) {
- Preamble += "#undef __OBJC_RW_EXTERN\n";
- Preamble += "#define __attribute__(X)\n";
- }
-}
-
-
-//===----------------------------------------------------------------------===//
-// Top Level Driver Code
-//===----------------------------------------------------------------------===//
-
-void RewriteObjC::HandleTopLevelDecl(Decl *D) {
- // Two cases: either the decl could be in the main file, or it could be in a
- // #included file. If the former, rewrite it now. If the later, check to see
- // if we rewrote the #include/#import.
- SourceLocation Loc = D->getLocation();
- Loc = SM->getLogicalLoc(Loc);
-
- // If this is for a builtin, ignore it.
- if (Loc.isInvalid()) return;
-
- // Look for built-in declarations that we need to refer during the rewrite.
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- RewriteFunctionDecl(FD);
- } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
- // declared in <Foundation/NSString.h>
- if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) {
- ConstantStringClassReference = FVD;
- return;
- }
- } else if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D)) {
- RewriteInterfaceDecl(MD);
- } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
- RewriteCategoryDecl(CD);
- } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
- RewriteProtocolDecl(PD);
- } else if (ObjCForwardProtocolDecl *FP =
- dyn_cast<ObjCForwardProtocolDecl>(D)){
- RewriteForwardProtocolDecl(FP);
- }
- // If we have a decl in the main file, see if we should rewrite it.
- if (SM->isFromMainFile(Loc))
- return HandleDeclInMainFile(D);
-}
-
-/// HandleDeclInMainFile - This is called for each top-level decl defined in the
-/// main file of the input.
-void RewriteObjC::HandleDeclInMainFile(Decl *D) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- if (Stmt *Body = FD->getBody())
- FD->setBody(RewriteFunctionBodyOrGlobalInitializer(Body));
-
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (Stmt *Body = MD->getBody()) {
- //Body->dump();
- CurMethodDecl = MD;
- MD->setBody(RewriteFunctionBodyOrGlobalInitializer(Body));
- CurMethodDecl = 0;
- }
- }
- if (ObjCImplementationDecl *CI = dyn_cast<ObjCImplementationDecl>(D))
- ClassImplementation.push_back(CI);
- else if (ObjCCategoryImplDecl *CI = dyn_cast<ObjCCategoryImplDecl>(D))
- CategoryImplementation.push_back(CI);
- else if (ObjCClassDecl *CD = dyn_cast<ObjCClassDecl>(D))
- RewriteForwardClassDecl(CD);
- else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- RewriteObjCQualifiedInterfaceTypes(VD);
- if (VD->getInit())
- RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
- }
- // Nothing yet.
-}
-
-void RewriteObjC::HandleTranslationUnit(TranslationUnit& TU) {
- // Get the top-level buffer that this corresponds to.
-
- // Rewrite tabs if we care.
- //RewriteTabs();
-
- if (Diags.hasErrorOccurred())
- return;
-
- // Create the output file.
-
- llvm::OwningPtr<llvm::raw_ostream> OwnedStream;
- llvm::raw_ostream *OutFile;
- if (OutFileName == "-") {
- OutFile = &llvm::outs();
- } else if (!OutFileName.empty()) {
- std::string Err;
- OutFile = new llvm::raw_fd_ostream(OutFileName.c_str(), Err);
- OwnedStream.reset(OutFile);
- } else if (InFileName == "-") {
- OutFile = &llvm::outs();
- } else {
- llvm::sys::Path Path(InFileName);
- Path.eraseSuffix();
- Path.appendSuffix("cpp");
- std::string Err;
- OutFile = new llvm::raw_fd_ostream(Path.toString().c_str(), Err);
- OwnedStream.reset(OutFile);
- }
-
- RewriteInclude();
-
- InsertText(SourceLocation::getFileLoc(MainFileID, 0),
- Preamble.c_str(), Preamble.size(), false);
-
- // Rewrite Objective-c meta data*
- std::string ResultStr;
- RewriteImplementations(ResultStr);
-
- // Get the buffer corresponding to MainFileID. If we haven't changed it, then
- // we are done.
- if (const RewriteBuffer *RewriteBuf =
- Rewrite.getRewriteBufferFor(MainFileID)) {
- //printf("Changed:\n");
- *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
- } else {
- fprintf(stderr, "No changes\n");
- }
- // Emit metadata.
- *OutFile << ResultStr;
- OutFile->flush();
-}
-
-//===----------------------------------------------------------------------===//
-// Syntactic (non-AST) Rewriting Code
-//===----------------------------------------------------------------------===//
-
-void RewriteObjC::RewriteInclude() {
- SourceLocation LocStart = SourceLocation::getFileLoc(MainFileID, 0);
- std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
- const char *MainBufStart = MainBuf.first;
- const char *MainBufEnd = MainBuf.second;
- size_t ImportLen = strlen("import");
- size_t IncludeLen = strlen("include");
-
- // Loop over the whole file, looking for includes.
- for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
- if (*BufPtr == '#') {
- if (++BufPtr == MainBufEnd)
- return;
- while (*BufPtr == ' ' || *BufPtr == '\t')
- if (++BufPtr == MainBufEnd)
- return;
- if (!strncmp(BufPtr, "import", ImportLen)) {
- // replace import with include
- SourceLocation ImportLoc =
- LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
- ReplaceText(ImportLoc, ImportLen, "include", IncludeLen);
- BufPtr += ImportLen;
- }
- }
- }
-}
-
-void RewriteObjC::RewriteTabs() {
- std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
- const char *MainBufStart = MainBuf.first;
- const char *MainBufEnd = MainBuf.second;
-
- // Loop over the whole file, looking for tabs.
- for (const char *BufPtr = MainBufStart; BufPtr != MainBufEnd; ++BufPtr) {
- if (*BufPtr != '\t')
- continue;
-
- // Okay, we found a tab. This tab will turn into at least one character,
- // but it depends on which 'virtual column' it is in. Compute that now.
- unsigned VCol = 0;
- while (BufPtr-VCol != MainBufStart && BufPtr[-VCol-1] != '\t' &&
- BufPtr[-VCol-1] != '\n' && BufPtr[-VCol-1] != '\r')
- ++VCol;
-
- // Okay, now that we know the virtual column, we know how many spaces to
- // insert. We assume 8-character tab-stops.
- unsigned Spaces = 8-(VCol & 7);
-
- // Get the location of the tab.
- SourceLocation TabLoc =
- SourceLocation::getFileLoc(MainFileID, BufPtr-MainBufStart);
-
- // Rewrite the single tab character into a sequence of spaces.
- ReplaceText(TabLoc, 1, " ", Spaces);
- }
-}
-
-
-void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
- int numDecls = ClassDecl->getNumForwardDecls();
- ObjCInterfaceDecl **ForwardDecls = ClassDecl->getForwardDecls();
-
- // Get the start location and compute the semi location.
- SourceLocation startLoc = ClassDecl->getLocation();
- const char *startBuf = SM->getCharacterData(startLoc);
- const char *semiPtr = strchr(startBuf, ';');
-
- // Translate to typedef's that forward reference structs with the same name
- // as the class. As a convenience, we include the original declaration
- // as a comment.
- std::string typedefString;
- typedefString += "// ";
- typedefString.append(startBuf, semiPtr-startBuf+1);
- typedefString += "\n";
- for (int i = 0; i < numDecls; i++) {
- ObjCInterfaceDecl *ForwardDecl = ForwardDecls[i];
- typedefString += "#ifndef _REWRITER_typedef_";
- typedefString += ForwardDecl->getName();
- typedefString += "\n";
- typedefString += "#define _REWRITER_typedef_";
- typedefString += ForwardDecl->getName();
- typedefString += "\n";
- typedefString += "typedef struct objc_object ";
- typedefString += ForwardDecl->getName();
- typedefString += ";\n#endif\n";
- }
-
- // Replace the @class with typedefs corresponding to the classes.
- ReplaceText(startLoc, semiPtr-startBuf+1,
- typedefString.c_str(), typedefString.size());
-}
-
-void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
- SourceLocation LocStart = Method->getLocStart();
- SourceLocation LocEnd = Method->getLocEnd();
-
- if (SM->getLineNumber(LocEnd) > SM->getLineNumber(LocStart)) {
- InsertText(LocStart, "/* ", 3);
- ReplaceText(LocEnd, 1, ";*/ ", 4);
- } else {
- InsertText(LocStart, "// ", 3);
- }
-}
-
-void RewriteObjC::RewriteProperties(unsigned nProperties, ObjCPropertyDecl **Properties)
-{
- for (unsigned i = 0; i < nProperties; i++) {
- ObjCPropertyDecl *Property = Properties[i];
- SourceLocation Loc = Property->getLocation();
-
- ReplaceText(Loc, 0, "// ", 3);
-
- // FIXME: handle properties that are declared across multiple lines.
- }
-}
-
-void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
- SourceLocation LocStart = CatDecl->getLocStart();
-
- // FIXME: handle category headers that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
-
- for (ObjCCategoryDecl::instmeth_iterator I = CatDecl->instmeth_begin(),
- E = CatDecl->instmeth_end(); I != E; ++I)
- RewriteMethodDeclaration(*I);
- for (ObjCCategoryDecl::classmeth_iterator I = CatDecl->classmeth_begin(),
- E = CatDecl->classmeth_end(); I != E; ++I)
- RewriteMethodDeclaration(*I);
-
- // Lastly, comment out the @end.
- ReplaceText(CatDecl->getAtEndLoc(), 0, "// ", 3);
-}
-
-void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
- std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
-
- SourceLocation LocStart = PDecl->getLocStart();
-
- // FIXME: handle protocol headers that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
-
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
- E = PDecl->instmeth_end(); I != E; ++I)
- RewriteMethodDeclaration(*I);
- for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
- E = PDecl->classmeth_end(); I != E; ++I)
- RewriteMethodDeclaration(*I);
-
- // Lastly, comment out the @end.
- SourceLocation LocEnd = PDecl->getAtEndLoc();
- ReplaceText(LocEnd, 0, "// ", 3);
-
- // Must comment out @optional/@required
- const char *startBuf = SM->getCharacterData(LocStart);
- const char *endBuf = SM->getCharacterData(LocEnd);
- for (const char *p = startBuf; p < endBuf; p++) {
- if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
- std::string CommentedOptional = "/* @optional */";
- SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
- ReplaceText(OptionalLoc, strlen("@optional"),
- CommentedOptional.c_str(), CommentedOptional.size());
-
- }
- else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
- std::string CommentedRequired = "/* @required */";
- SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
- ReplaceText(OptionalLoc, strlen("@required"),
- CommentedRequired.c_str(), CommentedRequired.size());
-
- }
- }
-}
-
-void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
- SourceLocation LocStart = PDecl->getLocation();
- if (LocStart.isInvalid())
- assert(false && "Invalid SourceLocation");
- // FIXME: handle forward protocol that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
-}
-
-void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
- std::string &ResultStr) {
- const FunctionType *FPRetType = 0;
- ResultStr += "\nstatic ";
- if (OMD->getResultType()->isObjCQualifiedIdType())
- ResultStr += "id";
- else if (OMD->getResultType()->isFunctionPointerType()) {
- // needs special handling, since pointer-to-functions have special
- // syntax (where a decaration models use).
- QualType retType = OMD->getResultType();
- if (const PointerType* PT = retType->getAsPointerType()) {
- QualType PointeeTy = PT->getPointeeType();
- if ((FPRetType = PointeeTy->getAsFunctionType())) {
- ResultStr += FPRetType->getResultType().getAsString();
- ResultStr += "(*";
- }
- }
- } else
- ResultStr += OMD->getResultType().getAsString();
- ResultStr += " ";
-
- // Unique method name
- std::string NameStr;
-
- if (OMD->isInstance())
- NameStr += "_I_";
- else
- NameStr += "_C_";
-
- NameStr += OMD->getClassInterface()->getName();
- NameStr += "_";
-
- NamedDecl *MethodContext = OMD->getMethodContext();
- if (ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(MethodContext)) {
- NameStr += CID->getName();
- NameStr += "_";
- }
- // Append selector names, replacing ':' with '_'
- if (OMD->getSelector().getName().find(':') == std::string::npos)
- NameStr += OMD->getSelector().getName();
- else {
- std::string selString = OMD->getSelector().getName();
- int len = selString.size();
- for (int i = 0; i < len; i++)
- if (selString[i] == ':')
- selString[i] = '_';
- NameStr += selString;
- }
- // Remember this name for metadata emission
- MethodInternalNames[OMD] = NameStr;
- ResultStr += NameStr;
-
- // Rewrite arguments
- ResultStr += "(";
-
- // invisible arguments
- if (OMD->isInstance()) {
- QualType selfTy = Context->getObjCInterfaceType(OMD->getClassInterface());
- selfTy = Context->getPointerType(selfTy);
- if (!LangOpts.Microsoft) {
- if (ObjCSynthesizedStructs.count(OMD->getClassInterface()))
- ResultStr += "struct ";
- }
- // When rewriting for Microsoft, explicitly omit the structure name.
- ResultStr += OMD->getClassInterface()->getName();
- ResultStr += " *";
- }
- else
- ResultStr += Context->getObjCIdType().getAsString();
-
- ResultStr += " self, ";
- ResultStr += Context->getObjCSelType().getAsString();
- ResultStr += " _cmd";
-
- // Method arguments.
- for (unsigned i = 0; i < OMD->getNumParams(); i++) {
- ParmVarDecl *PDecl = OMD->getParamDecl(i);
- ResultStr += ", ";
- if (PDecl->getType()->isObjCQualifiedIdType()) {
- ResultStr += "id ";
- ResultStr += PDecl->getName();
- } else {
- std::string Name = PDecl->getName();
- PDecl->getType().getAsStringInternal(Name);
- ResultStr += Name;
- }
- }
- if (OMD->isVariadic())
- ResultStr += ", ...";
- ResultStr += ") ";
-
- if (FPRetType) {
- ResultStr += ")"; // close the precedence "scope" for "*".
-
- // Now, emit the argument types (if any).
- if (const FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(FPRetType)) {
- ResultStr += "(";
- for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
- if (i) ResultStr += ", ";
- std::string ParamStr = FT->getArgType(i).getAsString();
- ResultStr += ParamStr;
- }
- if (FT->isVariadic()) {
- if (FT->getNumArgs()) ResultStr += ", ";
- ResultStr += "...";
- }
- ResultStr += ")";
- } else {
- ResultStr += "()";
- }
- }
-}
-void RewriteObjC::RewriteImplementationDecl(NamedDecl *OID) {
- ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
- ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
-
- if (IMD)
- InsertText(IMD->getLocStart(), "// ", 3);
- else
- InsertText(CID->getLocStart(), "// ", 3);
-
- for (ObjCCategoryImplDecl::instmeth_iterator
- I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
- E = IMD ? IMD->instmeth_end() : CID->instmeth_end(); I != E; ++I) {
- std::string ResultStr;
- ObjCMethodDecl *OMD = *I;
- RewriteObjCMethodDecl(OMD, ResultStr);
- SourceLocation LocStart = OMD->getLocStart();
- SourceLocation LocEnd = OMD->getBody()->getLocStart();
-
- const char *startBuf = SM->getCharacterData(LocStart);
- const char *endBuf = SM->getCharacterData(LocEnd);
- ReplaceText(LocStart, endBuf-startBuf,
- ResultStr.c_str(), ResultStr.size());
- }
-
- for (ObjCCategoryImplDecl::classmeth_iterator
- I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
- E = IMD ? IMD->classmeth_end() : CID->classmeth_end(); I != E; ++I) {
- std::string ResultStr;
- ObjCMethodDecl *OMD = *I;
- RewriteObjCMethodDecl(OMD, ResultStr);
- SourceLocation LocStart = OMD->getLocStart();
- SourceLocation LocEnd = OMD->getBody()->getLocStart();
-
- const char *startBuf = SM->getCharacterData(LocStart);
- const char *endBuf = SM->getCharacterData(LocEnd);
- ReplaceText(LocStart, endBuf-startBuf,
- ResultStr.c_str(), ResultStr.size());
- }
- if (IMD)
- InsertText(IMD->getLocEnd(), "// ", 3);
- else
- InsertText(CID->getLocEnd(), "// ", 3);
-}
-
-void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
- std::string ResultStr;
- if (!ObjCForwardDecls.count(ClassDecl)) {
- // we haven't seen a forward decl - generate a typedef.
- ResultStr = "#ifndef _REWRITER_typedef_";
- ResultStr += ClassDecl->getName();
- ResultStr += "\n";
- ResultStr += "#define _REWRITER_typedef_";
- ResultStr += ClassDecl->getName();
- ResultStr += "\n";
- ResultStr += "typedef struct objc_object ";
- ResultStr += ClassDecl->getName();
- ResultStr += ";\n#endif\n";
- // Mark this typedef as having been generated.
- ObjCForwardDecls.insert(ClassDecl);
- }
- SynthesizeObjCInternalStruct(ClassDecl, ResultStr);
-
- RewriteProperties(ClassDecl->getNumPropertyDecl(),
- ClassDecl->getPropertyDecl());
- for (ObjCInterfaceDecl::instmeth_iterator I = ClassDecl->instmeth_begin(),
- E = ClassDecl->instmeth_end(); I != E; ++I)
- RewriteMethodDeclaration(*I);
- for (ObjCInterfaceDecl::classmeth_iterator I = ClassDecl->classmeth_begin(),
- E = ClassDecl->classmeth_end(); I != E; ++I)
- RewriteMethodDeclaration(*I);
-
- // Lastly, comment out the @end.
- ReplaceText(ClassDecl->getAtEndLoc(), 0, "// ", 3);
-}
-
-Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
- SourceLocation OrigStart) {
- ObjCIvarDecl *D = IV->getDecl();
- if (CurMethodDecl) {
- if (const PointerType *pType = IV->getBase()->getType()->getAsPointerType()) {
- ObjCInterfaceType *iFaceDecl = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
- // lookup which class implements the instance variable.
- ObjCInterfaceDecl *clsDeclared = 0;
- iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), clsDeclared);
- assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
-
- // Synthesize an explicit cast to gain access to the ivar.
- std::string RecName = clsDeclared->getIdentifier()->getName();
- RecName += "_IMPL";
- IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
- RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
- SourceLocation(), II);
- assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
- QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
- CastExpr *castExpr = new ExplicitCastExpr(castT, IV->getBase(),
- SourceLocation());
- // Don't forget the parens to enforce the proper binding.
- ParenExpr *PE = new ParenExpr(IV->getBase()->getLocStart(),
- IV->getBase()->getLocEnd(),
- castExpr);
- if (IV->isFreeIvar() &&
- CurMethodDecl->getClassInterface() == iFaceDecl->getDecl()) {
- MemberExpr *ME = new MemberExpr(PE, true, D, IV->getLocation(),
- D->getType());
- ReplaceStmt(IV, ME);
- delete IV;
- return ME;
- }
-
- ReplaceStmt(IV->getBase(), PE);
- // Cannot delete IV->getBase(), since PE points to it.
- // Replace the old base with the cast. This is important when doing
- // embedded rewrites. For example, [newInv->_container addObject:0].
- IV->setBase(PE);
- return IV;
- }
- } else { // we are outside a method.
- assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
-
- // Explicit ivar refs need to have a cast inserted.
- // FIXME: consider sharing some of this code with the code above.
- if (const PointerType *pType = IV->getBase()->getType()->getAsPointerType()) {
- ObjCInterfaceType *iFaceDecl = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
- // lookup which class implements the instance variable.
- ObjCInterfaceDecl *clsDeclared = 0;
- iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), clsDeclared);
- assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
-
- // Synthesize an explicit cast to gain access to the ivar.
- std::string RecName = clsDeclared->getIdentifier()->getName();
- RecName += "_IMPL";
- IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
- RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
- SourceLocation(), II);
- assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
- QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
- CastExpr *castExpr = new ExplicitCastExpr(castT, IV->getBase(),
- SourceLocation());
- // Don't forget the parens to enforce the proper binding.
- ParenExpr *PE = new ParenExpr(IV->getBase()->getLocStart(),
- IV->getBase()->getLocEnd(), castExpr);
- ReplaceStmt(IV->getBase(), PE);
- // Cannot delete IV->getBase(), since PE points to it.
- // Replace the old base with the cast. This is important when doing
- // embedded rewrites. For example, [newInv->_container addObject:0].
- IV->setBase(PE);
- return IV;
- }
- }
- return IV;
-}
-
-//===----------------------------------------------------------------------===//
-// Function Body / Expression rewriting
-//===----------------------------------------------------------------------===//
-
-Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
- if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
- isa<DoStmt>(S) || isa<ForStmt>(S))
- Stmts.push_back(S);
- else if (isa<ObjCForCollectionStmt>(S)) {
- Stmts.push_back(S);
- ObjCBcLabelNo.push_back(++BcLabelCount);
- }
-
- SourceRange OrigStmtRange = S->getSourceRange();
-
- // Start by rewriting all children.
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI) {
- Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(*CI);
- if (newStmt)
- *CI = newStmt;
- }
-
- // Handle specific things.
- if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
- return RewriteAtEncode(AtEncode);
-
- if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S))
- return RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin());
-
- if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
- return RewriteAtSelector(AtSelector);
-
- if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
- return RewriteObjCStringLiteral(AtString);
-
- if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
- // Before we rewrite it, put the original message expression in a comment.
- SourceLocation startLoc = MessExpr->getLocStart();
- SourceLocation endLoc = MessExpr->getLocEnd();
-
- const char *startBuf = SM->getCharacterData(startLoc);
- const char *endBuf = SM->getCharacterData(endLoc);
-
- std::string messString;
- messString += "// ";
- messString.append(startBuf, endBuf-startBuf+1);
- messString += "\n";
-
- // FIXME: Missing definition of
- // InsertText(clang::SourceLocation, char const*, unsigned int).
- // InsertText(startLoc, messString.c_str(), messString.size());
- // Tried this, but it didn't work either...
- // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
- return RewriteMessageExpr(MessExpr);
- }
-
- if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
- return RewriteObjCTryStmt(StmtTry);
-
- if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
- return RewriteObjCSynchronizedStmt(StmtTry);
-
- if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
- return RewriteObjCThrowStmt(StmtThrow);
-
- if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
- return RewriteObjCProtocolExpr(ProtocolExp);
-
- if (ObjCForCollectionStmt *StmtForCollection =
- dyn_cast<ObjCForCollectionStmt>(S))
- return RewriteObjCForCollectionStmt(StmtForCollection,
- OrigStmtRange.getEnd());
- if (BreakStmt *StmtBreakStmt =
- dyn_cast<BreakStmt>(S))
- return RewriteBreakStmt(StmtBreakStmt);
- if (ContinueStmt *StmtContinueStmt =
- dyn_cast<ContinueStmt>(S))
- return RewriteContinueStmt(StmtContinueStmt);
-
- // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
- // and cast exprs.
- if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
- // FIXME: What we're doing here is modifying the type-specifier that
- // precedes the first Decl. In the future the DeclGroup should have
- // a separate type-specifier that we can rewrite.
- RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
- }
-
- if (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(S))
- RewriteObjCQualifiedInterfaceTypes(CE);
-
- if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
- isa<DoStmt>(S) || isa<ForStmt>(S)) {
- assert(!Stmts.empty() && "Statement stack is empty");
- assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
- isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
- && "Statement stack mismatch");
- Stmts.pop_back();
- }
-#if 0
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
- CastExpr *Replacement = new CastExpr(ICE->getType(), ICE->getSubExpr(), SourceLocation());
- // Get the new text.
- std::string SStr;
- llvm::raw_string_ostream Buf(SStr);
- Replacement->printPretty(Buf);
- const std::string &Str = Buf.str();
-
- printf("CAST = %s\n", &Str[0]);
- InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
- delete S;
- return Replacement;
- }
-#endif
- // Return this stmt unmodified.
- return S;
-}
-
-/// SynthCountByEnumWithState - To print:
-/// ((unsigned int (*)
-/// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
-/// (void *)objc_msgSend)((id)l_collection,
-/// sel_registerName(
-/// "countByEnumeratingWithState:objects:count:"),
-/// &enumState,
-/// (id *)items, (unsigned int)16)
-///
-void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
- buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
- "id *, unsigned int))(void *)objc_msgSend)";
- buf += "\n\t\t";
- buf += "((id)l_collection,\n\t\t";
- buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
- buf += "\n\t\t";
- buf += "&enumState, "
- "(id *)items, (unsigned int)16)";
-}
-
-/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
-/// statement to exit to its outer synthesized loop.
-///
-Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
- if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
- return S;
- // replace break with goto __break_label
- std::string buf;
-
- SourceLocation startLoc = S->getLocStart();
- buf = "goto __break_label_";
- buf += utostr(ObjCBcLabelNo.back());
- ReplaceText(startLoc, strlen("break"), buf.c_str(), buf.size());
-
- return 0;
-}
-
-/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
-/// statement to continue with its inner synthesized loop.
-///
-Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
- if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
- return S;
- // replace continue with goto __continue_label
- std::string buf;
-
- SourceLocation startLoc = S->getLocStart();
- buf = "goto __continue_label_";
- buf += utostr(ObjCBcLabelNo.back());
- ReplaceText(startLoc, strlen("continue"), buf.c_str(), buf.size());
-
- return 0;
-}
-
-/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
-/// It rewrites:
-/// for ( type elem in collection) { stmts; }
-
-/// Into:
-/// {
-/// type elem;
-/// struct __objcFastEnumerationState enumState = { 0 };
-/// id items[16];
-/// id l_collection = (id)collection;
-/// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
-/// objects:items count:16];
-/// if (limit) {
-/// unsigned long startMutations = *enumState.mutationsPtr;
-/// do {
-/// unsigned long counter = 0;
-/// do {
-/// if (startMutations != *enumState.mutationsPtr)
-/// objc_enumerationMutation(l_collection);
-/// elem = (type)enumState.itemsPtr[counter++];
-/// stmts;
-/// __continue_label: ;
-/// } while (counter < limit);
-/// } while (limit = [l_collection countByEnumeratingWithState:&enumState
-/// objects:items count:16]);
-/// elem = nil;
-/// __break_label: ;
-/// }
-/// else
-/// elem = nil;
-/// }
-///
-Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
- SourceLocation OrigEnd) {
- assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
- assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
- "ObjCForCollectionStmt Statement stack mismatch");
- assert(!ObjCBcLabelNo.empty() &&
- "ObjCForCollectionStmt - Label No stack empty");
-
- SourceLocation startLoc = S->getLocStart();
- const char *startBuf = SM->getCharacterData(startLoc);
- const char *elementName;
- std::string elementTypeAsString;
- std::string buf;
- buf = "\n{\n\t";
- if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
- // type elem;
- ScopedDecl* D = DS->getSolitaryDecl();
- QualType ElementType = cast<ValueDecl>(D)->getType();
- elementTypeAsString = ElementType.getAsString();
- buf += elementTypeAsString;
- buf += " ";
- elementName = D->getName();
- buf += elementName;
- buf += ";\n\t";
- }
- else {
- DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
- elementName = DR->getDecl()->getName();
- elementTypeAsString = DR->getDecl()->getType().getAsString();
- }
-
- // struct __objcFastEnumerationState enumState = { 0 };
- buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
- // id items[16];
- buf += "id items[16];\n\t";
- // id l_collection = (id)
- buf += "id l_collection = (id)";
- // Find start location of 'collection' the hard way!
- const char *startCollectionBuf = startBuf;
- startCollectionBuf += 3; // skip 'for'
- startCollectionBuf = strchr(startCollectionBuf, '(');
- startCollectionBuf++; // skip '('
- // find 'in' and skip it.
- while (*startCollectionBuf != ' ' ||
- *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
- (*(startCollectionBuf+3) != ' ' &&
- *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
- startCollectionBuf++;
- startCollectionBuf += 3;
-
- // Replace: "for (type element in" with string constructed thus far.
- ReplaceText(startLoc, startCollectionBuf - startBuf,
- buf.c_str(), buf.size());
- // Replace ')' in for '(' type elem in collection ')' with ';'
- SourceLocation rightParenLoc = S->getRParenLoc();
- const char *rparenBuf = SM->getCharacterData(rightParenLoc);
- SourceLocation lparenLoc = startLoc.getFileLocWithOffset(rparenBuf-startBuf);
- buf = ";\n\t";
-
- // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
- // objects:items count:16];
- // which is synthesized into:
- // unsigned int limit =
- // ((unsigned int (*)
- // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
- // (void *)objc_msgSend)((id)l_collection,
- // sel_registerName(
- // "countByEnumeratingWithState:objects:count:"),
- // (struct __objcFastEnumerationState *)&state,
- // (id *)items, (unsigned int)16);
- buf += "unsigned long limit =\n\t\t";
- SynthCountByEnumWithState(buf);
- buf += ";\n\t";
- /// if (limit) {
- /// unsigned long startMutations = *enumState.mutationsPtr;
- /// do {
- /// unsigned long counter = 0;
- /// do {
- /// if (startMutations != *enumState.mutationsPtr)
- /// objc_enumerationMutation(l_collection);
- /// elem = (type)enumState.itemsPtr[counter++];
- buf += "if (limit) {\n\t";
- buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
- buf += "do {\n\t\t";
- buf += "unsigned long counter = 0;\n\t\t";
- buf += "do {\n\t\t\t";
- buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
- buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
- buf += elementName;
- buf += " = (";
- buf += elementTypeAsString;
- buf += ")enumState.itemsPtr[counter++];";
- // Replace ')' in for '(' type elem in collection ')' with all of these.
- ReplaceText(lparenLoc, 1, buf.c_str(), buf.size());
-
- /// __continue_label: ;
- /// } while (counter < limit);
- /// } while (limit = [l_collection countByEnumeratingWithState:&enumState
- /// objects:items count:16]);
- /// elem = nil;
- /// __break_label: ;
- /// }
- /// else
- /// elem = nil;
- /// }
- ///
- buf = ";\n\t";
- buf += "__continue_label_";
- buf += utostr(ObjCBcLabelNo.back());
- buf += ": ;";
- buf += "\n\t\t";
- buf += "} while (counter < limit);\n\t";
- buf += "} while (limit = ";
- SynthCountByEnumWithState(buf);
- buf += ");\n\t";
- buf += elementName;
- buf += " = nil;\n\t";
- buf += "__break_label_";
- buf += utostr(ObjCBcLabelNo.back());
- buf += ": ;\n\t";
- buf += "}\n\t";
- buf += "else\n\t\t";
- buf += elementName;
- buf += " = nil;\n";
- buf += "}\n";
-
- // Insert all these *after* the statement body.
- if (isa<CompoundStmt>(S->getBody())) {
- SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(1);
- InsertText(endBodyLoc, buf.c_str(), buf.size());
- } else {
- /* Need to treat single statements specially. For example:
- *
- * for (A *a in b) if (stuff()) break;
- * for (A *a in b) xxxyy;
- *
- * The following code simply scans ahead to the semi to find the actual end.
- */
- const char *stmtBuf = SM->getCharacterData(OrigEnd);
- const char *semiBuf = strchr(stmtBuf, ';');
- assert(semiBuf && "Can't find ';'");
- SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(semiBuf-stmtBuf+1);
- InsertText(endBodyLoc, buf.c_str(), buf.size());
- }
- Stmts.pop_back();
- ObjCBcLabelNo.pop_back();
- return 0;
-}
-
-/// RewriteObjCSynchronizedStmt -
-/// This routine rewrites @synchronized(expr) stmt;
-/// into:
-/// objc_sync_enter(expr);
-/// @try stmt @finally { objc_sync_exit(expr); }
-///
-Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
- // Get the start location and compute the semi location.
- SourceLocation startLoc = S->getLocStart();
- const char *startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '@') && "bogus @synchronized location");
-
- std::string buf;
- buf = "objc_sync_enter((id)";
- const char *lparenBuf = startBuf;
- while (*lparenBuf != '(') lparenBuf++;
- ReplaceText(startLoc, lparenBuf-startBuf+1, buf.c_str(), buf.size());
- // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
- // the sync expression is typically a message expression that's already
- // been rewritten! (which implies the SourceLocation's are invalid).
- SourceLocation endLoc = S->getSynchBody()->getLocStart();
- const char *endBuf = SM->getCharacterData(endLoc);
- while (*endBuf != ')') endBuf--;
- SourceLocation rparenLoc = startLoc.getFileLocWithOffset(endBuf-startBuf);
- buf = ");\n";
- // declare a new scope with two variables, _stack and _rethrow.
- buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
- buf += "int buf[18/*32-bit i386*/];\n";
- buf += "char *pointers[4];} _stack;\n";
- buf += "id volatile _rethrow = 0;\n";
- buf += "objc_exception_try_enter(&_stack);\n";
- buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
- ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
- startLoc = S->getSynchBody()->getLocEnd();
- startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '}') && "bogus @synchronized block");
- SourceLocation lastCurlyLoc = startLoc;
- buf = "}\nelse {\n";
- buf += " _rethrow = objc_exception_extract(&_stack);\n";
- buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- buf += " objc_sync_exit(";
- Expr *syncExpr = new ExplicitCastExpr(Context->getObjCIdType(),
- S->getSynchExpr(), SourceLocation());
- std::string syncExprBufS;
- llvm::raw_string_ostream syncExprBuf(syncExprBufS);
- syncExpr->printPretty(syncExprBuf);
- buf += syncExprBuf.str();
- buf += ");\n";
- buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
- buf += "}\n";
- buf += "}";
-
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
- return 0;
-}
-
-Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
- // Get the start location and compute the semi location.
- SourceLocation startLoc = S->getLocStart();
- const char *startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '@') && "bogus @try location");
-
- std::string buf;
- // declare a new scope with two variables, _stack and _rethrow.
- buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
- buf += "int buf[18/*32-bit i386*/];\n";
- buf += "char *pointers[4];} _stack;\n";
- buf += "id volatile _rethrow = 0;\n";
- buf += "objc_exception_try_enter(&_stack);\n";
- buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
-
- ReplaceText(startLoc, 4, buf.c_str(), buf.size());
-
- startLoc = S->getTryBody()->getLocEnd();
- startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '}') && "bogus @try block");
-
- SourceLocation lastCurlyLoc = startLoc;
- ObjCAtCatchStmt *catchList = S->getCatchStmts();
- if (catchList) {
- startLoc = startLoc.getFileLocWithOffset(1);
- buf = " /* @catch begin */ else {\n";
- buf += " id _caught = objc_exception_extract(&_stack);\n";
- buf += " objc_exception_try_enter (&_stack);\n";
- buf += " if (_setjmp(_stack.buf))\n";
- buf += " _rethrow = objc_exception_extract(&_stack);\n";
- buf += " else { /* @catch continue */";
-
- InsertText(startLoc, buf.c_str(), buf.size());
- } else { /* no catch list */
- buf = "}\nelse {\n";
- buf += " _rethrow = objc_exception_extract(&_stack);\n";
- buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
- }
- bool sawIdTypedCatch = false;
- Stmt *lastCatchBody = 0;
- while (catchList) {
- Stmt *catchStmt = catchList->getCatchParamStmt();
-
- if (catchList == S->getCatchStmts())
- buf = "if ("; // we are generating code for the first catch clause
- else
- buf = "else if (";
- startLoc = catchList->getLocStart();
- startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '@') && "bogus @catch location");
-
- const char *lParenLoc = strchr(startBuf, '(');
-
- if (catchList->hasEllipsis()) {
- // Now rewrite the body...
- lastCatchBody = catchList->getCatchBody();
- SourceLocation bodyLoc = lastCatchBody->getLocStart();
- const char *bodyBuf = SM->getCharacterData(bodyLoc);
- assert(*SM->getCharacterData(catchList->getRParenLoc()) == ')' &&
- "bogus @catch paren location");
- assert((*bodyBuf == '{') && "bogus @catch body location");
-
- buf += "1) { id _tmp = _caught;";
- Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1,
- buf.c_str(), buf.size());
- } else if (DeclStmt *declStmt = dyn_cast<DeclStmt>(catchStmt)) {
- QualType t = dyn_cast<ValueDecl>(declStmt->getSolitaryDecl())->getType();
- if (t == Context->getObjCIdType()) {
- buf += "1) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
- sawIdTypedCatch = true;
- } else if (const PointerType *pType = t->getAsPointerType()) {
- ObjCInterfaceType *cls; // Should be a pointer to a class.
-
- cls = dyn_cast<ObjCInterfaceType>(pType->getPointeeType().getTypePtr());
- if (cls) {
- buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
- buf += cls->getDecl()->getName();
- buf += "\"), (struct objc_object *)_caught)) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
- }
- }
- // Now rewrite the body...
- lastCatchBody = catchList->getCatchBody();
- SourceLocation rParenLoc = catchList->getRParenLoc();
- SourceLocation bodyLoc = lastCatchBody->getLocStart();
- const char *bodyBuf = SM->getCharacterData(bodyLoc);
- const char *rParenBuf = SM->getCharacterData(rParenLoc);
- assert((*rParenBuf == ')') && "bogus @catch paren location");
- assert((*bodyBuf == '{') && "bogus @catch body location");
-
- buf = " = _caught;";
- // Here we replace ") {" with "= _caught;" (which initializes and
- // declares the @catch parameter).
- ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size());
- } else if (!isa<NullStmt>(catchStmt)) {
- assert(false && "@catch rewrite bug");
- }
- // make sure all the catch bodies get rewritten!
- catchList = catchList->getNextCatchStmt();
- }
- // Complete the catch list...
- if (lastCatchBody) {
- SourceLocation bodyLoc = lastCatchBody->getLocEnd();
- assert(*SM->getCharacterData(bodyLoc) == '}' &&
- "bogus @catch body location");
-
- // Insert the last (implicit) else clause *before* the right curly brace.
- bodyLoc = bodyLoc.getFileLocWithOffset(-1);
- buf = "} /* last catch end */\n";
- buf += "else {\n";
- buf += " _rethrow = _caught;\n";
- buf += " objc_exception_try_exit(&_stack);\n";
- buf += "} } /* @catch end */\n";
- if (!S->getFinallyStmt())
- buf += "}\n";
- InsertText(bodyLoc, buf.c_str(), buf.size());
-
- // Set lastCurlyLoc
- lastCurlyLoc = lastCatchBody->getLocEnd();
- }
- if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
- startLoc = finalStmt->getLocStart();
- startBuf = SM->getCharacterData(startLoc);
- assert((*startBuf == '@') && "bogus @finally start");
-
- buf = "/* @finally */";
- ReplaceText(startLoc, 8, buf.c_str(), buf.size());
-
- Stmt *body = finalStmt->getFinallyBody();
- SourceLocation startLoc = body->getLocStart();
- SourceLocation endLoc = body->getLocEnd();
- assert(*SM->getCharacterData(startLoc) == '{' &&
- "bogus @finally body location");
- assert(*SM->getCharacterData(endLoc) == '}' &&
- "bogus @finally body location");
-
- startLoc = startLoc.getFileLocWithOffset(1);
- buf = " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- InsertText(startLoc, buf.c_str(), buf.size());
- endLoc = endLoc.getFileLocWithOffset(-1);
- buf = " if (_rethrow) objc_exception_throw(_rethrow);\n";
- InsertText(endLoc, buf.c_str(), buf.size());
-
- // Set lastCurlyLoc
- lastCurlyLoc = body->getLocEnd();
- } else { /* no finally clause - make sure we synthesize an implicit one */
- buf = "{ /* implicit finally clause */\n";
- buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
- buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
- }
- // Now emit the final closing curly brace...
- lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);
- buf = " } /* @try scope end */\n";
- InsertText(lastCurlyLoc, buf.c_str(), buf.size());
- return 0;
-}
-
-Stmt *RewriteObjC::RewriteObjCCatchStmt(ObjCAtCatchStmt *S) {
- return 0;
-}
-
-Stmt *RewriteObjC::RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S) {
- return 0;
-}
-
-// This can't be done with ReplaceStmt(S, ThrowExpr), since
-// the throw expression is typically a message expression that's already
-// been rewritten! (which implies the SourceLocation's are invalid).
-Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
- // Get the start location and compute the semi location.
- SourceLocation startLoc = S->getLocStart();
- const char *startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '@') && "bogus @throw location");
-
- std::string buf;
- /* void objc_exception_throw(id) __attribute__((noreturn)); */
- if (S->getThrowExpr())
- buf = "objc_exception_throw(";
- else // add an implicit argument
- buf = "objc_exception_throw(_caught";
-
- // handle "@ throw" correctly.
- const char *wBuf = strchr(startBuf, 'w');
- assert((*wBuf == 'w') && "@throw: can't find 'w'");
- ReplaceText(startLoc, wBuf-startBuf+1, buf.c_str(), buf.size());
-
- const char *semiBuf = strchr(startBuf, ';');
- assert((*semiBuf == ';') && "@throw: can't find ';'");
- SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
- buf = ");";
- ReplaceText(semiLoc, 1, buf.c_str(), buf.size());
- return 0;
-}
-
-Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
- // Create a new string expression.
- QualType StrType = Context->getPointerType(Context->CharTy);
- std::string StrEncoding;
- Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding,
- EncodingRecordTypes);
- Expr *Replacement = new StringLiteral(StrEncoding.c_str(),
- StrEncoding.length(), false, StrType,
- SourceLocation(), SourceLocation());
- ReplaceStmt(Exp, Replacement);
-
- // Replace this subexpr in the parent.
- delete Exp;
- return Replacement;
-}
-
-Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
- assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
- // Create a call to sel_registerName("selName").
- llvm::SmallVector<Expr*, 8> SelExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- SelExprs.push_back(new StringLiteral(Exp->getSelector().getName().c_str(),
- Exp->getSelector().getName().size(),
- false, argType, SourceLocation(),
- SourceLocation()));
- CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size());
- ReplaceStmt(Exp, SelExp);
- delete Exp;
- return SelExp;
-}
-
-CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
- FunctionDecl *FD, Expr **args, unsigned nargs) {
- // Get the type, we will need to reference it in a couple spots.
- QualType msgSendType = FD->getType();
-
- // Create a reference to the objc_msgSend() declaration.
- DeclRefExpr *DRE = new DeclRefExpr(FD, msgSendType, SourceLocation());
-
- // Now, we cast the reference to a pointer to the objc_msgSend type.
- QualType pToFunc = Context->getPointerType(msgSendType);
- ImplicitCastExpr *ICE = new ImplicitCastExpr(pToFunc, DRE);
-
- const FunctionType *FT = msgSendType->getAsFunctionType();
-
- return new CallExpr(ICE, args, nargs, FT->getResultType(), SourceLocation());
-}
-
-static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
- const char *&startRef, const char *&endRef) {
- while (startBuf < endBuf) {
- if (*startBuf == '<')
- startRef = startBuf; // mark the start.
- if (*startBuf == '>') {
- if (startRef && *startRef == '<') {
- endRef = startBuf; // mark the end.
- return true;
- }
- return false;
- }
- startBuf++;
- }
- return false;
-}
-
-static void scanToNextArgument(const char *&argRef) {
- int angle = 0;
- while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
- if (*argRef == '<')
- angle++;
- else if (*argRef == '>')
- angle--;
- argRef++;
- }
- assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
-}
-
-bool RewriteObjC::needToScanForQualifiers(QualType T) {
-
- if (T->isObjCQualifiedIdType())
- return true;
-
- if (const PointerType *pType = T->getAsPointerType()) {
- Type *pointeeType = pType->getPointeeType().getTypePtr();
- if (isa<ObjCQualifiedInterfaceType>(pointeeType))
- return true; // we have "Class <Protocol> *".
- }
- return false;
-}
-
-void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
- QualType Type = E->getType();
- if (needToScanForQualifiers(Type)) {
- SourceLocation Loc = E->getLocStart();
- const char *startBuf = SM->getCharacterData(Loc);
- const char *endBuf = SM->getCharacterData(E->getLocEnd());
- const char *startRef = 0, *endRef = 0;
- if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
- // Get the locations of the startRef, endRef.
- SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf);
- SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1);
- // Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
- }
- }
-}
-
-void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
- SourceLocation Loc;
- QualType Type;
- const FunctionTypeProto *proto = 0;
- if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
- Loc = VD->getLocation();
- Type = VD->getType();
- }
- else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
- Loc = FD->getLocation();
- // Check for ObjC 'id' and class types that have been adorned with protocol
- // information (id<p>, C<p>*). The protocol references need to be rewritten!
- const FunctionType *funcType = FD->getType()->getAsFunctionType();
- assert(funcType && "missing function type");
- proto = dyn_cast<FunctionTypeProto>(funcType);
- if (!proto)
- return;
- Type = proto->getResultType();
- }
- else
- return;
-
- if (needToScanForQualifiers(Type)) {
- // Since types are unique, we need to scan the buffer.
-
- const char *endBuf = SM->getCharacterData(Loc);
- const char *startBuf = endBuf;
- while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
- startBuf--; // scan backward (from the decl location) for return type.
- const char *startRef = 0, *endRef = 0;
- if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
- // Get the locations of the startRef, endRef.
- SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf);
- SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1);
- // Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
- }
- }
- if (!proto)
- return; // most likely, was a variable
- // Now check arguments.
- const char *startBuf = SM->getCharacterData(Loc);
- const char *startFuncBuf = startBuf;
- for (unsigned i = 0; i < proto->getNumArgs(); i++) {
- if (needToScanForQualifiers(proto->getArgType(i))) {
- // Since types are unique, we need to scan the buffer.
-
- const char *endBuf = startBuf;
- // scan forward (from the decl location) for argument types.
- scanToNextArgument(endBuf);
- const char *startRef = 0, *endRef = 0;
- if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
- // Get the locations of the startRef, endRef.
- SourceLocation LessLoc =
- Loc.getFileLocWithOffset(startRef-startFuncBuf);
- SourceLocation GreaterLoc =
- Loc.getFileLocWithOffset(endRef-startFuncBuf+1);
- // Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
- }
- startBuf = ++endBuf;
- }
- else {
- // If the function name is derived from a macro expansion, then the
- // argument buffer will not follow the name. Need to speak with Chris.
- while (*startBuf && *startBuf != ')' && *startBuf != ',')
- startBuf++; // scan forward (from the decl location) for argument types.
- startBuf++;
- }
- }
-}
-
-// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
-void RewriteObjC::SynthSelGetUidFunctionDecl() {
- IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
- llvm::SmallVector<QualType, 16> ArgTys;
- ArgTys.push_back(Context->getPointerType(
- Context->CharTy.getQualifiedType(QualType::Const)));
- QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
- &ArgTys[0], ArgTys.size(),
- false /*isVariadic*/);
- SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- SelGetUidIdent, getFuncType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthGetProtocolFunctionDecl - Protocol objc_getProtocol(const char *proto);
-void RewriteObjC::SynthGetProtocolFunctionDecl() {
- IdentifierInfo *SelGetProtoIdent = &Context->Idents.get("objc_getProtocol");
- llvm::SmallVector<QualType, 16> ArgTys;
- ArgTys.push_back(Context->getPointerType(
- Context->CharTy.getQualifiedType(QualType::Const)));
- QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(),
- &ArgTys[0], ArgTys.size(),
- false /*isVariadic*/);
- GetProtocolFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- SelGetProtoIdent, getFuncType,
- FunctionDecl::Extern, false, 0);
-}
-
-void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
- // declared in <objc/objc.h>
- if (strcmp(FD->getName(), "sel_registerName") == 0) {
- SelGetUidFunctionDecl = FD;
- return;
- }
- RewriteObjCQualifiedInterfaceTypes(FD);
-}
-
-// SynthSuperContructorFunctionDecl - id objc_super(id obj, id super);
-void RewriteObjC::SynthSuperContructorFunctionDecl() {
- if (SuperContructorFunctionDecl)
- return;
- IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_super");
- llvm::SmallVector<QualType, 16> ArgTys;
- QualType argT = Context->getObjCIdType();
- assert(!argT.isNull() && "Can't find 'id' type");
- ArgTys.push_back(argT);
- ArgTys.push_back(argT);
- QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- false);
- SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- msgSendIdent, msgSendType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
-void RewriteObjC::SynthMsgSendFunctionDecl() {
- IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
- llvm::SmallVector<QualType, 16> ArgTys;
- QualType argT = Context->getObjCIdType();
- assert(!argT.isNull() && "Can't find 'id' type");
- ArgTys.push_back(argT);
- argT = Context->getObjCSelType();
- assert(!argT.isNull() && "Can't find 'SEL' type");
- ArgTys.push_back(argT);
- QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- true /*isVariadic*/);
- MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- msgSendIdent, msgSendType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
-void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
- IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
- llvm::SmallVector<QualType, 16> ArgTys;
- RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("objc_super"));
- QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
- assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
- ArgTys.push_back(argT);
- argT = Context->getObjCSelType();
- assert(!argT.isNull() && "Can't find 'SEL' type");
- ArgTys.push_back(argT);
- QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- true /*isVariadic*/);
- MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- msgSendIdent, msgSendType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
-void RewriteObjC::SynthMsgSendStretFunctionDecl() {
- IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
- llvm::SmallVector<QualType, 16> ArgTys;
- QualType argT = Context->getObjCIdType();
- assert(!argT.isNull() && "Can't find 'id' type");
- ArgTys.push_back(argT);
- argT = Context->getObjCSelType();
- assert(!argT.isNull() && "Can't find 'SEL' type");
- ArgTys.push_back(argT);
- QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- true /*isVariadic*/);
- MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- msgSendIdent, msgSendType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthMsgSendSuperStretFunctionDecl -
-// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
-void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
- IdentifierInfo *msgSendIdent =
- &Context->Idents.get("objc_msgSendSuper_stret");
- llvm::SmallVector<QualType, 16> ArgTys;
- RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("objc_super"));
- QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
- assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
- ArgTys.push_back(argT);
- argT = Context->getObjCSelType();
- assert(!argT.isNull() && "Can't find 'SEL' type");
- ArgTys.push_back(argT);
- QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- true /*isVariadic*/);
- MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- msgSendIdent, msgSendType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
-void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
- IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
- llvm::SmallVector<QualType, 16> ArgTys;
- QualType argT = Context->getObjCIdType();
- assert(!argT.isNull() && "Can't find 'id' type");
- ArgTys.push_back(argT);
- argT = Context->getObjCSelType();
- assert(!argT.isNull() && "Can't find 'SEL' type");
- ArgTys.push_back(argT);
- QualType msgSendType = Context->getFunctionType(Context->DoubleTy,
- &ArgTys[0], ArgTys.size(),
- true /*isVariadic*/);
- MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- msgSendIdent, msgSendType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
-void RewriteObjC::SynthGetClassFunctionDecl() {
- IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
- llvm::SmallVector<QualType, 16> ArgTys;
- ArgTys.push_back(Context->getPointerType(
- Context->CharTy.getQualifiedType(QualType::Const)));
- QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- false /*isVariadic*/);
- GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- getClassIdent, getClassType,
- FunctionDecl::Extern, false, 0);
-}
-
-// SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
-void RewriteObjC::SynthGetMetaClassFunctionDecl() {
- IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
- llvm::SmallVector<QualType, 16> ArgTys;
- ArgTys.push_back(Context->getPointerType(
- Context->CharTy.getQualifiedType(QualType::Const)));
- QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
- &ArgTys[0], ArgTys.size(),
- false /*isVariadic*/);
- GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- getClassIdent, getClassType,
- FunctionDecl::Extern, false, 0);
-}
-
-Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
- QualType strType = getConstantStringStructType();
-
- std::string S = "__NSConstantStringImpl_";
-
- std::string tmpName = InFileName;
- unsigned i;
- for (i=0; i < tmpName.length(); i++) {
- char c = tmpName.at(i);
- // replace any non alphanumeric characters with '_'.
- if (!isalpha(c) && (c < '0' || c > '9'))
- tmpName[i] = '_';
- }
- S += tmpName;
- S += "_";
- S += utostr(NumObjCStringLiterals++);
-
- Preamble += "static __NSConstantStringImpl " + S;
- Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
- Preamble += "0x000007c8,"; // utf8_str
- // The pretty printer for StringLiteral handles escape characters properly.
- std::string prettyBufS;
- llvm::raw_string_ostream prettyBuf(prettyBufS);
- Exp->getString()->printPretty(prettyBuf);
- Preamble += prettyBuf.str();
- Preamble += ",";
- // The minus 2 removes the begin/end double quotes.
- Preamble += utostr(prettyBuf.str().size()-2) + "};\n";
-
- VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
- &Context->Idents.get(S.c_str()), strType,
- VarDecl::Static, NULL);
- DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation());
- Expr *Unop = new UnaryOperator(DRE, UnaryOperator::AddrOf,
- Context->getPointerType(DRE->getType()),
- SourceLocation());
- // cast to NSConstantString *
- CastExpr *cast = new ExplicitCastExpr(Exp->getType(), Unop, SourceLocation());
- ReplaceStmt(Exp, cast);
- delete Exp;
- return cast;
-}
-
-ObjCInterfaceDecl *RewriteObjC::isSuperReceiver(Expr *recExpr) {
- // check if we are sending a message to 'super'
- if (!CurMethodDecl || !CurMethodDecl->isInstance()) return 0;
-
- if (PredefinedExpr *PDE = dyn_cast<PredefinedExpr>(recExpr))
- if (PDE->getIdentType() == PredefinedExpr::ObjCSuper) {
- const PointerType *PT = PDE->getType()->getAsPointerType();
- assert(PT);
- ObjCInterfaceType *IT = cast<ObjCInterfaceType>(PT->getPointeeType());
- return IT->getDecl();
- }
- return 0;
-}
-
-// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
-QualType RewriteObjC::getSuperStructType() {
- if (!SuperStructDecl) {
- SuperStructDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("objc_super"));
- QualType FieldTypes[2];
-
- // struct objc_object *receiver;
- FieldTypes[0] = Context->getObjCIdType();
- // struct objc_class *super;
- FieldTypes[1] = Context->getObjCClassType();
- // Create fields
- FieldDecl *FieldDecls[2];
-
- for (unsigned i = 0; i < 2; ++i)
- FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0,
- FieldTypes[i]);
-
- SuperStructDecl->defineBody(*Context, FieldDecls, 4);
- }
- return Context->getTagDeclType(SuperStructDecl);
-}
-
-QualType RewriteObjC::getConstantStringStructType() {
- if (!ConstantStringDecl) {
- ConstantStringDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("__NSConstantStringImpl"));
- QualType FieldTypes[4];
-
- // struct objc_object *receiver;
- FieldTypes[0] = Context->getObjCIdType();
- // int flags;
- FieldTypes[1] = Context->IntTy;
- // char *str;
- FieldTypes[2] = Context->getPointerType(Context->CharTy);
- // long length;
- FieldTypes[3] = Context->LongTy;
- // Create fields
- FieldDecl *FieldDecls[4];
-
- for (unsigned i = 0; i < 4; ++i)
- FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0,
- FieldTypes[i]);
-
- ConstantStringDecl->defineBody(*Context, FieldDecls, 4);
- }
- return Context->getTagDeclType(ConstantStringDecl);
-}
-
-Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
- if (!SelGetUidFunctionDecl)
- SynthSelGetUidFunctionDecl();
- if (!MsgSendFunctionDecl)
- SynthMsgSendFunctionDecl();
- if (!MsgSendSuperFunctionDecl)
- SynthMsgSendSuperFunctionDecl();
- if (!MsgSendStretFunctionDecl)
- SynthMsgSendStretFunctionDecl();
- if (!MsgSendSuperStretFunctionDecl)
- SynthMsgSendSuperStretFunctionDecl();
- if (!MsgSendFpretFunctionDecl)
- SynthMsgSendFpretFunctionDecl();
- if (!GetClassFunctionDecl)
- SynthGetClassFunctionDecl();
- if (!GetMetaClassFunctionDecl)
- SynthGetMetaClassFunctionDecl();
-
- // default to objc_msgSend().
- FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
- // May need to use objc_msgSend_stret() as well.
- FunctionDecl *MsgSendStretFlavor = 0;
- if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
- QualType resultType = mDecl->getResultType();
- if (resultType->isStructureType() || resultType->isUnionType())
- MsgSendStretFlavor = MsgSendStretFunctionDecl;
- else if (resultType->isRealFloatingType())
- MsgSendFlavor = MsgSendFpretFunctionDecl;
- }
-
- // Synthesize a call to objc_msgSend().
- llvm::SmallVector<Expr*, 8> MsgExprs;
- IdentifierInfo *clsName = Exp->getClassName();
-
- // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend().
- if (clsName) { // class message.
- // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle
- // the 'super' idiom within a class method.
- if (!strcmp(clsName->getName(), "super")) {
- MsgSendFlavor = MsgSendSuperFunctionDecl;
- if (MsgSendStretFlavor)
- MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
- assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
- ObjCInterfaceDecl *SuperDecl =
- CurMethodDecl->getClassInterface()->getSuperClass();
-
- llvm::SmallVector<Expr*, 4> InitExprs;
-
- // set the receiver to self, the first argument to all methods.
- InitExprs.push_back(new DeclRefExpr(
- CurMethodDecl->getSelfDecl(),
- Context->getObjCIdType(),
- SourceLocation()));
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(new StringLiteral(SuperDecl->getIdentifier()->getName(),
- SuperDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation(),
- SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size());
- // To turn off a warning, type-cast to 'id'
- InitExprs.push_back(
- new ExplicitCastExpr(Context->getObjCIdType(),
- Cls, SourceLocation())); // set 'super class', using objc_getClass().
- // struct objc_super
- QualType superType = getSuperStructType();
- Expr *SuperRep;
-
- if (LangOpts.Microsoft) {
- SynthSuperContructorFunctionDecl();
- // Simulate a contructor call...
- DeclRefExpr *DRE = new DeclRefExpr(SuperContructorFunctionDecl,
- superType, SourceLocation());
- SuperRep = new CallExpr(DRE, &InitExprs[0], InitExprs.size(),
- superType, SourceLocation());
- } else {
- // (struct objc_super) { <exprs from above> }
- InitListExpr *ILE = new InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- SuperRep = new CompoundLiteralExpr(SourceLocation(), superType, ILE, false);
- }
- // struct objc_super *
- Expr *Unop = new UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- MsgExprs.push_back(Unop);
- } else {
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(new StringLiteral(clsName->getName(),
- clsName->getLength(),
- false, argType, SourceLocation(),
- SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size());
- MsgExprs.push_back(Cls);
- }
- } else { // instance message.
- Expr *recExpr = Exp->getReceiver();
-
- if (ObjCInterfaceDecl *SuperDecl = isSuperReceiver(recExpr)) {
- MsgSendFlavor = MsgSendSuperFunctionDecl;
- if (MsgSendStretFlavor)
- MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
- assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
- llvm::SmallVector<Expr*, 4> InitExprs;
-
- InitExprs.push_back(
- new ExplicitCastExpr(Context->getObjCIdType(),
- new DeclRefExpr(CurMethodDecl->getSelfDecl(),
- Context->getObjCIdType(),
- SourceLocation()),
- SourceLocation())); // set the 'receiver'.
-
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(new StringLiteral(SuperDecl->getIdentifier()->getName(),
- SuperDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation(),
- SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size());
- // To turn off a warning, type-cast to 'id'
- InitExprs.push_back(
- new ExplicitCastExpr(Context->getObjCIdType(),
- Cls, SourceLocation())); // set 'super class', using objc_getClass().
- // struct objc_super
- QualType superType = getSuperStructType();
- Expr *SuperRep;
-
- if (LangOpts.Microsoft) {
- SynthSuperContructorFunctionDecl();
- // Simulate a contructor call...
- DeclRefExpr *DRE = new DeclRefExpr(SuperContructorFunctionDecl,
- superType, SourceLocation());
- SuperRep = new CallExpr(DRE, &InitExprs[0], InitExprs.size(),
- superType, SourceLocation());
- } else {
- // (struct objc_super) { <exprs from above> }
- InitListExpr *ILE = new InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- SuperRep = new CompoundLiteralExpr(SourceLocation(), superType, ILE, false);
- }
- // struct objc_super *
- Expr *Unop = new UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- MsgExprs.push_back(Unop);
- } else {
- // Remove all type-casts because it may contain objc-style types; e.g.
- // Foo<Proto> *.
- while (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(recExpr))
- recExpr = CE->getSubExpr();
- recExpr = new ExplicitCastExpr(Context->getObjCIdType(), recExpr,
- SourceLocation());
- MsgExprs.push_back(recExpr);
- }
- }
- // Create a call to sel_registerName("selName"), it will be the 2nd argument.
- llvm::SmallVector<Expr*, 8> SelExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- SelExprs.push_back(new StringLiteral(Exp->getSelector().getName().c_str(),
- Exp->getSelector().getName().size(),
- false, argType, SourceLocation(),
- SourceLocation()));
- CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size());
- MsgExprs.push_back(SelExp);
-
- // Now push any user supplied arguments.
- for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
- Expr *userExpr = Exp->getArg(i);
- // Make all implicit casts explicit...ICE comes in handy:-)
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
- // Reuse the ICE type, it is exactly what the doctor ordered.
- userExpr = new ExplicitCastExpr(ICE->getType()->isObjCQualifiedIdType()
- ? Context->getObjCIdType()
- : ICE->getType(), userExpr, SourceLocation());
- }
- // Make id<P...> cast into an 'id' cast.
- else if (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(userExpr)) {
- if (CE->getType()->isObjCQualifiedIdType()) {
- while ((CE = dyn_cast<ExplicitCastExpr>(userExpr)))
- userExpr = CE->getSubExpr();
- userExpr = new ExplicitCastExpr(Context->getObjCIdType(),
- userExpr, SourceLocation());
- }
- }
- MsgExprs.push_back(userExpr);
- // We've transferred the ownership to MsgExprs. Null out the argument in
- // the original expression, since we will delete it below.
- Exp->setArg(i, 0);
- }
- // Generate the funky cast.
- CastExpr *cast;
- llvm::SmallVector<QualType, 8> ArgTypes;
- QualType returnType;
-
- // Push 'id' and 'SEL', the 2 implicit arguments.
- if (MsgSendFlavor == MsgSendSuperFunctionDecl)
- ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
- else
- ArgTypes.push_back(Context->getObjCIdType());
- ArgTypes.push_back(Context->getObjCSelType());
- if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
- // Push any user argument types.
- for (unsigned i = 0; i < mDecl->getNumParams(); i++) {
- QualType t = mDecl->getParamDecl(i)->getType()->isObjCQualifiedIdType()
- ? Context->getObjCIdType()
- : mDecl->getParamDecl(i)->getType();
- ArgTypes.push_back(t);
- }
- returnType = mDecl->getResultType()->isObjCQualifiedIdType()
- ? Context->getObjCIdType() : mDecl->getResultType();
- } else {
- returnType = Context->getObjCIdType();
- }
- // Get the type, we will need to reference it in a couple spots.
- QualType msgSendType = MsgSendFlavor->getType();
-
- // Create a reference to the objc_msgSend() declaration.
- DeclRefExpr *DRE = new DeclRefExpr(MsgSendFlavor, msgSendType,
- SourceLocation());
-
- // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
- // If we don't do this cast, we get the following bizarre warning/note:
- // xx.m:13: warning: function called through a non-compatible type
- // xx.m:13: note: if this code is reached, the program will abort
- cast = new ExplicitCastExpr(Context->getPointerType(Context->VoidTy), DRE,
- SourceLocation());
-
- // Now do the "normal" pointer to function cast.
- QualType castType = Context->getFunctionType(returnType,
- &ArgTypes[0], ArgTypes.size(),
- // If we don't have a method decl, force a variadic cast.
- Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true);
- castType = Context->getPointerType(castType);
- cast = new ExplicitCastExpr(castType, cast, SourceLocation());
-
- // Don't forget the parens to enforce the proper binding.
- ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), cast);
-
- const FunctionType *FT = msgSendType->getAsFunctionType();
- CallExpr *CE = new CallExpr(PE, &MsgExprs[0], MsgExprs.size(),
- FT->getResultType(), SourceLocation());
- Stmt *ReplacingStmt = CE;
- if (MsgSendStretFlavor) {
- // We have the method which returns a struct/union. Must also generate
- // call to objc_msgSend_stret and hang both varieties on a conditional
- // expression which dictate which one to envoke depending on size of
- // method's return type.
-
- // Create a reference to the objc_msgSend_stret() declaration.
- DeclRefExpr *STDRE = new DeclRefExpr(MsgSendStretFlavor, msgSendType,
- SourceLocation());
- // Need to cast objc_msgSend_stret to "void *" (see above comment).
- cast = new ExplicitCastExpr(Context->getPointerType(Context->VoidTy), STDRE,
- SourceLocation());
- // Now do the "normal" pointer to function cast.
- castType = Context->getFunctionType(returnType,
- &ArgTypes[0], ArgTypes.size(),
- Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false);
- castType = Context->getPointerType(castType);
- cast = new ExplicitCastExpr(castType, cast, SourceLocation());
-
- // Don't forget the parens to enforce the proper binding.
- PE = new ParenExpr(SourceLocation(), SourceLocation(), cast);
-
- FT = msgSendType->getAsFunctionType();
- CallExpr *STCE = new CallExpr(PE, &MsgExprs[0], MsgExprs.size(),
- FT->getResultType(), SourceLocation());
-
- // Build sizeof(returnType)
- SizeOfAlignOfTypeExpr *sizeofExpr = new SizeOfAlignOfTypeExpr(true,
- returnType, Context->getSizeType(),
- SourceLocation(), SourceLocation());
- // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
- // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
- // For X86 it is more complicated and some kind of target specific routine
- // is needed to decide what to do.
- unsigned IntSize =
- static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
- IntegerLiteral *limit = new IntegerLiteral(llvm::APInt(IntSize, 8),
- Context->IntTy,
- SourceLocation());
- BinaryOperator *lessThanExpr = new BinaryOperator(sizeofExpr, limit,
- BinaryOperator::LE,
- Context->IntTy,
- SourceLocation());
- // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
- ConditionalOperator *CondExpr =
- new ConditionalOperator(lessThanExpr, CE, STCE, returnType);
- ReplacingStmt = new ParenExpr(SourceLocation(), SourceLocation(), CondExpr);
- }
- return ReplacingStmt;
-}
-
-Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
- Stmt *ReplacingStmt = SynthMessageExpr(Exp);
- // Now do the actual rewrite.
- ReplaceStmt(Exp, ReplacingStmt);
-
- delete Exp;
- return ReplacingStmt;
-}
-
-/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
-/// call to objc_getProtocol("proto-name").
-Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
- if (!GetProtocolFunctionDecl)
- SynthGetProtocolFunctionDecl();
- // Create a call to objc_getProtocol("ProtocolName").
- llvm::SmallVector<Expr*, 8> ProtoExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getName(),
- strlen(Exp->getProtocol()->getName()),
- false, argType, SourceLocation(),
- SourceLocation()));
- CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
- &ProtoExprs[0],
- ProtoExprs.size());
- ReplaceStmt(Exp, ProtoExp);
- delete Exp;
- return ProtoExp;
-
-}
-
-bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
- const char *endBuf) {
- while (startBuf < endBuf) {
- if (*startBuf == '#') {
- // Skip whitespace.
- for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
- ;
- if (!strncmp(startBuf, "if", strlen("if")) ||
- !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
- !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
- !strncmp(startBuf, "define", strlen("define")) ||
- !strncmp(startBuf, "undef", strlen("undef")) ||
- !strncmp(startBuf, "else", strlen("else")) ||
- !strncmp(startBuf, "elif", strlen("elif")) ||
- !strncmp(startBuf, "endif", strlen("endif")) ||
- !strncmp(startBuf, "pragma", strlen("pragma")) ||
- !strncmp(startBuf, "include", strlen("include")) ||
- !strncmp(startBuf, "import", strlen("import")) ||
- !strncmp(startBuf, "include_next", strlen("include_next")))
- return true;
- }
- startBuf++;
- }
- return false;
-}
-
-/// SynthesizeObjCInternalStruct - Rewrite one internal struct corresponding to
-/// an objective-c class with ivars.
-void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
- std::string &Result) {
- assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
- assert(CDecl->getName() && "Name missing in SynthesizeObjCInternalStruct");
- // Do not synthesize more than once.
- if (ObjCSynthesizedStructs.count(CDecl))
- return;
- ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
- int NumIvars = CDecl->ivar_size();
- SourceLocation LocStart = CDecl->getLocStart();
- SourceLocation LocEnd = CDecl->getLocEnd();
-
- const char *startBuf = SM->getCharacterData(LocStart);
- const char *endBuf = SM->getCharacterData(LocEnd);
-
- // If no ivars and no root or if its root, directly or indirectly,
- // have no ivars (thus not synthesized) then no need to synthesize this class.
- if ((CDecl->isForwardDecl() || NumIvars == 0) &&
- (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
- endBuf += Lexer::MeasureTokenLength(LocEnd, *SM);
- ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
- return;
- }
-
- // FIXME: This has potential of causing problem. If
- // SynthesizeObjCInternalStruct is ever called recursively.
- Result += "\nstruct ";
- Result += CDecl->getName();
- if (LangOpts.Microsoft)
- Result += "_IMPL";
-
- if (NumIvars > 0) {
- const char *cursor = strchr(startBuf, '{');
- assert((cursor && endBuf)
- && "SynthesizeObjCInternalStruct - malformed @interface");
- // If the buffer contains preprocessor directives, we do more fine-grained
- // rewrites. This is intended to fix code that looks like (which occurs in
- // NSURL.h, for example):
- //
- // #ifdef XYZ
- // @interface Foo : NSObject
- // #else
- // @interface FooBar : NSObject
- // #endif
- // {
- // int i;
- // }
- // @end
- //
- // This clause is segregated to avoid breaking the common case.
- if (BufferContainsPPDirectives(startBuf, cursor)) {
- SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() :
- CDecl->getClassLoc();
- const char *endHeader = SM->getCharacterData(L);
- endHeader += Lexer::MeasureTokenLength(L, *SM);
-
- if (!CDecl->getReferencedProtocols().empty()) {
- // advance to the end of the referenced protocols.
- while (endHeader < cursor && *endHeader != '>') endHeader++;
- endHeader++;
- }
- // rewrite the original header
- ReplaceText(LocStart, endHeader-startBuf, Result.c_str(), Result.size());
- } else {
- // rewrite the original header *without* disturbing the '{'
- ReplaceText(LocStart, cursor-startBuf-1, Result.c_str(), Result.size());
- }
- if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
- Result = "\n struct ";
- Result += RCDecl->getName();
- Result += "_IMPL ";
- Result += RCDecl->getName();
- Result += "_IVARS;\n";
-
- // insert the super class structure definition.
- SourceLocation OnePastCurly =
- LocStart.getFileLocWithOffset(cursor-startBuf+1);
- InsertText(OnePastCurly, Result.c_str(), Result.size());
- }
- cursor++; // past '{'
-
- // Now comment out any visibility specifiers.
- while (cursor < endBuf) {
- if (*cursor == '@') {
- SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- // Skip whitespace.
- for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
- /*scan*/;
-
- // FIXME: presence of @public, etc. inside comment results in
- // this transformation as well, which is still correct c-code.
- if (!strncmp(cursor, "public", strlen("public")) ||
- !strncmp(cursor, "private", strlen("private")) ||
- !strncmp(cursor, "package", strlen("package")) ||
- !strncmp(cursor, "protected", strlen("protected")))
- InsertText(atLoc, "// ", 3);
- }
- // FIXME: If there are cases where '<' is used in ivar declaration part
- // of user code, then scan the ivar list and use needToScanForQualifiers
- // for type checking.
- else if (*cursor == '<') {
- SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- InsertText(atLoc, "/* ", 3);
- cursor = strchr(cursor, '>');
- cursor++;
- atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- InsertText(atLoc, " */", 3);
- }
- cursor++;
- }
- // Don't forget to add a ';'!!
- InsertText(LocEnd.getFileLocWithOffset(1), ";", 1);
- } else { // we don't have any instance variables - insert super struct.
- endBuf += Lexer::MeasureTokenLength(LocEnd, *SM);
- Result += " {\n struct ";
- Result += RCDecl->getName();
- Result += "_IMPL ";
- Result += RCDecl->getName();
- Result += "_IVARS;\n};\n";
- ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
- }
- // Mark this struct as having been generated.
- if (!ObjCSynthesizedStructs.insert(CDecl))
- assert(false && "struct already synthesize- SynthesizeObjCInternalStruct");
-}
-
-// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
-/// class methods.
-void RewriteObjC::RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
- instmeth_iterator MethodEnd,
- bool IsInstanceMethod,
- const char *prefix,
- const char *ClassName,
- std::string &Result) {
- if (MethodBegin == MethodEnd) return;
-
- static bool objc_impl_method = false;
- if (!objc_impl_method) {
- /* struct _objc_method {
- SEL _cmd;
- char *method_types;
- void *_imp;
- }
- */
- Result += "\nstruct _objc_method {\n";
- Result += "\tSEL _cmd;\n";
- Result += "\tchar *method_types;\n";
- Result += "\tvoid *_imp;\n";
- Result += "};\n";
-
- objc_impl_method = true;
- }
-
- // Build _objc_method_list for class's methods if needed
-
- /* struct {
- struct _objc_method_list *next_method;
- int method_count;
- struct _objc_method method_list[];
- }
- */
- Result += "\nstatic struct {\n";
- Result += "\tstruct _objc_method_list *next_method;\n";
- Result += "\tint method_count;\n";
- Result += "\tstruct _objc_method method_list[";
- Result += utostr(MethodEnd-MethodBegin);
- Result += "];\n} _OBJC_";
- Result += prefix;
- Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
- Result += "_METHODS_";
- Result += ClassName;
- Result += " __attribute__ ((used, section (\"__OBJC, __";
- Result += IsInstanceMethod ? "inst" : "cls";
- Result += "_meth\")))= ";
- Result += "{\n\t0, " + utostr(MethodEnd-MethodBegin) + "\n";
-
- Result += "\t,{{(SEL)\"";
- Result += (*MethodBegin)->getSelector().getName().c_str();
- std::string MethodTypeString;
- Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
- Result += "\", \"";
- Result += MethodTypeString;
- Result += "\", (void *)";
- Result += MethodInternalNames[*MethodBegin];
- Result += "}\n";
- for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
- Result += "\t ,{(SEL)\"";
- Result += (*MethodBegin)->getSelector().getName().c_str();
- std::string MethodTypeString;
- Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
- Result += "\", \"";
- Result += MethodTypeString;
- Result += "\", (void *)";
- Result += MethodInternalNames[*MethodBegin];
- Result += "}\n";
- }
- Result += "\t }\n};\n";
-}
-
-/// RewriteObjCProtocolsMetaData - Rewrite protocols meta-data.
-void RewriteObjC::
-RewriteObjCProtocolsMetaData(const ObjCList<ObjCProtocolDecl> &Protocols,
- const char *prefix,
- const char *ClassName,
- std::string &Result) {
- static bool objc_protocol_methods = false;
- if (Protocols.empty()) return;
-
- for (unsigned i = 0; i != Protocols.size(); i++) {
- ObjCProtocolDecl *PDecl = Protocols[i];
- // Output struct protocol_methods holder of method selector and type.
- if (!objc_protocol_methods && !PDecl->isForwardDecl()) {
- /* struct protocol_methods {
- SEL _cmd;
- char *method_types;
- }
- */
- Result += "\nstruct protocol_methods {\n";
- Result += "\tSEL _cmd;\n";
- Result += "\tchar *method_types;\n";
- Result += "};\n";
-
- objc_protocol_methods = true;
- }
- // Do not synthesize the protocol more than once.
- if (ObjCSynthesizedProtocols.count(PDecl))
- continue;
-
- if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
- unsigned NumMethods = PDecl->getNumInstanceMethods();
- /* struct _objc_protocol_method_list {
- int protocol_method_count;
- struct protocol_methods protocols[];
- }
- */
- Result += "\nstatic struct {\n";
- Result += "\tint protocol_method_count;\n";
- Result += "\tstruct protocol_methods protocols[";
- Result += utostr(NumMethods);
- Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
- Result += PDecl->getName();
- Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
- "{\n\t" + utostr(NumMethods) + "\n";
-
- // Output instance methods declared in this protocol.
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
- E = PDecl->instmeth_end(); I != E; ++I) {
- if (I == PDecl->instmeth_begin())
- Result += "\t ,{{(SEL)\"";
- else
- Result += "\t ,{(SEL)\"";
- Result += (*I)->getSelector().getName().c_str();
- std::string MethodTypeString;
- Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
- Result += "\", \"";
- Result += MethodTypeString;
- Result += "\"}\n";
- }
- Result += "\t }\n};\n";
- }
-
- // Output class methods declared in this protocol.
- int NumMethods = PDecl->getNumClassMethods();
- if (NumMethods > 0) {
- /* struct _objc_protocol_method_list {
- int protocol_method_count;
- struct protocol_methods protocols[];
- }
- */
- Result += "\nstatic struct {\n";
- Result += "\tint protocol_method_count;\n";
- Result += "\tstruct protocol_methods protocols[";
- Result += utostr(NumMethods);
- Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
- Result += PDecl->getName();
- Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
- "{\n\t";
- Result += utostr(NumMethods);
- Result += "\n";
-
- // Output instance methods declared in this protocol.
- for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
- E = PDecl->classmeth_end(); I != E; ++I) {
- if (I == PDecl->classmeth_begin())
- Result += "\t ,{{(SEL)\"";
- else
- Result += "\t ,{(SEL)\"";
- Result += (*I)->getSelector().getName().c_str();
- std::string MethodTypeString;
- Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
- Result += "\", \"";
- Result += MethodTypeString;
- Result += "\"}\n";
- }
- Result += "\t }\n};\n";
- }
-
- // Output:
- /* struct _objc_protocol {
- // Objective-C 1.0 extensions
- struct _objc_protocol_extension *isa;
- char *protocol_name;
- struct _objc_protocol **protocol_list;
- struct _objc_protocol_method_list *instance_methods;
- struct _objc_protocol_method_list *class_methods;
- };
- */
- static bool objc_protocol = false;
- if (!objc_protocol) {
- Result += "\nstruct _objc_protocol {\n";
- Result += "\tstruct _objc_protocol_extension *isa;\n";
- Result += "\tchar *protocol_name;\n";
- Result += "\tstruct _objc_protocol **protocol_list;\n";
- Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
- Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
- Result += "};\n";
-
- objc_protocol = true;
- }
-
- Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
- Result += PDecl->getName();
- Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
- "{\n\t0, \"";
- Result += PDecl->getName();
- Result += "\", 0, ";
- if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
- Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
- Result += PDecl->getName();
- Result += ", ";
- }
- else
- Result += "0, ";
- if (PDecl->getNumClassMethods() > 0) {
- Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
- Result += PDecl->getName();
- Result += "\n";
- }
- else
- Result += "0\n";
- Result += "};\n";
-
- // Mark this protocol as having been generated.
- if (!ObjCSynthesizedProtocols.insert(PDecl))
- assert(false && "protocol already synthesized");
- }
- // Output the top lovel protocol meta-data for the class.
- /* struct _objc_protocol_list {
- struct _objc_protocol_list *next;
- int protocol_count;
- struct _objc_protocol *class_protocols[];
- }
- */
- Result += "\nstatic struct {\n";
- Result += "\tstruct _objc_protocol_list *next;\n";
- Result += "\tint protocol_count;\n";
- Result += "\tstruct _objc_protocol *class_protocols[";
- Result += utostr(Protocols.size());
- Result += "];\n} _OBJC_";
- Result += prefix;
- Result += "_PROTOCOLS_";
- Result += ClassName;
- Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
- "{\n\t0, ";
- Result += utostr(Protocols.size());
- Result += "\n";
-
- Result += "\t,{&_OBJC_PROTOCOL_";
- Result += Protocols[0]->getName();
- Result += " \n";
-
- for (unsigned i = 1; i != Protocols.size(); i++) {
- Result += "\t ,&_OBJC_PROTOCOL_";
- Result += Protocols[i]->getName();
- Result += "\n";
- }
- Result += "\t }\n};\n";
-}
-
-/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
-/// implementation.
-void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
- std::string &Result) {
- ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
- // Find category declaration for this implementation.
- ObjCCategoryDecl *CDecl;
- for (CDecl = ClassDecl->getCategoryList(); CDecl;
- CDecl = CDecl->getNextClassCategory())
- if (CDecl->getIdentifier() == IDecl->getIdentifier())
- break;
-
- std::string FullCategoryName = ClassDecl->getName();
- FullCategoryName += '_';
- FullCategoryName += IDecl->getName();
-
- // Build _objc_method_list for class's instance methods if needed
- RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
- true, "CATEGORY_", FullCategoryName.c_str(),
- Result);
-
- // Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
- false, "CATEGORY_", FullCategoryName.c_str(),
- Result);
-
- // Protocols referenced in class declaration?
- // Null CDecl is case of a category implementation with no category interface
- if (CDecl)
- RewriteObjCProtocolsMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
- FullCategoryName.c_str(), Result);
-
- /* struct _objc_category {
- char *category_name;
- char *class_name;
- struct _objc_method_list *instance_methods;
- struct _objc_method_list *class_methods;
- struct _objc_protocol_list *protocols;
- // Objective-C 1.0 extensions
- uint32_t size; // sizeof (struct _objc_category)
- struct _objc_property_list *instance_properties; // category's own
- // @property decl.
- };
- */
-
- static bool objc_category = false;
- if (!objc_category) {
- Result += "\nstruct _objc_category {\n";
- Result += "\tchar *category_name;\n";
- Result += "\tchar *class_name;\n";
- Result += "\tstruct _objc_method_list *instance_methods;\n";
- Result += "\tstruct _objc_method_list *class_methods;\n";
- Result += "\tstruct _objc_protocol_list *protocols;\n";
- Result += "\tunsigned int size;\n";
- Result += "\tstruct _objc_property_list *instance_properties;\n";
- Result += "};\n";
- objc_category = true;
- }
- Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
- Result += FullCategoryName;
- Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
- Result += IDecl->getName();
- Result += "\"\n\t, \"";
- Result += ClassDecl->getName();
- Result += "\"\n";
-
- if (IDecl->getNumInstanceMethods() > 0) {
- Result += "\t, (struct _objc_method_list *)"
- "&_OBJC_CATEGORY_INSTANCE_METHODS_";
- Result += FullCategoryName;
- Result += "\n";
- }
- else
- Result += "\t, 0\n";
- if (IDecl->getNumClassMethods() > 0) {
- Result += "\t, (struct _objc_method_list *)"
- "&_OBJC_CATEGORY_CLASS_METHODS_";
- Result += FullCategoryName;
- Result += "\n";
- }
- else
- Result += "\t, 0\n";
-
- if (CDecl && !CDecl->getReferencedProtocols().empty()) {
- Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
- Result += FullCategoryName;
- Result += "\n";
- }
- else
- Result += "\t, 0\n";
- Result += "\t, sizeof(struct _objc_category), 0\n};\n";
-}
-
-/// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
-/// ivar offset.
-void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl,
- ObjCIvarDecl *ivar,
- std::string &Result) {
- if (ivar->isBitField()) {
- // FIXME: The hack below doesn't work for bitfields. For now, we simply
- // place all bitfields at offset 0.
- Result += "0";
- } else {
- Result += "__OFFSETOFIVAR__(struct ";
- Result += IDecl->getName();
- if (LangOpts.Microsoft)
- Result += "_IMPL";
- Result += ", ";
- Result += ivar->getName();
- Result += ")";
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Meta Data Emission
-//===----------------------------------------------------------------------===//
-
-void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
- std::string &Result) {
- ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
-
- // Explictly declared @interface's are already synthesized.
- if (CDecl->ImplicitInterfaceDecl()) {
- // FIXME: Implementation of a class with no @interface (legacy) doese not
- // produce correct synthesis as yet.
- SynthesizeObjCInternalStruct(CDecl, Result);
- }
-
- // Build _objc_ivar_list metadata for classes ivars if needed
- unsigned NumIvars = !IDecl->ivar_empty()
- ? IDecl->ivar_size()
- : (CDecl ? CDecl->ivar_size() : 0);
- if (NumIvars > 0) {
- static bool objc_ivar = false;
- if (!objc_ivar) {
- /* struct _objc_ivar {
- char *ivar_name;
- char *ivar_type;
- int ivar_offset;
- };
- */
- Result += "\nstruct _objc_ivar {\n";
- Result += "\tchar *ivar_name;\n";
- Result += "\tchar *ivar_type;\n";
- Result += "\tint ivar_offset;\n";
- Result += "};\n";
-
- objc_ivar = true;
- }
-
- /* struct {
- int ivar_count;
- struct _objc_ivar ivar_list[nIvars];
- };
- */
- Result += "\nstatic struct {\n";
- Result += "\tint ivar_count;\n";
- Result += "\tstruct _objc_ivar ivar_list[";
- Result += utostr(NumIvars);
- Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
- Result += IDecl->getName();
- Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
- "{\n\t";
- Result += utostr(NumIvars);
- Result += "\n";
-
- ObjCInterfaceDecl::ivar_iterator IVI, IVE;
- if (!IDecl->ivar_empty()) {
- IVI = IDecl->ivar_begin();
- IVE = IDecl->ivar_end();
- } else {
- IVI = CDecl->ivar_begin();
- IVE = CDecl->ivar_end();
- }
- Result += "\t,{{\"";
- Result += (*IVI)->getName();
- Result += "\", \"";
- std::string StrEncoding;
- Context->getObjCEncodingForType((*IVI)->getType(), StrEncoding,
- EncodingRecordTypes);
- Result += StrEncoding;
- Result += "\", ";
- SynthesizeIvarOffsetComputation(IDecl, *IVI, Result);
- Result += "}\n";
- for (++IVI; IVI != IVE; ++IVI) {
- Result += "\t ,{\"";
- Result += (*IVI)->getName();
- Result += "\", \"";
- std::string StrEncoding;
- Context->getObjCEncodingForType((*IVI)->getType(), StrEncoding,
- EncodingRecordTypes);
- Result += StrEncoding;
- Result += "\", ";
- SynthesizeIvarOffsetComputation(IDecl, (*IVI), Result);
- Result += "}\n";
- }
-
- Result += "\t }\n};\n";
- }
-
- // Build _objc_method_list for class's instance methods if needed
- RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
- true, "", IDecl->getName(), Result);
-
- // Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
- false, "", IDecl->getName(), Result);
-
- // Protocols referenced in class declaration?
- RewriteObjCProtocolsMetaData(CDecl->getReferencedProtocols(),
- "CLASS", CDecl->getName(), Result);
-
-
- // Declaration of class/meta-class metadata
- /* struct _objc_class {
- struct _objc_class *isa; // or const char *root_class_name when metadata
- const char *super_class_name;
- char *name;
- long version;
- long info;
- long instance_size;
- struct _objc_ivar_list *ivars;
- struct _objc_method_list *methods;
- struct objc_cache *cache;
- struct objc_protocol_list *protocols;
- const char *ivar_layout;
- struct _objc_class_ext *ext;
- };
- */
- static bool objc_class = false;
- if (!objc_class) {
- Result += "\nstruct _objc_class {\n";
- Result += "\tstruct _objc_class *isa;\n";
- Result += "\tconst char *super_class_name;\n";
- Result += "\tchar *name;\n";
- Result += "\tlong version;\n";
- Result += "\tlong info;\n";
- Result += "\tlong instance_size;\n";
- Result += "\tstruct _objc_ivar_list *ivars;\n";
- Result += "\tstruct _objc_method_list *methods;\n";
- Result += "\tstruct objc_cache *cache;\n";
- Result += "\tstruct _objc_protocol_list *protocols;\n";
- Result += "\tconst char *ivar_layout;\n";
- Result += "\tstruct _objc_class_ext *ext;\n";
- Result += "};\n";
- objc_class = true;
- }
-
- // Meta-class metadata generation.
- ObjCInterfaceDecl *RootClass = 0;
- ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
- while (SuperClass) {
- RootClass = SuperClass;
- SuperClass = SuperClass->getSuperClass();
- }
- SuperClass = CDecl->getSuperClass();
-
- Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
- Result += CDecl->getName();
- Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
- "{\n\t(struct _objc_class *)\"";
- Result += (RootClass ? RootClass->getName() : CDecl->getName());
- Result += "\"";
-
- if (SuperClass) {
- Result += ", \"";
- Result += SuperClass->getName();
- Result += "\", \"";
- Result += CDecl->getName();
- Result += "\"";
- }
- else {
- Result += ", 0, \"";
- Result += CDecl->getName();
- Result += "\"";
- }
- // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
- // 'info' field is initialized to CLS_META(2) for metaclass
- Result += ", 0,2, sizeof(struct _objc_class), 0";
- if (IDecl->getNumClassMethods() > 0) {
- Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
- Result += IDecl->getName();
- Result += "\n";
- }
- else
- Result += ", 0\n";
- if (!CDecl->getReferencedProtocols().empty()) {
- Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
- Result += CDecl->getName();
- Result += ",0,0\n";
- }
- else
- Result += "\t,0,0,0,0\n";
- Result += "};\n";
-
- // class metadata generation.
- Result += "\nstatic struct _objc_class _OBJC_CLASS_";
- Result += CDecl->getName();
- Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
- "{\n\t&_OBJC_METACLASS_";
- Result += CDecl->getName();
- if (SuperClass) {
- Result += ", \"";
- Result += SuperClass->getName();
- Result += "\", \"";
- Result += CDecl->getName();
- Result += "\"";
- }
- else {
- Result += ", 0, \"";
- Result += CDecl->getName();
- Result += "\"";
- }
- // 'info' field is initialized to CLS_CLASS(1) for class
- Result += ", 0,1";
- if (!ObjCSynthesizedStructs.count(CDecl))
- Result += ",0";
- else {
- // class has size. Must synthesize its size.
- Result += ",sizeof(struct ";
- Result += CDecl->getName();
- if (LangOpts.Microsoft)
- Result += "_IMPL";
- Result += ")";
- }
- if (NumIvars > 0) {
- Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
- Result += CDecl->getName();
- Result += "\n\t";
- }
- else
- Result += ",0";
- if (IDecl->getNumInstanceMethods() > 0) {
- Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
- Result += CDecl->getName();
- Result += ", 0\n\t";
- }
- else
- Result += ",0,0";
- if (!CDecl->getReferencedProtocols().empty()) {
- Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
- Result += CDecl->getName();
- Result += ", 0,0\n";
- }
- else
- Result += ",0,0,0\n";
- Result += "};\n";
-}
-
-/// RewriteImplementations - This routine rewrites all method implementations
-/// and emits meta-data.
-
-void RewriteObjC::RewriteImplementations(std::string &Result) {
- int ClsDefCount = ClassImplementation.size();
- int CatDefCount = CategoryImplementation.size();
-
- if (ClsDefCount == 0 && CatDefCount == 0)
- return;
- // Rewrite implemented methods
- for (int i = 0; i < ClsDefCount; i++)
- RewriteImplementationDecl(ClassImplementation[i]);
-
- for (int i = 0; i < CatDefCount; i++)
- RewriteImplementationDecl(CategoryImplementation[i]);
-
- // This is needed for determining instance variable offsets.
- Result += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)\n";
- // For each implemented class, write out all its meta data.
- for (int i = 0; i < ClsDefCount; i++)
- RewriteObjCClassMetaData(ClassImplementation[i], Result);
-
- // For each implemented category, write out all its meta data.
- for (int i = 0; i < CatDefCount; i++)
- RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
-
- // Write objc_symtab metadata
- /*
- struct _objc_symtab
- {
- long sel_ref_cnt;
- SEL *refs;
- short cls_def_cnt;
- short cat_def_cnt;
- void *defs[cls_def_cnt + cat_def_cnt];
- };
- */
-
- Result += "\nstruct _objc_symtab {\n";
- Result += "\tlong sel_ref_cnt;\n";
- Result += "\tSEL *refs;\n";
- Result += "\tshort cls_def_cnt;\n";
- Result += "\tshort cat_def_cnt;\n";
- Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
- Result += "};\n\n";
-
- Result += "static struct _objc_symtab "
- "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
- Result += "\t0, 0, " + utostr(ClsDefCount)
- + ", " + utostr(CatDefCount) + "\n";
- for (int i = 0; i < ClsDefCount; i++) {
- Result += "\t,&_OBJC_CLASS_";
- Result += ClassImplementation[i]->getName();
- Result += "\n";
- }
-
- for (int i = 0; i < CatDefCount; i++) {
- Result += "\t,&_OBJC_CATEGORY_";
- Result += CategoryImplementation[i]->getClassInterface()->getName();
- Result += "_";
- Result += CategoryImplementation[i]->getName();
- Result += "\n";
- }
-
- Result += "};\n\n";
-
- // Write objc_module metadata
-
- /*
- struct _objc_module {
- long version;
- long size;
- const char *name;
- struct _objc_symtab *symtab;
- }
- */
-
- Result += "\nstruct _objc_module {\n";
- Result += "\tlong version;\n";
- Result += "\tlong size;\n";
- Result += "\tconst char *name;\n";
- Result += "\tstruct _objc_symtab *symtab;\n";
- Result += "};\n\n";
- Result += "static struct _objc_module "
- "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
- Result += "\t" + utostr(OBJC_ABI_VERSION) +
- ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
- Result += "};\n\n";
-
- if (LangOpts.Microsoft) {
- Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
- Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
- Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
- Result += "&_OBJC_MODULES;\n";
- Result += "#pragma data_seg(pop)\n\n";
- }
-}
-
-
-
-
diff --git a/clang/Driver/SerializationTest.cpp b/clang/Driver/SerializationTest.cpp
deleted file mode 100644
index 9f93479912c9..000000000000
--- a/clang/Driver/SerializationTest.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-//===--- SerializationTest.cpp - Experimental Object Serialization --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements prototype code for serialization of objects in clang.
-// It is not intended yet for public use, but simply is a placeholder to
-// experiment with new serialization features. Serialization will eventually
-// be integrated as a proper component of the clang libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/CFG.h"
-#include "clang/AST/Decl.h"
-#include "clang.h"
-#include "ASTConsumers.h"
-#include "clang/AST/TranslationUnit.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/Streams.h"
-#include <fstream>
-#include <cstring>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Driver code.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class SerializationTest : public ASTConsumer {
- Diagnostic &Diags;
- FileManager &FMgr;
-public:
- SerializationTest(Diagnostic &d, FileManager& fmgr)
- : Diags(d), FMgr(fmgr) {}
-
- ~SerializationTest() {}
-
- virtual void HandleTranslationUnit(TranslationUnit& TU);
-
-private:
- bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint,
- TranslationUnit& TU);
-
- bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
-};
-
-} // end anonymous namespace
-
-ASTConsumer*
-clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr) {
- return new SerializationTest(Diags, FMgr);
-}
-
-
-bool SerializationTest::Serialize(llvm::sys::Path& Filename,
- llvm::sys::Path& FNameDeclPrint,
- TranslationUnit& TU) {
- {
- // Pretty-print the decls to a temp file.
- std::string Err;
- llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), Err);
- assert (Err.empty() && "Could not open file for printing out decls.");
- llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
-
- for (TranslationUnit::iterator I=TU.begin(), E=TU.end(); I!=E; ++I)
- FilePrinter->HandleTopLevelDecl(*I);
- }
-
- // Serialize the translation unit.
- return EmitASTBitcodeFile(TU,Filename);
-}
-
-bool SerializationTest::Deserialize(llvm::sys::Path& Filename,
- llvm::sys::Path& FNameDeclPrint) {
-
- // Deserialize the translation unit.
- TranslationUnit* NewTU = ReadASTBitcodeFile(Filename, FMgr);
-
- if (!NewTU)
- return false;
-
- {
- // Pretty-print the deserialized decls to a temp file.
- std::string Err;
- llvm::raw_fd_ostream DeclPP(FNameDeclPrint.c_str(), Err);
- assert (Err.empty() && "Could not open file for printing out decls.");
- llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
-
- for (TranslationUnit::iterator I=NewTU->begin(), E=NewTU->end(); I!=E; ++I)
- FilePrinter->HandleTopLevelDecl(*I);
- }
-
- delete NewTU;
-
- return true;
-}
-
-namespace {
- class TmpDirJanitor {
- llvm::sys::Path& Dir;
- public:
- explicit TmpDirJanitor(llvm::sys::Path& dir) : Dir(dir) {}
-
- ~TmpDirJanitor() {
- llvm::cerr << "Removing: " << Dir.c_str() << '\n';
- Dir.eraseFromDisk(true);
- }
- };
-}
-
-void SerializationTest::HandleTranslationUnit(TranslationUnit& TU) {
-
- std::string ErrMsg;
- llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
-
- if (Dir.isEmpty()) {
- llvm::cerr << "Error: " << ErrMsg << "\n";
- return;
- }
-
- TmpDirJanitor RemoveTmpOnExit(Dir);
-
- llvm::sys::Path FNameDeclBefore = Dir;
- FNameDeclBefore.appendComponent("test.decl_before.txt");
-
- if (FNameDeclBefore.makeUnique(true,&ErrMsg)) {
- llvm::cerr << "Error: " << ErrMsg << "\n";
- return;
- }
-
- llvm::sys::Path FNameDeclAfter = Dir;
- FNameDeclAfter.appendComponent("test.decl_after.txt");
-
- if (FNameDeclAfter.makeUnique(true,&ErrMsg)) {
- llvm::cerr << "Error: " << ErrMsg << "\n";
- return;
- }
-
- llvm::sys::Path ASTFilename = Dir;
- ASTFilename.appendComponent("test.ast");
-
- if (ASTFilename.makeUnique(true,&ErrMsg)) {
- llvm::cerr << "Error: " << ErrMsg << "\n";
- return;
- }
-
- // Serialize and then deserialize the ASTs.
- bool status = Serialize(ASTFilename, FNameDeclBefore, TU);
- assert (status && "Serialization failed.");
- status = Deserialize(ASTFilename, FNameDeclAfter);
- assert (status && "Deserialization failed.");
-
- // Read both pretty-printed files and compare them.
-
- using llvm::MemoryBuffer;
-
- llvm::OwningPtr<MemoryBuffer>
- MBufferSer(MemoryBuffer::getFile(FNameDeclBefore.c_str()));
-
- if(!MBufferSer) {
- llvm::cerr << "ERROR: Cannot read pretty-printed file (pre-pickle).\n";
- return;
- }
-
- llvm::OwningPtr<MemoryBuffer>
- MBufferDSer(MemoryBuffer::getFile(FNameDeclAfter.c_str()));
-
- if(!MBufferDSer) {
- llvm::cerr << "ERROR: Cannot read pretty-printed file (post-pickle).\n";
- return;
- }
-
- const char *p1 = MBufferSer->getBufferStart();
- const char *e1 = MBufferSer->getBufferEnd();
- const char *p2 = MBufferDSer->getBufferStart();
- const char *e2 = MBufferDSer->getBufferEnd();
-
- if (MBufferSer->getBufferSize() == MBufferDSer->getBufferSize())
- for ( ; p1 != e1 ; ++p1, ++p2 )
- if (*p1 != *p2) break;
-
- if (p1 != e1 || p2 != e2 )
- llvm::cerr << "ERROR: Pretty-printed files are not the same.\n";
- else
- llvm::cerr << "SUCCESS: Pretty-printed files are the same.\n";
-}
diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
deleted file mode 100644
index 8e5bca22f81b..000000000000
--- a/clang/Driver/clang.cpp
+++ /dev/null
@@ -1,1366 +0,0 @@
-//===--- clang.cpp - C-Language Front-end ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This utility may be invoked in the following manner:
-// clang --help - Output help info.
-// clang [options] - Read from stdin.
-// clang [options] file - Read from "file".
-// clang [options] file1 file2 - Read these files.
-//
-//===----------------------------------------------------------------------===//
-//
-// TODO: Options to support:
-//
-// -ffatal-errors
-// -ftabstop=width
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang.h"
-#include "ASTConsumers.h"
-#include "clang/Driver/HTMLDiagnostics.h"
-#include "clang/Driver/InitHeaderSearch.h"
-#include "clang/Driver/TextDiagnosticBuffer.h"
-#include "clang/Driver/TextDiagnosticPrinter.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/TranslationUnit.h"
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "clang/Sema/ParseAST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Parse/Parser.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Config/config.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Signals.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Global options.
-//===----------------------------------------------------------------------===//
-
-bool HadErrors = false;
-
-static llvm::cl::opt<bool>
-Verbose("v", llvm::cl::desc("Enable verbose output"));
-static llvm::cl::opt<bool>
-Stats("print-stats",
- llvm::cl::desc("Print performance metrics and statistics"));
-
-enum ProgActions {
- RewriteObjC, // ObjC->C Rewriter.
- RewriteBlocks, // ObjC->C Rewriter for Blocks.
- RewriteMacros, // Expand macros but not #includes.
- HTMLTest, // HTML displayer testing stuff.
- EmitLLVM, // Emit a .ll file.
- EmitBC, // Emit a .bc file.
- SerializeAST, // Emit a .ast file.
- EmitHTML, // Translate input source into HTML.
- ASTPrint, // Parse ASTs and print them.
- ASTDump, // Parse ASTs and dump them.
- ASTView, // Parse ASTs and view them in Graphviz.
- TestSerialization, // Run experimental serialization code.
- ParsePrintCallbacks, // Parse and print each callback.
- ParseSyntaxOnly, // Parse and perform semantic analysis.
- ParseNoop, // Parse with noop callbacks.
- RunPreprocessorOnly, // Just lex, no output.
- PrintPreprocessedInput, // -E mode.
- DumpTokens, // Token dump mode.
- RunAnalysis // Run one or more source code analyses.
-};
-
-static llvm::cl::opt<ProgActions>
-ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
- llvm::cl::init(ParseSyntaxOnly),
- llvm::cl::values(
- clEnumValN(RunPreprocessorOnly, "Eonly",
- "Just run preprocessor, no output (for timings)"),
- clEnumValN(PrintPreprocessedInput, "E",
- "Run preprocessor, emit preprocessed file"),
- clEnumValN(DumpTokens, "dumptokens",
- "Run preprocessor, dump internal rep of tokens"),
- clEnumValN(ParseNoop, "parse-noop",
- "Run parser with noop callbacks (for timings)"),
- clEnumValN(ParseSyntaxOnly, "fsyntax-only",
- "Run parser and perform semantic analysis"),
- clEnumValN(ParsePrintCallbacks, "parse-print-callbacks",
- "Run parser and print each callback invoked"),
- clEnumValN(EmitHTML, "emit-html",
- "Output input source as HTML"),
- clEnumValN(ASTPrint, "ast-print",
- "Build ASTs and then pretty-print them"),
- clEnumValN(ASTDump, "ast-dump",
- "Build ASTs and then debug dump them"),
- clEnumValN(ASTView, "ast-view",
- "Build ASTs and view them with GraphViz"),
- clEnumValN(TestSerialization, "test-pickling",
- "Run prototype serialization code"),
- clEnumValN(EmitLLVM, "emit-llvm",
- "Build ASTs then convert to LLVM, emit .ll file"),
- clEnumValN(EmitBC, "emit-llvm-bc",
- "Build ASTs then convert to LLVM, emit .bc file"),
- clEnumValN(SerializeAST, "serialize",
- "Build ASTs and emit .ast file"),
- clEnumValN(RewriteObjC, "rewrite-objc",
- "Rewrite ObjC into C (code rewriter example)"),
- clEnumValN(RewriteMacros, "rewrite-macros",
- "Expand macros without full preprocessing"),
- clEnumValN(RewriteBlocks, "rewrite-blocks",
- "Rewrite Blocks to C"),
- clEnumValEnd));
-
-
-static llvm::cl::opt<std::string>
-OutputFile("o",
- llvm::cl::value_desc("path"),
- llvm::cl::desc("Specify output file (for --serialize, this is a directory)"));
-
-//===----------------------------------------------------------------------===//
-// Code Generator Options
-//===----------------------------------------------------------------------===//
-static llvm::cl::opt<bool>
-GenerateDebugInfo("g",
- llvm::cl::desc("Generate source level debug information"));
-
-//===----------------------------------------------------------------------===//
-// Diagnostic Options
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<bool>
-VerifyDiagnostics("verify",
- llvm::cl::desc("Verify emitted diagnostics and warnings"));
-
-static llvm::cl::opt<std::string>
-HTMLDiag("html-diags",
- llvm::cl::desc("Generate HTML to report diagnostics"),
- llvm::cl::value_desc("HTML directory"));
-
-static llvm::cl::opt<bool>
-NoShowColumn("fno-show-column",
- llvm::cl::desc("Do not include column number on diagnostics"));
-
-static llvm::cl::opt<bool>
-NoCaretDiagnostics("fno-caret-diagnostics",
- llvm::cl::desc("Do not include source line and caret with"
- " diagnostics"));
-
-
-//===----------------------------------------------------------------------===//
-// Analyzer Options
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<bool>
-VisualizeEGDot("analyzer-viz-egraph-graphviz",
- llvm::cl::desc("Display exploded graph using GraphViz"));
-
-static llvm::cl::opt<bool>
-VisualizeEGUbi("analyzer-viz-egraph-ubigraph",
- llvm::cl::desc("Display exploded graph using Ubigraph"));
-
-static llvm::cl::opt<bool>
-AnalyzeAll("analyzer-opt-analyze-headers",
- llvm::cl::desc("Force the static analyzer to analyze "
- "functions defined in header files"));
-
-static llvm::cl::list<Analyses>
-AnalysisList(llvm::cl::desc("Available Source Code Analyses:"),
-llvm::cl::values(
-#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
-clEnumValN(NAME, CMDFLAG, DESC),
-#include "Analyses.def"
-clEnumValEnd));
-
-//===----------------------------------------------------------------------===//
-// Language Options
-//===----------------------------------------------------------------------===//
-
-enum LangKind {
- langkind_unspecified,
- langkind_c,
- langkind_c_cpp,
- langkind_cxx,
- langkind_cxx_cpp,
- langkind_objc,
- langkind_objc_cpp,
- langkind_objcxx,
- langkind_objcxx_cpp
-};
-
-/* TODO: GCC also accepts:
- c-header c++-header objective-c-header objective-c++-header
- assembler assembler-with-cpp
- ada, f77*, ratfor (!), f95, java, treelang
- */
-static llvm::cl::opt<LangKind>
-BaseLang("x", llvm::cl::desc("Base language to compile"),
- llvm::cl::init(langkind_unspecified),
- llvm::cl::values(clEnumValN(langkind_c, "c", "C"),
- clEnumValN(langkind_cxx, "c++", "C++"),
- clEnumValN(langkind_objc, "objective-c", "Objective C"),
- clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
- clEnumValN(langkind_c_cpp, "c-cpp-output",
- "Preprocessed C"),
- clEnumValN(langkind_cxx_cpp, "c++-cpp-output",
- "Preprocessed C++"),
- clEnumValN(langkind_objc_cpp, "objective-c-cpp-output",
- "Preprocessed Objective C"),
- clEnumValN(langkind_objcxx_cpp,"objective-c++-cpp-output",
- "Preprocessed Objective C++"),
- clEnumValEnd));
-
-static llvm::cl::opt<bool>
-LangObjC("ObjC", llvm::cl::desc("Set base language to Objective-C"),
- llvm::cl::Hidden);
-static llvm::cl::opt<bool>
-LangObjCXX("ObjC++", llvm::cl::desc("Set base language to Objective-C++"),
- llvm::cl::Hidden);
-
-/// InitializeBaseLanguage - Handle the -x foo options.
-static void InitializeBaseLanguage() {
- if (LangObjC)
- BaseLang = langkind_objc;
- else if (LangObjCXX)
- BaseLang = langkind_objcxx;
-}
-
-static LangKind GetLanguage(const std::string &Filename) {
- if (BaseLang != langkind_unspecified)
- return BaseLang;
-
- std::string::size_type DotPos = Filename.rfind('.');
-
- if (DotPos == std::string::npos) {
- BaseLang = langkind_c; // Default to C if no extension.
- return langkind_c;
- }
-
- std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
- // C header: .h
- // C++ header: .hh or .H;
- // assembler no preprocessing: .s
- // assembler: .S
- if (Ext == "c")
- return langkind_c;
- else if (Ext == "i")
- return langkind_c_cpp;
- else if (Ext == "ii")
- return langkind_cxx_cpp;
- else if (Ext == "m")
- return langkind_objc;
- else if (Ext == "mi")
- return langkind_objc_cpp;
- else if (Ext == "mm" || Ext == "M")
- return langkind_objcxx;
- else if (Ext == "mii")
- return langkind_objcxx_cpp;
- else if (Ext == "C" || Ext == "cc" || Ext == "cpp" || Ext == "CPP" ||
- Ext == "c++" || Ext == "cp" || Ext == "cxx")
- return langkind_cxx;
- else
- return langkind_c;
-}
-
-
-static void InitializeLangOptions(LangOptions &Options, LangKind LK) {
- // FIXME: implement -fpreprocessed mode.
- bool NoPreprocess = false;
-
- switch (LK) {
- default: assert(0 && "Unknown language kind!");
- case langkind_c_cpp:
- NoPreprocess = true;
- // FALLTHROUGH
- case langkind_c:
- break;
- case langkind_cxx_cpp:
- NoPreprocess = true;
- // FALLTHROUGH
- case langkind_cxx:
- Options.CPlusPlus = 1;
- break;
- case langkind_objc_cpp:
- NoPreprocess = true;
- // FALLTHROUGH
- case langkind_objc:
- Options.ObjC1 = Options.ObjC2 = 1;
- break;
- case langkind_objcxx_cpp:
- NoPreprocess = true;
- // FALLTHROUGH
- case langkind_objcxx:
- Options.ObjC1 = Options.ObjC2 = 1;
- Options.CPlusPlus = 1;
- break;
- }
-}
-
-/// LangStds - Language standards we support.
-enum LangStds {
- lang_unspecified,
- lang_c89, lang_c94, lang_c99,
- lang_gnu_START,
- lang_gnu89 = lang_gnu_START, lang_gnu99,
- lang_cxx98, lang_gnucxx98,
- lang_cxx0x, lang_gnucxx0x
-};
-
-static llvm::cl::opt<LangStds>
-LangStd("std", llvm::cl::desc("Language standard to compile for"),
- llvm::cl::init(lang_unspecified),
- llvm::cl::values(clEnumValN(lang_c89, "c89", "ISO C 1990"),
- clEnumValN(lang_c89, "c90", "ISO C 1990"),
- clEnumValN(lang_c89, "iso9899:1990", "ISO C 1990"),
- clEnumValN(lang_c94, "iso9899:199409",
- "ISO C 1990 with amendment 1"),
- clEnumValN(lang_c99, "c99", "ISO C 1999"),
-// clEnumValN(lang_c99, "c9x", "ISO C 1999"),
- clEnumValN(lang_c99, "iso9899:1999", "ISO C 1999"),
-// clEnumValN(lang_c99, "iso9899:199x", "ISO C 1999"),
- clEnumValN(lang_gnu89, "gnu89",
- "ISO C 1990 with GNU extensions (default for C)"),
- clEnumValN(lang_gnu99, "gnu99",
- "ISO C 1999 with GNU extensions"),
- clEnumValN(lang_gnu99, "gnu9x",
- "ISO C 1999 with GNU extensions"),
- clEnumValN(lang_cxx98, "c++98",
- "ISO C++ 1998 with amendments"),
- clEnumValN(lang_gnucxx98, "gnu++98",
- "ISO C++ 1998 with amendments and GNU "
- "extensions (default for C++)"),
- clEnumValN(lang_cxx0x, "c++0x",
- "Upcoming ISO C++ 200x with amendments"),
- clEnumValN(lang_gnucxx0x, "gnu++0x",
- "Upcoming ISO C++ 200x with amendments and GNU "
- "extensions (default for C++)"),
- clEnumValEnd));
-
-static llvm::cl::opt<bool>
-NoOperatorNames("fno-operator-names",
- llvm::cl::desc("Do not treat C++ operator name keywords as "
- "synonyms for operators"));
-
-static llvm::cl::opt<bool>
-PascalStrings("fpascal-strings",
- llvm::cl::desc("Recognize and construct Pascal-style "
- "string literals"));
-
-static llvm::cl::opt<bool>
-MSExtensions("fms-extensions",
- llvm::cl::desc("Accept some non-standard constructs used in "
- "Microsoft header files "));
-
-static llvm::cl::opt<bool>
-WritableStrings("fwritable-strings",
- llvm::cl::desc("Store string literals as writable data"));
-
-static llvm::cl::opt<bool>
-LaxVectorConversions("flax-vector-conversions",
- llvm::cl::desc("Allow implicit conversions between vectors"
- " with a different number of elements or "
- "different element types"));
-
-// FIXME: This (and all GCC -f options) really come in -f... and
-// -fno-... forms, and additionally support automagic behavior when
-// they are not defined. For example, -fexceptions defaults to on or
-// off depending on the language. We should support this behavior in
-// some form (perhaps just add a facility for distinguishing when an
-// has its default value from when it has been set to its default
-// value).
-static llvm::cl::opt<bool>
-Exceptions("fexceptions",
- llvm::cl::desc("Enable support for exception handling."));
-
-static llvm::cl::opt<bool>
-GNURuntime("fgnu-runtime",
- llvm::cl::desc("Generate output compatible with the standard GNU Objective-C runtime."));
-
-static llvm::cl::opt<bool>
-NeXTRuntime("fnext-runtime",
- llvm::cl::desc("Generate output compatible with the NeXT runtime."));
-
-
-
-static llvm::cl::opt<bool>
-Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences."));
-
-static llvm::cl::opt<bool>
-Ansi("ansi", llvm::cl::desc("Equivalent to specifying -std=c89."));
-
-// FIXME: add:
-// -fdollars-in-identifiers
-// -fpascal-strings
-static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
- TargetInfo *Target) {
-
- if (Ansi) // "The -ansi option is equivalent to -std=c89."
- LangStd = lang_c89;
-
- if (LangStd == lang_unspecified) {
- // Based on the base language, pick one.
- switch (LK) {
- default: assert(0 && "Unknown base language");
- case langkind_c:
- case langkind_c_cpp:
- case langkind_objc:
- case langkind_objc_cpp:
- LangStd = lang_gnu99;
- break;
- case langkind_cxx:
- case langkind_cxx_cpp:
- case langkind_objcxx:
- case langkind_objcxx_cpp:
- LangStd = lang_gnucxx98;
- break;
- }
- }
-
- switch (LangStd) {
- default: assert(0 && "Unknown language standard!");
-
- // Fall through from newer standards to older ones. This isn't really right.
- // FIXME: Enable specifically the right features based on the language stds.
- case lang_gnucxx0x:
- case lang_cxx0x:
- Options.CPlusPlus0x = 1;
- // FALL THROUGH
- case lang_gnucxx98:
- case lang_cxx98:
- Options.CPlusPlus = 1;
- Options.CXXOperatorNames = !NoOperatorNames;
- Options.Boolean = 1;
- // FALL THROUGH.
- case lang_gnu99:
- case lang_c99:
- Options.C99 = 1;
- Options.HexFloats = 1;
- // FALL THROUGH.
- case lang_gnu89:
- Options.BCPLComment = 1; // Only for C99/C++.
- // FALL THROUGH.
- case lang_c94:
- Options.Digraphs = 1; // C94, C99, C++.
- // FALL THROUGH.
- case lang_c89:
- break;
- }
-
- if (Options.CPlusPlus) {
- Options.C99 = 0;
- Options.HexFloats = (LangStd == lang_gnucxx98 || LangStd==lang_gnucxx0x);
- }
-
- if (LangStd == lang_c89 || LangStd == lang_c94 || LangStd == lang_gnu89)
- Options.ImplicitInt = 1;
- else
- Options.ImplicitInt = 0;
-
- // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs or -ansi
- // is specified, or -std is set to a conforming mode.
- Options.Trigraphs = LangStd < lang_gnu_START || Trigraphs ? 1 : 0;
-
- Options.DollarIdents = 1; // FIXME: Really a target property.
- Options.PascalStrings = PascalStrings;
- Options.Microsoft = MSExtensions;
- Options.WritableStrings = WritableStrings;
- Options.LaxVectorConversions = LaxVectorConversions;
- Options.Exceptions = Exceptions;
-
- if (NeXTRuntime) {
- Options.NeXTRuntime = 1;
- } else if (GNURuntime) {
- Options.NeXTRuntime = 0;
- } else {
- Options.NeXTRuntime = Target->useNeXTRuntimeAsDefault();
- }
-}
-
-static llvm::cl::opt<bool>
-ObjCExclusiveGC("fobjc-gc-only",
- llvm::cl::desc("Use GC exclusively for Objective-C related "
- "memory management"));
-
-static llvm::cl::opt<bool>
-ObjCEnableGC("fobjc-gc",
- llvm::cl::desc("Enable Objective-C garbage collection"));
-
-void InitializeGCMode(LangOptions &Options) {
- if (ObjCExclusiveGC)
- Options.setGCMode(LangOptions::GCOnly);
- else if (ObjCEnableGC)
- Options.setGCMode(LangOptions::HybridGC);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Our DiagnosticClient implementation
-//===----------------------------------------------------------------------===//
-
-// FIXME: Werror should take a list of things, -Werror=foo,bar
-static llvm::cl::opt<bool>
-WarningsAsErrors("Werror", llvm::cl::desc("Treat all warnings as errors"));
-
-static llvm::cl::opt<bool>
-SilenceWarnings("w", llvm::cl::desc("Do not emit any warnings"));
-
-static llvm::cl::opt<bool>
-WarnOnExtensions("pedantic", llvm::cl::init(false),
- llvm::cl::desc("Issue a warning on uses of GCC extensions"));
-
-static llvm::cl::opt<bool>
-ErrorOnExtensions("pedantic-errors",
- llvm::cl::desc("Issue an error on uses of GCC extensions"));
-
-static llvm::cl::opt<bool>
-SuppressSystemWarnings("suppress-system-warnings",
- llvm::cl::desc("Suppress warnings issued in system headers"),
- llvm::cl::init(true));
-
-static llvm::cl::opt<bool>
-WarnUnusedMacros("Wunused_macros",
- llvm::cl::desc("Warn for unused macros in the main translation unit"));
-
-static llvm::cl::opt<bool>
-WarnFloatEqual("Wfloat-equal",
- llvm::cl::desc("Warn about equality comparisons of floating point values"));
-
-static llvm::cl::opt<bool>
-WarnNoFormatNonLiteral("Wno-format-nonliteral",
- llvm::cl::desc("Do not warn about non-literal format strings"));
-
-static llvm::cl::opt<bool>
-WarnUndefMacros("Wundef",
- llvm::cl::desc("Warn on use of undefined macros in #if's"));
-
-static llvm::cl::opt<bool>
-WarnImplicitFunctionDeclaration("Wimplicit-function-declaration",
- llvm::cl::desc("Warn about uses of implicitly defined functions"));
-
-/// InitializeDiagnostics - Initialize the diagnostic object, based on the
-/// current command line option settings.
-static void InitializeDiagnostics(Diagnostic &Diags) {
- Diags.setIgnoreAllWarnings(SilenceWarnings);
- Diags.setWarningsAsErrors(WarningsAsErrors);
- Diags.setWarnOnExtensions(WarnOnExtensions);
- Diags.setErrorOnExtensions(ErrorOnExtensions);
-
- // Suppress warnings in system headers unless requested not to.
- Diags.setSuppressSystemWarnings(SuppressSystemWarnings);
-
- // Silence the "macro is not used" warning unless requested.
- if (!WarnUnusedMacros)
- Diags.setDiagnosticMapping(diag::pp_macro_not_used, diag::MAP_IGNORE);
-
- // Silence "floating point comparison" warnings unless requested.
- if (!WarnFloatEqual)
- Diags.setDiagnosticMapping(diag::warn_floatingpoint_eq, diag::MAP_IGNORE);
-
- // Silence "format string is not a string literal" warnings if requested
- if (WarnNoFormatNonLiteral)
- Diags.setDiagnosticMapping(diag::warn_printf_not_string_constant,
- diag::MAP_IGNORE);
- if (!WarnUndefMacros)
- Diags.setDiagnosticMapping(diag::warn_pp_undef_identifier,diag::MAP_IGNORE);
-
- if (!WarnImplicitFunctionDeclaration)
- Diags.setDiagnosticMapping(diag::warn_implicit_function_decl,
- diag::MAP_IGNORE);
-
- if (MSExtensions) // MS allows unnamed struct/union fields.
- Diags.setDiagnosticMapping(diag::w_no_declarators, diag::MAP_IGNORE);
-
- // If -pedantic-errors is set, turn extensions that warn by default into
- // errors.
- if (ErrorOnExtensions) {
- Diags.setDiagnosticMapping(diag::warn_hex_escape_too_large,
- diag::MAP_ERROR);
- Diags.setDiagnosticMapping(diag::warn_octal_escape_too_large,
- diag::MAP_ERROR);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Analysis-specific options.
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<std::string>
-AnalyzeSpecificFunction("analyze-function",
- llvm::cl::desc("Run analysis on specific function"));
-
-static llvm::cl::opt<bool>
-TrimGraph("trim-egraph",
- llvm::cl::desc("Only show error-related paths in the analysis graph"));
-
-//===----------------------------------------------------------------------===//
-// Target Triple Processing.
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<std::string>
-TargetTriple("triple",
- llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)"));
-
-static llvm::cl::opt<std::string>
-Arch("arch", llvm::cl::desc("Specify target architecture (e.g. i686)"));
-
-static llvm::cl::opt<std::string>
-MacOSVersionMin("mmacosx-version-min",
- llvm::cl::desc("Specify target Mac OS/X version (e.g. 10.5)"));
-
-// If -mmacosx-version-min=10.3.9 is specified, change the triple from being
-// something like powerpc-apple-darwin9 to powerpc-apple-darwin7
-static void HandleMacOSVersionMin(std::string &Triple) {
- std::string::size_type DarwinDashIdx = Triple.find("-darwin");
- if (DarwinDashIdx == std::string::npos) {
- fprintf(stderr,
- "-mmacosx-version-min only valid for darwin (Mac OS/X) targets\n");
- exit(1);
- }
- unsigned DarwinNumIdx = DarwinDashIdx + strlen("-darwin");
-
- // Remove the number.
- Triple.resize(DarwinNumIdx);
-
- // Validate that MacOSVersionMin is a 'version number', starting with 10.[3-9]
- bool MacOSVersionMinIsInvalid = false;
- int VersionNum = 0;
- if (MacOSVersionMin.size() < 4 ||
- MacOSVersionMin.substr(0, 3) != "10." ||
- !isdigit(MacOSVersionMin[3])) {
- MacOSVersionMinIsInvalid = true;
- } else {
- const char *Start = MacOSVersionMin.c_str()+3;
- char *End = 0;
- VersionNum = (int)strtol(Start, &End, 10);
-
- // The version number must be in the range 0-9.
- MacOSVersionMinIsInvalid = (unsigned)VersionNum > 9;
-
- // Turn MacOSVersionMin into a darwin number: e.g. 10.3.9 is 3 -> 7.
- Triple += llvm::itostr(VersionNum+4);
-
- if (End[0] == '.' && isdigit(End[1]) && End[2] == '\0') { // 10.4.7 is ok.
- // Add the period piece (.7) to the end of the triple. This gives us
- // something like ...-darwin8.7
- Triple += End;
- } else if (End[0] != '\0') { // "10.4" is ok. 10.4x is not.
- MacOSVersionMinIsInvalid = true;
- }
- }
-
- if (MacOSVersionMinIsInvalid) {
- fprintf(stderr,
- "-mmacosx-version-min=%s is invalid, expected something like '10.4'.\n",
- MacOSVersionMin.c_str());
- exit(1);
- }
-}
-
-/// CreateTargetTriple - Process the various options that affect the target
-/// triple and build a final aggregate triple that we are compiling for.
-static std::string CreateTargetTriple() {
- // Initialize base triple. If a -triple option has been specified, use
- // that triple. Otherwise, default to the host triple.
- std::string Triple = TargetTriple;
- if (Triple.empty()) {
- Triple = LLVM_HOSTTRIPLE;
-
- // On darwin, we want to update the version to match that of the
- // host.
- std::string::size_type DarwinDashIdx = Triple.find("-darwin");
- if (DarwinDashIdx != std::string::npos) {
- Triple.resize(DarwinDashIdx + strlen("-darwin"));
-
- Triple += llvm::sys::osVersion();
- }
- }
-
- // If -arch foo was specified, remove the architecture from the triple we have
- // so far and replace it with the specified one.
- if (!Arch.empty()) {
- // Decompose the base triple into "arch" and suffix.
- std::string::size_type FirstDashIdx = Triple.find('-');
-
- if (FirstDashIdx == std::string::npos) {
- fprintf(stderr,
- "Malformed target triple: \"%s\" ('-' could not be found).\n",
- Triple.c_str());
- exit(1);
- }
-
- Triple = Arch + std::string(Triple.begin()+FirstDashIdx, Triple.end());
- }
-
- // If -mmacosx-version-min=10.3.9 is specified, change the triple from being
- // something like powerpc-apple-darwin9 to powerpc-apple-darwin7
- if (!MacOSVersionMin.empty())
- HandleMacOSVersionMin(Triple);
-
- return Triple;
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Initialization
-//===----------------------------------------------------------------------===//
-
-// FIXME: Preprocessor builtins to support.
-// -A... - Play with #assertions
-// -undef - Undefine all predefined macros
-
-static llvm::cl::list<std::string>
-D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
- llvm::cl::desc("Predefine the specified macro"));
-static llvm::cl::list<std::string>
-U_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
- llvm::cl::desc("Undefine the specified macro"));
-
-static llvm::cl::list<std::string>
-ImplicitIncludes("include", llvm::cl::value_desc("file"),
- llvm::cl::desc("Include file before parsing"));
-
-
-// Append a #define line to Buf for Macro. Macro should be of the form XXX,
-// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
-// "#define XXX Y z W". To get a #define with no value, use "XXX=".
-static void DefineBuiltinMacro(std::vector<char> &Buf, const char *Macro,
- const char *Command = "#define ") {
- Buf.insert(Buf.end(), Command, Command+strlen(Command));
- if (const char *Equal = strchr(Macro, '=')) {
- // Turn the = into ' '.
- Buf.insert(Buf.end(), Macro, Equal);
- Buf.push_back(' ');
- Buf.insert(Buf.end(), Equal+1, Equal+strlen(Equal));
- } else {
- // Push "macroname 1".
- Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
- Buf.push_back(' ');
- Buf.push_back('1');
- }
- Buf.push_back('\n');
-}
-
-/// AddImplicitInclude - Add an implicit #include of the specified file to the
-/// predefines buffer.
-static void AddImplicitInclude(std::vector<char> &Buf, const std::string &File){
- const char *Inc = "#include \"";
- Buf.insert(Buf.end(), Inc, Inc+strlen(Inc));
- Buf.insert(Buf.end(), File.begin(), File.end());
- Buf.push_back('"');
- Buf.push_back('\n');
-}
-
-
-/// InitializePreprocessor - Initialize the preprocessor getting it and the
-/// environment ready to process a single file. This returns true on error.
-///
-static bool InitializePreprocessor(Preprocessor &PP,
- bool InitializeSourceMgr,
- const std::string &InFile) {
- FileManager &FileMgr = PP.getFileManager();
-
- // Figure out where to get and map in the main file.
- SourceManager &SourceMgr = PP.getSourceManager();
-
- if (InitializeSourceMgr) {
- if (InFile != "-") {
- const FileEntry *File = FileMgr.getFile(InFile);
- if (File) SourceMgr.createMainFileID(File, SourceLocation());
- if (SourceMgr.getMainFileID() == 0) {
- fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
- return true;
- }
- } else {
- llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
- if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
- if (SourceMgr.getMainFileID() == 0) {
- fprintf(stderr, "Error reading standard input! Empty?\n");
- return true;
- }
- }
- }
-
- std::vector<char> PredefineBuffer;
-
- // Add macros from the command line.
- unsigned d = 0, D = D_macros.size();
- unsigned u = 0, U = U_macros.size();
- while (d < D || u < U) {
- if (u == U || (d < D && D_macros.getPosition(d) < U_macros.getPosition(u)))
- DefineBuiltinMacro(PredefineBuffer, D_macros[d++].c_str());
- else
- DefineBuiltinMacro(PredefineBuffer, U_macros[u++].c_str(), "#undef ");
- }
-
- // FIXME: Read any files specified by -imacros.
-
- // Add implicit #includes from -include.
- for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i)
- AddImplicitInclude(PredefineBuffer, ImplicitIncludes[i]);
-
- // Null terminate PredefinedBuffer and add it.
- PredefineBuffer.push_back(0);
- PP.setPredefines(&PredefineBuffer[0]);
-
- // Once we've read this, we're done.
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor include path information.
-//===----------------------------------------------------------------------===//
-
-// This tool exports a large number of command line options to control how the
-// preprocessor searches for header files. At root, however, the Preprocessor
-// object takes a very simple interface: a list of directories to search for
-//
-// FIXME: -nostdinc,-nostdinc++
-// FIXME: -imultilib
-//
-// FIXME: -imacros
-
-static llvm::cl::opt<bool>
-nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
-
-// Various command line options. These four add directories to each chain.
-static llvm::cl::list<std::string>
-F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
- llvm::cl::desc("Add directory to framework include search path"));
-static llvm::cl::list<std::string>
-I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
- llvm::cl::desc("Add directory to include search path"));
-static llvm::cl::list<std::string>
-idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
- llvm::cl::desc("Add directory to AFTER include search path"));
-static llvm::cl::list<std::string>
-iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
- llvm::cl::desc("Add directory to QUOTE include search path"));
-static llvm::cl::list<std::string>
-isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix,
- llvm::cl::desc("Add directory to SYSTEM include search path"));
-
-// These handle -iprefix/-iwithprefix/-iwithprefixbefore.
-static llvm::cl::list<std::string>
-iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix,
- llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix"));
-static llvm::cl::list<std::string>
-iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix,
- llvm::cl::desc("Set directory to SYSTEM include search path with prefix"));
-static llvm::cl::list<std::string>
-iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
- llvm::cl::Prefix,
- llvm::cl::desc("Set directory to include search path with prefix"));
-
-static llvm::cl::opt<std::string>
-isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
- llvm::cl::desc("Set the system root directory (usually /)"));
-
-// Finally, implement the code that groks the options above.
-
-/// InitializeIncludePaths - Process the -I options and set them in the
-/// HeaderSearch object.
-void InitializeIncludePaths(const char *Argv0, HeaderSearch &Headers,
- FileManager &FM, const LangOptions &Lang) {
- InitHeaderSearch Init(Headers, Verbose, isysroot);
-
- // Handle -I... and -F... options, walking the lists in parallel.
- unsigned Iidx = 0, Fidx = 0;
- while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) {
- if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) {
- Init.AddPath(I_dirs[Iidx], InitHeaderSearch::Angled, false, true, false);
- ++Iidx;
- } else {
- Init.AddPath(F_dirs[Fidx], InitHeaderSearch::Angled, false, true, true);
- ++Fidx;
- }
- }
-
- // Consume what's left from whatever list was longer.
- for (; Iidx != I_dirs.size(); ++Iidx)
- Init.AddPath(I_dirs[Iidx], InitHeaderSearch::Angled, false, true, false);
- for (; Fidx != F_dirs.size(); ++Fidx)
- Init.AddPath(F_dirs[Fidx], InitHeaderSearch::Angled, false, true, true);
-
- // Handle -idirafter... options.
- for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
- Init.AddPath(idirafter_dirs[i], InitHeaderSearch::After,
- false, true, false);
-
- // Handle -iquote... options.
- for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
- Init.AddPath(iquote_dirs[i], InitHeaderSearch::Quoted, false, true, false);
-
- // Handle -isystem... options.
- for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
- Init.AddPath(isystem_dirs[i], InitHeaderSearch::System, false, true, false);
-
- // Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in
- // parallel, processing the values in order of occurance to get the right
- // prefixes.
- {
- std::string Prefix = ""; // FIXME: this isn't the correct default prefix.
- unsigned iprefix_idx = 0;
- unsigned iwithprefix_idx = 0;
- unsigned iwithprefixbefore_idx = 0;
- bool iprefix_done = iprefix_vals.empty();
- bool iwithprefix_done = iwithprefix_vals.empty();
- bool iwithprefixbefore_done = iwithprefixbefore_vals.empty();
- while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) {
- if (!iprefix_done &&
- (iwithprefix_done ||
- iprefix_vals.getPosition(iprefix_idx) <
- iwithprefix_vals.getPosition(iwithprefix_idx)) &&
- (iwithprefixbefore_done ||
- iprefix_vals.getPosition(iprefix_idx) <
- iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
- Prefix = iprefix_vals[iprefix_idx];
- ++iprefix_idx;
- iprefix_done = iprefix_idx == iprefix_vals.size();
- } else if (!iwithprefix_done &&
- (iwithprefixbefore_done ||
- iwithprefix_vals.getPosition(iwithprefix_idx) <
- iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) {
- Init.AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
- InitHeaderSearch::System, false, false, false);
- ++iwithprefix_idx;
- iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
- } else {
- Init.AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
- InitHeaderSearch::Angled, false, false, false);
- ++iwithprefixbefore_idx;
- iwithprefixbefore_done =
- iwithprefixbefore_idx == iwithprefixbefore_vals.size();
- }
- }
- }
-
- Init.AddDefaultEnvVarPaths(Lang);
-
- // Add the clang headers, which are relative to the clang driver.
- llvm::sys::Path MainExecutablePath =
- llvm::sys::Path::GetMainExecutable(Argv0,
- (void*)(intptr_t)InitializeIncludePaths);
- if (!MainExecutablePath.isEmpty()) {
- MainExecutablePath.eraseComponent(); // Remove /clang from foo/bin/clang
- MainExecutablePath.eraseComponent(); // Remove /bin from foo/bin
- MainExecutablePath.appendComponent("Headers"); // Get foo/Headers
- Init.AddPath(MainExecutablePath.c_str(), InitHeaderSearch::System,
- false, false, false);
- }
-
- if (!nostdinc)
- Init.AddDefaultSystemIncludePaths(Lang);
-
- // Now that we have collected all of the include paths, merge them all
- // together and tell the preprocessor about them.
-
- Init.Realize();
-}
-
-//===----------------------------------------------------------------------===//
-// Driver PreprocessorFactory - For lazily generating preprocessors ...
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN DriverPreprocessorFactory : public PreprocessorFactory {
- const std::string &InFile;
- Diagnostic &Diags;
- const LangOptions &LangInfo;
- TargetInfo &Target;
- SourceManager &SourceMgr;
- HeaderSearch &HeaderInfo;
- bool InitializeSourceMgr;
-
-public:
- DriverPreprocessorFactory(const std::string &infile,
- Diagnostic &diags, const LangOptions &opts,
- TargetInfo &target, SourceManager &SM,
- HeaderSearch &Headers)
- : InFile(infile), Diags(diags), LangInfo(opts), Target(target),
- SourceMgr(SM), HeaderInfo(Headers), InitializeSourceMgr(true) {}
-
-
- virtual ~DriverPreprocessorFactory() {}
-
- virtual Preprocessor* CreatePreprocessor() {
- Preprocessor* PP = new Preprocessor(Diags, LangInfo, Target,
- SourceMgr, HeaderInfo);
-
- if (InitializePreprocessor(*PP, InitializeSourceMgr, InFile)) {
- delete PP;
- return NULL;
- }
-
- InitializeSourceMgr = false;
- return PP;
- }
-};
-}
-
-//===----------------------------------------------------------------------===//
-// Basic Parser driver
-//===----------------------------------------------------------------------===//
-
-static void ParseFile(Preprocessor &PP, MinimalAction *PA) {
- Parser P(PP, *PA);
- PP.EnterMainSourceFile();
-
- // Parsing the specified input file.
- P.ParseTranslationUnit();
- delete PA;
-}
-
-//===----------------------------------------------------------------------===//
-// Main driver
-//===----------------------------------------------------------------------===//
-
-/// CreateASTConsumer - Create the ASTConsumer for the corresponding program
-/// action. These consumers can operate on both ASTs that are freshly
-/// parsed from source files as well as those deserialized from Bitcode.
-static ASTConsumer* CreateASTConsumer(const std::string& InFile,
- Diagnostic& Diag, FileManager& FileMgr,
- const LangOptions& LangOpts,
- Preprocessor *PP,
- PreprocessorFactory *PPF) {
- switch (ProgAction) {
- default:
- return NULL;
-
- case ASTPrint:
- return CreateASTPrinter();
-
- case ASTDump:
- return CreateASTDumper();
-
- case ASTView:
- return CreateASTViewer();
-
- case EmitHTML:
- return CreateHTMLPrinter(OutputFile, Diag, PP, PPF);
-
- case TestSerialization:
- return CreateSerializationTest(Diag, FileMgr);
-
- case EmitLLVM:
- case EmitBC:
- return CreateLLVMCodeGenWriter(ProgAction == EmitBC, Diag, LangOpts,
- InFile, OutputFile, GenerateDebugInfo);
-
- case SerializeAST:
- // FIXME: Allow user to tailor where the file is written.
- return CreateASTSerializer(InFile, OutputFile, Diag);
-
- case RewriteObjC:
- return CreateCodeRewriterTest(InFile, OutputFile, Diag, LangOpts);
-
- case RewriteBlocks:
- return CreateBlockRewriter(InFile, OutputFile, Diag, LangOpts);
-
- case RunAnalysis:
- assert (!AnalysisList.empty());
- return CreateAnalysisConsumer(&AnalysisList[0],
- &AnalysisList[0]+AnalysisList.size(),
- Diag, PP, PPF, LangOpts,
- AnalyzeSpecificFunction,
- OutputFile, VisualizeEGDot, VisualizeEGUbi,
- TrimGraph, AnalyzeAll);
- }
-}
-
-/// ProcessInputFile - Process a single input file with the specified state.
-///
-static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
- const std::string &InFile) {
-
- llvm::OwningPtr<ASTConsumer> Consumer;
- bool ClearSourceMgr = false;
-
- switch (ProgAction) {
- default:
- Consumer.reset(CreateASTConsumer(InFile, PP.getDiagnostics(),
- PP.getFileManager(), PP.getLangOptions(),
- &PP, &PPF));
-
- if (!Consumer) {
- fprintf(stderr, "Unexpected program action!\n");
- HadErrors = true;
- return;
- }
-
- break;
-
- case DumpTokens: { // Token dump mode.
- Token Tok;
- // Start parsing the specified input file.
- PP.EnterMainSourceFile();
- do {
- PP.Lex(Tok);
- PP.DumpToken(Tok, true);
- fprintf(stderr, "\n");
- } while (Tok.isNot(tok::eof));
- ClearSourceMgr = true;
- break;
- }
- case RunPreprocessorOnly: { // Just lex as fast as we can, no output.
- Token Tok;
- // Start parsing the specified input file.
- PP.EnterMainSourceFile();
- do {
- PP.Lex(Tok);
- } while (Tok.isNot(tok::eof));
- ClearSourceMgr = true;
- break;
- }
-
- case PrintPreprocessedInput: // -E mode.
- DoPrintPreprocessedInput(PP, OutputFile);
- ClearSourceMgr = true;
- break;
-
- case ParseNoop: // -parse-noop
- ParseFile(PP, new MinimalAction(PP.getIdentifierTable()));
- ClearSourceMgr = true;
- break;
-
- case ParsePrintCallbacks:
- ParseFile(PP, CreatePrintParserActionsAction(PP.getIdentifierTable()));
- ClearSourceMgr = true;
- break;
-
- case ParseSyntaxOnly: // -fsyntax-only
- Consumer.reset(new ASTConsumer());
- break;
-
- case RewriteMacros:
- RewriteMacrosInInput(PP, InFile, OutputFile);
- ClearSourceMgr = true;
- break;
- }
-
- if (Consumer) {
- if (VerifyDiagnostics)
- exit(CheckASTConsumer(PP, Consumer.get()));
-
- ParseAST(PP, Consumer.get(), Stats);
- } else {
- if (VerifyDiagnostics)
- exit(CheckDiagnostics(PP));
- }
-
- if (Stats) {
- fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
- PP.PrintStats();
- PP.getIdentifierTable().PrintStats();
- PP.getHeaderSearchInfo().PrintStats();
- if (ClearSourceMgr)
- PP.getSourceManager().PrintStats();
- fprintf(stderr, "\n");
- }
-
- // For a multi-file compilation, some things are ok with nuking the source
- // manager tables, other require stable fileid/macroid's across multiple
- // files.
- if (ClearSourceMgr)
- PP.getSourceManager().clearIDTables();
-}
-
-static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
- FileManager& FileMgr) {
-
- if (VerifyDiagnostics) {
- fprintf(stderr, "-verify does not yet work with serialized ASTs.\n");
- exit (1);
- }
-
- llvm::sys::Path Filename(InFile);
-
- if (!Filename.isValid()) {
- fprintf(stderr, "serialized file '%s' not available.\n",InFile.c_str());
- exit (1);
- }
-
- llvm::OwningPtr<TranslationUnit> TU(ReadASTBitcodeFile(Filename, FileMgr));
-
- if (!TU) {
- fprintf(stderr, "error: file '%s' could not be deserialized\n",
- InFile.c_str());
- exit (1);
- }
-
- // Observe that we use the source file name stored in the deserialized
- // translation unit, rather than InFile.
- llvm::OwningPtr<ASTConsumer>
- Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOptions(),
- 0, 0));
-
- if (!Consumer) {
- fprintf(stderr, "Unsupported program action with serialized ASTs!\n");
- exit (1);
- }
-
- Consumer->Initialize(TU->getContext());
-
- // FIXME: We need to inform Consumer about completed TagDecls as well.
- for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
- Consumer->HandleTopLevelDecl(*I);
-}
-
-
-static llvm::cl::list<std::string>
-InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));
-
-static bool isSerializedFile(const std::string& InFile) {
- if (InFile.size() < 4)
- return false;
-
- const char* s = InFile.c_str()+InFile.size()-4;
-
- return s[0] == '.' &&
- s[1] == 'a' &&
- s[2] == 's' &&
- s[3] == 't';
-}
-
-
-int main(int argc, char **argv) {
- llvm::cl::ParseCommandLineOptions(argc, argv, " llvm clang cfe\n");
- llvm::sys::PrintStackTraceOnErrorSignal();
-
- // If no input was specified, read from stdin.
- if (InputFilenames.empty())
- InputFilenames.push_back("-");
-
- // Create a file manager object to provide access to and cache the filesystem.
- FileManager FileMgr;
-
- // Create the diagnostic client for reporting errors or for
- // implementing -verify.
- DiagnosticClient* TextDiagClient = 0;
-
- if (!VerifyDiagnostics) {
- // Print diagnostics to stderr by default.
- TextDiagClient = new TextDiagnosticPrinter(!NoShowColumn,
- !NoCaretDiagnostics);
- } else {
- // When checking diagnostics, just buffer them up.
- TextDiagClient = new TextDiagnosticBuffer();
-
- if (InputFilenames.size() != 1) {
- fprintf(stderr,
- "-verify only works on single input files for now.\n");
- return 1;
- }
- }
-
- // Configure our handling of diagnostics.
- llvm::OwningPtr<DiagnosticClient> DiagClient(TextDiagClient);
- Diagnostic Diags(DiagClient.get());
- InitializeDiagnostics(Diags);
-
- // -I- is a deprecated GCC feature, scan for it and reject it.
- for (unsigned i = 0, e = I_dirs.size(); i != e; ++i) {
- if (I_dirs[i] == "-") {
- Diags.Report(diag::err_pp_I_dash_not_supported);
- I_dirs.erase(I_dirs.begin()+i);
- --i;
- }
- }
-
- // Get information about the target being compiled for.
- std::string Triple = CreateTargetTriple();
- llvm::OwningPtr<TargetInfo> Target(TargetInfo::CreateTargetInfo(Triple));
-
- if (Target == 0) {
- fprintf(stderr, "Sorry, I don't know what target this is: %s\n",
- Triple.c_str());
- fprintf(stderr, "Please use -triple or -arch.\n");
- exit(1);
- }
-
- // Are we invoking one or more source analyses?
- if (!AnalysisList.empty() && ProgAction == ParseSyntaxOnly)
- ProgAction = RunAnalysis;
-
- llvm::OwningPtr<SourceManager> SourceMgr;
-
- for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
- const std::string &InFile = InputFilenames[i];
-
- if (isSerializedFile(InFile)) {
- Diags.setClient(TextDiagClient);
- ProcessSerializedFile(InFile,Diags,FileMgr);
- }
- else {
- /// Create a SourceManager object. This tracks and owns all the file
- /// buffers allocated to a translation unit.
- if (!SourceMgr)
- SourceMgr.reset(new SourceManager());
- else
- SourceMgr->clearIDTables();
-
- // Initialize language options, inferring file types from input filenames.
- LangOptions LangInfo;
- InitializeBaseLanguage();
- LangKind LK = GetLanguage(InFile);
- InitializeLangOptions(LangInfo, LK);
- InitializeLanguageStandard(LangInfo, LK, Target.get());
- InitializeGCMode(LangInfo);
-
- // Process the -I options and set them in the HeaderInfo.
- HeaderSearch HeaderInfo(FileMgr);
-
- InitializeIncludePaths(argv[0], HeaderInfo, FileMgr, LangInfo);
-
- // Set up the preprocessor with these options.
- DriverPreprocessorFactory PPFactory(InFile, Diags, LangInfo, *Target,
- *SourceMgr.get(), HeaderInfo);
-
- llvm::OwningPtr<Preprocessor> PP(PPFactory.CreatePreprocessor());
-
- if (!PP)
- continue;
-
- // Create the HTMLDiagnosticsClient if we are using one. Otherwise,
- // always reset to using TextDiagClient.
- llvm::OwningPtr<DiagnosticClient> TmpClient;
-
- if (!HTMLDiag.empty()) {
- TmpClient.reset(CreateHTMLDiagnosticClient(HTMLDiag, PP.get(),
- &PPFactory));
- Diags.setClient(TmpClient.get());
- }
- else
- Diags.setClient(TextDiagClient);
-
- // Process the source file.
- ProcessInputFile(*PP, PPFactory, InFile);
- HeaderInfo.ClearFileInfo();
-
- if (Stats)
- SourceMgr->PrintStats();
- }
- }
-
- if (unsigned NumDiagnostics = Diags.getNumDiagnostics())
- fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
- (NumDiagnostics == 1 ? "" : "s"));
-
- if (Stats) {
- FileMgr.PrintStats();
- fprintf(stderr, "\n");
- }
-
- return HadErrors || (Diags.getNumErrors() != 0);
-}
diff --git a/clang/Driver/clang.h b/clang/Driver/clang.h
deleted file mode 100644
index ddb5dcb11d8f..000000000000
--- a/clang/Driver/clang.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===--- clang.h - C-Language Front-end -----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the header file that pulls together the top-level driver.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CLANG_H
-#define LLVM_CLANG_CLANG_H
-
-#include <vector>
-#include <string>
-
-namespace clang {
-class Preprocessor;
-class MinimalAction;
-class TargetInfo;
-class Diagnostic;
-class ASTConsumer;
-class IdentifierTable;
-class SourceManager;
-
-/// DoPrintPreprocessedInput - Implement -E mode.
-void DoPrintPreprocessedInput(Preprocessor &PP, const std::string& OutFile);
-
-/// RewriteMacrosInInput - Implement -rewrite-macros mode.
-void RewriteMacrosInInput(Preprocessor &PP, const std::string &InFileName,
- const std::string& OutFile);
-
-/// CreatePrintParserActionsAction - Return the actions implementation that
-/// implements the -parse-print-callbacks option.
-MinimalAction *CreatePrintParserActionsAction(IdentifierTable &);
-
-/// EmitLLVMFromASTs - Implement -emit-llvm, which generates llvm IR from C.
-void EmitLLVMFromASTs(Preprocessor &PP, bool PrintStats);
-
-/// CheckASTConsumer - Implement diagnostic checking for AST consumers.
-bool CheckASTConsumer(Preprocessor &PP, ASTConsumer* C);
-
-/// CheckDiagnostics - Gather the expected diagnostics and check them.
-bool CheckDiagnostics(Preprocessor &PP);
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/INPUTS/Cocoa_h.m b/clang/INPUTS/Cocoa_h.m
deleted file mode 100644
index e6ba59924d6d..000000000000
--- a/clang/INPUTS/Cocoa_h.m
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#import <Cocoa/Cocoa.h>
diff --git a/clang/INPUTS/carbon_h.c b/clang/INPUTS/carbon_h.c
deleted file mode 100644
index 599f123a36c6..000000000000
--- a/clang/INPUTS/carbon_h.c
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#include <Carbon/Carbon.h>
-
-//#import<vecLib/vecLib.h>
diff --git a/clang/INPUTS/iostream.cc b/clang/INPUTS/iostream.cc
deleted file mode 100644
index eb12fc9aaf4e..000000000000
--- a/clang/INPUTS/iostream.cc
+++ /dev/null
@@ -1,5 +0,0 @@
-// clang -I/usr/include/c++/4.0.0 -I/usr/include/c++/4.0.0/powerpc-apple-darwin8 -I/usr/include/c++/4.0.0/backward INPUTS/iostream.cc -Eonly
-
-#include <iostream>
-
-#include <stdint.h>
diff --git a/clang/INPUTS/macro_pounder_fn.c b/clang/INPUTS/macro_pounder_fn.c
deleted file mode 100644
index 73f40a1d6db8..000000000000
--- a/clang/INPUTS/macro_pounder_fn.c
+++ /dev/null
@@ -1,17 +0,0 @@
-
-// This pounds on macro expansion for performance reasons. This is currently
-// heavily constrained by darwin's malloc.
-
-// Function-like macros.
-#define A0(A, B) A B
-#define A1(A, B) A0(A,B) A0(A,B) A0(A,B) A0(A,B) A0(A,B) A0(A,B)
-#define A2(A, B) A1(A,B) A1(A,B) A1(A,B) A1(A,B) A1(A,B) A1(A,B)
-#define A3(A, B) A2(A,B) A2(A,B) A2(A,B) A2(A,B) A2(A,B) A2(A,B)
-#define A4(A, B) A3(A,B) A3(A,B) A3(A,B) A3(A,B) A3(A,B) A3(A,B)
-#define A5(A, B) A4(A,B) A4(A,B) A4(A,B) A4(A,B) A4(A,B) A4(A,B)
-#define A6(A, B) A5(A,B) A5(A,B) A5(A,B) A5(A,B) A5(A,B) A5(A,B)
-#define A7(A, B) A6(A,B) A6(A,B) A6(A,B) A6(A,B) A6(A,B) A6(A,B)
-#define A8(A, B) A7(A,B) A7(A,B) A7(A,B) A7(A,B) A7(A,B) A7(A,B)
-
-A8(a, b)
-
diff --git a/clang/INPUTS/macro_pounder_obj.c b/clang/INPUTS/macro_pounder_obj.c
deleted file mode 100644
index d2465f34edb7..000000000000
--- a/clang/INPUTS/macro_pounder_obj.c
+++ /dev/null
@@ -1,16 +0,0 @@
-
-// This pounds on macro expansion for performance reasons. This is currently
-// heavily constrained by darwin's malloc.
-
-// Object-like expansions
-#define A0 a b
-#define A1 A0 A0 A0 A0 A0 A0
-#define A2 A1 A1 A1 A1 A1 A1
-#define A3 A2 A2 A2 A2 A2 A2
-#define A4 A3 A3 A3 A3 A3 A3
-#define A5 A4 A4 A4 A4 A4 A4
-#define A6 A5 A5 A5 A5 A5 A5
-#define A7 A6 A6 A6 A6 A6 A6
-#define A8 A7 A7 A7 A7 A7 A7
-
-A8
diff --git a/clang/INPUTS/stpcpy-test.c b/clang/INPUTS/stpcpy-test.c
deleted file mode 100644
index b96a8066e63c..000000000000
--- a/clang/INPUTS/stpcpy-test.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#define __extension__
-
-#define __stpcpy(dest, src) (__extension__ (__builtin_constant_p (src) ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8 ? __stpcpy_small (dest, __stpcpy_args (src), strlen (src) + 1) : ((char *) __mempcpy (dest, src, strlen (src) + 1) - 1)) : __stpcpy (dest, src)))
-#define stpcpy(dest, src) __stpcpy (dest, src)
-#define __stpcpy_args(src) __extension__ __STRING2_SMALL_GET16 (src, 0), __extension__ __STRING2_SMALL_GET16 (src, 4), __extension__ __STRING2_SMALL_GET32 (src, 0), __extension__ __STRING2_SMALL_GET32 (src, 4)
-
-#define __mempcpy(dest, src, n) (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) && __string2_1bptr_p (src) && n <= 8 ? __mempcpy_small (dest, __mempcpy_args (src), n) : __mempcpy (dest, src, n)))
-#define mempcpy(dest, src, n) __mempcpy (dest, src, n)
-#define __mempcpy_args(src) ((char *) (src))[0], ((char *) (src))[2], ((char *) (src))[4], ((char *) (src))[6], __extension__ __STRING2_SMALL_GET16 (src, 0), __extension__ __STRING2_SMALL_GET16 (src, 4), __extension__ __STRING2_SMALL_GET32 (src, 0), __extension__ __STRING2_SMALL_GET32 (src, 4)
-
-#define __STRING2_SMALL_GET16(src, idx) (((__const unsigned char *) (__const char *) (src))[idx + 1] << 8 | ((__const unsigned char *) (__const char *) (src))[idx])
-
-#define __STRING2_SMALL_GET32(src, idx) (((((__const unsigned char *) (__const char *) (src))[idx + 3] << 8 | ((__const unsigned char *) (__const char *) (src))[idx + 2]) << 8 | ((__const unsigned char *) (__const char *) (src))[idx + 1]) << 8 | ((__const unsigned char *) (__const char *) (src))[idx])
-
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
-stpcpy (stpcpy (stpcpy (stpcpy (a, b), c), d), e)
diff --git a/clang/LICENSE.TXT b/clang/LICENSE.TXT
deleted file mode 100644
index 21cb5c7ac589..000000000000
--- a/clang/LICENSE.TXT
+++ /dev/null
@@ -1,63 +0,0 @@
-==============================================================================
-LLVM Release License
-==============================================================================
-University of Illinois/NCSA
-Open Source License
-
-Copyright (c) 2007 University of Illinois at Urbana-Champaign.
-All rights reserved.
-
-Developed by:
-
- LLVM Team
-
- University of Illinois at Urbana-Champaign
-
- http://llvm.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal with
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimers.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimers in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the names of the LLVM Team, University of Illinois at
- Urbana-Champaign, nor the names of its contributors may be used to
- endorse or promote products derived from this Software without specific
- prior written permission.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
-SOFTWARE.
-
-==============================================================================
-The LLVM software contains code written by third parties. Such software will
-have its own individual LICENSE.TXT file in the directory in which it appears.
-This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the LLVM Distribution, and nothing in any of the
-other licenses gives permission to use the names of the LLVM Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
-
-The following pieces of software have additional or alternate copyrights,
-licenses, and/or restrictions:
-
-Program Directory
-------- ---------
-<none yet>
-
diff --git a/clang/Makefile b/clang/Makefile
deleted file mode 100644
index 06b92886911d..000000000000
--- a/clang/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-LEVEL = ../..
-DIRS := lib Driver docs
-
-include $(LEVEL)/Makefile.common
-
-test::
- @ $(MAKE) -C test
-
-report::
- @ $(MAKE) -C test report
-
-clean::
- @ $(MAKE) -C test clean
-
-.PHONY: test report clean
diff --git a/clang/ModuleInfo.txt b/clang/ModuleInfo.txt
deleted file mode 100644
index 4368ef067aea..000000000000
--- a/clang/ModuleInfo.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file provides information for llvm-top
-DepModule: llvm
-ConfigCmd:
-ConfigTest:
-BuildCmd:
diff --git a/clang/NOTES.txt b/clang/NOTES.txt
deleted file mode 100644
index 0759acf3552e..000000000000
--- a/clang/NOTES.txt
+++ /dev/null
@@ -1,136 +0,0 @@
-//===---------------------------------------------------------------------===//
-// Random Notes
-//===---------------------------------------------------------------------===//
-
-C90/C99/C++ Comparisons:
-http://david.tribble.com/text/cdiffs.htm
-
-//===---------------------------------------------------------------------===//
-
-To time GCC preprocessing speed without output, use:
- "time gcc -MM file"
-This is similar to -Eonly.
-
-
-//===---------------------------------------------------------------------===//
-
- C++ Template Instantiation benchmark:
- http://users.rcn.com/abrahams/instantiation_speed/index.html
-
-//===---------------------------------------------------------------------===//
-
-TODO: File Manager Speedup:
-
- We currently do a lot of stat'ing for files that don't exist, particularly
- when lots of -I paths exist (e.g. see the <iostream> example, check for
- failures in stat in FileManager::getFile). It would be far better to make
- the following changes:
- 1. FileEntry contains a sys::Path instead of a std::string for Name.
- 2. sys::Path contains timestamp and size, lazily computed. Eliminate from
- FileEntry.
- 3. File UIDs are created on request, not when files are opened.
- These changes make it possible to efficiently have FileEntry objects for
- files that exist on the file system, but have not been used yet.
-
- Once this is done:
- 1. DirectoryEntry gets a boolean value "has read entries". When false, not
- all entries in the directory are in the file mgr, when true, they are.
- 2. Instead of stat'ing the file in FileManager::getFile, check to see if
- the dir has been read. If so, fail immediately, if not, read the dir,
- then retry.
- 3. Reading the dir uses the getdirentries syscall, creating an FileEntry
- for all files found.
-
-//===---------------------------------------------------------------------===//
-
-TODO: Fast #Import:
-
- * Get frameworks that don't use #import to do so, e.g.
- DirectoryService, AudioToolbox, CoreFoundation, etc. Why not using #import?
- Because they work in C mode? C has #import.
- * Have the lexer return a token for #import instead of handling it itself.
- - Create a new preprocessor object with no external state (no -D/U options
- from the command line, etc). Alternatively, keep track of exactly which
- external state is used by a #import: declare it somehow.
- * When having reading a #import file, keep track of whether we have (and/or
- which) seen any "configuration" macros. Various cases:
- - Uses of target args (__POWERPC__, __i386): Header has to be parsed
- multiple times, per-target. What about #ifndef checks? How do we know?
- - "Configuration" preprocessor macros not defined: POWERPC, etc. What about
- things like __STDC__ etc? What is and what isn't allowed.
- * Special handling for "umbrella" headers, which just contain #import stmts:
- - Cocoa.h/AppKit.h - Contain pointers to digests instead of entire digests
- themselves? Foundation.h isn't pure umbrella!
- * Frameworks digests:
- - Can put "digest" of a framework-worth of headers into the framework
- itself. To open AppKit, just mmap
- /System/Library/Frameworks/AppKit.framework/"digest", which provides a
- symbol table in a well defined format. Lazily unstream stuff that is
- needed. Contains declarations, macros, and debug information.
- - System frameworks ship with digests. How do we handle configuration
- information? How do we handle stuff like:
- #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
- which guards a bunch of decls? Should there be a couple of default
- configs, then have the UI fall back to building/caching its own?
- - GUI automatically builds digests when UI is idle, both of system
- frameworks if they aren't not available in the right config, and of app
- frameworks.
- - GUI builds dependence graph of frameworks/digests based on #imports. If a
- digest is out date, dependent digests are automatically invalidated.
-
- * New constraints on #import for objc-v3:
- - #imported file must not define non-inline function bodies.
- - Alternatively, they can, and these bodies get compiled/linked *once*
- per app into a dylib. What about building user dylibs?
- - Restrictions on ObjC grammar: can't #import the body of a for stmt or fn.
- - Compiler must detect and reject these cases.
- - #defines defined within a #import have two behaviors:
- - By default, they escape the header. These macros *cannot* be #undef'd
- by other code: this is enforced by the front-end.
- - Optionally, user can specify what macros escape (whitelist) or can use
- #undef.
-
-//===---------------------------------------------------------------------===//
-
-TODO: New language feature: Configuration queries:
- - Instead of #ifdef __POWERPC__, use "if (strcmp(`cpu`, __POWERPC__))", or
- some other, better, syntax.
- - Use it to increase the number of "architecture-clean" #import'd files,
- allowing a single index to be used for all fat slices.
-
-//===---------------------------------------------------------------------===//
-// 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.
-
-The "selection of target" behavior is defined as follows:
-
-(1) If the user does not specify -triple, we default to the host triple.
-(2) If the user specifies a -arch, that overrides the arch in the host or
- specified triple.
-
-//===---------------------------------------------------------------------===//
-
-
-verifyInputConstraint and verifyOutputConstraint should not return bool.
-
-Instead we should return something like:
-
-enum VerifyConstraintResult {
- Valid,
-
- // Output only
- OutputOperandConstraintLacksEqualsCharacter,
- MatchingConstraintNotValidInOutputOperand,
-
- // Input only
- InputOperandConstraintContainsEqualsCharacter,
- MatchingConstraintReferencesInvalidOperandNumber,
-
- // Both
- PercentConstraintUsedWithLastOperand
-};
-
-//===---------------------------------------------------------------------===//
diff --git a/clang/README.txt b/clang/README.txt
deleted file mode 100644
index 41f08fe18bd7..000000000000
--- a/clang/README.txt
+++ /dev/null
@@ -1,199 +0,0 @@
-//===----------------------------------------------------------------------===//
-// C Language Family Front-end
-//===----------------------------------------------------------------------===//
- Chris Lattner
-
-I. Introduction:
-
- clang: noun
- 1. A loud, resonant, metallic sound.
- 2. The strident call of a crane or goose.
- 3. C-language family front-end toolkit.
-
- The world needs better compiler tools, tools which are built as libraries. This
- design point allows reuse of the tools in new and novel ways. However, building
- the tools as libraries isn't enough: they must have clean APIs, be as
- decoupled from each other as possible, and be easy to modify/extend. This
- requires clean layering, decent design, and avoiding tying the libraries to a
- specific use. Oh yeah, did I mention that we want the resultant libraries to
- be as fast as possible? :)
-
- This front-end is built as a component of the LLVM toolkit that can be used
- with the LLVM backend or independently of it. In this spirit, the API has been
- carefully designed as the following components:
-
- libsupport - Basic support library, reused from LLVM.
-
- libsystem - System abstraction library, reused from LLVM.
-
- libbasic - Diagnostics, SourceLocations, SourceBuffer abstraction,
- file system caching for input source files. This depends on
- libsupport and libsystem.
-
- libast - Provides classes to represent the C AST, the C type system,
- builtin functions, and various helpers for analyzing and
- manipulating the AST (visitors, pretty printers, etc). This
- library depends on libbasic.
-
-
- liblex - C/C++/ObjC lexing and preprocessing, identifier hash table,
- pragma handling, tokens, and macros. This depends on libbasic.
-
- libparse - C (for now) parsing and local semantic analysis. This library
- invokes coarse-grained 'Actions' provided by the client to do
- stuff (e.g. libsema builds ASTs). This depends on liblex.
-
- libsema - Provides a set of parser actions to build a standardized AST
- for programs. AST's are 'streamed' out a top-level declaration
- at a time, allowing clients to use decl-at-a-time processing,
- build up entire translation units, or even build 'whole
- program' ASTs depending on how they use the APIs. This depends
- on libast and libparse.
-
- librewrite - Fast, scalable rewriting of source code. This operates on
- the raw syntactic text of source code, allowing a client
- to insert and delete text in very large source files using
- the same source location information embedded in ASTs. This
- is intended to be a low-level API that is useful for
- higher-level clients and libraries such as code refactoring.
-
- libanalysis - Source-level dataflow analysis useful for performing analyses
- such as computing live variables. It also includes a
- path-sensitive "graph-reachability" engine for writing
- analyses that reason about different possible paths of
- execution through source code. This is currently being
- employed to write a set of checks for finding bugs in software.
-
- libcodegen - Lower the AST to LLVM IR for optimization & codegen. Depends
- on libast.
-
- clang - An example driver, client of the libraries at various levels.
- This depends on all these libraries, and on LLVM VMCore.
-
- This front-end has been intentionally built as a DAG of libraries, making it
- easy to reuse individual parts or replace pieces if desired. For example, to
- build a preprocessor, you take the Basic and Lexer libraries. If you want an
- indexer, you take those plus the Parser library and provide some actions for
- indexing. If you want a refactoring, static analysis, or source-to-source
- compiler tool, it makes sense to take those plus the AST building and semantic
- analyzer library. Finally, if you want to use this with the LLVM backend,
- you'd take these components plus the AST to LLVM lowering code.
-
- In the future I hope this toolkit will grow to include new and interesting
- components, including a C++ front-end, ObjC support, and a whole lot of other
- things.
-
- Finally, it should be pointed out that the goal here is to build something that
- is high-quality and industrial-strength: all the obnoxious features of the C
- family must be correctly supported (trigraphs, preprocessor arcana, K&R-style
- prototypes, GCC/MS extensions, etc). It cannot be used if it is not 'real'.
-
-
-II. Usage of clang driver:
-
- * Basic Command-Line Options:
- - Help: clang --help
- - Standard GCC options accepted: -E, -I*, -i*, -pedantic, -std=c90, etc.
- - To make diagnostics more gcc-like: -fno-caret-diagnostics -fno-show-column
- - Enable metric printing: -stats
-
- * -fsyntax-only is currently the default mode.
-
- * -E mode works the same way as GCC.
-
- * -Eonly mode does all preprocessing, but does not print the output,
- useful for timing the preprocessor.
-
- * -fsyntax-only is currently partially implemented, lacking some
- semantic analysis (some errors and warnings are not produced).
-
- * -parse-noop parses code without building an AST. This is useful
- for timing the cost of the parser without including AST building
- time.
-
- * -parse-ast builds ASTs, but doesn't print them. This is most
- useful for timing AST building vs -parse-noop.
-
- * -parse-ast-print pretty prints most expression and statements nodes.
-
- * -parse-ast-check checks that diagnostic messages that are expected
- are reported and that those which are reported are expected.
-
- * -dump-cfg builds ASTs and then CFGs. CFGs are then pretty-printed.
-
- * -view-cfg builds ASTs and then CFGs. CFGs are then visualized by
- invoking Graphviz.
-
- For more information on getting Graphviz to work with clang/LLVM,
- see: http://llvm.org/docs/ProgrammersManual.html#ViewGraph
-
-
-III. Current advantages over GCC:
-
- * Column numbers are fully tracked (no 256 col limit, no GCC-style pruning).
- * All diagnostics have column numbers, includes 'caret diagnostics', and they
- highlight regions of interesting code (e.g. the LHS and RHS of a binop).
- * Full diagnostic customization by client (can format diagnostics however they
- like, e.g. in an IDE or refactoring tool) through DiagnosticClient interface.
- * Built as a framework, can be reused by multiple tools.
- * All languages supported linked into same library (no cc1,cc1obj, ...).
- * mmap's code in read-only, does not dirty the pages like GCC (mem footprint).
- * LLVM License, can be linked into non-GPL projects.
- * Full diagnostic control, per diagnostic. Diagnostics are identified by ID.
- * Significantly faster than GCC at semantic analysis, parsing, preprocessing
- and lexing.
- * Defers exposing platform-specific stuff to as late as possible, tracks use of
- platform-specific features (e.g. #ifdef PPC) to allow 'portable bytecodes'.
- * The lexer doesn't rely on the "lexer hack": it has no notion of scope and
- does not categorize identifiers as types or variables -- this is up to the
- parser to decide.
-
-Potential Future Features:
-
- * Fine grained diag control within the source (#pragma enable/disable warning).
- * Better token tracking within macros? (Token came from this line, which is
- a macro argument instantiated here, recursively instantiated here).
- * Fast #import with a module system.
- * Dependency tracking: change to header file doesn't recompile every function
- that texually depends on it: recompile only those functions that need it.
- This is aka 'incremental parsing'.
-
-
-IV. Missing Functionality / Improvements
-
-clang driver:
- * Include search paths are hard-coded into the driver. Doh.
-
-File Manager:
- * Reduce syscalls for reduced compile time, see NOTES.txt.
-
-Lexer:
- * Source character mapping. GCC supports ASCII and UTF-8.
- See GCC options: -ftarget-charset and -ftarget-wide-charset.
- * Universal character support. Experimental in GCC, enabled with
- -fextended-identifiers.
- * -fpreprocessed mode.
-
-Preprocessor:
- * Know about apple header maps.
- * #assert/#unassert
- * #line / #file directives (currently accepted and ignored).
- * MSExtension: "L#param" stringizes to a wide string literal.
- * Charize extension: "#define F(o) #@o F(a)" -> 'a'.
- * Consider merging the parser's expression parser into the preprocessor to
- eliminate duplicate code.
- * Add support for -M*
-
-Traditional Preprocessor:
- * Currently, we have none. :)
-
-Parser:
- * C90/K&R modes are only partially implemented.
- * __extension__ is currently just skipped and ignored.
-
-Semantic Analysis:
- * Perhaps 85% done.
-
-LLVM Code Gen:
- * Most of the easy stuff is done, probably 65.42% done so far.
-
diff --git a/clang/TODO.txt b/clang/TODO.txt
deleted file mode 100644
index 111f747275d9..000000000000
--- a/clang/TODO.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-//===---------------------------------------------------------------------===//
-// Minor random things that can be improved
-//===---------------------------------------------------------------------===//
-
-
-Warn about "X && 0x1000" saying that the user may mean "X & 0x1000".
-We should do this for any immediate except zero, so long as it doesn't come
-from a macro expansion. Likewise for ||.
-
-//===---------------------------------------------------------------------===//
-
-Lexer-related diagnostics should point to the problematic character, not the
-start of the token. For example:
-
-int y = 0000\
-00080;
-
-diag.c:4:9: error: invalid digit '8' in octal constant
-int y = 0000\
- ^
-
-should be:
-
-diag.c:4:9: error: invalid digit '8' in octal constant
-00080;
- ^
-
-This specific diagnostic is implemented, but others should be updated.
-
-//===---------------------------------------------------------------------===//
-
-C++ (checker): For iterators, warn of the use of "iterator++" instead
- of "++iterator" when when the value returned by operator++(int) is
- ignored.
diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj
deleted file mode 100644
index 1d3aa080a96c..000000000000
--- a/clang/clang.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1380 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 42;
- objects = {
-
-/* Begin PBXBuildFile section */
- 035611E20DB40C8100D2EF2A /* RewriteObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 035611E10DB40C8100D2EF2A /* RewriteObjC.cpp */; };
- 03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F50AC50D416EAA00B9CF60 /* Targets.cpp */; };
- 1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
- 1A32C17F0E1C87AD00A6B483 /* ExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A32C17E0E1C87AD00A6B483 /* ExprConstant.cpp */; };
- 1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */; };
- 1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D5E570E5E81010023C059 /* CGCXX.cpp */; };
- 1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
- 1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
- 1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
- 1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
- 3507E4C20E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */; };
- 350F4B470E5F32E100A21EA9 /* InitHeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 350F4B460E5F32E100A21EA9 /* InitHeaderSearch.cpp */; };
- 351318600CD14468006B66F7 /* DeclSerialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3513185F0CD14468006B66F7 /* DeclSerialization.cpp */; };
- 35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */; };
- 352712510DAFE54700C76352 /* IdentifierResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352712500DAFE54700C76352 /* IdentifierResolver.cpp */; };
- 352981090CC58344008B5E84 /* SerializationTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 352981080CC58344008B5E84 /* SerializationTest.cpp */; };
- 3534A01D0E129849002709B2 /* ParseCXXInlineMethods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3534A01C0E129849002709B2 /* ParseCXXInlineMethods.cpp */; };
- 3536456B0E23EBF7009C6509 /* Environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3536456A0E23EBF7009C6509 /* Environment.cpp */; };
- 35475B200E79973F0000BFE4 /* CGCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35475B1F0E79973F0000BFE4 /* CGCall.cpp */; };
- 355106860E9A8507006A4E44 /* MemRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 355106850E9A8507006A4E44 /* MemRegion.cpp */; };
- 3551068C0E9A8546006A4E44 /* ParsePragma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3551068A0E9A8546006A4E44 /* ParsePragma.cpp */; };
- 3551068D0E9A8546006A4E44 /* ParseTentative.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3551068B0E9A8546006A4E44 /* ParseTentative.cpp */; };
- 3552E7550E520D80003A8CA5 /* PPCaching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3552E7540E520D80003A8CA5 /* PPCaching.cpp */; };
- 3552E7590E520DD7003A8CA5 /* CGObjCMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */; };
- 3558F76D0E267C8300A5B0DF /* BasicStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3558F76C0E267C8300A5B0DF /* BasicStore.cpp */; };
- 356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */; };
- 35707EFE0CD0F5CC000B2204 /* SourceLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */; };
- 3580CC0C0D072E5C00C5E4F4 /* LangOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3580CC0B0D072E5C00C5E4F4 /* LangOptions.cpp */; };
- 35839B0B0CDF845F006ED061 /* StmtSerialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35839B090CDF845F006ED061 /* StmtSerialization.cpp */; };
- 35839B0C0CDF845F006ED061 /* TypeSerialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35839B0A0CDF845F006ED061 /* TypeSerialization.cpp */; };
- 35847BE50CC7DBAF00C40FFF /* StmtIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35847BE40CC7DBAF00C40FFF /* StmtIterator.cpp */; };
- 35862B0D0E3628CB0009F542 /* CheckDeadStores.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35862B0C0E3628CB0009F542 /* CheckDeadStores.cpp */; };
- 35862B120E3629850009F542 /* GRExprEngineInternalChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35862B110E3629850009F542 /* GRExprEngineInternalChecks.cpp */; };
- 358CFBB80E65AB04002A8E19 /* BasicConstraintManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 358CFBB70E65AB04002A8E19 /* BasicConstraintManager.cpp */; };
- 358D230B0E8BEB9D0003DDCC /* DeclGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 358D230A0E8BEB9D0003DDCC /* DeclGroup.cpp */; };
- 358F51520E529AA4007F2102 /* GRState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 358F51510E529AA4007F2102 /* GRState.cpp */; };
- 3593790A0DA48ABA0043B19C /* BugReporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359379090DA48ABA0043B19C /* BugReporter.cpp */; };
- 3595AFB80E1C8D62004CDF09 /* CheckObjCDealloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3595AFB70E1C8D62004CDF09 /* CheckObjCDealloc.cpp */; };
- 359603460E49496E00C6282B /* TextDiagnosticBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359603430E49496E00C6282B /* TextDiagnosticBuffer.cpp */; };
- 359603470E49496E00C6282B /* TextDiagnosticPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359603440E49496E00C6282B /* TextDiagnosticPrinter.cpp */; };
- 359763260E633C7500B68AB7 /* HTMLDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359763250E633C7500B68AB7 /* HTMLDiagnostics.cpp */; };
- 3599299B0DE2425300A8A33E /* SemaInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3599299A0DE2425300A8A33E /* SemaInit.cpp */; };
- 359DBBD40E1AC9CC00F43FA0 /* AnalysisConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359DBBD30E1AC9CC00F43FA0 /* AnalysisConsumer.cpp */; };
- 35A3E7020DD3874400757F74 /* CGDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */; };
- 35A8FCF90D9B4B2A001C2F97 /* PathDiagnostic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */; };
- 35BAC1E80E82C5B7003FB76F /* CheckNSError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35BAC1E70E82C5B7003FB76F /* CheckNSError.cpp */; };
- 35BB2D7D0D19951A00944DB5 /* TranslationUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35BB2D7C0D19951A00944DB5 /* TranslationUnit.cpp */; };
- 35BB2D7F0D19954000944DB5 /* ASTConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35BB2D7E0D19954000944DB5 /* ASTConsumer.cpp */; };
- 35CFFE000CA1CBCB00E6F2BE /* StmtViz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */; };
- 35D55B270D81D8C60092E734 /* BasicValueFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */; };
- 35D55B280D81D8C60092E734 /* CFRefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35D55B250D81D8C60092E734 /* CFRefCount.cpp */; };
- 35EE48B10E0C4CCA00715C54 /* DeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EE48AF0E0C4CCA00715C54 /* DeclCXX.cpp */; };
- 35EE48B20E0C4CCA00715C54 /* ParentMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EE48B00E0C4CCA00715C54 /* ParentMap.cpp */; };
- 35EF67700DAD1D2C00B19414 /* SemaDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */; };
- 35EFEFB60DB67ED60020783D /* GRTransferFuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */; };
- 35F2A01E0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35F2A01D0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp */; };
- 35F8D0D60D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */; };
- 35FE6BCF0DF6EE1F00739712 /* DeclBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35FE6BCE0DF6EE1F00739712 /* DeclBase.cpp */; };
- 72D16C1F0D9975C400E6DA4A /* HTMLRewrite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72D16C1E0D9975C400E6DA4A /* HTMLRewrite.cpp */; };
- 72D16C220D9975EA00E6DA4A /* HTMLPrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72D16C210D9975EA00E6DA4A /* HTMLPrint.cpp */; };
- 84AF36A10CB17A3B00C820A5 /* DeclObjC.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */; };
- 84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; };
- 84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; };
- 9030C10A0E807A9300941490 /* RewriteBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9030C1090E807A9300941490 /* RewriteBlocks.cpp */; };
- DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
- DE06756C0C051CFE00EBBFD8 /* ParseExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */; };
- DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06B73D0A8307640050E87E /* LangOptions.h */; };
- DE06BECB0A854E4B0050E87E /* Scope.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06BECA0A854E4B0050E87E /* Scope.h */; };
- DE06D4310A8BB52D0050E87E /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06D42F0A8BB52D0050E87E /* Parser.cpp */; };
- DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06E8130A8FF9330050E87E /* Action.h */; };
- DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE0FCA620A95859D00248FD5 /* Expr.h */; };
- DE0FCB340A9C21F100248FD5 /* Expr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0FCB330A9C21F100248FD5 /* Expr.cpp */; };
- DE1733000B068B700080B521 /* ASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE1732FF0B068B700080B521 /* ASTContext.cpp */; };
- DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE17336D0B068DC20080B521 /* DeclSpec.cpp */; };
- DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE17336F0B068DC60080B521 /* DeclSpec.h */; };
- DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
- DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */; };
- DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */; };
- DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */; };
- DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */; };
- DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */; };
- DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */; };
- DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3450D60AEB543100DBC861 /* DirectoryLookup.h */; };
- DE3452410AEF1A2D00DBC861 /* Stmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3452400AEF1A2D00DBC861 /* Stmt.cpp */; };
- DE3452810AEF1B1800DBC861 /* Stmt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3452800AEF1B1800DBC861 /* Stmt.h */; };
- DE345C1A0AFC658B00DBC861 /* StmtVisitor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE345C190AFC658B00DBC861 /* StmtVisitor.h */; };
- DE345F220AFD347900DBC861 /* StmtNodes.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE345F210AFD347900DBC861 /* StmtNodes.def */; };
- DE3460000AFDCC1900DBC861 /* ParseObjc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */; };
- DE3460050AFDCC6500DBC861 /* ParseInit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3460040AFDCC6500DBC861 /* ParseInit.cpp */; };
- DE34600B0AFDCCBF00DBC861 /* ParseStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */; };
- DE34600F0AFDCCCE00DBC861 /* ParseDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */; };
- DE3460130AFDCCDA00DBC861 /* ParseExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */; };
- DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */; };
- DE34621D0AFEB19B00DBC861 /* StmtPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */; };
- DE3464220B03040900DBC861 /* Type.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3464210B03040900DBC861 /* Type.h */; };
- DE38CD500D794D0100A273B6 /* CGObjCGNU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */; };
- DE38CF160D8C9DE000A273B6 /* DiagChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE38CF150D8C9DE000A273B6 /* DiagChecker.cpp */; };
- DE38CF270D8C9E6C00A273B6 /* DeclObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE38CF260D8C9E6C00A273B6 /* DeclObjC.cpp */; };
- DE3985790CB8ADC800223765 /* ASTConsumers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3985780CB8ADC800223765 /* ASTConsumers.h */; };
- DE39857B0CB8ADCB00223765 /* ASTConsumers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */; };
- DE3986F00CB8D4B300223765 /* IdentifierTable.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3986EF0CB8D4B300223765 /* IdentifierTable.h */; };
- DE3986F40CB8D50C00223765 /* IdentifierTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */; };
- DE4121350D7F1C1C0080F80A /* SymbolManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */; };
- DE4121360D7F1C1C0080F80A /* ExplodedGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */; };
- DE4121370D7F1C1C0080F80A /* UninitializedValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */; };
- DE4121380D7F1C1C0080F80A /* GRCoreEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */; };
- DE41213B0D7F1C1C0080F80A /* RValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE41212E0D7F1C1C0080F80A /* RValues.cpp */; };
- DE41213C0D7F1C1C0080F80A /* GRSimpleVals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */; };
- DE41213D0D7F1C1C0080F80A /* GRBlockCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */; };
- DE41213E0D7F1C1C0080F80A /* GRExprEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */; };
- DE4264FC0C113592005A861D /* CGDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4264FB0C113592005A861D /* CGDecl.cpp */; };
- DE46BF280AE0A82D00CC047C /* TargetInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE46BF270AE0A82D00CC047C /* TargetInfo.h */; };
- DE4772FA0C10EAE5002239E8 /* CGStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4772F90C10EAE5002239E8 /* CGStmt.cpp */; };
- DE4772FC0C10EAEC002239E8 /* CGExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */; };
- DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */; };
- DE5932D10AD60FF400BC794C /* clang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5932CD0AD60FF400BC794C /* clang.cpp */; };
- DE5932D20AD60FF400BC794C /* clang.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE5932CE0AD60FF400BC794C /* clang.h */; };
- DE5932D30AD60FF400BC794C /* PrintParserCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */; };
- DE5932D40AD60FF400BC794C /* PrintPreprocessedOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */; };
- DE67E70B0C020EC500F66BC5 /* SemaType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E70A0C020EC500F66BC5 /* SemaType.cpp */; };
- DE67E70D0C020ECA00F66BC5 /* SemaStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */; };
- DE67E70F0C020ECF00F66BC5 /* SemaExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */; };
- DE67E7110C020ED400F66BC5 /* SemaExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */; };
- DE67E7130C020ED900F66BC5 /* SemaDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */; };
- DE67E7150C020EDF00F66BC5 /* Sema.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE67E7140C020EDF00F66BC5 /* Sema.h */; };
- DE67E7170C020EE400F66BC5 /* Sema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7160C020EE400F66BC5 /* Sema.cpp */; };
- DE67E71A0C020F4F00F66BC5 /* ParseAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */; };
- DE67E7280C02109800F66BC5 /* ParseAST.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE67E7270C02109800F66BC5 /* ParseAST.h */; };
- DE6951C70C4D1F5D00A5826B /* RecordLayout.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE6951C60C4D1F5D00A5826B /* RecordLayout.h */; };
- DE6954640C5121BD00A5826B /* Token.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE6954630C5121BD00A5826B /* Token.h */; };
- DE704B260D0FBEBE009C7762 /* SemaDeclObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */; };
- DE704DD20D1668A4009C7762 /* HeaderMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE704DD10D1668A4009C7762 /* HeaderMap.cpp */; };
- DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE75ED280B044DC90020CF81 /* ASTContext.h */; };
- DE75EDF10B06880E0020CF81 /* Type.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE75EDF00B06880E0020CF81 /* Type.cpp */; };
- DE85CD810D8380B10070E26E /* TokenLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CD800D8380B10070E26E /* TokenLexer.cpp */; };
- DE85CDA30D8383B20070E26E /* MacroArgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDA20D8383B20070E26E /* MacroArgs.cpp */; };
- DE85CDAC0D838C120070E26E /* PPMacroExpansion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDAB0D838C120070E26E /* PPMacroExpansion.cpp */; };
- DE85CDB00D838C390070E26E /* PPDirectives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDAF0D838C390070E26E /* PPDirectives.cpp */; };
- DE85CDB60D839BAE0070E26E /* PPLexerChange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE85CDB50D839BAE0070E26E /* PPLexerChange.cpp */; };
- DE928B130C05659200231DA4 /* ModuleBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B120C05659200231DA4 /* ModuleBuilder.cpp */; };
- DE928B200C0565B000231DA4 /* ModuleBuilder.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */; };
- DE928B7D0C0A615100231DA4 /* CodeGenModule.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE928B7C0C0A615100231DA4 /* CodeGenModule.h */; };
- DE928B7F0C0A615600231DA4 /* CodeGenModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */; };
- DE928B810C0A615B00231DA4 /* CodeGenFunction.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE928B800C0A615B00231DA4 /* CodeGenFunction.h */; };
- DE928B830C0A616000231DA4 /* CodeGenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */; };
- DEA0EBDA0DD2D3C8007A02A9 /* RewriteMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEA0EBD90DD2D3C8007A02A9 /* RewriteMacros.cpp */; };
- DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */; };
- DEAEED4B0A5AF89A0045101B /* NOTES.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEED4A0A5AF89A0045101B /* NOTES.txt */; };
- DEC63B1A0C7B940200DBF169 /* CFG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEC63B190C7B940200DBF169 /* CFG.cpp */; };
- DEC63B1C0C7B940600DBF169 /* CFG.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC63B1B0C7B940600DBF169 /* CFG.h */; };
- DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9900A9433CD00353FCA /* Decl.h */; };
- DEC8D9A40A94346E00353FCA /* AST.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9A30A94346E00353FCA /* AST.h */; };
- DECAB0D00DB3C84200E13CCB /* RewriteRope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */; };
- DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; };
- DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */; };
- DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676D00B6C786700AAD4A3 /* Builtins.def */; };
- DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676F90B6C797B00AAD4A3 /* Builtins.h */; };
- DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED677C80B6C854100AAD4A3 /* Builtins.cpp */; };
- DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; };
- DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; };
- DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; };
- DED7D7450A524295003AD0FB /* SourceLocation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7350A524295003AD0FB /* SourceLocation.h */; };
- DED7D7460A524295003AD0FB /* SourceManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7360A524295003AD0FB /* SourceManager.h */; };
- DED7D7470A524295003AD0FB /* TokenKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7370A524295003AD0FB /* TokenKinds.def */; };
- DED7D7480A524295003AD0FB /* TokenKinds.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7380A524295003AD0FB /* TokenKinds.h */; };
- DED7D74A0A524295003AD0FB /* Lexer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D73B0A524295003AD0FB /* Lexer.h */; };
- DED7D74D0A524295003AD0FB /* MacroInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D73E0A524295003AD0FB /* MacroInfo.h */; };
- DED7D74E0A524295003AD0FB /* Pragma.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D73F0A524295003AD0FB /* Pragma.h */; };
- DED7D74F0A524295003AD0FB /* Preprocessor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7400A524295003AD0FB /* Preprocessor.h */; };
- DED7D77A0A5242C7003AD0FB /* Diagnostic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D75D0A5242C7003AD0FB /* Diagnostic.cpp */; };
- DED7D77B0A5242C7003AD0FB /* FileManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D75E0A5242C7003AD0FB /* FileManager.cpp */; };
- DED7D7890A5242C7003AD0FB /* SourceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D76D0A5242C7003AD0FB /* SourceManager.cpp */; };
- DED7D78A0A5242C7003AD0FB /* TokenKinds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D76E0A5242C7003AD0FB /* TokenKinds.cpp */; };
- DED7D7C30A5242E6003AD0FB /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D79E0A5242E6003AD0FB /* Lexer.cpp */; };
- DED7D7C50A5242E6003AD0FB /* MacroInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A00A5242E6003AD0FB /* MacroInfo.cpp */; };
- DED7D7C70A5242E6003AD0FB /* PPExpressions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A20A5242E6003AD0FB /* PPExpressions.cpp */; };
- DED7D7C80A5242E6003AD0FB /* Pragma.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A30A5242E6003AD0FB /* Pragma.cpp */; };
- DED7D7C90A5242E6003AD0FB /* Preprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D7A40A5242E6003AD0FB /* Preprocessor.cpp */; };
- DED7D7D80A524302003AD0FB /* README.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7D70A524302003AD0FB /* README.txt */; };
- DED7D9180A52518C003AD0FB /* ScratchBuffer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D9170A52518C003AD0FB /* ScratchBuffer.h */; };
- DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
- DEEBBD440C19C5D200A9FE82 /* TODO.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEEBBD430C19C5D200A9FE82 /* TODO.txt */; };
- DEEBC3BA0C2363B800A9FE82 /* CodeGenTypes.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */; };
- DEEBC3BC0C2363BC00A9FE82 /* CodeGenTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */; };
- DEF2E95F0C5FBD74000C4259 /* InternalsManual.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */; };
- DEF2EDA70C6A4252000C4259 /* StmtDumper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */; };
- DEF2EFF30C6CDD74000C4259 /* CGExprAgg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */; };
- DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */; };
- DEF7D9F70C9C8B1A0001F598 /* Rewriter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */; };
- DEF7D9F90C9C8B1D0001F598 /* Rewriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEF7D9F80C9C8B1D0001F598 /* Rewriter.cpp */; };
- DEFFECA70DB1546600B4E7C3 /* DeltaTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEFFECA60DB1546600B4E7C3 /* DeltaTree.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 8DD76F690486A84900D96B5E /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 8;
- dstPath = /usr/share/man/man1/;
- dstSubfolderSpec = 0;
- files = (
- DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */,
- DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */,
- DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */,
- DED7D7450A524295003AD0FB /* SourceLocation.h in CopyFiles */,
- DED7D7460A524295003AD0FB /* SourceManager.h in CopyFiles */,
- DED7D7470A524295003AD0FB /* TokenKinds.def in CopyFiles */,
- DED7D7480A524295003AD0FB /* TokenKinds.h in CopyFiles */,
- DED7D74A0A524295003AD0FB /* Lexer.h in CopyFiles */,
- DED7D74D0A524295003AD0FB /* MacroInfo.h in CopyFiles */,
- DED7D74E0A524295003AD0FB /* Pragma.h in CopyFiles */,
- DED7D74F0A524295003AD0FB /* Preprocessor.h in CopyFiles */,
- DED7D7D80A524302003AD0FB /* README.txt in CopyFiles */,
- DED7D9180A52518C003AD0FB /* ScratchBuffer.h in CopyFiles */,
- DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */,
- DEAEED4B0A5AF89A0045101B /* NOTES.txt in CopyFiles */,
- DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */,
- DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */,
- DE06BECB0A854E4B0050E87E /* Scope.h in CopyFiles */,
- DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */,
- DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */,
- DEC8D9A40A94346E00353FCA /* AST.h in CopyFiles */,
- DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */,
- DE5932D20AD60FF400BC794C /* clang.h in CopyFiles */,
- DE46BF280AE0A82D00CC047C /* TargetInfo.h in CopyFiles */,
- DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */,
- DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */,
- DE3452810AEF1B1800DBC861 /* Stmt.h in CopyFiles */,
- DE345C1A0AFC658B00DBC861 /* StmtVisitor.h in CopyFiles */,
- DE345F220AFD347900DBC861 /* StmtNodes.def in CopyFiles */,
- DE3464220B03040900DBC861 /* Type.h in CopyFiles */,
- DE75ED290B044DC90020CF81 /* ASTContext.h in CopyFiles */,
- DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */,
- DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */,
- DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */,
- DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */,
- 1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */,
- 1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */,
- DE67E7150C020EDF00F66BC5 /* Sema.h in CopyFiles */,
- DE67E7280C02109800F66BC5 /* ParseAST.h in CopyFiles */,
- DE928B200C0565B000231DA4 /* ModuleBuilder.h in CopyFiles */,
- DE928B7D0C0A615100231DA4 /* CodeGenModule.h in CopyFiles */,
- DE928B810C0A615B00231DA4 /* CodeGenFunction.h in CopyFiles */,
- DEEBBD440C19C5D200A9FE82 /* TODO.txt in CopyFiles */,
- 84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */,
- DEEBC3BA0C2363B800A9FE82 /* CodeGenTypes.h in CopyFiles */,
- DE6951C70C4D1F5D00A5826B /* RecordLayout.h in CopyFiles */,
- DE6954640C5121BD00A5826B /* Token.h in CopyFiles */,
- DEF2E95F0C5FBD74000C4259 /* InternalsManual.html in CopyFiles */,
- DEC63B1C0C7B940600DBF169 /* CFG.h in CopyFiles */,
- DEF7D9F70C9C8B1A0001F598 /* Rewriter.h in CopyFiles */,
- 84AF36A10CB17A3B00C820A5 /* DeclObjC.h in CopyFiles */,
- DE3985790CB8ADC800223765 /* ASTConsumers.h in CopyFiles */,
- DE3986F00CB8D4B300223765 /* IdentifierTable.h in CopyFiles */,
- );
- runOnlyForDeploymentPostprocessing = 1;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 035611470DA6A45C00D2EF2A /* DeclBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclBase.h; path = clang/AST/DeclBase.h; sourceTree = "<group>"; };
- 035611E10DB40C8100D2EF2A /* RewriteObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteObjC.cpp; path = Driver/RewriteObjC.cpp; sourceTree = "<group>"; };
- 03F50AC50D416EAA00B9CF60 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Targets.cpp; sourceTree = "<group>"; };
- 1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
- 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; };
- 1A5D5E570E5E81010023C059 /* CGCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGCXX.cpp; path = lib/CodeGen/CGCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PPCBuiltins.def; path = clang/AST/PPCBuiltins.def; sourceTree = "<group>"; };
- 1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetBuiltins.h; path = clang/AST/TargetBuiltins.h; sourceTree = "<group>"; };
- 1A68BC130D0CADDD001A28C8 /* X86Builtins.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = X86Builtins.def; path = clang/AST/X86Builtins.def; sourceTree = "<group>"; };
- 1A72BEAC0D641E9400B085E9 /* Attr.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Attr.h; path = clang/AST/Attr.h; sourceTree = "<group>"; tabWidth = 2; };
- 1A7342470C7B57D500122F56 /* CGObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjC.cpp; path = lib/CodeGen/CGObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
- 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
- 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; };
- 3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCInstMethSignature.cpp; path = lib/Analysis/CheckObjCInstMethSignature.cpp; sourceTree = "<group>"; };
- 350F4B460E5F32E100A21EA9 /* InitHeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitHeaderSearch.cpp; path = lib/Driver/InitHeaderSearch.cpp; sourceTree = "<group>"; };
- 350F4B490E5F36EE00A21EA9 /* InitHeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InitHeaderSearch.h; path = clang/Driver/InitHeaderSearch.h; sourceTree = "<group>"; };
- 3513185F0CD14468006B66F7 /* DeclSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DeclSerialization.cpp; path = lib/AST/DeclSerialization.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 352028460E2C16820096ADE0 /* Analyses.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Analyses.def; path = Driver/Analyses.def; sourceTree = "<group>"; };
- 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = lib/AST/ExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 3527124F0DAFE54700C76352 /* IdentifierResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = IdentifierResolver.h; path = lib/Sema/IdentifierResolver.h; sourceTree = "<group>"; tabWidth = 2; };
- 352712500DAFE54700C76352 /* IdentifierResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = IdentifierResolver.cpp; path = lib/Sema/IdentifierResolver.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 352981080CC58344008B5E84 /* SerializationTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SerializationTest.cpp; path = Driver/SerializationTest.cpp; sourceTree = "<group>"; };
- 352C19DC0CA321C80045DB98 /* CFGRecStmtDeclVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGRecStmtDeclVisitor.h; path = clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h; sourceTree = "<group>"; };
- 352C19DD0CA321C80045DB98 /* CFGRecStmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGRecStmtVisitor.h; path = clang/Analysis/Visitors/CFGRecStmtVisitor.h; sourceTree = "<group>"; };
- 352C19DE0CA321C80045DB98 /* CFGStmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGStmtVisitor.h; path = clang/Analysis/Visitors/CFGStmtVisitor.h; sourceTree = "<group>"; };
- 352C19DF0CA321C80045DB98 /* CFGVarDeclVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFGVarDeclVisitor.h; path = clang/Analysis/Visitors/CFGVarDeclVisitor.h; sourceTree = "<group>"; };
- 3534A01C0E129849002709B2 /* ParseCXXInlineMethods.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseCXXInlineMethods.cpp; path = lib/Parse/ParseCXXInlineMethods.cpp; sourceTree = "<group>"; };
- 3536456A0E23EBF7009C6509 /* Environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Environment.cpp; path = lib/Analysis/Environment.cpp; sourceTree = "<group>"; };
- 3536457C0E2406B0009C6509 /* Environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Environment.h; path = clang/Analysis/PathSensitive/Environment.h; sourceTree = "<group>"; };
- 3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = "<group>"; };
- 35475B1F0E79973F0000BFE4 /* CGCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGCall.cpp; path = lib/CodeGen/CGCall.cpp; sourceTree = "<group>"; };
- 35475B220E7997680000BFE4 /* CGCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGCall.h; path = lib/CodeGen/CGCall.h; sourceTree = "<group>"; };
- 35475B230E7997680000BFE4 /* CGValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGValue.h; path = lib/CodeGen/CGValue.h; sourceTree = "<group>"; };
- 355106850E9A8507006A4E44 /* MemRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemRegion.cpp; path = lib/Analysis/MemRegion.cpp; sourceTree = "<group>"; };
- 355106880E9A851B006A4E44 /* MemRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemRegion.h; path = clang/Analysis/PathSensitive/MemRegion.h; sourceTree = "<group>"; };
- 3551068A0E9A8546006A4E44 /* ParsePragma.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParsePragma.cpp; path = lib/Parse/ParsePragma.cpp; sourceTree = "<group>"; };
- 3551068B0E9A8546006A4E44 /* ParseTentative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTentative.cpp; path = lib/Parse/ParseTentative.cpp; sourceTree = "<group>"; };
- 3551068E0E9A855F006A4E44 /* AccessSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AccessSpecifier.h; path = clang/Parse/AccessSpecifier.h; sourceTree = "<group>"; };
- 3551068F0E9A857C006A4E44 /* ParsePragma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParsePragma.h; path = lib/Parse/ParsePragma.h; sourceTree = "<group>"; };
- 3552E7540E520D80003A8CA5 /* PPCaching.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCaching.cpp; sourceTree = "<group>"; };
- 3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCMac.cpp; path = lib/CodeGen/CGObjCMac.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 3553EB9A0E5F7089007D7359 /* GRStateTrait.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRStateTrait.h; path = clang/Analysis/PathSensitive/GRStateTrait.h; sourceTree = "<group>"; };
- 3558F76C0E267C8300A5B0DF /* BasicStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicStore.cpp; path = lib/Analysis/BasicStore.cpp; sourceTree = "<group>"; };
- 3558F76F0E267C9A00A5B0DF /* Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Store.h; path = clang/Analysis/PathSensitive/Store.h; sourceTree = "<group>"; };
- 355CF6820C90A8B600A08AA3 /* LocalCheckers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LocalCheckers.h; path = clang/Analysis/LocalCheckers.h; sourceTree = "<group>"; };
- 356B89760D9BFDC100CBEBE9 /* BasicObjCFoundationChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BasicObjCFoundationChecks.h; path = lib/Analysis/BasicObjCFoundationChecks.h; sourceTree = "<group>"; };
- 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LiveVariables.cpp; path = lib/Analysis/LiveVariables.cpp; sourceTree = "<group>"; };
- 35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceLocation.cpp; sourceTree = "<group>"; };
- 3580CC0B0D072E5C00C5E4F4 /* LangOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LangOptions.cpp; sourceTree = "<group>"; };
- 35839B090CDF845F006ED061 /* StmtSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtSerialization.cpp; path = lib/AST/StmtSerialization.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35839B0A0CDF845F006ED061 /* TypeSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSerialization.cpp; path = lib/AST/TypeSerialization.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35847BE30CC7DB9000C40FFF /* StmtIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtIterator.h; path = clang/AST/StmtIterator.h; sourceTree = "<group>"; };
- 35847BE40CC7DBAF00C40FFF /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtIterator.cpp; path = lib/AST/StmtIterator.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35862B0C0E3628CB0009F542 /* CheckDeadStores.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckDeadStores.cpp; path = lib/Analysis/CheckDeadStores.cpp; sourceTree = "<group>"; };
- 35862B110E3629850009F542 /* GRExprEngineInternalChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRExprEngineInternalChecks.cpp; path = lib/Analysis/GRExprEngineInternalChecks.cpp; sourceTree = "<group>"; };
- 358CFBB70E65AB04002A8E19 /* BasicConstraintManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicConstraintManager.cpp; path = lib/Analysis/BasicConstraintManager.cpp; sourceTree = "<group>"; };
- 358D23090E8BEB850003DDCC /* DeclGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclGroup.h; path = clang/AST/DeclGroup.h; sourceTree = "<group>"; };
- 358D230A0E8BEB9D0003DDCC /* DeclGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DeclGroup.cpp; path = lib/AST/DeclGroup.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 358F514F0E529A87007F2102 /* GRState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRState.h; path = clang/Analysis/PathSensitive/GRState.h; sourceTree = "<group>"; };
- 358F51510E529AA4007F2102 /* GRState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRState.cpp; path = lib/Analysis/GRState.cpp; sourceTree = "<group>"; };
- 359378FF0DA486490043B19C /* BugReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugReporter.h; path = clang/Analysis/PathSensitive/BugReporter.h; sourceTree = "<group>"; };
- 359379090DA48ABA0043B19C /* BugReporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BugReporter.cpp; path = lib/Analysis/BugReporter.cpp; sourceTree = "<group>"; };
- 3595AFB70E1C8D62004CDF09 /* CheckObjCDealloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCDealloc.cpp; path = lib/Analysis/CheckObjCDealloc.cpp; sourceTree = "<group>"; };
- 3596033F0E49494D00C6282B /* TextDiagnosticBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextDiagnosticBuffer.h; path = clang/Driver/TextDiagnosticBuffer.h; sourceTree = "<group>"; };
- 359603400E49494D00C6282B /* TextDiagnosticPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextDiagnosticPrinter.h; path = clang/Driver/TextDiagnosticPrinter.h; sourceTree = "<group>"; };
- 359603430E49496E00C6282B /* TextDiagnosticBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnosticBuffer.cpp; path = lib/Driver/TextDiagnosticBuffer.cpp; sourceTree = "<group>"; };
- 359603440E49496E00C6282B /* TextDiagnosticPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnosticPrinter.cpp; path = lib/Driver/TextDiagnosticPrinter.cpp; sourceTree = "<group>"; };
- 359763240E633C6500B68AB7 /* HTMLDiagnostics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLDiagnostics.h; path = clang/Driver/HTMLDiagnostics.h; sourceTree = "<group>"; };
- 359763250E633C7500B68AB7 /* HTMLDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLDiagnostics.cpp; path = lib/Driver/HTMLDiagnostics.cpp; sourceTree = "<group>"; };
- 3599299A0DE2425300A8A33E /* SemaInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaInit.cpp; path = lib/Sema/SemaInit.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 359DBBD30E1AC9CC00F43FA0 /* AnalysisConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalysisConsumer.cpp; path = Driver/AnalysisConsumer.cpp; sourceTree = "<group>"; };
- 359DBBE20E1ACD4700F43FA0 /* AnalysisConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnalysisConsumer.h; path = Driver/AnalysisConsumer.h; sourceTree = "<group>"; };
- 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = SemaUtil.h; path = lib/Sema/SemaUtil.h; sourceTree = "<group>"; tabWidth = 2; };
- 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDebugInfo.cpp; path = lib/CodeGen/CGDebugInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35A3E7010DD3874400757F74 /* CGDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGDebugInfo.h; path = lib/CodeGen/CGDebugInfo.h; sourceTree = "<group>"; tabWidth = 2; };
- 35A8FCF60D9B4ADD001C2F97 /* ProgramPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgramPoint.h; path = clang/Analysis/ProgramPoint.h; sourceTree = "<group>"; };
- 35A8FCF70D9B4ADD001C2F97 /* PathDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PathDiagnostic.h; path = clang/Analysis/PathDiagnostic.h; sourceTree = "<group>"; };
- 35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathDiagnostic.cpp; path = lib/Analysis/PathDiagnostic.cpp; sourceTree = "<group>"; };
- 35BAC1E70E82C5B7003FB76F /* CheckNSError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckNSError.cpp; path = lib/Analysis/CheckNSError.cpp; sourceTree = "<group>"; };
- 35BB2D7A0D1994FA00944DB5 /* TranslationUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TranslationUnit.h; path = clang/AST/TranslationUnit.h; sourceTree = "<group>"; };
- 35BB2D7C0D19951A00944DB5 /* TranslationUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TranslationUnit.cpp; path = lib/AST/TranslationUnit.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35BB2D7E0D19954000944DB5 /* ASTConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumer.cpp; path = lib/AST/ASTConsumer.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumer.h; path = clang/AST/ASTConsumer.h; sourceTree = "<group>"; };
- 35CEA05A0DF9E82700A41296 /* ExprObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExprObjC.h; path = clang/AST/ExprObjC.h; sourceTree = "<group>"; };
- 35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtViz.cpp; path = lib/AST/StmtViz.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtGraphTraits.h; path = clang/AST/StmtGraphTraits.h; sourceTree = "<group>"; };
- 35D1DDD10CA9C6D50096E967 /* DataflowSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataflowSolver.h; path = clang/Analysis/FlowSensitive/DataflowSolver.h; sourceTree = "<group>"; };
- 35D1DDD20CA9C6D50096E967 /* DataflowValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataflowValues.h; path = clang/Analysis/FlowSensitive/DataflowValues.h; sourceTree = "<group>"; };
- 35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicValueFactory.cpp; path = lib/Analysis/BasicValueFactory.cpp; sourceTree = "<group>"; };
- 35D55B250D81D8C60092E734 /* CFRefCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CFRefCount.cpp; path = lib/Analysis/CFRefCount.cpp; sourceTree = "<group>"; };
- 35D55B290D81D8E50092E734 /* BasicValueFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BasicValueFactory.h; path = clang/Analysis/PathSensitive/BasicValueFactory.h; sourceTree = "<group>"; };
- 35EE48AD0E0C4CB200715C54 /* DeclCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeclCXX.h; path = clang/AST/DeclCXX.h; sourceTree = "<group>"; };
- 35EE48AE0E0C4CB200715C54 /* ParentMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParentMap.h; path = clang/AST/ParentMap.h; sourceTree = "<group>"; };
- 35EE48AF0E0C4CCA00715C54 /* DeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DeclCXX.cpp; path = lib/AST/DeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35EE48B00E0C4CCA00715C54 /* ParentMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParentMap.cpp; path = lib/AST/ParentMap.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclCXX.cpp; path = lib/Sema/SemaDeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRTransferFuncs.cpp; path = lib/Analysis/GRTransferFuncs.cpp; sourceTree = "<group>"; };
- 35F1ACE60E66166C001F4532 /* ConstraintManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstraintManager.h; path = clang/Analysis/PathSensitive/ConstraintManager.h; sourceTree = "<group>"; };
- 35F2A01D0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckObjCUnusedIVars.cpp; path = lib/Analysis/CheckObjCUnusedIVars.cpp; sourceTree = "<group>"; };
- 35F2BE7B0DAC2963006E7668 /* HTMLRewrite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLRewrite.h; path = clang/Rewrite/HTMLRewrite.h; sourceTree = "<group>"; };
- 35F8D0CA0D9B7E8200D91C5E /* GRSimpleAPICheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRSimpleAPICheck.h; path = clang/Analysis/PathSensitive/GRSimpleAPICheck.h; sourceTree = "<group>"; };
- 35F8D0CB0D9B7E8200D91C5E /* GRAuditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRAuditor.h; path = clang/Analysis/PathSensitive/GRAuditor.h; sourceTree = "<group>"; };
- 35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BasicObjCFoundationChecks.cpp; path = lib/Analysis/BasicObjCFoundationChecks.cpp; sourceTree = "<group>"; };
- 35F9B1530D1C6ADF00DDFDAE /* ExprDeclBitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExprDeclBitVector.h; path = clang/Analysis/Support/ExprDeclBitVector.h; sourceTree = "<group>"; };
- 35F9B1550D1C6B2E00DDFDAE /* LiveVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LiveVariables.h; path = clang/Analysis/Analyses/LiveVariables.h; sourceTree = "<group>"; };
- 35F9B1560D1C6B2E00DDFDAE /* UninitializedValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UninitializedValues.h; path = clang/Analysis/Analyses/UninitializedValues.h; sourceTree = "<group>"; };
- 35FE6BCE0DF6EE1F00739712 /* DeclBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DeclBase.cpp; path = lib/AST/DeclBase.cpp; sourceTree = "<group>"; tabWidth = 2; };
- 72D16C1E0D9975C400E6DA4A /* HTMLRewrite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLRewrite.cpp; path = lib/Rewrite/HTMLRewrite.cpp; sourceTree = "<group>"; };
- 72D16C210D9975EA00E6DA4A /* HTMLPrint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLPrint.cpp; path = Driver/HTMLPrint.cpp; sourceTree = "<group>"; };
- 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeclObjC.h; path = clang/AST/DeclObjC.h; sourceTree = "<group>"; };
- 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = lib/Parse/AttributeList.cpp; sourceTree = "<group>"; };
- 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
- 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
- 9030C1090E807A9300941490 /* RewriteBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteBlocks.cpp; path = Driver/RewriteBlocks.cpp; sourceTree = "<group>"; };
- DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
- DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = lib/Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
- DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; tabWidth = 2; };
- DE06BECA0A854E4B0050E87E /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Parse/Scope.h; sourceTree = "<group>"; };
- DE06D42F0A8BB52D0050E87E /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = lib/Parse/Parser.cpp; sourceTree = "<group>"; };
- DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- DE0FCA620A95859D00248FD5 /* Expr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Expr.h; path = clang/AST/Expr.h; sourceTree = "<group>"; };
- DE0FCB330A9C21F100248FD5 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Expr.cpp; path = lib/AST/Expr.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE1732FF0B068B700080B521 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ASTContext.cpp; path = lib/AST/ASTContext.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE17336D0B068DC20080B521 /* DeclSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DeclSpec.cpp; path = lib/Parse/DeclSpec.cpp; sourceTree = "<group>"; };
- DE17336F0B068DC60080B521 /* DeclSpec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeclSpec.h; path = clang/Parse/DeclSpec.h; sourceTree = "<group>"; };
- DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; };
- DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = lib/CodeGen/CGExprComplex.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = lib/CodeGen/CGExprScalar.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDeclCXX.cpp; path = lib/Parse/ParseDeclCXX.cpp; sourceTree = "<group>"; };
- DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclAttr.cpp; path = lib/Sema/SemaDeclAttr.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HeaderSearch.h; sourceTree = "<group>"; };
- DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderSearch.cpp; sourceTree = "<group>"; };
- DE3450D60AEB543100DBC861 /* DirectoryLookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DirectoryLookup.h; sourceTree = "<group>"; };
- DE3452400AEF1A2D00DBC861 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Stmt.cpp; path = lib/AST/Stmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE3452800AEF1B1800DBC861 /* Stmt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Stmt.h; path = clang/AST/Stmt.h; sourceTree = "<group>"; };
- DE345C190AFC658B00DBC861 /* StmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = StmtVisitor.h; path = clang/AST/StmtVisitor.h; sourceTree = "<group>"; };
- DE345F210AFD347900DBC861 /* StmtNodes.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = StmtNodes.def; path = clang/AST/StmtNodes.def; sourceTree = "<group>"; };
- DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseObjc.cpp; path = lib/Parse/ParseObjc.cpp; sourceTree = "<group>"; };
- DE3460040AFDCC6500DBC861 /* ParseInit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseInit.cpp; path = lib/Parse/ParseInit.cpp; sourceTree = "<group>"; };
- DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseStmt.cpp; path = lib/Parse/ParseStmt.cpp; sourceTree = "<group>"; };
- DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDecl.cpp; path = lib/Parse/ParseDecl.cpp; sourceTree = "<group>"; };
- DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExpr.cpp; path = lib/Parse/ParseExpr.cpp; sourceTree = "<group>"; };
- DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MinimalAction.cpp; path = lib/Parse/MinimalAction.cpp; sourceTree = "<group>"; };
- DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtPrinter.cpp; path = lib/AST/StmtPrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE3464210B03040900DBC861 /* Type.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Type.h; path = clang/AST/Type.h; sourceTree = "<group>"; };
- DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGObjCRuntime.h; path = lib/CodeGen/CGObjCRuntime.h; sourceTree = "<group>"; tabWidth = 2; };
- DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCGNU.cpp; path = lib/CodeGen/CGObjCGNU.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE38CF150D8C9DE000A273B6 /* DiagChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DiagChecker.cpp; path = Driver/DiagChecker.cpp; sourceTree = "<group>"; };
- DE38CF260D8C9E6C00A273B6 /* DeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DeclObjC.cpp; path = lib/AST/DeclObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE3985780CB8ADC800223765 /* ASTConsumers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTConsumers.h; path = Driver/ASTConsumers.h; sourceTree = "<group>"; };
- DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = Driver/ASTConsumers.cpp; sourceTree = "<group>"; };
- DE3986EF0CB8D4B300223765 /* IdentifierTable.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = IdentifierTable.h; sourceTree = "<group>"; tabWidth = 2; };
- DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IdentifierTable.cpp; sourceTree = "<group>"; };
- DE41211B0D7F1BBE0080F80A /* RValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RValues.h; path = clang/Analysis/PathSensitive/RValues.h; sourceTree = "<group>"; };
- DE41211D0D7F1BBE0080F80A /* GRWorkList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRWorkList.h; path = clang/Analysis/PathSensitive/GRWorkList.h; sourceTree = "<group>"; };
- DE41211E0D7F1BBE0080F80A /* SymbolManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SymbolManager.h; path = clang/Analysis/PathSensitive/SymbolManager.h; sourceTree = "<group>"; };
- DE41211F0D7F1BBE0080F80A /* GRBlockCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRBlockCounter.h; path = clang/Analysis/PathSensitive/GRBlockCounter.h; sourceTree = "<group>"; };
- DE4121200D7F1BBE0080F80A /* ExplodedGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExplodedGraph.h; path = clang/Analysis/PathSensitive/ExplodedGraph.h; sourceTree = "<group>"; };
- DE4121210D7F1BBE0080F80A /* GRExprEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRExprEngine.h; path = clang/Analysis/PathSensitive/GRExprEngine.h; sourceTree = "<group>"; };
- DE4121220D7F1BBE0080F80A /* GRTransferFuncs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRTransferFuncs.h; path = clang/Analysis/PathSensitive/GRTransferFuncs.h; sourceTree = "<group>"; };
- DE4121230D7F1BBE0080F80A /* GRCoreEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRCoreEngine.h; path = clang/Analysis/PathSensitive/GRCoreEngine.h; sourceTree = "<group>"; };
- DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolManager.cpp; path = lib/Analysis/SymbolManager.cpp; sourceTree = "<group>"; };
- DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExplodedGraph.cpp; path = lib/Analysis/ExplodedGraph.cpp; sourceTree = "<group>"; };
- DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UninitializedValues.cpp; path = lib/Analysis/UninitializedValues.cpp; sourceTree = "<group>"; };
- DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRCoreEngine.cpp; path = lib/Analysis/GRCoreEngine.cpp; sourceTree = "<group>"; };
- DE41212C0D7F1C1C0080F80A /* GRSimpleVals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GRSimpleVals.h; path = lib/Analysis/GRSimpleVals.h; sourceTree = "<group>"; };
- DE41212E0D7F1C1C0080F80A /* RValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RValues.cpp; path = lib/Analysis/RValues.cpp; sourceTree = "<group>"; };
- DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRSimpleVals.cpp; path = lib/Analysis/GRSimpleVals.cpp; sourceTree = "<group>"; };
- DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRBlockCounter.cpp; path = lib/Analysis/GRBlockCounter.cpp; sourceTree = "<group>"; };
- DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRExprEngine.cpp; path = lib/Analysis/GRExprEngine.cpp; sourceTree = "<group>"; };
- DE4264FB0C113592005A861D /* CGDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDecl.cpp; path = lib/CodeGen/CGDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE46BF270AE0A82D00CC047C /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = TargetInfo.h; sourceTree = "<group>"; tabWidth = 2; };
- DE4772F90C10EAE5002239E8 /* CGStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGStmt.cpp; path = lib/CodeGen/CGStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExpr.cpp; path = lib/CodeGen/CGExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprObjC.cpp; path = lib/Sema/SemaExprObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE53370B0CE2D96F00D9A028 /* RewriteRope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RewriteRope.h; path = clang/Rewrite/RewriteRope.h; sourceTree = "<group>"; };
- DE5932CD0AD60FF400BC794C /* clang.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = clang.cpp; path = Driver/clang.cpp; sourceTree = "<group>"; };
- DE5932CE0AD60FF400BC794C /* clang.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = clang.h; path = Driver/clang.h; sourceTree = "<group>"; };
- DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintParserCallbacks.cpp; path = Driver/PrintParserCallbacks.cpp; sourceTree = "<group>"; };
- DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintPreprocessedOutput.cpp; path = Driver/PrintPreprocessedOutput.cpp; sourceTree = "<group>"; };
- DE613EF30E0E148D00B05B79 /* APValue.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = APValue.h; path = clang/AST/APValue.h; sourceTree = "<group>"; tabWidth = 2; };
- DE67E70A0C020EC500F66BC5 /* SemaType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaType.cpp; path = lib/Sema/SemaType.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaStmt.cpp; path = lib/Sema/SemaStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprCXX.cpp; path = lib/Sema/SemaExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExpr.cpp; path = lib/Sema/SemaExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDecl.cpp; path = lib/Sema/SemaDecl.cpp; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
- DE67E7140C020EDF00F66BC5 /* Sema.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Sema.h; path = lib/Sema/Sema.h; sourceTree = "<group>"; tabWidth = 2; };
- DE67E7160C020EE400F66BC5 /* Sema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Sema.cpp; path = lib/Sema/Sema.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ParseAST.cpp; path = lib/Sema/ParseAST.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE67E7270C02109800F66BC5 /* ParseAST.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ParseAST.h; path = clang/Sema/ParseAST.h; sourceTree = "<group>"; };
- DE6951C60C4D1F5D00A5826B /* RecordLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = RecordLayout.h; path = clang/AST/RecordLayout.h; sourceTree = "<group>"; };
- DE6954630C5121BD00A5826B /* Token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; };
- DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclObjC.cpp; path = lib/Sema/SemaDeclObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE704BD10D1647E7009C7762 /* HeaderMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeaderMap.h; sourceTree = "<group>"; };
- DE704DD10D1668A4009C7762 /* HeaderMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderMap.cpp; sourceTree = "<group>"; };
- DE75ED280B044DC90020CF81 /* ASTContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTContext.h; path = clang/AST/ASTContext.h; sourceTree = "<group>"; };
- DE75EDF00B06880E0020CF81 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Type.cpp; path = lib/AST/Type.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE85CD800D8380B10070E26E /* TokenLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenLexer.cpp; sourceTree = "<group>"; };
- DE85CD840D8380F20070E26E /* TokenLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TokenLexer.h; sourceTree = "<group>"; };
- DE85CD9E0D8382DD0070E26E /* MacroArgs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroArgs.h; sourceTree = "<group>"; };
- DE85CDA20D8383B20070E26E /* MacroArgs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroArgs.cpp; sourceTree = "<group>"; };
- DE85CDAB0D838C120070E26E /* PPMacroExpansion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPMacroExpansion.cpp; sourceTree = "<group>"; };
- DE85CDAF0D838C390070E26E /* PPDirectives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPDirectives.cpp; sourceTree = "<group>"; };
- DE85CDB50D839BAE0070E26E /* PPLexerChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPLexerChange.cpp; sourceTree = "<group>"; };
- DE928B120C05659200231DA4 /* ModuleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleBuilder.cpp; path = lib/CodeGen/ModuleBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ModuleBuilder.h; path = clang/CodeGen/ModuleBuilder.h; sourceTree = "<group>"; };
- DE928B7C0C0A615100231DA4 /* CodeGenModule.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenModule.h; path = lib/CodeGen/CodeGenModule.h; sourceTree = "<group>"; tabWidth = 2; };
- DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenModule.cpp; path = lib/CodeGen/CodeGenModule.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DE928B800C0A615B00231DA4 /* CodeGenFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenFunction.h; path = lib/CodeGen/CodeGenFunction.h; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
- DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenFunction.cpp; path = lib/CodeGen/CodeGenFunction.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DEA0EBD90DD2D3C8007A02A9 /* RewriteMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteMacros.cpp; path = Driver/RewriteMacros.cpp; sourceTree = "<group>"; };
- DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = "<group>"; };
- DEAEED4A0A5AF89A0045101B /* NOTES.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = NOTES.txt; sourceTree = "<group>"; };
- DEC63B190C7B940200DBF169 /* CFG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CFG.cpp; path = lib/AST/CFG.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DEC63B1B0C7B940600DBF169 /* CFG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFG.h; path = clang/AST/CFG.h; sourceTree = "<group>"; };
- DEC8D9900A9433CD00353FCA /* Decl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Decl.h; path = clang/AST/Decl.h; sourceTree = "<group>"; };
- DEC8D9A30A94346E00353FCA /* AST.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AST.h; path = clang/AST/AST.h; sourceTree = "<group>"; };
- DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteRope.cpp; path = lib/Rewrite/RewriteRope.cpp; sourceTree = "<group>"; };
- DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = "<group>"; };
- DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Decl.cpp; path = lib/AST/Decl.cpp; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
- DED676D00B6C786700AAD4A3 /* Builtins.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = Builtins.def; path = clang/AST/Builtins.def; sourceTree = "<group>"; };
- DED676F90B6C797B00AAD4A3 /* Builtins.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Builtins.h; path = clang/AST/Builtins.h; sourceTree = "<group>"; };
- DED677C80B6C854100AAD4A3 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Builtins.cpp; path = lib/AST/Builtins.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7320A524295003AD0FB /* DiagnosticKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; path = DiagnosticKinds.def; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7350A524295003AD0FB /* SourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SourceLocation.h; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7360A524295003AD0FB /* SourceManager.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SourceManager.h; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7370A524295003AD0FB /* TokenKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; path = TokenKinds.def; sourceTree = "<group>"; tabWidth = 2; };
- DED7D7380A524295003AD0FB /* TokenKinds.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = TokenKinds.h; sourceTree = "<group>"; tabWidth = 2; };
- DED7D73B0A524295003AD0FB /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = "<group>"; };
- DED7D73E0A524295003AD0FB /* MacroInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MacroInfo.h; sourceTree = "<group>"; };
- DED7D73F0A524295003AD0FB /* Pragma.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Pragma.h; sourceTree = "<group>"; };
- DED7D7400A524295003AD0FB /* Preprocessor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Preprocessor.h; sourceTree = "<group>"; };
- DED7D75D0A5242C7003AD0FB /* Diagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Diagnostic.cpp; sourceTree = "<group>"; };
- DED7D75E0A5242C7003AD0FB /* FileManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FileManager.cpp; sourceTree = "<group>"; };
- DED7D76D0A5242C7003AD0FB /* SourceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SourceManager.cpp; sourceTree = "<group>"; };
- DED7D76E0A5242C7003AD0FB /* TokenKinds.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TokenKinds.cpp; sourceTree = "<group>"; };
- DED7D79E0A5242E6003AD0FB /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = "<group>"; };
- DED7D7A00A5242E6003AD0FB /* MacroInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MacroInfo.cpp; sourceTree = "<group>"; };
- DED7D7A20A5242E6003AD0FB /* PPExpressions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPExpressions.cpp; sourceTree = "<group>"; };
- DED7D7A30A5242E6003AD0FB /* Pragma.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Pragma.cpp; sourceTree = "<group>"; };
- DED7D7A40A5242E6003AD0FB /* Preprocessor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Preprocessor.cpp; sourceTree = "<group>"; };
- DED7D7D70A524302003AD0FB /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
- DED7D9170A52518C003AD0FB /* ScratchBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScratchBuffer.h; sourceTree = "<group>"; };
- DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchBuffer.cpp; sourceTree = "<group>"; };
- DEEBBD430C19C5D200A9FE82 /* TODO.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TODO.txt; sourceTree = "<group>"; };
- DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenTypes.h; path = lib/CodeGen/CodeGenTypes.h; sourceTree = "<group>"; tabWidth = 2; };
- DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenTypes.cpp; path = lib/CodeGen/CodeGenTypes.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; name = InternalsManual.html; path = docs/InternalsManual.html; sourceTree = "<group>"; };
- DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtDumper.cpp; path = lib/AST/StmtDumper.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprAgg.cpp; path = lib/CodeGen/CGExprAgg.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaChecking.cpp; path = lib/Sema/SemaChecking.cpp; sourceTree = "<group>"; tabWidth = 2; };
- DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Rewriter.h; path = clang/Rewrite/Rewriter.h; sourceTree = "<group>"; };
- DEF7D9F80C9C8B1D0001F598 /* Rewriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Rewriter.cpp; path = lib/Rewrite/Rewriter.cpp; sourceTree = "<group>"; };
- DEFFECA30DB093D100B4E7C3 /* DeltaTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeltaTree.h; path = clang/Rewrite/DeltaTree.h; sourceTree = "<group>"; };
- DEFFECA60DB1546600B4E7C3 /* DeltaTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeltaTree.cpp; path = lib/Rewrite/DeltaTree.cpp; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 8DD76F660486A84900D96B5E /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 08FB7794FE84155DC02AAC07 /* clang */ = {
- isa = PBXGroup;
- children = (
- DED7D72E0A524295003AD0FB /* include */,
- 08FB7795FE84155DC02AAC07 /* Source */,
- DEAEECAE0A5AF0FA0045101B /* Driver */,
- C6859E8C029090F304C91782 /* Documentation */,
- 1AB674ADFE9D54B511CA2CBB /* Products */,
- );
- name = clang;
- sourceTree = "<group>";
- };
- 08FB7795FE84155DC02AAC07 /* Source */ = {
- isa = PBXGroup;
- children = (
- DED7D7500A5242C7003AD0FB /* Basic */,
- DED7D78C0A5242E6003AD0FB /* Lex */,
- DE1F22600A7D8C9B00FBF588 /* Parse */,
- DEC8D9920A9433F400353FCA /* AST */,
- DE67E7070C020EAB00F66BC5 /* Sema */,
- DE927FCC0C0557CD00231DA4 /* CodeGen */,
- 356EF9B30C8F7DCA006650F5 /* Analysis */,
- DEF7D9F50C9C8B0C0001F598 /* Rewrite */,
- 359603420E49495900C6282B /* Driver */,
- );
- name = Source;
- sourceTree = "<group>";
- };
- 1AB674ADFE9D54B511CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 8DD76F6C0486A84900D96B5E /* clang */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 3507E4C30E27FE3800FB7B57 /* Checks */ = {
- isa = PBXGroup;
- children = (
- 35BAC1E70E82C5B7003FB76F /* CheckNSError.cpp */,
- 356B89760D9BFDC100CBEBE9 /* BasicObjCFoundationChecks.h */,
- 35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */,
- 35862B0C0E3628CB0009F542 /* CheckDeadStores.cpp */,
- 3595AFB70E1C8D62004CDF09 /* CheckObjCDealloc.cpp */,
- 3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */,
- 35F2A01D0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp */,
- DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */,
- );
- name = Checks;
- sourceTree = "<group>";
- };
- 3507E4C60E27FE5500FB7B57 /* Path-Sensitive Core */ = {
- isa = PBXGroup;
- children = (
- 355106850E9A8507006A4E44 /* MemRegion.cpp */,
- 358CFBB70E65AB04002A8E19 /* BasicConstraintManager.cpp */,
- 3558F76C0E267C8300A5B0DF /* BasicStore.cpp */,
- 35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */,
- 3536456A0E23EBF7009C6509 /* Environment.cpp */,
- DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */,
- DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */,
- DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */,
- DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */,
- 35862B110E3629850009F542 /* GRExprEngineInternalChecks.cpp */,
- 358F51510E529AA4007F2102 /* GRState.cpp */,
- 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */,
- DE41212E0D7F1C1C0080F80A /* RValues.cpp */,
- DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */,
- );
- name = "Path-Sensitive Core";
- sourceTree = "<group>";
- };
- 3507E4C90E27FE9000FB7B57 /* Bug Reporting */ = {
- isa = PBXGroup;
- children = (
- 35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */,
- 359379090DA48ABA0043B19C /* BugReporter.cpp */,
- );
- name = "Bug Reporting";
- sourceTree = "<group>";
- };
- 3507E4CC0E27FEB900FB7B57 /* Flow-Sensitive Analyses */ = {
- isa = PBXGroup;
- children = (
- 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */,
- );
- name = "Flow-Sensitive Analyses";
- sourceTree = "<group>";
- };
- 352C19DB0CA321AC0045DB98 /* Visitors */ = {
- isa = PBXGroup;
- children = (
- 352C19DC0CA321C80045DB98 /* CFGRecStmtDeclVisitor.h */,
- 352C19DD0CA321C80045DB98 /* CFGRecStmtVisitor.h */,
- 352C19DE0CA321C80045DB98 /* CFGStmtVisitor.h */,
- 352C19DF0CA321C80045DB98 /* CFGVarDeclVisitor.h */,
- );
- name = Visitors;
- sourceTree = "<group>";
- };
- 356EF9AF0C8F7DA4006650F5 /* Analysis */ = {
- isa = PBXGroup;
- children = (
- 35A8FCF60D9B4ADD001C2F97 /* ProgramPoint.h */,
- 35A8FCF70D9B4ADD001C2F97 /* PathDiagnostic.h */,
- 355CF6820C90A8B600A08AA3 /* LocalCheckers.h */,
- 35F9B1540D1C6AFC00DDFDAE /* Analyses */,
- 35D1DDCF0CA9C6BE0096E967 /* FlowSensitive */,
- DE4121130D7F1B980080F80A /* PathSensitive */,
- 35F9B1520D1C6ACB00DDFDAE /* Support */,
- 352C19DB0CA321AC0045DB98 /* Visitors */,
- );
- name = Analysis;
- sourceTree = "<group>";
- };
- 356EF9B30C8F7DCA006650F5 /* Analysis */ = {
- isa = PBXGroup;
- children = (
- 3507E4CC0E27FEB900FB7B57 /* Flow-Sensitive Analyses */,
- 3507E4C30E27FE3800FB7B57 /* Checks */,
- 35862B130E3629BC0009F542 /* Transfer Function Analyses */,
- 3507E4C60E27FE5500FB7B57 /* Path-Sensitive Core */,
- 3507E4C90E27FE9000FB7B57 /* Bug Reporting */,
- );
- name = Analysis;
- sourceTree = "<group>";
- };
- 35862B130E3629BC0009F542 /* Transfer Function Analyses */ = {
- isa = PBXGroup;
- children = (
- 35D55B250D81D8C60092E734 /* CFRefCount.cpp */,
- DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */,
- DE41212C0D7F1C1C0080F80A /* GRSimpleVals.h */,
- );
- name = "Transfer Function Analyses";
- sourceTree = "<group>";
- };
- 3596033E0E49493700C6282B /* Driver */ = {
- isa = PBXGroup;
- children = (
- 359763240E633C6500B68AB7 /* HTMLDiagnostics.h */,
- 350F4B490E5F36EE00A21EA9 /* InitHeaderSearch.h */,
- 3596033F0E49494D00C6282B /* TextDiagnosticBuffer.h */,
- 359603400E49494D00C6282B /* TextDiagnosticPrinter.h */,
- );
- name = Driver;
- sourceTree = "<group>";
- };
- 359603420E49495900C6282B /* Driver */ = {
- isa = PBXGroup;
- children = (
- 359763250E633C7500B68AB7 /* HTMLDiagnostics.cpp */,
- 350F4B460E5F32E100A21EA9 /* InitHeaderSearch.cpp */,
- 359603430E49496E00C6282B /* TextDiagnosticBuffer.cpp */,
- 359603440E49496E00C6282B /* TextDiagnosticPrinter.cpp */,
- );
- name = Driver;
- sourceTree = "<group>";
- };
- 35D1DDCF0CA9C6BE0096E967 /* FlowSensitive */ = {
- isa = PBXGroup;
- children = (
- 35D1DDD10CA9C6D50096E967 /* DataflowSolver.h */,
- 35D1DDD20CA9C6D50096E967 /* DataflowValues.h */,
- );
- name = FlowSensitive;
- sourceTree = "<group>";
- };
- 35F9B1520D1C6ACB00DDFDAE /* Support */ = {
- isa = PBXGroup;
- children = (
- 35F9B1530D1C6ADF00DDFDAE /* ExprDeclBitVector.h */,
- );
- name = Support;
- sourceTree = "<group>";
- };
- 35F9B1540D1C6AFC00DDFDAE /* Analyses */ = {
- isa = PBXGroup;
- children = (
- 35F9B1550D1C6B2E00DDFDAE /* LiveVariables.h */,
- 35F9B1560D1C6B2E00DDFDAE /* UninitializedValues.h */,
- );
- name = Analyses;
- sourceTree = "<group>";
- };
- C6859E8C029090F304C91782 /* Documentation */ = {
- isa = PBXGroup;
- children = (
- DEAEED4A0A5AF89A0045101B /* NOTES.txt */,
- DED7D7D70A524302003AD0FB /* README.txt */,
- DEEBBD430C19C5D200A9FE82 /* TODO.txt */,
- DEF2E95E0C5FBD74000C4259 /* InternalsManual.html */,
- );
- name = Documentation;
- sourceTree = "<group>";
- };
- DE1F21F20A7D84E800FBF588 /* Parse */ = {
- isa = PBXGroup;
- children = (
- 3551068E0E9A855F006A4E44 /* AccessSpecifier.h */,
- 84D9A88B0C1A581300AC7ABC /* AttributeList.h */,
- DE06E8130A8FF9330050E87E /* Action.h */,
- DE17336F0B068DC60080B521 /* DeclSpec.h */,
- DE1F22020A7D852A00FBF588 /* Parser.h */,
- DE06BECA0A854E4B0050E87E /* Scope.h */,
- );
- name = Parse;
- sourceTree = "<group>";
- };
- DE1F22600A7D8C9B00FBF588 /* Parse */ = {
- isa = PBXGroup;
- children = (
- 3551068F0E9A857C006A4E44 /* ParsePragma.h */,
- 3551068A0E9A8546006A4E44 /* ParsePragma.cpp */,
- 3551068B0E9A8546006A4E44 /* ParseTentative.cpp */,
- 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */,
- DE17336D0B068DC20080B521 /* DeclSpec.cpp */,
- DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */,
- DE06D42F0A8BB52D0050E87E /* Parser.cpp */,
- DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */,
- DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */,
- DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */,
- DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */,
- 3534A01C0E129849002709B2 /* ParseCXXInlineMethods.cpp */,
- DE3460040AFDCC6500DBC861 /* ParseInit.cpp */,
- DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */,
- DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */,
- );
- name = Parse;
- sourceTree = "<group>";
- };
- DE4121130D7F1B980080F80A /* PathSensitive */ = {
- isa = PBXGroup;
- children = (
- 355106880E9A851B006A4E44 /* MemRegion.h */,
- 35F1ACE60E66166C001F4532 /* ConstraintManager.h */,
- 3553EB9A0E5F7089007D7359 /* GRStateTrait.h */,
- 3558F76F0E267C9A00A5B0DF /* Store.h */,
- 3536457C0E2406B0009C6509 /* Environment.h */,
- DE4121230D7F1BBE0080F80A /* GRCoreEngine.h */,
- DE4121210D7F1BBE0080F80A /* GRExprEngine.h */,
- DE4121220D7F1BBE0080F80A /* GRTransferFuncs.h */,
- 358F514F0E529A87007F2102 /* GRState.h */,
- 359378FF0DA486490043B19C /* BugReporter.h */,
- 35F8D0CA0D9B7E8200D91C5E /* GRSimpleAPICheck.h */,
- 35F8D0CB0D9B7E8200D91C5E /* GRAuditor.h */,
- 35D55B290D81D8E50092E734 /* BasicValueFactory.h */,
- DE41211B0D7F1BBE0080F80A /* RValues.h */,
- DE41211D0D7F1BBE0080F80A /* GRWorkList.h */,
- DE41211E0D7F1BBE0080F80A /* SymbolManager.h */,
- DE41211F0D7F1BBE0080F80A /* GRBlockCounter.h */,
- DE4121200D7F1BBE0080F80A /* ExplodedGraph.h */,
- );
- name = PathSensitive;
- sourceTree = "<group>";
- };
- DE67E7070C020EAB00F66BC5 /* Sema */ = {
- isa = PBXGroup;
- children = (
- 3527124F0DAFE54700C76352 /* IdentifierResolver.h */,
- 352712500DAFE54700C76352 /* IdentifierResolver.cpp */,
- DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */,
- DE67E7140C020EDF00F66BC5 /* Sema.h */,
- 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */,
- DE67E7160C020EE400F66BC5 /* Sema.cpp */,
- DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */,
- DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,
- DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */,
- 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */,
- DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */,
- DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */,
- DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */,
- DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */,
- 3599299A0DE2425300A8A33E /* SemaInit.cpp */,
- DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */,
- DE67E70A0C020EC500F66BC5 /* SemaType.cpp */,
- );
- name = Sema;
- sourceTree = "<group>";
- };
- DE67E7260C02108300F66BC5 /* Sema */ = {
- isa = PBXGroup;
- children = (
- DE67E7270C02109800F66BC5 /* ParseAST.h */,
- );
- name = Sema;
- sourceTree = "<group>";
- };
- DE927FCC0C0557CD00231DA4 /* CodeGen */ = {
- isa = PBXGroup;
- children = (
- 35475B220E7997680000BFE4 /* CGCall.h */,
- 35475B230E7997680000BFE4 /* CGValue.h */,
- 35475B1F0E79973F0000BFE4 /* CGCall.cpp */,
- DE928B800C0A615B00231DA4 /* CodeGenFunction.h */,
- DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */,
- DE928B7C0C0A615100231DA4 /* CodeGenModule.h */,
- DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */,
- DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */,
- DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */,
- 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */,
- 1A5D5E570E5E81010023C059 /* CGCXX.cpp */,
- 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */,
- 35A3E7010DD3874400757F74 /* CGDebugInfo.h */,
- DE4264FB0C113592005A861D /* CGDecl.cpp */,
- DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
- DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */,
- DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */,
- 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */,
- DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */,
- 1A7342470C7B57D500122F56 /* CGObjC.cpp */,
- DE38CD4E0D794CF900A273B6 /* CGObjCRuntime.h */,
- DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */,
- 3552E7580E520DD7003A8CA5 /* CGObjCMac.cpp */,
- DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
- DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
- );
- name = CodeGen;
- sourceTree = "<group>";
- };
- DE928B140C05659A00231DA4 /* CodeGen */ = {
- isa = PBXGroup;
- children = (
- DE928B1F0C0565B000231DA4 /* ModuleBuilder.h */,
- );
- name = CodeGen;
- sourceTree = "<group>";
- };
- DEAEECAE0A5AF0FA0045101B /* Driver */ = {
- isa = PBXGroup;
- children = (
- DE5932CD0AD60FF400BC794C /* clang.cpp */,
- DE5932CE0AD60FF400BC794C /* clang.h */,
- 359DBBE20E1ACD4700F43FA0 /* AnalysisConsumer.h */,
- 359DBBD30E1AC9CC00F43FA0 /* AnalysisConsumer.cpp */,
- 352028460E2C16820096ADE0 /* Analyses.def */,
- DE3985780CB8ADC800223765 /* ASTConsumers.h */,
- DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */,
- DE38CF150D8C9DE000A273B6 /* DiagChecker.cpp */,
- 72D16C210D9975EA00E6DA4A /* HTMLPrint.cpp */,
- DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */,
- DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */,
- 9030C1090E807A9300941490 /* RewriteBlocks.cpp */,
- DEA0EBD90DD2D3C8007A02A9 /* RewriteMacros.cpp */,
- 035611E10DB40C8100D2EF2A /* RewriteObjC.cpp */,
- 352981080CC58344008B5E84 /* SerializationTest.cpp */,
- );
- name = Driver;
- sourceTree = "<group>";
- };
- DEC8D98B0A9433BC00353FCA /* AST */ = {
- isa = PBXGroup;
- children = (
- 358D23090E8BEB850003DDCC /* DeclGroup.h */,
- DE613EF30E0E148D00B05B79 /* APValue.h */,
- DEC8D9A30A94346E00353FCA /* AST.h */,
- 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */,
- DE75ED280B044DC90020CF81 /* ASTContext.h */,
- 1A72BEAC0D641E9400B085E9 /* Attr.h */,
- DED676D00B6C786700AAD4A3 /* Builtins.def */,
- DED676F90B6C797B00AAD4A3 /* Builtins.h */,
- 1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */,
- 1A68BC130D0CADDD001A28C8 /* X86Builtins.def */,
- DEC63B1B0C7B940600DBF169 /* CFG.h */,
- DEC8D9900A9433CD00353FCA /* Decl.h */,
- 035611470DA6A45C00D2EF2A /* DeclBase.h */,
- 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */,
- 35EE48AD0E0C4CB200715C54 /* DeclCXX.h */,
- DE0FCA620A95859D00248FD5 /* Expr.h */,
- 1A30A9E80B93A4C800201A91 /* ExprCXX.h */,
- 35CEA05A0DF9E82700A41296 /* ExprObjC.h */,
- 35EE48AE0E0C4CB200715C54 /* ParentMap.h */,
- 3547129D0C88881300B3E1D5 /* PrettyPrinter.h */,
- DE6951C60C4D1F5D00A5826B /* RecordLayout.h */,
- DE3452800AEF1B1800DBC861 /* Stmt.h */,
- DE345F210AFD347900DBC861 /* StmtNodes.def */,
- DE345C190AFC658B00DBC861 /* StmtVisitor.h */,
- 35847BE30CC7DB9000C40FFF /* StmtIterator.h */,
- 35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */,
- 1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */,
- 35BB2D7A0D1994FA00944DB5 /* TranslationUnit.h */,
- DE3464210B03040900DBC861 /* Type.h */,
- );
- name = AST;
- sourceTree = "<group>";
- };
- DEC8D9920A9433F400353FCA /* AST */ = {
- isa = PBXGroup;
- children = (
- 358D230A0E8BEB9D0003DDCC /* DeclGroup.cpp */,
- 35BB2D7E0D19954000944DB5 /* ASTConsumer.cpp */,
- DE1732FF0B068B700080B521 /* ASTContext.cpp */,
- DED677C80B6C854100AAD4A3 /* Builtins.cpp */,
- DEC63B190C7B940200DBF169 /* CFG.cpp */,
- 35FE6BCE0DF6EE1F00739712 /* DeclBase.cpp */,
- DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
- 35EE48AF0E0C4CCA00715C54 /* DeclCXX.cpp */,
- DE38CF260D8C9E6C00A273B6 /* DeclObjC.cpp */,
- 3513185F0CD14468006B66F7 /* DeclSerialization.cpp */,
- DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
- 1A32C17E0E1C87AD00A6B483 /* ExprConstant.cpp */,
- 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */,
- 35EE48B00E0C4CCA00715C54 /* ParentMap.cpp */,
- DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
- DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */,
- DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */,
- 35847BE40CC7DBAF00C40FFF /* StmtIterator.cpp */,
- 35839B090CDF845F006ED061 /* StmtSerialization.cpp */,
- 35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */,
- 35BB2D7C0D19951A00944DB5 /* TranslationUnit.cpp */,
- DE75EDF00B06880E0020CF81 /* Type.cpp */,
- 35839B0A0CDF845F006ED061 /* TypeSerialization.cpp */,
- );
- name = AST;
- sourceTree = "<group>";
- };
- DED7D72E0A524295003AD0FB /* include */ = {
- isa = PBXGroup;
- children = (
- DED7D7300A524295003AD0FB /* Basic */,
- DED7D7390A524295003AD0FB /* Lex */,
- DE1F21F20A7D84E800FBF588 /* Parse */,
- DEC8D98B0A9433BC00353FCA /* AST */,
- DE67E7260C02108300F66BC5 /* Sema */,
- DE928B140C05659A00231DA4 /* CodeGen */,
- 356EF9AF0C8F7DA4006650F5 /* Analysis */,
- DEF7D9F40C9C8B020001F598 /* Rewrite */,
- 3596033E0E49493700C6282B /* Driver */,
- );
- path = include;
- sourceTree = "<group>";
- };
- DED7D7300A524295003AD0FB /* Basic */ = {
- isa = PBXGroup;
- children = (
- DED7D7310A524295003AD0FB /* Diagnostic.h */,
- DED7D7320A524295003AD0FB /* DiagnosticKinds.def */,
- DED7D7330A524295003AD0FB /* FileManager.h */,
- DE3986EF0CB8D4B300223765 /* IdentifierTable.h */,
- DE06B73D0A8307640050E87E /* LangOptions.h */,
- DED7D7350A524295003AD0FB /* SourceLocation.h */,
- DED7D7360A524295003AD0FB /* SourceManager.h */,
- DE46BF270AE0A82D00CC047C /* TargetInfo.h */,
- DED7D7370A524295003AD0FB /* TokenKinds.def */,
- DED7D7380A524295003AD0FB /* TokenKinds.h */,
- );
- name = Basic;
- path = clang/Basic;
- sourceTree = "<group>";
- };
- DED7D7390A524295003AD0FB /* Lex */ = {
- isa = PBXGroup;
- children = (
- DE3450D60AEB543100DBC861 /* DirectoryLookup.h */,
- DE704BD10D1647E7009C7762 /* HeaderMap.h */,
- DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */,
- DED7D73B0A524295003AD0FB /* Lexer.h */,
- 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */,
- DED7D73E0A524295003AD0FB /* MacroInfo.h */,
- DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */,
- DE01DA480B12ADA300AC22CE /* PPCallbacks.h */,
- DED7D73F0A524295003AD0FB /* Pragma.h */,
- DED7D7400A524295003AD0FB /* Preprocessor.h */,
- DED7D9170A52518C003AD0FB /* ScratchBuffer.h */,
- DE6954630C5121BD00A5826B /* Token.h */,
- DE85CD840D8380F20070E26E /* TokenLexer.h */,
- );
- name = Lex;
- path = clang/Lex;
- sourceTree = "<group>";
- };
- DED7D7500A5242C7003AD0FB /* Basic */ = {
- isa = PBXGroup;
- children = (
- DED7D75D0A5242C7003AD0FB /* Diagnostic.cpp */,
- DED7D75E0A5242C7003AD0FB /* FileManager.cpp */,
- DE3986F30CB8D50C00223765 /* IdentifierTable.cpp */,
- 3580CC0B0D072E5C00C5E4F4 /* LangOptions.cpp */,
- 35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */,
- DED7D76D0A5242C7003AD0FB /* SourceManager.cpp */,
- DED626C80AE0C065001E80A4 /* TargetInfo.cpp */,
- 03F50AC50D416EAA00B9CF60 /* Targets.cpp */,
- DED7D76E0A5242C7003AD0FB /* TokenKinds.cpp */,
- );
- name = Basic;
- path = lib/Basic;
- sourceTree = "<group>";
- };
- DED7D78C0A5242E6003AD0FB /* Lex */ = {
- isa = PBXGroup;
- children = (
- 3552E7540E520D80003A8CA5 /* PPCaching.cpp */,
- DE704DD10D1668A4009C7762 /* HeaderMap.cpp */,
- DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */,
- DED7D79E0A5242E6003AD0FB /* Lexer.cpp */,
- 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */,
- DE85CD9E0D8382DD0070E26E /* MacroArgs.h */,
- DE85CDA20D8383B20070E26E /* MacroArgs.cpp */,
- DED7D7A00A5242E6003AD0FB /* MacroInfo.cpp */,
- DE85CDAF0D838C390070E26E /* PPDirectives.cpp */,
- DED7D7A20A5242E6003AD0FB /* PPExpressions.cpp */,
- DE85CDB50D839BAE0070E26E /* PPLexerChange.cpp */,
- DE85CDAB0D838C120070E26E /* PPMacroExpansion.cpp */,
- DED7D7A30A5242E6003AD0FB /* Pragma.cpp */,
- DED7D7A40A5242E6003AD0FB /* Preprocessor.cpp */,
- DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */,
- DE85CD800D8380B10070E26E /* TokenLexer.cpp */,
- );
- name = Lex;
- path = lib/Lex;
- sourceTree = "<group>";
- };
- DEF7D9F40C9C8B020001F598 /* Rewrite */ = {
- isa = PBXGroup;
- children = (
- DEFFECA30DB093D100B4E7C3 /* DeltaTree.h */,
- 35F2BE7B0DAC2963006E7668 /* HTMLRewrite.h */,
- DEF7D9F60C9C8B1A0001F598 /* Rewriter.h */,
- DE53370B0CE2D96F00D9A028 /* RewriteRope.h */,
- );
- name = Rewrite;
- sourceTree = "<group>";
- };
- DEF7D9F50C9C8B0C0001F598 /* Rewrite */ = {
- isa = PBXGroup;
- children = (
- DEFFECA60DB1546600B4E7C3 /* DeltaTree.cpp */,
- 72D16C1E0D9975C400E6DA4A /* HTMLRewrite.cpp */,
- DEF7D9F80C9C8B1D0001F598 /* Rewriter.cpp */,
- DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */,
- );
- name = Rewrite;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 8DD76F620486A84900D96B5E /* clang */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "clang" */;
- buildPhases = (
- 8DD76F640486A84900D96B5E /* Sources */,
- 8DD76F660486A84900D96B5E /* Frameworks */,
- 8DD76F690486A84900D96B5E /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = clang;
- productInstallPath = "$(HOME)/bin";
- productName = clang;
- productReference = 8DD76F6C0486A84900D96B5E /* clang */;
- productType = "com.apple.product-type.tool";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 08FB7793FE84155DC02AAC07 /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
- compatibilityVersion = "Xcode 2.4";
- hasScannedForEncodings = 1;
- mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 8DD76F620486A84900D96B5E /* clang */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
- 8DD76F640486A84900D96B5E /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- DED7D77A0A5242C7003AD0FB /* Diagnostic.cpp in Sources */,
- DED7D77B0A5242C7003AD0FB /* FileManager.cpp in Sources */,
- DED7D7890A5242C7003AD0FB /* SourceManager.cpp in Sources */,
- DED7D78A0A5242C7003AD0FB /* TokenKinds.cpp in Sources */,
- DED7D7C30A5242E6003AD0FB /* Lexer.cpp in Sources */,
- DED7D7C50A5242E6003AD0FB /* MacroInfo.cpp in Sources */,
- DED7D7C70A5242E6003AD0FB /* PPExpressions.cpp in Sources */,
- DED7D7C80A5242E6003AD0FB /* Pragma.cpp in Sources */,
- DED7D7C90A5242E6003AD0FB /* Preprocessor.cpp in Sources */,
- DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */,
- DE06D4310A8BB52D0050E87E /* Parser.cpp in Sources */,
- DE0FCB340A9C21F100248FD5 /* Expr.cpp in Sources */,
- DE5932D10AD60FF400BC794C /* clang.cpp in Sources */,
- DE5932D30AD60FF400BC794C /* PrintParserCallbacks.cpp in Sources */,
- DE5932D40AD60FF400BC794C /* PrintPreprocessedOutput.cpp in Sources */,
- DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */,
- DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */,
- DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */,
- DE3452410AEF1A2D00DBC861 /* Stmt.cpp in Sources */,
- DE3460000AFDCC1900DBC861 /* ParseObjc.cpp in Sources */,
- DE3460050AFDCC6500DBC861 /* ParseInit.cpp in Sources */,
- DE34600B0AFDCCBF00DBC861 /* ParseStmt.cpp in Sources */,
- DE34600F0AFDCCCE00DBC861 /* ParseDecl.cpp in Sources */,
- DE3460130AFDCCDA00DBC861 /* ParseExpr.cpp in Sources */,
- DE3461270AFE68BE00DBC861 /* MinimalAction.cpp in Sources */,
- DE34621D0AFEB19B00DBC861 /* StmtPrinter.cpp in Sources */,
- DE75EDF10B06880E0020CF81 /* Type.cpp in Sources */,
- DE1733000B068B700080B521 /* ASTContext.cpp in Sources */,
- DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
- DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */,
- 1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */,
- DE67E70B0C020EC500F66BC5 /* SemaType.cpp in Sources */,
- DE67E70D0C020ECA00F66BC5 /* SemaStmt.cpp in Sources */,
- DE67E70F0C020ECF00F66BC5 /* SemaExprCXX.cpp in Sources */,
- DE67E7110C020ED400F66BC5 /* SemaExpr.cpp in Sources */,
- DE67E7130C020ED900F66BC5 /* SemaDecl.cpp in Sources */,
- DE67E7170C020EE400F66BC5 /* Sema.cpp in Sources */,
- DE67E71A0C020F4F00F66BC5 /* ParseAST.cpp in Sources */,
- DE06756C0C051CFE00EBBFD8 /* ParseExprCXX.cpp in Sources */,
- DE928B130C05659200231DA4 /* ModuleBuilder.cpp in Sources */,
- DE928B7F0C0A615600231DA4 /* CodeGenModule.cpp in Sources */,
- DE928B830C0A616000231DA4 /* CodeGenFunction.cpp in Sources */,
- DE4772FA0C10EAE5002239E8 /* CGStmt.cpp in Sources */,
- DE4772FC0C10EAEC002239E8 /* CGExpr.cpp in Sources */,
- DE4264FC0C113592005A861D /* CGDecl.cpp in Sources */,
- 84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */,
- DEEBC3BC0C2363BC00A9FE82 /* CodeGenTypes.cpp in Sources */,
- DEF2EDA70C6A4252000C4259 /* StmtDumper.cpp in Sources */,
- DEF2EFF30C6CDD74000C4259 /* CGExprAgg.cpp in Sources */,
- DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
- 1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
- DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */,
- 1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
- DEC63B1A0C7B940200DBF169 /* CFG.cpp in Sources */,
- DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */,
- 35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */,
- DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */,
- 356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */,
- DEF7D9F90C9C8B1D0001F598 /* Rewriter.cpp in Sources */,
- 35CFFE000CA1CBCB00E6F2BE /* StmtViz.cpp in Sources */,
- DE39857B0CB8ADCB00223765 /* ASTConsumers.cpp in Sources */,
- DE3986F40CB8D50C00223765 /* IdentifierTable.cpp in Sources */,
- 352981090CC58344008B5E84 /* SerializationTest.cpp in Sources */,
- 35847BE50CC7DBAF00C40FFF /* StmtIterator.cpp in Sources */,
- 35707EFE0CD0F5CC000B2204 /* SourceLocation.cpp in Sources */,
- 351318600CD14468006B66F7 /* DeclSerialization.cpp in Sources */,
- 35839B0B0CDF845F006ED061 /* StmtSerialization.cpp in Sources */,
- 35839B0C0CDF845F006ED061 /* TypeSerialization.cpp in Sources */,
- 3580CC0C0D072E5C00C5E4F4 /* LangOptions.cpp in Sources */,
- DE704B260D0FBEBE009C7762 /* SemaDeclObjC.cpp in Sources */,
- DE704DD20D1668A4009C7762 /* HeaderMap.cpp in Sources */,
- 35BB2D7D0D19951A00944DB5 /* TranslationUnit.cpp in Sources */,
- 35BB2D7F0D19954000944DB5 /* ASTConsumer.cpp in Sources */,
- DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */,
- 03F50AC60D416EAA00B9CF60 /* Targets.cpp in Sources */,
- 1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */,
- DE38CD500D794D0100A273B6 /* CGObjCGNU.cpp in Sources */,
- DE4121350D7F1C1C0080F80A /* SymbolManager.cpp in Sources */,
- DE4121360D7F1C1C0080F80A /* ExplodedGraph.cpp in Sources */,
- DE4121370D7F1C1C0080F80A /* UninitializedValues.cpp in Sources */,
- DE4121380D7F1C1C0080F80A /* GRCoreEngine.cpp in Sources */,
- DE41213B0D7F1C1C0080F80A /* RValues.cpp in Sources */,
- DE41213C0D7F1C1C0080F80A /* GRSimpleVals.cpp in Sources */,
- DE41213D0D7F1C1C0080F80A /* GRBlockCounter.cpp in Sources */,
- DE41213E0D7F1C1C0080F80A /* GRExprEngine.cpp in Sources */,
- 35D55B270D81D8C60092E734 /* BasicValueFactory.cpp in Sources */,
- 35D55B280D81D8C60092E734 /* CFRefCount.cpp in Sources */,
- DE85CD810D8380B10070E26E /* TokenLexer.cpp in Sources */,
- DE85CDA30D8383B20070E26E /* MacroArgs.cpp in Sources */,
- DE85CDAC0D838C120070E26E /* PPMacroExpansion.cpp in Sources */,
- DE85CDB00D838C390070E26E /* PPDirectives.cpp in Sources */,
- DE85CDB60D839BAE0070E26E /* PPLexerChange.cpp in Sources */,
- DE38CF160D8C9DE000A273B6 /* DiagChecker.cpp in Sources */,
- DE38CF270D8C9E6C00A273B6 /* DeclObjC.cpp in Sources */,
- 72D16C1F0D9975C400E6DA4A /* HTMLRewrite.cpp in Sources */,
- 72D16C220D9975EA00E6DA4A /* HTMLPrint.cpp in Sources */,
- 35A8FCF90D9B4B2A001C2F97 /* PathDiagnostic.cpp in Sources */,
- 35F8D0D60D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp in Sources */,
- 3593790A0DA48ABA0043B19C /* BugReporter.cpp in Sources */,
- 35EF67700DAD1D2C00B19414 /* SemaDeclCXX.cpp in Sources */,
- 352712510DAFE54700C76352 /* IdentifierResolver.cpp in Sources */,
- DEFFECA70DB1546600B4E7C3 /* DeltaTree.cpp in Sources */,
- DECAB0D00DB3C84200E13CCB /* RewriteRope.cpp in Sources */,
- 035611E20DB40C8100D2EF2A /* RewriteObjC.cpp in Sources */,
- 35EFEFB60DB67ED60020783D /* GRTransferFuncs.cpp in Sources */,
- DEA0EBDA0DD2D3C8007A02A9 /* RewriteMacros.cpp in Sources */,
- 35A3E7020DD3874400757F74 /* CGDebugInfo.cpp in Sources */,
- 3599299B0DE2425300A8A33E /* SemaInit.cpp in Sources */,
- 35FE6BCF0DF6EE1F00739712 /* DeclBase.cpp in Sources */,
- 35EE48B10E0C4CCA00715C54 /* DeclCXX.cpp in Sources */,
- 35EE48B20E0C4CCA00715C54 /* ParentMap.cpp in Sources */,
- 3534A01D0E129849002709B2 /* ParseCXXInlineMethods.cpp in Sources */,
- DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */,
- 359DBBD40E1AC9CC00F43FA0 /* AnalysisConsumer.cpp in Sources */,
- 1A32C17F0E1C87AD00A6B483 /* ExprConstant.cpp in Sources */,
- 3595AFB80E1C8D62004CDF09 /* CheckObjCDealloc.cpp in Sources */,
- 3536456B0E23EBF7009C6509 /* Environment.cpp in Sources */,
- 3558F76D0E267C8300A5B0DF /* BasicStore.cpp in Sources */,
- 3507E4C20E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp in Sources */,
- 35862B0D0E3628CB0009F542 /* CheckDeadStores.cpp in Sources */,
- 35862B120E3629850009F542 /* GRExprEngineInternalChecks.cpp in Sources */,
- 35F2A01E0E36AFF100D17527 /* CheckObjCUnusedIVars.cpp in Sources */,
- 359603460E49496E00C6282B /* TextDiagnosticBuffer.cpp in Sources */,
- 359603470E49496E00C6282B /* TextDiagnosticPrinter.cpp in Sources */,
- 3552E7550E520D80003A8CA5 /* PPCaching.cpp in Sources */,
- 3552E7590E520DD7003A8CA5 /* CGObjCMac.cpp in Sources */,
- 358F51520E529AA4007F2102 /* GRState.cpp in Sources */,
- 1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */,
- 350F4B470E5F32E100A21EA9 /* InitHeaderSearch.cpp in Sources */,
- 359763260E633C7500B68AB7 /* HTMLDiagnostics.cpp in Sources */,
- 358CFBB80E65AB04002A8E19 /* BasicConstraintManager.cpp in Sources */,
- 35475B200E79973F0000BFE4 /* CGCall.cpp in Sources */,
- 9030C10A0E807A9300941490 /* RewriteBlocks.cpp in Sources */,
- 35BAC1E80E82C5B7003FB76F /* CheckNSError.cpp in Sources */,
- 358D230B0E8BEB9D0003DDCC /* DeclGroup.cpp in Sources */,
- 355106860E9A8507006A4E44 /* MemRegion.cpp in Sources */,
- 3551068C0E9A8546006A4E44 /* ParsePragma.cpp in Sources */,
- 3551068D0E9A8546006A4E44 /* ParseTentative.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 1DEB923208733DC60010E9CD /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = i386;
- COPY_PHASE_STRIP = NO;
- GCC_CW_ASM_SYNTAX = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_ENABLE_PASCAL_STRINGS = NO;
- GCC_ENABLE_SYMBOL_SEPARATION = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = "__STDC_LIMIT_MACROS=1";
- GCC_STRICT_ALIASING = YES;
- GCC_THREADSAFE_STATICS = NO;
- GCC_USE_GCC3_PFE_SUPPORT = NO;
- INSTALL_PATH = "$(HOME)/bin";
- OTHER_LDFLAGS = (
- "-lLLVMCore",
- "-lLLVMSupport",
- "-lLLVMSystem",
- "-lLLVMBitWriter",
- "-lLLVMBitReader",
- "-lLLVMCodeGen",
- "-lLLVMAnalysis",
- "-lLLVMTarget",
- );
- PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
- PRODUCT_NAME = clang;
- };
- name = Debug;
- };
- 1DEB923308733DC60010E9CD /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = i386;
- GCC_CW_ASM_SYNTAX = NO;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_ENABLE_PASCAL_STRINGS = NO;
- GCC_ENABLE_SYMBOL_SEPARATION = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_PREPROCESSOR_DEFINITIONS = "__STDC_LIMIT_MACROS=1";
- GCC_STRICT_ALIASING = YES;
- GCC_THREADSAFE_STATICS = NO;
- GCC_USE_GCC3_PFE_SUPPORT = NO;
- INSTALL_PATH = "$(HOME)/bin";
- OTHER_LDFLAGS = (
- "-lLLVMCore",
- "-lLLVMSupport",
- "-lLLVMSystem",
- "-lLLVMBitWriter",
- "-lLLVMBitReader",
- "-lLLVMCodeGen",
- "-lLLVMAnalysis",
- "-lLLVMTarget",
- );
- PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
- PRODUCT_NAME = clang;
- };
- name = Release;
- };
- 1DEB923608733DC60010E9CD /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_VERSION = "";
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- ../../include,
- include,
- );
- LIBRARY_SEARCH_PATHS = ../../Debug/lib;
- OTHER_LDFLAGS = "";
- PREBINDING = NO;
- };
- name = Debug;
- };
- 1DEB923708733DC60010E9CD /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- ../../include,
- include,
- );
- LIBRARY_SEARCH_PATHS = ../../Release;
- OTHER_LDFLAGS = "";
- PREBINDING = NO;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "clang" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1DEB923208733DC60010E9CD /* Debug */,
- 1DEB923308733DC60010E9CD /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1DEB923608733DC60010E9CD /* Debug */,
- 1DEB923708733DC60010E9CD /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/clang/docs/InternalsManual.html b/clang/docs/InternalsManual.html
deleted file mode 100644
index 81fefab2adff..000000000000
--- a/clang/docs/InternalsManual.html
+++ /dev/null
@@ -1,624 +0,0 @@
-<html>
-<head>
-<title>"clang" CFE Internals Manual</title>
-<link type="text/css" rel="stylesheet" href="../menu.css" />
-<link type="text/css" rel="stylesheet" href="../content.css" />
-</head>
-<body>
-
-<!--#include virtual="../menu.html.incl"-->
-
-<div id="content">
-
-<h1>"clang" CFE Internals Manual</h1>
-
-<ul>
-<li><a href="#intro">Introduction</a></li>
-<li><a href="#libsystem">LLVM System and Support Libraries</a></li>
-<li><a href="#libbasic">The clang 'Basic' Library</a>
- <ul>
- <li><a href="#SourceLocation">The SourceLocation and SourceManager
- classes</a></li>
- </ul>
-</li>
-<li><a href="#liblex">The Lexer and Preprocessor Library</a>
- <ul>
- <li><a href="#Token">The Token class</a></li>
- <li><a href="#Lexer">The Lexer class</a></li>
- <li><a href="#TokenLexer">The TokenLexer class</a></li>
- <li><a href="#MultipleIncludeOpt">The MultipleIncludeOpt class</a></li>
- </ul>
-</li>
-<li><a href="#libparse">The Parser Library</a>
- <ul>
- </ul>
-</li>
-<li><a href="#libast">The AST Library</a>
- <ul>
- <li><a href="#Type">The Type class and its subclasses</a></li>
- <li><a href="#QualType">The QualType class</a></li>
- <li><a href="#CFG">The CFG class</a></li>
- </ul>
-</li>
-</ul>
-
-
-<!-- ======================================================================= -->
-<h2 id="intro">Introduction</h2>
-<!-- ======================================================================= -->
-
-<p>This document describes some of the more important APIs and internal design
-decisions made in the clang C front-end. The purpose of this document is to
-both capture some of this high level information and also describe some of the
-design decisions behind it. This is meant for people interested in hacking on
-clang, not for end-users. The description below is categorized by
-libraries, and does not describe any of the clients of the libraries.</p>
-
-<!-- ======================================================================= -->
-<h2 id="libsystem">LLVM System and Support Libraries</h2>
-<!-- ======================================================================= -->
-
-<p>The LLVM libsystem library provides the basic clang system abstraction layer,
-which is used for file system access. The LLVM libsupport library provides many
-underlying libraries and <a
-href="http://llvm.org/docs/ProgrammersManual.html">data-structures</a>,
- including command line option
-processing and various containers.</p>
-
-<!-- ======================================================================= -->
-<h2 id="libbasic">The clang 'Basic' Library</h2>
-<!-- ======================================================================= -->
-
-<p>This library certainly needs a better name. The 'basic' library contains a
-number of low-level utilities for tracking and manipulating source buffers,
-locations within the source buffers, diagnostics, tokens, target abstraction,
-and information about the subset of the language being compiled for.</p>
-
-<p>Part of this infrastructure is specific to C (such as the TargetInfo class),
-other parts could be reused for other non-C-based languages (SourceLocation,
-SourceManager, Diagnostics, FileManager). When and if there is future demand
-we can figure out if it makes sense to introduce a new library, move the general
-classes somewhere else, or introduce some other solution.</p>
-
-<p>We describe the roles of these classes in order of their dependencies.</p>
-
-<!-- ======================================================================= -->
-<h3 id="SourceLocation">The SourceLocation and SourceManager classes</h3>
-<!-- ======================================================================= -->
-
-<p>Strangely enough, the SourceLocation class represents a location within the
-source code of the program. Important design points include:</p>
-
-<ol>
-<li>sizeof(SourceLocation) must be extremely small, as these are embedded into
- many AST nodes and are passed around often. Currently it is 32 bits.</li>
-<li>SourceLocation must be a simple value object that can be efficiently
- copied.</li>
-<li>We should be able to represent a source location for any byte of any input
- file. This includes in the middle of tokens, in whitespace, in trigraphs,
- etc.</li>
-<li>A SourceLocation must encode the current #include stack that was active when
- the location was processed. For example, if the location corresponds to a
- token, it should contain the set of #includes active when the token was
- lexed. This allows us to print the #include stack for a diagnostic.</li>
-<li>SourceLocation must be able to describe macro expansions, capturing both
- the ultimate instantiation point and the source of the original character
- data.</li>
-</ol>
-
-<p>In practice, the SourceLocation works together with the SourceManager class
-to encode two pieces of information about a location: it's physical location
-and it's virtual location. For most tokens, these will be the same. However,
-for a macro expansion (or tokens that came from a _Pragma directive) these will
-describe the location of the characters corresponding to the token and the
-location where the token was used (i.e. the macro instantiation point or the
-location of the _Pragma itself).</p>
-
-<p>For efficiency, we only track one level of macro instantions: if a token was
-produced by multiple instantiations, we only track the source and ultimate
-destination. Though we could track the intermediate instantiation points, this
-would require extra bookkeeping and no known client would benefit substantially
-from this.</p>
-
-<p>The clang front-end inherently depends on the location of a token being
-tracked correctly. If it is ever incorrect, the front-end may get confused and
-die. The reason for this is that the notion of the 'spelling' of a Token in
-clang depends on being able to find the original input characters for the token.
-This concept maps directly to the "physical" location for the token.</p>
-
-<!-- ======================================================================= -->
-<h2 id="liblex">The Lexer and Preprocessor Library</h2>
-<!-- ======================================================================= -->
-
-<p>The Lexer library contains several tightly-connected classes that are involved
-with the nasty process of lexing and preprocessing C source code. The main
-interface to this library for outside clients is the large <a
-href="#Preprocessor">Preprocessor</a> class.
-It contains the various pieces of state that are required to coherently read
-tokens out of a translation unit.</p>
-
-<p>The core interface to the Preprocessor object (once it is set up) is the
-Preprocessor::Lex method, which returns the next <a href="#Token">Token</a> from
-the preprocessor stream. There are two types of token providers that the
-preprocessor is capable of reading from: a buffer lexer (provided by the <a
-href="#Lexer">Lexer</a> class) and a buffered token stream (provided by the <a
-href="#TokenLexer">TokenLexer</a> class).
-
-
-<!-- ======================================================================= -->
-<h3 id="Token">The Token class</h3>
-<!-- ======================================================================= -->
-
-<p>The Token class is used to represent a single lexed token. Tokens are
-intended to be used by the lexer/preprocess and parser libraries, but are not
-intended to live beyond them (for example, they should not live in the ASTs).<p>
-
-<p>Tokens most often live on the stack (or some other location that is efficient
-to access) as the parser is running, but occasionally do get buffered up. For
-example, macro definitions are stored as a series of tokens, and the C++
-front-end will eventually need to buffer tokens up for tentative parsing and
-various pieces of look-ahead. As such, the size of a Token matter. On a 32-bit
-system, sizeof(Token) is currently 16 bytes.</p>
-
-<p>Tokens contain the following information:</p>
-
-<ul>
-<li><b>A SourceLocation</b> - This indicates the location of the start of the
-token.</li>
-
-<li><b>A length</b> - This stores the length of the token as stored in the
-SourceBuffer. For tokens that include them, this length includes trigraphs and
-escaped newlines which are ignored by later phases of the compiler. By pointing
-into the original source buffer, it is always possible to get the original
-spelling of a token completely accurately.</li>
-
-<li><b>IdentifierInfo</b> - If a token takes the form of an identifier, and if
-identifier lookup was enabled when the token was lexed (e.g. the lexer was not
-reading in 'raw' mode) this contains a pointer to the unique hash value for the
-identifier. Because the lookup happens before keyword identification, this
-field is set even for language keywords like 'for'.</li>
-
-<li><b>TokenKind</b> - This indicates the kind of token as classified by the
-lexer. This includes things like <tt>tok::starequal</tt> (for the "*="
-operator), <tt>tok::ampamp</tt> for the "&amp;&amp;" token, and keyword values
-(e.g. <tt>tok::kw_for</tt>) for identifiers that correspond to keywords. Note
-that some tokens can be spelled multiple ways. For example, C++ supports
-"operator keywords", where things like "and" are treated exactly like the
-"&amp;&amp;" operator. In these cases, the kind value is set to
-<tt>tok::ampamp</tt>, which is good for the parser, which doesn't have to
-consider both forms. For something that cares about which form is used (e.g.
-the preprocessor 'stringize' operator) the spelling indicates the original
-form.</li>
-
-<li><b>Flags</b> - There are currently four flags tracked by the
-lexer/preprocessor system on a per-token basis:
-
- <ol>
- <li><b>StartOfLine</b> - This was the first token that occurred on its input
- source line.</li>
- <li><b>LeadingSpace</b> - There was a space character either immediately
- before the token or transitively before the token as it was expanded
- through a macro. The definition of this flag is very closely defined by
- the stringizing requirements of the preprocessor.</li>
- <li><b>DisableExpand</b> - This flag is used internally to the preprocessor to
- represent identifier tokens which have macro expansion disabled. This
- prevents them from being considered as candidates for macro expansion ever
- in the future.</li>
- <li><b>NeedsCleaning</b> - This flag is set if the original spelling for the
- token includes a trigraph or escaped newline. Since this is uncommon,
- many pieces of code can fast-path on tokens that did not need cleaning.
- </p>
- </ol>
-</li>
-</ul>
-
-<p>One interesting (and somewhat unusual) aspect of tokens is that they don't
-contain any semantic information about the lexed value. For example, if the
-token was a pp-number token, we do not represent the value of the number that
-was lexed (this is left for later pieces of code to decide). Additionally, the
-lexer library has no notion of typedef names vs variable names: both are
-returned as identifiers, and the parser is left to decide whether a specific
-identifier is a typedef or a variable (tracking this requires scope information
-among other things).</p>
-
-<!-- ======================================================================= -->
-<h3 id="Lexer">The Lexer class</h3>
-<!-- ======================================================================= -->
-
-<p>The Lexer class provides the mechanics of lexing tokens out of a source
-buffer and deciding what they mean. The Lexer is complicated by the fact that
-it operates on raw buffers that have not had spelling eliminated (this is a
-necessity to get decent performance), but this is countered with careful coding
-as well as standard performance techniques (for example, the comment handling
-code is vectorized on X86 and PowerPC hosts).</p>
-
-<p>The lexer has a couple of interesting modal features:</p>
-
-<ul>
-<li>The lexer can operate in 'raw' mode. This mode has several features that
- make it possible to quickly lex the file (e.g. it stops identifier lookup,
- doesn't specially handle preprocessor tokens, handles EOF differently, etc).
- This mode is used for lexing within an "<tt>#if 0</tt>" block, for
- example.</li>
-<li>The lexer can capture and return comments as tokens. This is required to
- support the -C preprocessor mode, which passes comments through, and is
- used by the diagnostic checker to identifier expect-error annotations.</li>
-<li>The lexer can be in ParsingFilename mode, which happens when preprocessing
- after reading a #include directive. This mode changes the parsing of '&lt;'
- to return an "angled string" instead of a bunch of tokens for each thing
- within the filename.</li>
-<li>When parsing a preprocessor directive (after "<tt>#</tt>") the
- ParsingPreprocessorDirective mode is entered. This changes the parser to
- return EOM at a newline.</li>
-<li>The Lexer uses a LangOptions object to know whether trigraphs are enabled,
- whether C++ or ObjC keywords are recognized, etc.</li>
-</ul>
-
-<p>In addition to these modes, the lexer keeps track of a couple of other
- features that are local to a lexed buffer, which change as the buffer is
- lexed:</p>
-
-<ul>
-<li>The Lexer uses BufferPtr to keep track of the current character being
- lexed.</li>
-<li>The Lexer uses IsAtStartOfLine to keep track of whether the next lexed token
- will start with its "start of line" bit set.</li>
-<li>The Lexer keeps track of the current #if directives that are active (which
- can be nested).</li>
-<li>The Lexer keeps track of an <a href="#MultipleIncludeOpt">
- MultipleIncludeOpt</a> object, which is used to
- detect whether the buffer uses the standard "<tt>#ifndef XX</tt> /
- <tt>#define XX</tt>" idiom to prevent multiple inclusion. If a buffer does,
- subsequent includes can be ignored if the XX macro is defined.</li>
-</ul>
-
-<!-- ======================================================================= -->
-<h3 id="TokenLexer">The TokenLexer class</h3>
-<!-- ======================================================================= -->
-
-<p>The TokenLexer class is a token provider that returns tokens from a list
-of tokens that came from somewhere else. It typically used for two things: 1)
-returning tokens from a macro definition as it is being expanded 2) returning
-tokens from an arbitrary buffer of tokens. The later use is used by _Pragma and
-will most likely be used to handle unbounded look-ahead for the C++ parser.</p>
-
-<!-- ======================================================================= -->
-<h3 id="MultipleIncludeOpt">The MultipleIncludeOpt class</h3>
-<!-- ======================================================================= -->
-
-<p>The MultipleIncludeOpt class implements a really simple little state machine
-that is used to detect the standard "<tt>#ifndef XX</tt> / <tt>#define XX</tt>"
-idiom that people typically use to prevent multiple inclusion of headers. If a
-buffer uses this idiom and is subsequently #include'd, the preprocessor can
-simply check to see whether the guarding condition is defined or not. If so,
-the preprocessor can completely ignore the include of the header.</p>
-
-
-
-<!-- ======================================================================= -->
-<h2 id="libparse">The Parser Library</h2>
-<!-- ======================================================================= -->
-
-<!-- ======================================================================= -->
-<h2 id="libast">The AST Library</h2>
-<!-- ======================================================================= -->
-
-<!-- ======================================================================= -->
-<h3 id="Type">The Type class and its subclasses</h3>
-<!-- ======================================================================= -->
-
-<p>The Type class (and its subclasses) are an important part of the AST. Types
-are accessed through the ASTContext class, which implicitly creates and uniques
-them as they are needed. Types have a couple of non-obvious features: 1) they
-do not capture type qualifiers like const or volatile (See
-<a href="#QualType">QualType</a>), and 2) they implicitly capture typedef
-information. Once created, types are immutable (unlike decls).</p>
-
-<p>Typedefs in C make semantic analysis a bit more complex than it would
-be without them. The issue is that we want to capture typedef information
-and represent it in the AST perfectly, but the semantics of operations need to
-"see through" typedefs. For example, consider this code:</p>
-
-<code>
-void func() {<br>
-&nbsp;&nbsp;typedef int foo;<br>
-&nbsp;&nbsp;foo X, *Y;<br>
-&nbsp;&nbsp;typedef foo* bar;<br>
-&nbsp;&nbsp;bar Z;<br>
-&nbsp;&nbsp;*X; <i>// error</i><br>
-&nbsp;&nbsp;**Y; <i>// error</i><br>
-&nbsp;&nbsp;**Z; <i>// error</i><br>
-}<br>
-</code>
-
-<p>The code above is illegal, and thus we expect there to be diagnostics emitted
-on the annotated lines. In this example, we expect to get:</p>
-
-<pre>
-<b>test.c:6:1: error: indirection requires pointer operand ('foo' invalid)</b>
-*X; // error
-<font color="blue">^~</font>
-<b>test.c:7:1: error: indirection requires pointer operand ('foo' invalid)</b>
-**Y; // error
-<font color="blue">^~~</font>
-<b>test.c:8:1: error: indirection requires pointer operand ('foo' invalid)</b>
-**Z; // error
-<font color="blue">^~~</font>
-</pre>
-
-<p>While this example is somewhat silly, it illustrates the point: we want to
-retain typedef information where possible, so that we can emit errors about
-"<tt>std::string</tt>" instead of "<tt>std::basic_string&lt;char, std:...</tt>".
-Doing this requires properly keeping typedef information (for example, the type
-of "X" is "foo", not "int"), and requires properly propagating it through the
-various operators (for example, the type of *Y is "foo", not "int"). In order
-to retain this information, the type of these expressions is an instance of the
-TypedefType class, which indicates that the type of these expressions is a
-typedef for foo.
-</p>
-
-<p>Representing types like this is great for diagnostics, because the
-user-specified type is always immediately available. There are two problems
-with this: first, various semantic checks need to make judgements about the
-<em>actual structure</em> of a type, ignoring typdefs. Second, we need an
-efficient way to query whether two types are structurally identical to each
-other, ignoring typedefs. The solution to both of these problems is the idea of
-canonical types.</p>
-
-<h4>Canonical Types</h4>
-
-<p>Every instance of the Type class contains a canonical type pointer. For
-simple types with no typedefs involved (e.g. "<tt>int</tt>", "<tt>int*</tt>",
-"<tt>int**</tt>"), the type just points to itself. For types that have a
-typedef somewhere in their structure (e.g. "<tt>foo</tt>", "<tt>foo*</tt>",
-"<tt>foo**</tt>", "<tt>bar</tt>"), the canonical type pointer points to their
-structurally equivalent type without any typedefs (e.g. "<tt>int</tt>",
-"<tt>int*</tt>", "<tt>int**</tt>", and "<tt>int*</tt>" respectively).</p>
-
-<p>This design provides a constant time operation (dereferencing the canonical
-type pointer) that gives us access to the structure of types. For example,
-we can trivially tell that "bar" and "foo*" are the same type by dereferencing
-their canonical type pointers and doing a pointer comparison (they both point
-to the single "<tt>int*</tt>" type).</p>
-
-<p>Canonical types and typedef types bring up some complexities that must be
-carefully managed. Specifically, the "isa/cast/dyncast" operators generally
-shouldn't be used in code that is inspecting the AST. For example, when type
-checking the indirection operator (unary '*' on a pointer), the type checker
-must verify that the operand has a pointer type. It would not be correct to
-check that with "<tt>isa&lt;PointerType&gt;(SubExpr-&gt;getType())</tt>",
-because this predicate would fail if the subexpression had a typedef type.</p>
-
-<p>The solution to this problem are a set of helper methods on Type, used to
-check their properties. In this case, it would be correct to use
-"<tt>SubExpr-&gt;getType()-&gt;isPointerType()</tt>" to do the check. This
-predicate will return true if the <em>canonical type is a pointer</em>, which is
-true any time the type is structurally a pointer type. The only hard part here
-is remembering not to use the <tt>isa/cast/dyncast</tt> operations.</p>
-
-<p>The second problem we face is how to get access to the pointer type once we
-know it exists. To continue the example, the result type of the indirection
-operator is the pointee type of the subexpression. In order to determine the
-type, we need to get the instance of PointerType that best captures the typedef
-information in the program. If the type of the expression is literally a
-PointerType, we can return that, otherwise we have to dig through the
-typedefs to find the pointer type. For example, if the subexpression had type
-"<tt>foo*</tt>", we could return that type as the result. If the subexpression
-had type "<tt>bar</tt>", we want to return "<tt>foo*</tt>" (note that we do
-<em>not</em> want "<tt>int*</tt>"). In order to provide all of this, Type has
-a getAsPointerType() method that checks whether the type is structurally a
-PointerType and, if so, returns the best one. If not, it returns a null
-pointer.</p>
-
-<p>This structure is somewhat mystical, but after meditating on it, it will
-make sense to you :).</p>
-
-<!-- ======================================================================= -->
-<h3 id="QualType">The QualType class</h3>
-<!-- ======================================================================= -->
-
-<p>The QualType class is designed as a trivial value class that is small,
-passed by-value and is efficient to query. The idea of QualType is that it
-stores the type qualifiers (const, volatile, restrict) separately from the types
-themselves: QualType is conceptually a pair of "Type*" and bits for the type
-qualifiers.</p>
-
-<p>By storing the type qualifiers as bits in the conceptual pair, it is
-extremely efficient to get the set of qualifiers on a QualType (just return the
-field of the pair), add a type qualifier (which is a trivial constant-time
-operation that sets a bit), and remove one or more type qualifiers (just return
-a QualType with the bitfield set to empty).</p>
-
-<p>Further, because the bits are stored outside of the type itself, we do not
-need to create duplicates of types with different sets of qualifiers (i.e. there
-is only a single heap allocated "int" type: "const int" and "volatile const int"
-both point to the same heap allocated "int" type). This reduces the heap size
-used to represent bits and also means we do not have to consider qualifiers when
-uniquing types (<a href="#Type">Type</a> does not even contain qualifiers).</p>
-
-<p>In practice, on hosts where it is safe, the 3 type qualifiers are stored in
-the low bit of the pointer to the Type object. This means that QualType is
-exactly the same size as a pointer, and this works fine on any system where
-malloc'd objects are at least 8 byte aligned.</p>
-
-<!-- ======================================================================= -->
-<h3 id="CFG">The <tt>CFG</tt> class</h3>
-<!-- ======================================================================= -->
-
-<p>The <tt>CFG</tt> class is designed to represent a source-level
-control-flow graph for a single statement (<tt>Stmt*</tt>). Typically
-instances of <tt>CFG</tt> are constructed for function bodies (usually
-an instance of <tt>CompoundStmt</tt>), but can also be instantiated to
-represent the control-flow of any class that subclasses <tt>Stmt</tt>,
-which includes simple expressions. Control-flow graphs are especially
-useful for performing
-<a href="http://en.wikipedia.org/wiki/Data_flow_analysis#Sensitivities">flow-
-or path-sensitive</a> program analyses on a given function.</p>
-
-<h4>Basic Blocks</h4>
-
-<p>Concretely, an instance of <tt>CFG</tt> is a collection of basic
-blocks. Each basic block is an instance of <tt>CFGBlock</tt>, which
-simply contains an ordered sequence of <tt>Stmt*</tt> (each referring
-to statements in the AST). The ordering of statements within a block
-indicates unconditional flow of control from one statement to the
-next. <a href="#ConditionalControlFlow">Conditional control-flow</a>
-is represented using edges between basic blocks. The statements
-within a given <tt>CFGBlock</tt> can be traversed using
-the <tt>CFGBlock::*iterator</tt> interface.</p>
-
-<p>
-A <tt>CFG</tt> object owns the instances of <tt>CFGBlock</tt> within
-the control-flow graph it represents. Each <tt>CFGBlock</tt> within a
-CFG is also uniquely numbered (accessible
-via <tt>CFGBlock::getBlockID()</tt>). Currently the number is
-based on the ordering the blocks were created, but no assumptions
-should be made on how <tt>CFGBlock</tt>s are numbered other than their
-numbers are unique and that they are numbered from 0..N-1 (where N is
-the number of basic blocks in the CFG).</p>
-
-<h4>Entry and Exit Blocks</h4>
-
-Each instance of <tt>CFG</tt> contains two special blocks:
-an <i>entry</i> block (accessible via <tt>CFG::getEntry()</tt>), which
-has no incoming edges, and an <i>exit</i> block (accessible
-via <tt>CFG::getExit()</tt>), which has no outgoing edges. Neither
-block contains any statements, and they serve the role of providing a
-clear entrance and exit for a body of code such as a function body.
-The presence of these empty blocks greatly simplifies the
-implementation of many analyses built on top of CFGs.
-
-<h4 id ="ConditionalControlFlow">Conditional Control-Flow</h4>
-
-<p>Conditional control-flow (such as those induced by if-statements
-and loops) is represented as edges between <tt>CFGBlock</tt>s.
-Because different C language constructs can induce control-flow,
-each <tt>CFGBlock</tt> also records an extra <tt>Stmt*</tt> that
-represents the <i>terminator</i> of the block. A terminator is simply
-the statement that caused the control-flow, and is used to identify
-the nature of the conditional control-flow between blocks. For
-example, in the case of an if-statement, the terminator refers to
-the <tt>IfStmt</tt> object in the AST that represented the given
-branch.</p>
-
-<p>To illustrate, consider the following code example:</p>
-
-<code>
-int foo(int x) {<br>
-&nbsp;&nbsp;x = x + 1;<br>
-<br>
-&nbsp;&nbsp;if (x > 2) x++;<br>
-&nbsp;&nbsp;else {<br>
-&nbsp;&nbsp;&nbsp;&nbsp;x += 2;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;x *= 2;<br>
-&nbsp;&nbsp;}<br>
-<br>
-&nbsp;&nbsp;return x;<br>
-}
-</code>
-
-<p>After invoking the parser+semantic analyzer on this code fragment,
-the AST of the body of <tt>foo</tt> is referenced by a
-single <tt>Stmt*</tt>. We can then construct an instance
-of <tt>CFG</tt> representing the control-flow graph of this function
-body by single call to a static class method:</p>
-
-<code>
-&nbsp;&nbsp;Stmt* FooBody = ...<br>
-&nbsp;&nbsp;CFG* FooCFG = <b>CFG::buildCFG</b>(FooBody);
-</code>
-
-<p>It is the responsibility of the caller of <tt>CFG::buildCFG</tt>
-to <tt>delete</tt> the returned <tt>CFG*</tt> when the CFG is no
-longer needed.</p>
-
-<p>Along with providing an interface to iterate over
-its <tt>CFGBlock</tt>s, the <tt>CFG</tt> class also provides methods
-that are useful for debugging and visualizing CFGs. For example, the
-method
-<tt>CFG::dump()</tt> dumps a pretty-printed version of the CFG to
-standard error. This is especially useful when one is using a
-debugger such as gdb. For example, here is the output
-of <tt>FooCFG->dump()</tt>:</p>
-
-<code>
-&nbsp;[ B5 (ENTRY) ]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (0):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B4<br>
-<br>
-&nbsp;[ B4 ]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;1: x = x + 1<br>
-&nbsp;&nbsp;&nbsp;&nbsp;2: (x > 2)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<b>T: if [B4.2]</b><br>
-&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B5<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Successors (2): B3 B2<br>
-<br>
-&nbsp;[ B3 ]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;1: x++<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B4<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B1<br>
-<br>
-&nbsp;[ B2 ]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;1: x += 2<br>
-&nbsp;&nbsp;&nbsp;&nbsp;2: x *= 2<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B4<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B1<br>
-<br>
-&nbsp;[ B1 ]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;1: return x;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (2): B2 B3<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Successors (1): B0<br>
-<br>
-&nbsp;[ B0 (EXIT) ]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Predecessors (1): B1<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Successors (0):
-</code>
-
-<p>For each block, the pretty-printed output displays for each block
-the number of <i>predecessor</i> blocks (blocks that have outgoing
-control-flow to the given block) and <i>successor</i> blocks (blocks
-that have control-flow that have incoming control-flow from the given
-block). We can also clearly see the special entry and exit blocks at
-the beginning and end of the pretty-printed output. For the entry
-block (block B5), the number of predecessor blocks is 0, while for the
-exit block (block B0) the number of successor blocks is 0.</p>
-
-<p>The most interesting block here is B4, whose outgoing control-flow
-represents the branching caused by the sole if-statement
-in <tt>foo</tt>. Of particular interest is the second statement in
-the block, <b><tt>(x > 2)</tt></b>, and the terminator, printed
-as <b><tt>if [B4.2]</tt></b>. The second statement represents the
-evaluation of the condition of the if-statement, which occurs before
-the actual branching of control-flow. Within the <tt>CFGBlock</tt>
-for B4, the <tt>Stmt*</tt> for the second statement refers to the
-actual expression in the AST for <b><tt>(x > 2)</tt></b>. Thus
-pointers to subclasses of <tt>Expr</tt> can appear in the list of
-statements in a block, and not just subclasses of <tt>Stmt</tt> that
-refer to proper C statements.</p>
-
-<p>The terminator of block B4 is a pointer to the <tt>IfStmt</tt>
-object in the AST. The pretty-printer outputs <b><tt>if
-[B4.2]</tt></b> because the condition expression of the if-statement
-has an actual place in the basic block, and thus the terminator is
-essentially
-<i>referring</i> to the expression that is the second statement of
-block B4 (i.e., B4.2). In this manner, conditions for control-flow
-(which also includes conditions for loops and switch statements) are
-hoisted into the actual basic block.</p>
-
-<!--
-<h4>Implicit Control-Flow</h4>
--->
-
-<!--
-<p>A key design principle of the <tt>CFG</tt> class was to not require
-any transformations to the AST in order to represent control-flow.
-Thus the <tt>CFG</tt> does not perform any "lowering" of the
-statements in an AST: loops are not transformed into guarded gotos,
-short-circuit operations are not converted to a set of if-statements,
-and so on.</p>
--->
-
-</div>
-</body>
-</html> \ No newline at end of file
diff --git a/clang/docs/Makefile b/clang/docs/Makefile
deleted file mode 100644
index f4a0df7a0c95..000000000000
--- a/clang/docs/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-##===- docs/Makefile ---------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-DIRS :=
-
-ifdef BUILD_FOR_WEBSITE
-PROJ_OBJ_DIR = .
-DOXYGEN = doxygen
-
-$(PROJ_OBJ_DIR)/doxygen.cfg: doxygen.cfg.in
- cat $< | sed \
- -e 's/@abs_top_srcdir@/../g' \
- -e 's/@DOT@/dot/g' \
- -e 's/@PACKAGE_VERSION@/mainline/' \
- -e 's/@abs_top_builddir@/../g' > $@
-endif
-
-include $(LEVEL)/Makefile.common
-
-HTML := $(wildcard $(PROJ_SRC_DIR)/*.html) \
- $(wildcard $(PROJ_SRC_DIR)/*.css)
-#IMAGES := $(wildcard $(PROJ_SRC_DIR)/img/*.*)
-DOXYFILES := doxygen.cfg.in doxygen.css doxygen.footer doxygen.header \
- doxygen.intro
-EXTRA_DIST := $(HTML) $(DOXYFILES) llvm.css CommandGuide img
-
-.PHONY: install-html install-doxygen doxygen generated
-
-install_targets := install-html
-ifeq ($(ENABLE_DOXYGEN),1)
-install_targets += install-doxygen
-endif
-install-local:: $(install_targets)
-
-# Live documentation is generated for the web site using this target:
-# 'make generated BUILD_FOR_WEBSITE=1'
-generated:: doxygen
-
-install-html: $(PROJ_OBJ_DIR)/html.tar.gz
- $(Echo) Installing HTML documentation
- $(Verb) $(MKDIR) $(PROJ_docsdir)/html
- $(Verb) $(MKDIR) $(PROJ_docsdir)/html/img
- $(Verb) $(DataInstall) $(HTML) $(PROJ_docsdir)/html
-# $(Verb) $(DataInstall) $(IMAGES) $(PROJ_docsdir)/html/img
- $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(PROJ_docsdir)
-
-$(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
- $(Echo) Packaging HTML documentation
- $(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/html.tar
- $(Verb) cd $(PROJ_SRC_DIR) && \
- $(TAR) cf $(PROJ_OBJ_DIR)/html.tar *.html
- $(Verb) $(GZIP) $(PROJ_OBJ_DIR)/html.tar
-
-install-doxygen: doxygen
- $(Echo) Installing doxygen documentation
- $(Verb) $(MKDIR) $(PROJ_docsdir)/html/doxygen
- $(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_docsdir)
- $(Verb) cd $(PROJ_OBJ_DIR)/doxygen && \
- $(FIND) . -type f -exec \
- $(DataInstall) {} $(PROJ_docsdir)/html/doxygen \;
-
-doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz
-
-regendoc:
- $(Echo) Building doxygen documentation
- $(Verb) if test -e $(PROJ_OBJ_DIR)/doxygen ; then \
- $(RM) -rf $(PROJ_OBJ_DIR)/doxygen ; \
- fi
- $(Verb) $(DOXYGEN) $(PROJ_OBJ_DIR)/doxygen.cfg
-
-$(PROJ_OBJ_DIR)/doxygen.tar.gz: $(DOXYFILES) $(PROJ_OBJ_DIR)/doxygen.cfg
- $(Echo) Packaging doxygen documentation
- $(Verb) $(RM) -rf $@ $(PROJ_OBJ_DIR)/doxygen.tar
- $(Verb) $(TAR) cf $(PROJ_OBJ_DIR)/doxygen.tar doxygen
- $(Verb) $(GZIP) $(PROJ_OBJ_DIR)/doxygen.tar
- $(Verb) $(CP) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_OBJ_DIR)/doxygen/html/
-
-userloc: $(LLVM_SRC_ROOT)/docs/userloc.html
-
-$(LLVM_SRC_ROOT)/docs/userloc.html:
- $(Echo) Making User LOC Table
- $(Verb) cd $(LLVM_SRC_ROOT) ; ./utils/userloc.pl -details -recurse \
- -html lib include tools runtime utils examples autoconf test > docs/userloc.html
-
-uninstall-local::
- $(Echo) Uninstalling Documentation
- $(Verb) $(RM) -rf $(PROJ_docsdir)
diff --git a/clang/docs/doxygen.cfg b/clang/docs/doxygen.cfg
deleted file mode 100644
index 40180b2415df..000000000000
--- a/clang/docs/doxygen.cfg
+++ /dev/null
@@ -1,1230 +0,0 @@
-# Doxyfile 1.4.4
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = clang
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = mainline
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = ../docs/doxygen
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH = ../..
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-#SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 2
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
-# only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is YES.
-
-SHOW_DIRECTORIES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the progam writes to standard output
-# is used as the file version. See the manual for examples.
-
-#FILE_VERSION_FILTER =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = NO
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = NO
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-#WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT =
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = ../include \
- ../lib \
- ../docs/doxygen.intro
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH = ../examples
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = YES
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH = ../docs/img
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-#USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 4
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX = llvm::
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER = ../docs/doxygen.header
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER = ../docs/doxygen.footer
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET = ../docs/doxygen.css
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT =
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = letter
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT =
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT =
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION =
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH = ../include
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = YES
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = NO
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = YES
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-#GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-#DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH = dot
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that a graph may be further truncated if the graph's
-# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
-# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
-# the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-#DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-#DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
diff --git a/clang/docs/doxygen.cfg.in b/clang/docs/doxygen.cfg.in
deleted file mode 100644
index c1130fba4eee..000000000000
--- a/clang/docs/doxygen.cfg.in
+++ /dev/null
@@ -1,1230 +0,0 @@
-# Doxyfile 1.4.4
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = clang
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = @PACKAGE_VERSION@
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = @abs_top_builddir@/docs/doxygen
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH = ../..
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-#SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 2
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
-# only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is YES.
-
-SHOW_DIRECTORIES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the progam writes to standard output
-# is used as the file version. See the manual for examples.
-
-#FILE_VERSION_FILTER =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = NO
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = NO
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-#WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT =
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = @abs_top_srcdir@/include \
- @abs_top_srcdir@/lib \
- @abs_top_srcdir@/docs/doxygen.intro
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH = @abs_top_srcdir@/examples
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = YES
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH = @abs_top_srcdir@/docs/img
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-#USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 4
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX = clang::
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER = @abs_top_srcdir@/docs/doxygen.header
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER = @abs_top_srcdir@/docs/doxygen.footer
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET = @abs_top_srcdir@/docs/doxygen.css
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT =
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = letter
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT =
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT =
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION =
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH = ../include
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = YES
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = NO
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = YES
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-#GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-#DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH = @DOT@
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that a graph may be further truncated if the graph's
-# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
-# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
-# the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-#DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-#DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
diff --git a/clang/docs/doxygen.css b/clang/docs/doxygen.css
deleted file mode 100644
index f105e202761f..000000000000
--- a/clang/docs/doxygen.css
+++ /dev/null
@@ -1,378 +0,0 @@
-BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
- font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
-}
-BODY,TD {
- font-size: 90%;
-}
-H1 {
- text-align: center;
- font-size: 140%;
- font-weight: bold;
-}
-H2 {
- font-size: 120%;
- font-style: italic;
-}
-H3 {
- font-size: 100%;
-}
-CAPTION { font-weight: bold }
-DIV.qindex {
- width: 100%;
- background-color: #eeeeff;
- border: 1px solid #b0b0b0;
- text-align: center;
- margin: 2px;
- padding: 2px;
- line-height: 140%;
-}
-DIV.nav {
- width: 100%;
- background-color: #eeeeff;
- border: 1px solid #b0b0b0;
- text-align: center;
- margin: 2px;
- padding: 2px;
- line-height: 140%;
-}
-DIV.navtab {
- background-color: #eeeeff;
- border: 1px solid #b0b0b0;
- text-align: center;
- margin: 2px;
- margin-right: 15px;
- padding: 2px;
-}
-TD.navtab {
- font-size: 70%;
-}
-A.qindex {
- text-decoration: none;
- font-weight: bold;
- color: #1A419D;
-}
-A.qindex:visited {
- text-decoration: none;
- font-weight: bold;
- color: #1A419D
-}
-A.qindex:hover {
- text-decoration: none;
- background-color: #ddddff;
-}
-A.qindexHL {
- text-decoration: none;
- font-weight: bold;
- background-color: #6666cc;
- color: #ffffff;
- border: 1px double #9295C2;
-}
-A.qindexHL:hover {
- text-decoration: none;
- background-color: #6666cc;
- color: #ffffff;
-}
-A.qindexHL:visited {
- text-decoration: none; background-color: #6666cc; color: #ffffff }
-A.el { text-decoration: none; font-weight: bold }
-A.elRef { font-weight: bold }
-A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
-A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
-A.codeRef:link { font-weight: normal; color: #0000FF}
-A.codeRef:visited { font-weight: normal; color: #0000FF}
-A:hover { text-decoration: none; background-color: #f2f2ff }
-DL.el { margin-left: -1cm }
-.fragment {
- font-family: Fixed, monospace;
- font-size: 95%;
-}
-PRE.fragment {
- border: 1px solid #CCCCCC;
- background-color: #f5f5f5;
- margin-top: 4px;
- margin-bottom: 4px;
- margin-left: 2px;
- margin-right: 8px;
- padding-left: 6px;
- padding-right: 6px;
- padding-top: 4px;
- padding-bottom: 4px;
-}
-DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
-TD.md { background-color: #F4F4FB; font-weight: bold; }
-TD.mdPrefix {
- background-color: #F4F4FB;
- color: #606060;
- font-size: 80%;
-}
-TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
-TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
-DIV.groupHeader {
- margin-left: 16px;
- margin-top: 12px;
- margin-bottom: 6px;
- font-weight: bold;
-}
-DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
-BODY {
- background: white;
- color: black;
- margin-right: 20px;
- margin-left: 20px;
-}
-TD.indexkey {
- background-color: #eeeeff;
- font-weight: bold;
- padding-right : 10px;
- padding-top : 2px;
- padding-left : 10px;
- padding-bottom : 2px;
- margin-left : 0px;
- margin-right : 0px;
- margin-top : 2px;
- margin-bottom : 2px;
- border: 1px solid #CCCCCC;
-}
-TD.indexvalue {
- background-color: #eeeeff;
- font-style: italic;
- padding-right : 10px;
- padding-top : 2px;
- padding-left : 10px;
- padding-bottom : 2px;
- margin-left : 0px;
- margin-right : 0px;
- margin-top : 2px;
- margin-bottom : 2px;
- border: 1px solid #CCCCCC;
-}
-TR.memlist {
- background-color: #f0f0f0;
-}
-P.formulaDsp { text-align: center; }
-IMG.formulaDsp { }
-IMG.formulaInl { vertical-align: middle; }
-SPAN.keyword { color: #008000 }
-SPAN.keywordtype { color: #604020 }
-SPAN.keywordflow { color: #e08000 }
-SPAN.comment { color: #800000 }
-SPAN.preprocessor { color: #806020 }
-SPAN.stringliteral { color: #002080 }
-SPAN.charliteral { color: #008080 }
-.mdTable {
- border: 1px solid #868686;
- background-color: #F4F4FB;
-}
-.mdRow {
- padding: 8px 10px;
-}
-.mdescLeft {
- padding: 0px 8px 4px 8px;
- font-size: 80%;
- font-style: italic;
- background-color: #FAFAFA;
- border-top: 1px none #E0E0E0;
- border-right: 1px none #E0E0E0;
- border-bottom: 1px none #E0E0E0;
- border-left: 1px none #E0E0E0;
- margin: 0px;
-}
-.mdescRight {
- padding: 0px 8px 4px 8px;
- font-size: 80%;
- font-style: italic;
- background-color: #FAFAFA;
- border-top: 1px none #E0E0E0;
- border-right: 1px none #E0E0E0;
- border-bottom: 1px none #E0E0E0;
- border-left: 1px none #E0E0E0;
- margin: 0px;
-}
-.memItemLeft {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
-}
-.memItemRight {
- padding: 1px 8px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
-}
-.memTemplItemLeft {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: none;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
-}
-.memTemplItemRight {
- padding: 1px 8px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: none;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
-}
-.memTemplParams {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- color: #606060;
- background-color: #FAFAFA;
- font-size: 80%;
-}
-.search { color: #003399;
- font-weight: bold;
-}
-FORM.search {
- margin-bottom: 0px;
- margin-top: 0px;
-}
-INPUT.search { font-size: 75%;
- color: #000080;
- font-weight: normal;
- background-color: #eeeeff;
-}
-TD.tiny { font-size: 75%;
-}
-a {
- color: #252E78;
-}
-a:visited {
- color: #3D2185;
-}
-.dirtab { padding: 4px;
- border-collapse: collapse;
- border: 1px solid #b0b0b0;
-}
-TH.dirtab { background: #eeeeff;
- font-weight: bold;
-}
-HR { height: 1px;
- border: none;
- border-top: 1px solid black;
-}
-
-/*
- * LLVM Modifications.
- * Note: Everything above here is generated with "doxygen -w htlm" command. See
- * "doxygen --help" for details. What follows are CSS overrides for LLVM
- * specific formatting. We want to keep the above so it can be replaced with
- * subsequent doxygen upgrades.
- */
-
-.footer {
- font-size: 80%;
- font-weight: bold;
- text-align: center;
- vertical-align: middle;
-}
-.title {
- font-size: 25pt;
- color: black; background: url("http://llvm.org/img/lines.gif");
- font-weight: bold;
- border-width: 1px;
- border-style: solid none solid none;
- text-align: center;
- vertical-align: middle;
- padding-left: 8pt;
- padding-top: 1px;
- padding-bottom: 2px
-}
-A:link {
- cursor: pointer;
- text-decoration: none;
- font-weight: bolder;
-}
-A:visited {
- cursor: pointer;
- text-decoration: underline;
- font-weight: bolder;
-}
-A:hover {
- cursor: pointer;
- text-decoration: underline;
- font-weight: bolder;
-}
-A:active {
- cursor: pointer;
- text-decoration: underline;
- font-weight: bolder;
- font-style: italic;
-}
-H1 {
- text-align: center;
- font-size: 140%;
- font-weight: bold;
-}
-H2 {
- font-size: 120%;
- font-style: italic;
-}
-H3 {
- font-size: 100%;
-}
-A.qindex {}
-A.qindexRef {}
-A.el { text-decoration: none; font-weight: bold }
-A.elRef { font-weight: bold }
-A.code { text-decoration: none; font-weight: normal; color: #4444ee }
-A.codeRef { font-weight: normal; color: #4444ee }
diff --git a/clang/docs/doxygen.footer b/clang/docs/doxygen.footer
deleted file mode 100644
index 524e9a2bb8b9..000000000000
--- a/clang/docs/doxygen.footer
+++ /dev/null
@@ -1,10 +0,0 @@
-<hr>
-<p class="footer">
-Generated on $datetime by <a href="http://www.doxygen.org">Doxygen
-$doxygenversion</a>.</p>
-
-<p class="footer">
-See the <a href="http://clang.llvm.org">Main Clang Web Page</a> for more
-information.</p>
-</body>
-</html>
diff --git a/clang/docs/doxygen.header b/clang/docs/doxygen.header
deleted file mode 100644
index bea51371ed27..000000000000
--- a/clang/docs/doxygen.header
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head>
-<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
-<meta name="keywords" content="clang,LLVM,Low Level Virtual Machine,C,C++,doxygen,API,frontend,documentation"/>
-<meta name="description" content="C++ source code API documentation for clang."/>
-<title>clang: $title</title>
-<link href="doxygen.css" rel="stylesheet" type="text/css"/>
-</head><body>
-<p class="title">clang API Documentation</p>
diff --git a/clang/docs/doxygen.intro b/clang/docs/doxygen.intro
deleted file mode 100644
index accab72bd085..000000000000
--- a/clang/docs/doxygen.intro
+++ /dev/null
@@ -1,15 +0,0 @@
-/// @mainpage clang
-///
-/// @section main_intro Introduction
-/// Welcome to the clang project.
-///
-/// This documentation describes the @b internal software that makes
-/// up clang, not the @b external use of clang. There are no instructions
-/// here on how to use clang, only the APIs that make up the software. For
-/// usage instructions, please see the programmer's guide or reference
-/// manual.
-///
-/// @section main_caveat Caveat
-/// This documentation is generated directly from the source code with doxygen.
-/// Since clang is constantly under active development, what you're about to
-/// read is out of date!
diff --git a/clang/docs/index.html b/clang/docs/index.html
deleted file mode 100644
index d741b68a4160..000000000000
--- a/clang/docs/index.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<title>'clang' C frontend documentation</title>
-
-None yet, sorry :(
-
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
deleted file mode 100644
index 2360473c556c..000000000000
--- a/clang/include/clang/AST/APValue.h
+++ /dev/null
@@ -1,246 +0,0 @@
-//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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 APValue class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_APVALUE_H
-#define LLVM_CLANG_AST_APVALUE_H
-
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/APFloat.h"
-
-namespace clang {
- class Expr;
-
-/// APValue - This class implements a discriminated union of [uninitialized]
-/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset].
-class APValue {
- typedef llvm::APSInt APSInt;
- typedef llvm::APFloat APFloat;
-public:
- enum ValueKind {
- Uninitialized,
- Int,
- Float,
- ComplexInt,
- ComplexFloat,
- LValue
- };
-private:
- ValueKind Kind;
-
- struct ComplexAPSInt {
- APSInt Real, Imag;
- ComplexAPSInt() : Real(1), Imag(1) {}
- };
- struct ComplexAPFloat {
- APFloat Real, Imag;
- ComplexAPFloat() : Real(0.0), Imag(0.0) {}
- };
-
- struct LV {
- Expr* Base;
- uint64_t Offset;
- };
-
- enum {
- MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
- sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
- };
-
- /// Data - space for the largest member in units of void*. This is an effort
- /// to ensure that the APSInt/APFloat values have proper alignment.
- void *Data[(MaxSize+sizeof(void*)-1)/sizeof(void*)];
-
-public:
- APValue() : Kind(Uninitialized) {}
- explicit APValue(const APSInt &I) : Kind(Uninitialized) {
- MakeInt(); setInt(I);
- }
- explicit APValue(const APFloat &F) : Kind(Uninitialized) {
- MakeFloat(); setFloat(F);
- }
- APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
- MakeComplexInt(); setComplexInt(R, I);
- }
- APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
- MakeComplexFloat(); setComplexFloat(R, I);
- }
- APValue(const APValue &RHS) : Kind(Uninitialized) {
- *this = RHS;
- }
- APValue(Expr* B, uint64_t O) : Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O);
- }
- ~APValue() {
- MakeUninit();
- }
-
- ValueKind getKind() const { return Kind; }
- bool isUninit() const { return Kind == Uninitialized; }
- bool isInt() const { return Kind == Int; }
- bool isFloat() const { return Kind == Float; }
- bool isComplexInt() const { return Kind == ComplexInt; }
- bool isComplexFloat() const { return Kind == ComplexFloat; }
- bool isLValue() const { return Kind == LValue; }
-
- APSInt &getInt() {
- assert(isInt() && "Invalid accessor");
- return *(APSInt*)(void*)Data;
- }
- const APSInt &getInt() const {
- return const_cast<APValue*>(this)->getInt();
- }
-
- APFloat &getFloat() {
- assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(void*)Data;
- }
- const APFloat &getFloat() const {
- return const_cast<APValue*>(this)->getFloat();
- }
-
- APSInt &getComplexIntReal() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(void*)Data)->Real;
- }
- const APSInt &getComplexIntReal() const {
- return const_cast<APValue*>(this)->getComplexIntReal();
- }
-
- APSInt &getComplexIntImag() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(void*)Data)->Imag;
- }
- const APSInt &getComplexIntImag() const {
- return const_cast<APValue*>(this)->getComplexIntImag();
- }
-
- APFloat &getComplexFloatReal() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(void*)Data)->Real;
- }
- const APFloat &getComplexFloatReal() const {
- return const_cast<APValue*>(this)->getComplexFloatReal();
- }
-
- APFloat &getComplexFloatImag() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(void*)Data)->Imag;
- }
- const APFloat &getComplexFloatImag() const {
- return const_cast<APValue*>(this)->getComplexFloatImag();
- }
-
- Expr* getLValueBase() const {
- assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data)->Base;
- }
- uint64_t getLValueOffset() const {
- assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data)->Offset;
- }
-
- void setInt(const APSInt &I) {
- assert(isInt() && "Invalid accessor");
- *(APSInt*)(void*)Data = I;
- }
- void setFloat(const APFloat &F) {
- assert(isFloat() && "Invalid accessor");
- *(APFloat*)(void*)Data = F;
- }
- void setComplexInt(const APSInt &R, const APSInt &I) {
- assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt*)(void*)Data)->Real = R;
- ((ComplexAPSInt*)(void*)Data)->Imag = I;
- }
- void setComplexFloat(const APFloat &R, const APFloat &I) {
- assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat*)(void*)Data)->Real = R;
- ((ComplexAPFloat*)(void*)Data)->Imag = I;
- }
- void setLValue(Expr *B, uint64_t O) {
- assert(isLValue() && "Invalid accessor");
- ((LV*)(void*)Data)->Base = B;
- ((LV*)(void*)Data)->Offset = O;
- }
-
- const APValue &operator=(const APValue &RHS) {
- if (Kind != RHS.Kind) {
- MakeUninit();
- if (RHS.isInt())
- MakeInt();
- else if (RHS.isFloat())
- MakeFloat();
- else if (RHS.isComplexInt())
- MakeComplexInt();
- else if (RHS.isComplexFloat())
- MakeComplexFloat();
- else if (RHS.isLValue())
- MakeLValue();
- }
- if (isInt())
- setInt(RHS.getInt());
- else if (isFloat())
- setFloat(RHS.getFloat());
- else if (isComplexInt())
- setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
- else if (isComplexFloat())
- setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
- else if (isLValue())
- setLValue(RHS.getLValueBase(), RHS.getLValueOffset());
- return *this;
- }
-
-private:
- void MakeUninit() {
- if (Kind == Int)
- ((APSInt*)(void*)Data)->~APSInt();
- else if (Kind == Float)
- ((APFloat*)(void*)Data)->~APFloat();
- else if (Kind == ComplexInt)
- ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt();
- else if (Kind == ComplexFloat)
- ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat();
- else if (Kind == LValue) {
- ((LV*)(void*)Data)->~LV();
- }
- }
- void MakeInt() {
- assert(isUninit() && "Bad state change");
- new ((void*)Data) APSInt(1);
- Kind = Int;
- }
- void MakeFloat() {
- assert(isUninit() && "Bad state change");
- new ((APFloat*)(void*)Data) APFloat(0.0);
- Kind = Float;
- }
- void MakeComplexInt() {
- assert(isUninit() && "Bad state change");
- new ((ComplexAPSInt*)(void*)Data) ComplexAPSInt();
- Kind = ComplexInt;
- }
- void MakeComplexFloat() {
- assert(isUninit() && "Bad state change");
- new ((ComplexAPFloat*)(void*)Data) ComplexAPFloat();
- Kind = ComplexFloat;
- }
- void MakeLValue() {
- assert(isUninit() && "Bad state change");
- new ((LV*)(void*)Data) LV();
- Kind = LValue;
- }
-};
-
-}
-
-#endif
diff --git a/clang/include/clang/AST/AST.h b/clang/include/clang/AST/AST.h
deleted file mode 100644
index 96e887cfc0d7..000000000000
--- a/clang/include/clang/AST/AST.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//===--- AST.h - "Umbrella" header for AST library --------------*- 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 interface to the AST classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_AST_H
-#define LLVM_CLANG_AST_AST_H
-
-// This header exports all AST interfaces.
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/StmtVisitor.h"
-
-#endif
diff --git a/clang/include/clang/AST/ASTConsumer.h b/clang/include/clang/AST/ASTConsumer.h
deleted file mode 100644
index 2ba36b0a5751..000000000000
--- a/clang/include/clang/AST/ASTConsumer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- 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 ASTConsumer class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
-#define LLVM_CLANG_AST_ASTCONSUMER_H
-
-namespace clang {
- class ASTContext;
- class TranslationUnit;
- class Decl;
- class TagDecl;
- class HandleTagDeclDefinition;
-
-/// ASTConsumer - This is an abstract interface that should be implemented by
-/// clients that read ASTs. This abstraction layer allows the client to be
-/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
-class ASTConsumer {
-public:
- virtual ~ASTConsumer();
-
- /// Initialize - This is called to initialize the consumer, providing the
- /// ASTContext.
- virtual void Initialize(ASTContext &Context) {}
-
- virtual void InitializeTU(TranslationUnit& TU);
-
- /// HandleTopLevelDecl - Handle the specified top-level declaration. This is
- /// called by the parser to process every top-level Decl*. Note that D can
- /// be the head of a chain of Decls (e.g. for `int a, b` the chain will have
- /// two elements). Use ScopedDecl::getNextDeclarator() to walk the chain.
- virtual void HandleTopLevelDecl(Decl *D) {}
-
- /// HandleTranslationUnit - This method is called when the ASTs for entire
- /// translation unit have been parsed.
- virtual void HandleTranslationUnit(TranslationUnit& TU) {}
-
- /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
- /// (e.g. struct, union, enum, class) is completed. This allows the client to
- /// hack on the type, which can occur at any point in the file (because these
- /// can be defined in declspecs).
- virtual void HandleTagDeclDefinition(TagDecl *D) {}
-
- /// PrintStats - If desired, print any statistics.
- virtual void PrintStats() {
- }
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
deleted file mode 100644
index 7f0a75742899..000000000000
--- a/clang/include/clang/AST/ASTContext.h
+++ /dev/null
@@ -1,480 +0,0 @@
-//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- 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 ASTContext interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
-#define LLVM_CLANG_AST_ASTCONTEXT_H
-
-#include "clang/Basic/LangOptions.h"
-#include "clang/AST/Builtins.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include "llvm/Support/Allocator.h"
-#include <vector>
-
-namespace llvm {
- struct fltSemantics;
-}
-
-namespace clang {
- class ASTRecordLayout;
- class Expr;
- class IdentifierTable;
- class TargetInfo;
- class SelectorTable;
- class SourceManager;
- // Decls
- class Decl;
- class ObjCPropertyDecl;
- class RecordDecl;
- class TagDecl;
- class TranslationUnitDecl;
- class TypeDecl;
- class TypedefDecl;
-
-/// ASTContext - This class holds long-lived AST nodes (such as types and
-/// decls) that can be referred to throughout the semantic analysis of a file.
-class ASTContext {
- std::vector<Type*> Types;
- llvm::FoldingSet<ASQualType> ASQualTypes;
- llvm::FoldingSet<ComplexType> ComplexTypes;
- llvm::FoldingSet<PointerType> PointerTypes;
- llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
- llvm::FoldingSet<ReferenceType> ReferenceTypes;
- llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
- llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
- std::vector<VariableArrayType*> VariableArrayTypes;
- llvm::FoldingSet<VectorType> VectorTypes;
- llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
- llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
- llvm::FoldingSet<ObjCQualifiedInterfaceType> ObjCQualifiedInterfaceTypes;
- llvm::FoldingSet<ObjCQualifiedIdType> ObjCQualifiedIdTypes;
- /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.
- /// This is lazily created. This is intentionally not serialized.
- llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts;
- llvm::DenseMap<const ObjCInterfaceDecl*,
- const ASTRecordLayout*> ASTObjCInterfaces;
-
- llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
-
- /// BuiltinVaListType - built-in va list type.
- /// This is initially null and set by Sema::LazilyCreateBuiltin when
- /// a builtin that takes a valist is encountered.
- QualType BuiltinVaListType;
-
- /// ObjCIdType - a pseudo built-in typedef type (set by Sema).
- QualType ObjCIdType;
- const RecordType *IdStructType;
-
- /// ObjCSelType - another pseudo built-in typedef type (set by Sema).
- QualType ObjCSelType;
- const RecordType *SelStructType;
-
- /// ObjCProtoType - another pseudo built-in typedef type (set by Sema).
- QualType ObjCProtoType;
- const RecordType *ProtoStructType;
-
- /// ObjCClassType - another pseudo built-in typedef type (set by Sema).
- QualType ObjCClassType;
- const RecordType *ClassStructType;
-
- QualType ObjCConstantStringType;
- RecordDecl *CFConstantStringTypeDecl;
-
- RecordDecl *ObjCFastEnumerationStateTypeDecl;
-
- TranslationUnitDecl *TUDecl;
-
- /// SourceMgr - The associated SourceManager object.
- SourceManager &SourceMgr;
-
- /// LangOpts - The language options used to create the AST associated with
- /// this ASTContext object.
- LangOptions LangOpts;
-
- /// Allocator - The allocator object used to create AST objects.
- llvm::MallocAllocator Allocator;
-
-public:
- TargetInfo &Target;
- IdentifierTable &Idents;
- SelectorTable &Selectors;
-
- SourceManager& getSourceManager() { return SourceMgr; }
- llvm::MallocAllocator &getAllocator() { return Allocator; }
- const LangOptions& getLangOptions() const { return LangOpts; }
-
- FullSourceLoc getFullLoc(SourceLocation Loc) const {
- return FullSourceLoc(Loc,SourceMgr);
- }
-
- TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
-
- /// This is intentionally not serialized. It is populated by the
- /// ASTContext ctor, and there are no external pointers/references to
- /// internal variables of BuiltinInfo.
- Builtin::Context BuiltinInfo;
-
- // Builtin Types.
- QualType VoidTy;
- QualType BoolTy;
- QualType CharTy;
- QualType WCharTy; // [C++ 3.9.1p5]
- QualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy;
- QualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
- QualType UnsignedLongLongTy;
- QualType FloatTy, DoubleTy, LongDoubleTy;
- QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- QualType VoidPtrTy;
-
- ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
- IdentifierTable &idents, SelectorTable &sels,
- unsigned size_reserve=0);
-
- ~ASTContext();
-
- void PrintStats() const;
- const std::vector<Type*>& getTypes() const { return Types; }
-
- //===--------------------------------------------------------------------===//
- // Type Constructors
- //===--------------------------------------------------------------------===//
-
- /// getASQualType - Return the uniqued reference to the type for an address
- /// space qualified type with the specified type and address space. The
- /// resulting type has a union of the qualifiers from T and the address space.
- // If T already has an address space specifier, it is silently replaced.
- QualType getASQualType(QualType T, unsigned AddressSpace);
-
- /// getComplexType - Return the uniqued reference to the type for a complex
- /// number with the specified element type.
- QualType getComplexType(QualType T);
-
- /// getPointerType - Return the uniqued reference to the type for a pointer to
- /// the specified type.
- QualType getPointerType(QualType T);
-
- /// getBlockPointerType - Return the uniqued reference to the type for a block
- /// of the specified type.
- QualType getBlockPointerType(QualType T);
-
- /// getReferenceType - Return the uniqued reference to the type for a
- /// reference to the specified type.
- QualType getReferenceType(QualType T);
-
- /// getVariableArrayType - Returns a non-unique reference to the type for a
- /// variable array of the specified element type.
- QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals);
-
- /// getIncompleteArrayType - Returns a unique reference to the type for a
- /// incomplete array of the specified element type.
- QualType getIncompleteArrayType(QualType EltTy,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals);
-
- /// getConstantArrayType - Return the unique reference to the type for a
- /// constant array of the specified element type.
- QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals);
-
- /// getVectorType - Return the unique reference to a vector type of
- /// the specified element type and size. VectorType must be a built-in type.
- QualType getVectorType(QualType VectorType, unsigned NumElts);
-
- /// getExtVectorType - Return the unique reference to an extended vector type
- /// of the specified element type and size. VectorType must be a built-in
- /// type.
- QualType getExtVectorType(QualType VectorType, unsigned NumElts);
-
- /// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
- ///
- QualType getFunctionTypeNoProto(QualType ResultTy);
-
- /// getFunctionType - Return a normal function type with a typed argument
- /// list. isVariadic indicates whether the argument list includes '...'.
- QualType getFunctionType(QualType ResultTy, const QualType *ArgArray,
- unsigned NumArgs, bool isVariadic);
-
- /// getTypeDeclType - Return the unique reference to the type for
- /// the specified type declaration.
- QualType getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl=0);
-
- /// getTypedefType - Return the unique reference to the type for the
- /// specified typename decl.
- QualType getTypedefType(TypedefDecl *Decl);
- QualType getObjCInterfaceType(ObjCInterfaceDecl *Decl);
-
- /// getObjCQualifiedInterfaceType - Return a
- /// ObjCQualifiedInterfaceType type for the given interface decl and
- /// the conforming protocol list.
- QualType getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **ProtocolList, unsigned NumProtocols);
-
- /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for a
- /// given 'id' and conforming protocol list.
- QualType getObjCQualifiedIdType(ObjCProtocolDecl **ProtocolList,
- unsigned NumProtocols);
-
-
- /// getTypeOfType - GCC extension.
- QualType getTypeOfExpr(Expr *e);
- QualType getTypeOfType(QualType t);
-
- /// getTagDeclType - Return the unique reference to the type for the
- /// specified TagDecl (struct/union/class/enum) decl.
- QualType getTagDeclType(TagDecl *Decl);
-
- /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined
- /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
- QualType getSizeType() const;
-
- /// getWCharType - Return the unique type for "wchar_t" (C99 7.17), defined
- /// in <stddef.h>. Wide strings require this (C99 6.4.5p5).
- QualType getWCharType() const;
-
- /// getSignedWCharType - Return the type of "signed wchar_t".
- /// Used when in C++, as a GCC extension.
- QualType getSignedWCharType() const;
-
- /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
- /// Used when in C++, as a GCC extension.
- QualType getUnsignedWCharType() const;
-
- /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
- /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
- QualType getPointerDiffType() const;
-
- // getCFConstantStringType - Return the C structure type used to represent
- // constant CFStrings.
- QualType getCFConstantStringType();
-
- // This setter/getter represents the ObjC type for an NSConstantString.
- void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
- QualType getObjCConstantStringInterface() const {
- return ObjCConstantStringType;
- }
-
- //// This gets the struct used to keep track of fast enumerations.
- QualType getObjCFastEnumerationStateType();
-
- // Return the ObjC type encoding for a given type.
- void getObjCEncodingForType(QualType t, std::string &S,
- llvm::SmallVector<const RecordType*,8> &RT) const;
-
- // Put the string version of type qualifiers into S.
- void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
- std::string &S) const;
-
- /// getObjCEncodingForMethodDecl - Return the encoded type for this method
- /// declaration.
- void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, 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
- /// only be NULL when getting encodings for protocol properties.
- void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
- const Decl *Container,
- std::string &S);
-
- /// getObjCEncodingTypeSize returns size of type for objective-c encoding
- /// purpose.
- int getObjCEncodingTypeSize(QualType t);
-
- /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
- /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct.
- QualType getObjCIdType() const { return ObjCIdType; }
- void setObjCIdType(TypedefDecl *Decl);
-
- void setObjCSelType(TypedefDecl *Decl);
- QualType getObjCSelType() const { return ObjCSelType; }
-
- void setObjCProtoType(QualType QT);
- QualType getObjCProtoType() const { return ObjCProtoType; }
-
- /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by
- /// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a
- /// struct.
- QualType getObjCClassType() const { return ObjCClassType; }
- void setObjCClassType(TypedefDecl *Decl);
-
- void setBuiltinVaListType(QualType T);
- QualType getBuiltinVaListType() const { return BuiltinVaListType; }
-
- //===--------------------------------------------------------------------===//
- // Type Predicates.
- //===--------------------------------------------------------------------===//
-
- /// isObjCObjectPointerType - Returns true if type is an Objective-C pointer
- /// to an object type. This includes "id" and "Class" (two 'special' pointers
- /// to struct), Interface* (pointer to ObjCInterfaceType) and id<P> (qualified
- /// ID type).
- bool isObjCObjectPointerType(QualType Ty) const;
-
- //===--------------------------------------------------------------------===//
- // Type Sizing and Analysis
- //===--------------------------------------------------------------------===//
-
- /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
- /// scalar floating point type.
- const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
-
- /// getTypeInfo - Get the size and alignment of the specified complete type in
- /// bits.
- std::pair<uint64_t, unsigned> getTypeInfo(QualType T);
-
- /// getTypeSize - Return the size of the specified type, in bits. This method
- /// does not work on incomplete types.
- uint64_t getTypeSize(QualType T) {
- return getTypeInfo(T).first;
- }
-
- /// getTypeAlign - Return the alignment of the specified type, in bits. This
- /// method does not work on incomplete types.
- unsigned getTypeAlign(QualType T) {
- return getTypeInfo(T).second;
- }
-
- /// getASTRecordLayout - Get or compute information about the layout of the
- /// specified record (struct/union/class), which indicates its size and field
- /// position information.
- const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D);
-
- const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
- //===--------------------------------------------------------------------===//
- // Type Operators
- //===--------------------------------------------------------------------===//
-
- /// getCanonicalType - Return the canonical (structural) type corresponding to
- /// the specified potentially non-canonical type. The non-canonical version
- /// of a type may have many "decorated" versions of types. Decorators can
- /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
- /// to be free of any of these, allowing two canonical types to be compared
- /// for exact equality with a simple pointer comparison.
- QualType getCanonicalType(QualType T);
-
- /// Type Query functions. If the type is an instance of the specified class,
- /// return the Type pointer for the underlying maximally pretty type. This
- /// is a member of ASTContext because this may need to do some amount of
- /// canonicalization, e.g. to move type qualifiers into the element type.
- const ArrayType *getAsArrayType(QualType T);
- const ConstantArrayType *getAsConstantArrayType(QualType T) {
- return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
- }
- const VariableArrayType *getAsVariableArrayType(QualType T) {
- return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
- }
- const IncompleteArrayType *getAsIncompleteArrayType(QualType T) {
- return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
- }
-
- /// getArrayDecayedType - Return the properly qualified result of decaying the
- /// specified array type to a pointer. This operation is non-trivial when
- /// handling typedefs etc. The canonical type of "T" must be an array type,
- /// this returns a pointer to a properly qualified element of the array.
- ///
- /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
- QualType getArrayDecayedType(QualType T);
-
- /// getIntegerTypeOrder - Returns the highest ranked integer type:
- /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
- /// LHS < RHS, return -1.
- int getIntegerTypeOrder(QualType LHS, QualType RHS);
-
- /// getFloatingTypeOrder - Compare the rank of the two specified floating
- /// point types, ignoring the domain of the type (i.e. 'double' ==
- /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If
- /// LHS < RHS, return -1.
- int getFloatingTypeOrder(QualType LHS, QualType RHS);
-
- /// getFloatingTypeOfSizeWithinDomain - Returns a real floating
- /// point or a complex type (based on typeDomain/typeSize).
- /// 'typeDomain' is a real floating point or complex type.
- /// 'typeSize' is a real floating point or complex type.
- QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
- QualType typeDomain) const;
-
- //===--------------------------------------------------------------------===//
- // Type Compatibility Predicates
- //===--------------------------------------------------------------------===//
-
- /// Compatibility predicates used to check assignment expressions.
- bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
- bool typesAreBlockCompatible(QualType lhs, QualType rhs);
-
- bool isObjCIdType(QualType T) const {
- if (!IdStructType) // ObjC isn't enabled
- return false;
- return T->getAsStructureType() == IdStructType;
- }
- bool isObjCClassType(QualType T) const {
- if (!ClassStructType) // ObjC isn't enabled
- return false;
- return T->getAsStructureType() == ClassStructType;
- }
- bool isObjCSelType(QualType T) const {
- assert(SelStructType && "isObjCSelType used before 'SEL' type is built");
- return T->getAsStructureType() == SelStructType;
- }
-
- // Check the safety of assignment from LHS to RHS
- bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
- const ObjCInterfaceType *RHS);
-
- // Functions for calculating composite types
- QualType mergeTypes(QualType, QualType);
- QualType mergeFunctionTypes(QualType, QualType);
-
- //===--------------------------------------------------------------------===//
- // Integer Predicates
- //===--------------------------------------------------------------------===//
-
- // The width of an integer, as defined in C99 6.2.6.2. This is the number
- // of bits in an integer type excluding any padding bits.
- unsigned getIntWidth(QualType T);
-
- // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
- // unsigned integer type. This method takes a signed type, and returns the
- // corresponding unsigned integer type.
- QualType getCorrespondingUnsignedType(QualType T);
-
- //===--------------------------------------------------------------------===//
- // Serialization
- //===--------------------------------------------------------------------===//
-
- void Emit(llvm::Serializer& S) const;
- static ASTContext* Create(llvm::Deserializer& D);
-
-private:
- ASTContext(const ASTContext&); // DO NOT IMPLEMENT
- void operator=(const ASTContext&); // DO NOT IMPLEMENT
-
- void InitBuiltinTypes();
- void InitBuiltinType(QualType &R, BuiltinType::Kind K);
-
- /// setRecordDefinition - Used by RecordDecl::defineBody to inform ASTContext
- /// about which RecordDecl serves as the definition of a particular
- /// struct/union/class. This will eventually be used by enums as well.
- void setTagDefinition(TagDecl* R);
- friend class RecordDecl;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
deleted file mode 100644
index c6fb1d16c76a..000000000000
--- a/clang/include/clang/AST/Attr.h
+++ /dev/null
@@ -1,409 +0,0 @@
-//===--- Attr.h - Classes for representing expressions ----------*- 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 Attr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ATTR_H
-#define LLVM_CLANG_AST_ATTR_H
-
-#include <cassert>
-#include <cstring>
-#include <string>
-#include <algorithm>
-
-namespace clang {
-
-/// Attr - This represents one attribute.
-class Attr {
-public:
- enum Kind {
- Alias,
- Aligned,
- Annotate,
- AsmLabel, // Represent GCC asm label extension.
- Constructor,
- Deprecated,
- Destructor,
- DLLImport,
- DLLExport,
- FastCall,
- Format,
- IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
- NonNull,
- NoReturn,
- NoThrow,
- ObjCGC,
- Packed,
- StdCall,
- TransparentUnion,
- Unused,
- Visibility,
- Weak,
- Blocks,
- Const,
- Pure
- };
-
-private:
- Attr *Next;
- Kind AttrKind;
-
-protected:
- Attr(Kind AK) : Next(0), AttrKind(AK) {}
-public:
- virtual ~Attr() {
- delete Next;
- }
-
- Kind getKind() const { return AttrKind; }
-
- Attr *getNext() { return Next; }
- const Attr *getNext() const { return Next; }
- void setNext(Attr *next) { Next = next; }
-
- void addAttr(Attr *attr) {
- assert((attr != 0) && "addAttr(): attr is null");
-
- // FIXME: This doesn't preserve the order in any way.
- attr->Next = Next;
- Next = attr;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *) { return true; }
-};
-
-class PackedAttr : public Attr {
-public:
- PackedAttr() : Attr(Packed) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == Packed;
- }
- static bool classof(const PackedAttr *A) { return true; }
-};
-
-class AlignedAttr : public Attr {
- unsigned Alignment;
-public:
- AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
-
- unsigned getAlignment() const { return Alignment; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == Aligned;
- }
- static bool classof(const AlignedAttr *A) { return true; }
-};
-
-class AnnotateAttr : public Attr {
- std::string Annotation;
-public:
- AnnotateAttr(const std::string &ann) : Attr(Annotate), Annotation(ann) {}
-
- const std::string& getAnnotation() const { return Annotation; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == Annotate;
- }
- static bool classof(const AnnotateAttr *A) { return true; }
-};
-
-class AsmLabelAttr : public Attr {
- std::string Label;
-public:
- AsmLabelAttr(const std::string &L) : Attr(AsmLabel), Label(L) {}
-
- const std::string& getLabel() const { return Label; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == AsmLabel;
- }
- static bool classof(const AsmLabelAttr *A) { return true; }
-};
-
-class AliasAttr : public Attr {
- std::string Aliasee;
-public:
- AliasAttr(const std::string &aliasee) : Attr(Alias), Aliasee(aliasee) {}
-
- const std::string& getAliasee() const { return Aliasee; }
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Alias; }
- static bool classof(const AliasAttr *A) { return true; }
-};
-
-class ConstructorAttr : public Attr {
- int priority;
-public:
- ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
-
- int getPriority() const { return priority; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Constructor; }
- static bool classof(const ConstructorAttr *A) { return true; }
-};
-
-class DestructorAttr : public Attr {
- int priority;
-public:
- DestructorAttr(int p) : Attr(Destructor), priority(p) {}
-
- int getPriority() const { return priority; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Destructor; }
- static bool classof(const DestructorAttr *A) { return true; }
-};
-
-class IBOutletAttr : public Attr {
-public:
- IBOutletAttr() : Attr(IBOutletKind) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == IBOutletKind;
- }
- static bool classof(const IBOutletAttr *A) { return true; }
-};
-
-class NoReturnAttr : public Attr {
-public:
- NoReturnAttr() : Attr(NoReturn) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == NoReturn; }
- static bool classof(const NoReturnAttr *A) { return true; }
-};
-
-class DeprecatedAttr : public Attr {
-public:
- DeprecatedAttr() : Attr(Deprecated) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Deprecated; }
- static bool classof(const DeprecatedAttr *A) { return true; }
-};
-
-class UnusedAttr : public Attr {
-public:
- UnusedAttr() : Attr(Unused) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Unused; }
- static bool classof(const UnusedAttr *A) { return true; }
-};
-
-class WeakAttr : public Attr {
-public:
- WeakAttr() : Attr(Weak) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Weak; }
- static bool classof(const WeakAttr *A) { return true; }
-};
-
-class NoThrowAttr : public Attr {
-public:
- NoThrowAttr() : Attr(NoThrow) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == NoThrow; }
- static bool classof(const NoThrowAttr *A) { return true; }
-};
-
-class ConstAttr : public Attr {
-public:
- ConstAttr() : Attr(Const) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Const; }
- static bool classof(const ConstAttr *A) { return true; }
-};
-
-class PureAttr : public Attr {
-public:
- PureAttr() : Attr(Pure) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Pure; }
- static bool classof(const PureAttr *A) { return true; }
-};
-
-class NonNullAttr : public Attr {
- unsigned* ArgNums;
- unsigned Size;
-public:
- NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
- ArgNums(0), Size(0) {
-
- if (size) {
- assert (arg_nums);
- ArgNums = new unsigned[size];
- Size = size;
- memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
- }
- }
-
- virtual ~NonNullAttr() {
- delete [] ArgNums;
- }
-
- bool isNonNull(unsigned arg) const {
- return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
- }
-
- static bool classof(const Attr *A) { return A->getKind() == NonNull; }
- static bool classof(const NonNullAttr *A) { return true; }
-};
-
-class FormatAttr : public Attr {
- std::string Type;
- int formatIdx, firstArg;
-public:
- FormatAttr(const std::string &type, int idx, int first) : Attr(Format),
- Type(type), formatIdx(idx), firstArg(first) {}
-
- const std::string& getType() const { return Type; }
- int getFormatIdx() const { return formatIdx; }
- int getFirstArg() const { return firstArg; }
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Format; }
- static bool classof(const FormatAttr *A) { return true; }
-};
-
-class VisibilityAttr : public Attr {
-public:
- /// @brief An enumeration for the kinds of visibility of symbols.
- enum VisibilityTypes {
- DefaultVisibility = 0,
- HiddenVisibility,
- ProtectedVisibility
- };
-private:
- VisibilityTypes VisibilityType;
-public:
- VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
- VisibilityType(v) {}
-
- VisibilityTypes getVisibility() const { return VisibilityType; }
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Visibility; }
- static bool classof(const VisibilityAttr *A) { return true; }
-};
-
-class DLLImportAttr : public Attr {
-public:
- DLLImportAttr() : Attr(DLLImport) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == DLLImport; }
- static bool classof(const DLLImportAttr *A) { return true; }
-};
-
-class DLLExportAttr : public Attr {
-public:
- DLLExportAttr() : Attr(DLLExport) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == DLLExport; }
- static bool classof(const DLLExportAttr *A) { return true; }
-};
-
-class FastCallAttr : public Attr {
-public:
- FastCallAttr() : Attr(FastCall) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == FastCall; }
- static bool classof(const FastCallAttr *A) { return true; }
-};
-
-class StdCallAttr : public Attr {
-public:
- StdCallAttr() : Attr(StdCall) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == StdCall; }
- static bool classof(const StdCallAttr *A) { return true; }
-};
-
-class TransparentUnionAttr : public Attr {
-public:
- TransparentUnionAttr() : Attr(TransparentUnion) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == TransparentUnion; }
- static bool classof(const TransparentUnionAttr *A) { return true; }
-};
-
-class ObjCGCAttr : public Attr {
-public:
- enum GCAttrTypes {
- Weak = 0,
- Strong
- };
-private:
- GCAttrTypes GCAttrType;
-public:
- ObjCGCAttr(GCAttrTypes t) : Attr(ObjCGC), GCAttrType(t) {}
-
- GCAttrTypes getType() const { return GCAttrType; }
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == ObjCGC; }
- static bool classof(const ObjCGCAttr *A) { return true; }
-};
-
-class BlocksAttr : public Attr {
-public:
- enum BlocksAttrTypes {
- ByRef = 0
- };
-private:
- BlocksAttrTypes BlocksAttrType;
-public:
- BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
-
- BlocksAttrTypes getType() const { return BlocksAttrType; }
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Blocks; }
- static bool classof(const ObjCGCAttr *A) { return true; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/Builtins.def b/clang/include/clang/AST/Builtins.def
deleted file mode 100644
index d23cc14eb92b..000000000000
--- a/clang/include/clang/AST/Builtins.def
+++ /dev/null
@@ -1,168 +0,0 @@
-//===--- Builtins.def - Builtin function info database ----------*- 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 standard builtin function database. Users of this file
-// must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
-// adding stuff on demand.
-//
-// FIXME: This should really be a .td file, but that requires modifying tblgen.
-// Perhaps tblgen should have plugins.
-
-// The first value provided to the macro specifies the function name of the
-// builtin, and results in a clang::builtin::BIXX enum value for XX.
-
-// The second value provided to the macro specifies the type of the function
-// (result value, then each argument) as follows:
-// v -> void
-// c -> char
-// s -> short
-// i -> int
-// f -> float
-// d -> double
-// z -> size_t
-// F -> constant CFString
-// a -> __builtin_va_list
-// V -> Vector, following num elements and a base type.
-// . -> "...". This may only occur at the end of the function list.
-//
-// Types maybe prefixed with the following modifiers:
-// L -> long (e.g. Li for 'long int')
-// LL -> long long
-// S -> signed
-// U -> unsigned
-//
-// Types may be postfixed with the following modifiers:
-// * -> pointer
-// & -> reference
-// C -> const
-
-// The third value provided to the macro specifies information about attributes
-// of the function. These must be kept in sync with the predicates in the
-// Builtin::Context class. Currently we have:
-// n -> nothrow
-// c -> const
-// F -> this is a libc/libm function with a '__builtin_' prefix added.
-// FIXME: gcc has nonnull
-
-// Standard libc/libm functions:
-BUILTIN(__builtin_huge_val, "d", "nc")
-BUILTIN(__builtin_huge_valf, "f", "nc")
-BUILTIN(__builtin_huge_vall, "Ld", "nc")
-BUILTIN(__builtin_inf , "d" , "nc")
-BUILTIN(__builtin_inff , "f" , "nc")
-BUILTIN(__builtin_infl , "Ld" , "nc")
-BUILTIN(__builtin_nan, "dcC*" , "ncF")
-BUILTIN(__builtin_nanf, "fcC*" , "ncF")
-BUILTIN(__builtin_nanl, "LdcC*", "ncF")
-BUILTIN(__builtin_nans, "dcC*" , "ncF")
-BUILTIN(__builtin_nansf, "fcC*" , "ncF")
-BUILTIN(__builtin_nansl, "LdcC*", "ncF")
-BUILTIN(__builtin_abs , "ii" , "ncF")
-BUILTIN(__builtin_fabs , "dd" , "ncF")
-BUILTIN(__builtin_fabsf, "ff" , "ncF")
-BUILTIN(__builtin_fabsl, "LdLd", "ncF")
-BUILTIN(__builtin_copysign, "ddd", "ncF")
-BUILTIN(__builtin_copysignf, "fff", "ncF")
-BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
-BUILTIN(__builtin_powi , "ddi" , "nc")
-BUILTIN(__builtin_powif, "ffi" , "nc")
-BUILTIN(__builtin_powil, "LdLdi", "nc")
-
-// FP Comparisons.
-BUILTIN(__builtin_isgreater , "i.", "nc")
-BUILTIN(__builtin_isgreaterequal, "i.", "nc")
-BUILTIN(__builtin_isless , "i.", "nc")
-BUILTIN(__builtin_islessequal , "i.", "nc")
-BUILTIN(__builtin_islessgreater , "i.", "nc")
-BUILTIN(__builtin_isunordered , "i.", "nc")
-
-// Builtins for arithmetic.
-BUILTIN(__builtin_clz , "iUi" , "nc")
-BUILTIN(__builtin_clzl , "iULi" , "nc")
-BUILTIN(__builtin_clzll, "iULLi", "nc")
-// TODO: int clzimax(uintmax_t)
-BUILTIN(__builtin_ctz , "iUi" , "nc")
-BUILTIN(__builtin_ctzl , "iULi" , "nc")
-BUILTIN(__builtin_ctzll, "iULLi", "nc")
-// TODO: int ctzimax(uintmax_t)
-BUILTIN(__builtin_ffs , "iUi" , "nc")
-BUILTIN(__builtin_ffsl , "iULi" , "nc")
-BUILTIN(__builtin_ffsll, "iULLi", "nc")
-BUILTIN(__builtin_parity , "iUi" , "nc")
-BUILTIN(__builtin_parityl , "iULi" , "nc")
-BUILTIN(__builtin_parityll, "iULLi", "nc")
-BUILTIN(__builtin_popcount , "iUi" , "nc")
-BUILTIN(__builtin_popcountl , "iULi" , "nc")
-BUILTIN(__builtin_popcountll, "iULLi", "nc")
-
-// FIXME: These type signatures are not correct for targets with int != 32-bits
-// or with ULL != 64-bits.
-BUILTIN(__builtin_bswap32, "UiUi", "nc")
-BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
-
-// Random GCC builtins
-BUILTIN(__builtin_constant_p, "UsUs", "nc")
-BUILTIN(__builtin_classify_type, "i.", "nc")
-BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
-BUILTIN(__builtin_va_start, "va&.", "n")
-BUILTIN(__builtin_va_end, "va&", "n")
-BUILTIN(__builtin_va_copy, "va&a", "n")
-BUILTIN(__builtin_stdarg_start, "va&a", "n")
-BUILTIN(__builtin_bzero, "vv*z", "n")
-BUILTIN(__builtin_memcpy, "v*v*vC*z", "n")
-BUILTIN(__builtin_memmove, "v*v*vC*z", "n")
-BUILTIN(__builtin_memset, "v*v*cz", "n")
-BUILTIN(__builtin_return_address, "v*Ui", "n")
-BUILTIN(__builtin_frame_address, "v*Ui", "n")
-// GCC Object size checking builtins
-BUILTIN(__builtin_object_size, "zv*i", "n")
-BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
-BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
-BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
-BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "F") // FIXME: format printf attribute
-BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "F") // FIXME: format printf attribute
-BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "F") // FIXME: format printf attribute
-BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "F") // FIXME: format printf attribute
-//BUILTIN(__builtin___fprintf_chk, "i(FIXME:FILEPTR)icC*.", "F") // FIXME: format printf attribute
-BUILTIN(__builtin___printf_chk, "iicC*.", "F")
-//BUILTIN(__builtin___vfprintf_chk, "i(FIXME:FILEPTR)icC*a", "F") // FIXME: format printf attribute
-BUILTIN(__builtin___vprintf_chk, "iicC*a", "F") // FIXME: format printf attribute
-
-BUILTIN(__builtin_expect, "iii" , "nc")
-BUILTIN(__builtin_prefetch, "vCv*.", "nc")
-BUILTIN(__builtin_trap, "v", "n")
-
-BUILTIN(__builtin_shufflevector, "v." , "nc")
-
-BUILTIN(__builtin_alloca, "v*z" , "n")
-
-// Atomic operators builtin.
-BUILTIN(__sync_fetch_and_add,"ii*i", "n")
-BUILTIN(__sync_fetch_and_sub,"ii*i", "n")
-BUILTIN(__sync_fetch_and_min,"ii*i", "n")
-BUILTIN(__sync_fetch_and_max,"ii*i", "n")
-BUILTIN(__sync_fetch_and_umin,"UiUi*Ui", "n")
-BUILTIN(__sync_fetch_and_umax,"UiUi*Ui", "n")
-BUILTIN(__sync_fetch_and_and,"ii*i", "n")
-BUILTIN(__sync_fetch_and_or,"ii*i", "n")
-BUILTIN(__sync_fetch_and_xor,"ii*i", "n")
-BUILTIN(__sync_lock_test_and_set,"ii*i", "n")
-BUILTIN(__sync_val_compare_and_swap,"ii*ii", "n")
-
-#undef BUILTIN
diff --git a/clang/include/clang/AST/Builtins.h b/clang/include/clang/AST/Builtins.h
deleted file mode 100644
index 7da9a5f26af0..000000000000
--- a/clang/include/clang/AST/Builtins.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===--- Builtins.h - Builtin function header -------------------*- 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 enum values for all the target-independent builtin
-// functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_BUILTINS_H
-#define LLVM_CLANG_AST_BUILTINS_H
-
-#include <cstring>
-
-namespace clang {
- class TargetInfo;
- class IdentifierTable;
- class ASTContext;
- class QualType;
-
-namespace Builtin {
-enum ID {
- NotBuiltin = 0, // This is not a builtin function.
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/AST/Builtins.def"
- FirstTSBuiltin
-};
-
-struct Info {
- const char *Name, *Type, *Attributes;
-
- bool operator==(const Info &RHS) const {
- return !strcmp(Name, RHS.Name) &&
- !strcmp(Type, RHS.Type) &&
- !strcmp(Attributes, RHS.Attributes);
- }
- bool operator!=(const Info &RHS) const { return !(*this == RHS); }
-};
-
-/// Builtin::Context - This holds information about target-independent and
-/// target-specific builtins, allowing easy queries by clients.
-class Context {
- const Info *TSRecords;
- unsigned NumTSRecords;
-public:
- Context() : TSRecords(0), NumTSRecords(0) {}
-
- /// InitializeBuiltins - Mark the identifiers for all the builtins with their
- /// appropriate builtin ID # and mark any non-portable builtin identifiers as
- /// such.
- void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target);
-
- /// Builtin::GetName - Return the identifier name for the specified builtin,
- /// e.g. "__builtin_abs".
- const char *GetName(unsigned ID) const {
- return GetRecord(ID).Name;
- }
-
- /// isConst - Return true if this function has no side effects and doesn't
- /// read memory.
- bool isConst(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'c') != 0;
- }
-
- /// isNoThrow - Return true if we know this builtin never throws an exception.
- bool isNoThrow(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'n') != 0;
- }
-
- /// isLibFunction - Return true if this is a builtin for a libc/libm function,
- /// with a "__builtin_" prefix (e.g. __builtin_abs).
- bool isLibFunction(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'F') != 0;
- }
-
- /// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
- /// as an operand or return type.
- bool hasVAListUse(unsigned ID) const {
- return strchr(GetRecord(ID).Type, 'a') != 0;
- }
-
- /// GetBuiltinType - Return the type for the specified builtin.
- QualType GetBuiltinType(unsigned ID, ASTContext &Context) const;
-private:
- const Info &GetRecord(unsigned ID) const;
-};
-
-}
-} // end namespace clang
-#endif
diff --git a/clang/include/clang/AST/CFG.h b/clang/include/clang/AST/CFG.h
deleted file mode 100644
index 2f3183c53359..000000000000
--- a/clang/include/clang/AST/CFG.h
+++ /dev/null
@@ -1,397 +0,0 @@
-//===--- CFG.h - Classes for representing and building CFGs------*- 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 CFG and CFGBuilder classes for representing and
-// building Control-Flow Graphs (CFGs) from ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CFG_H
-#define LLVM_CLANG_CFG_H
-
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
-#include <list>
-#include <vector>
-#include <cassert>
-
-namespace clang {
- class Stmt;
- class Expr;
- class CFG;
- class PrinterHelper;
- class BlockEdge;
-
-/// CFGBlock - Represents a single basic block in a source-level CFG.
-/// It consists of:
-///
-/// (1) A set of statements/expressions (which may contain subexpressions).
-/// (2) A "terminator" statement (not in the set of statements).
-/// (3) A list of successors and predecessors.
-///
-/// Terminator: The terminator represents the type of control-flow that occurs
-/// at the end of the basic block. The terminator is a Stmt* referring to an
-/// AST node that has control-flow: if-statements, breaks, loops, etc.
-/// If the control-flow is conditional, the condition expression will appear
-/// within the set of statements in the block (usually the last statement).
-///
-/// Predecessors: the order in the set of predecessors is arbitrary.
-///
-/// Successors: the order in the set of successors is NOT arbitrary. We
-/// currently have the following orderings based on the terminator:
-///
-/// Terminator Successor Ordering
-/// -----------------------------------------------------
-/// if Then Block; Else Block
-/// ? operator LHS expression; RHS expression
-/// &&, || expression that uses result of && or ||, RHS
-///
-class CFGBlock {
- typedef std::vector<Stmt*> StatementListTy;
- /// Stmts - The set of statements in the basic block.
- StatementListTy Stmts;
-
- /// Label - An (optional) label that prefixes the executable
- /// statements in the block. When this variable is non-NULL, it is
- /// either an instance of LabelStmt or SwitchCase.
- Stmt* Label;
-
- /// Terminator - The terminator for a basic block that
- /// indicates the type of control-flow that occurs between a block
- /// and its successors.
- Stmt* Terminator;
-
- /// BlockID - A numerical ID assigned to a CFGBlock during construction
- /// of the CFG.
- unsigned BlockID;
-
- /// Predecessors/Successors - Keep track of the predecessor / successor
- /// CFG blocks.
- typedef std::vector<CFGBlock*> AdjacentBlocks;
- AdjacentBlocks Preds;
- AdjacentBlocks Succs;
-
-public:
- explicit CFGBlock(unsigned blockid) : Label(NULL), Terminator(NULL),
- BlockID(blockid) {}
- ~CFGBlock() {};
-
- // Statement iterators
- typedef StatementListTy::iterator iterator;
- typedef StatementListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- Stmt* front() const { return Stmts.front(); }
- Stmt* back() const { return Stmts.back(); }
-
- iterator begin() { return Stmts.begin(); }
- iterator end() { return Stmts.end(); }
- const_iterator begin() const { return Stmts.begin(); }
- const_iterator end() const { return Stmts.end(); }
-
- reverse_iterator rbegin() { return Stmts.rbegin(); }
- reverse_iterator rend() { return Stmts.rend(); }
- const_reverse_iterator rbegin() const { return Stmts.rbegin(); }
- const_reverse_iterator rend() const { return Stmts.rend(); }
-
- unsigned size() const { return Stmts.size(); }
- bool empty() const { return Stmts.empty(); }
-
- Stmt* operator[](size_t i) const { assert (i < size()); return Stmts[i]; }
-
- // CFG iterators
- typedef AdjacentBlocks::iterator pred_iterator;
- typedef AdjacentBlocks::const_iterator const_pred_iterator;
- typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
-
- typedef AdjacentBlocks::iterator succ_iterator;
- typedef AdjacentBlocks::const_iterator const_succ_iterator;
- typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
-
- pred_iterator pred_begin() { return Preds.begin(); }
- pred_iterator pred_end() { return Preds.end(); }
- const_pred_iterator pred_begin() const { return Preds.begin(); }
- const_pred_iterator pred_end() const { return Preds.end(); }
-
- pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); }
- pred_reverse_iterator pred_rend() { return Preds.rend(); }
- const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
- const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
-
- succ_iterator succ_begin() { return Succs.begin(); }
- succ_iterator succ_end() { return Succs.end(); }
- const_succ_iterator succ_begin() const { return Succs.begin(); }
- const_succ_iterator succ_end() const { return Succs.end(); }
-
- succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); }
- succ_reverse_iterator succ_rend() { return Succs.rend(); }
- const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
- const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
-
- unsigned succ_size() const { return Succs.size(); }
- bool succ_empty() const { return Succs.empty(); }
-
- unsigned pred_size() const { return Preds.size(); }
- bool pred_empty() const { return Preds.empty(); }
-
- // Manipulation of block contents
-
- void appendStmt(Stmt* Statement) { Stmts.push_back(Statement); }
- void setTerminator(Stmt* Statement) { Terminator = Statement; }
- void setLabel(Stmt* Statement) { Label = Statement; }
-
- Stmt* getTerminator() { return Terminator; }
- const Stmt* getTerminator() const { return Terminator; }
-
- Expr* getTerminatorCondition();
-
- const Expr* getTerminatorCondition() const {
- return const_cast<CFGBlock*>(this)->getTerminatorCondition();
- }
-
- bool hasBinaryBranchTerminator() const;
-
- Stmt* getLabel() { return Label; }
- const Stmt* getLabel() const { return Label; }
-
- void reverseStmts();
-
- void addSuccessor(CFGBlock* Block) {
- Block->Preds.push_back(this);
- Succs.push_back(Block);
- }
-
- unsigned getBlockID() const { return BlockID; }
-
- void dump(const CFG* cfg) const;
- void print(llvm::raw_ostream& OS, const CFG* cfg) const;
- void printTerminator(llvm::raw_ostream& OS) const;
-};
-
-
-/// CFG - Represents a source-level, intra-procedural CFG that represents the
-/// control-flow of a Stmt. The Stmt can represent an entire function body,
-/// or a single expression. A CFG will always contain one empty block that
-/// represents the Exit point of the CFG. A CFG will also contain a designated
-/// Entry block. The CFG solely represents control-flow; it consists of
-/// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
-/// was constructed from.
-class CFG {
-public:
- //===--------------------------------------------------------------------===//
- // CFG Construction & Manipulation.
- //===--------------------------------------------------------------------===//
-
- /// buildCFG - Builds a CFG from an AST. The responsibility to free the
- /// constructed CFG belongs to the caller.
- static CFG* buildCFG(Stmt* AST);
-
- /// createBlock - Create a new block in the CFG. The CFG owns the block;
- /// the caller should not directly free it.
- CFGBlock* createBlock();
-
- /// setEntry - Set the entry block of the CFG. This is typically used
- /// only during CFG construction. Most CFG clients expect that the
- /// entry block has no predecessors and contains no statements.
- void setEntry(CFGBlock *B) { Entry = B; }
-
- /// setExit - Set the exit block of the CFG. This is typically used
- /// only during CFG construction. Most CFG clients expect that the
- /// exit block has no successors and contains no statements.
- void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
-
- //===--------------------------------------------------------------------===//
- // Block Iterators
- //===--------------------------------------------------------------------===//
-
- typedef std::list<CFGBlock> CFGBlockListTy;
-
- typedef CFGBlockListTy::iterator iterator;
- typedef CFGBlockListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- CFGBlock& front() { return Blocks.front(); }
- CFGBlock& back() { return Blocks.back(); }
-
- iterator begin() { return Blocks.begin(); }
- iterator end() { return Blocks.end(); }
- const_iterator begin() const { return Blocks.begin(); }
- const_iterator end() const { return Blocks.end(); }
-
- reverse_iterator rbegin() { return Blocks.rbegin(); }
- reverse_iterator rend() { return Blocks.rend(); }
- const_reverse_iterator rbegin() const { return Blocks.rbegin(); }
- const_reverse_iterator rend() const { return Blocks.rend(); }
-
- CFGBlock& getEntry() { return *Entry; }
- const CFGBlock& getEntry() const { return *Entry; }
- CFGBlock& getExit() { return *Exit; }
- const CFGBlock& getExit() const { return *Exit; }
-
- CFGBlock* getIndirectGotoBlock() { return IndirectGotoBlock; }
- const CFGBlock* getIndirectGotoBlock() const { return IndirectGotoBlock; }
-
- //===--------------------------------------------------------------------===//
- // Member templates useful for various batch operations over CFGs.
- //===--------------------------------------------------------------------===//
-
- template <typename CALLBACK>
- void VisitBlockStmts(CALLBACK& O) const {
- for (const_iterator I=begin(), E=end(); I != E; ++I)
- for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI != BE; ++BI)
- O(*BI);
- }
-
- //===--------------------------------------------------------------------===//
- // CFG Introspection.
- //===--------------------------------------------------------------------===//
-
- struct BlkExprNumTy {
- const signed Idx;
- explicit BlkExprNumTy(signed idx) : Idx(idx) {}
- explicit BlkExprNumTy() : Idx(-1) {}
- operator bool() const { return Idx >= 0; }
- operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
- };
-
- bool isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
- BlkExprNumTy getBlkExprNum(const Stmt* S);
- unsigned getNumBlkExprs();
-
- unsigned getNumBlockIDs() const { return NumBlockIDs; }
-
- //===--------------------------------------------------------------------===//
- // CFG Debugging: Pretty-Printing and Visualization.
- //===--------------------------------------------------------------------===//
-
- void viewCFG() const;
- void print(llvm::raw_ostream& OS) const;
- void dump() const;
-
- //===--------------------------------------------------------------------===//
- // Internal: constructors and data.
- //===--------------------------------------------------------------------===//
-
- CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
- BlkExprMap(NULL) {};
-
- ~CFG();
-
- llvm::BumpPtrAllocator& getAllocator() {
- return Alloc;
- }
-
-private:
- CFGBlock* Entry;
- CFGBlock* Exit;
- CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
- // for indirect gotos
- CFGBlockListTy Blocks;
- unsigned NumBlockIDs;
-
- // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
- // It represents a map from Expr* to integers to record the set of
- // block-level expressions and their "statement number" in the CFG.
- void* BlkExprMap;
-
- /// Alloc - An internal allocator.
- llvm::BumpPtrAllocator Alloc;
-};
-} // end namespace clang
-
-//===----------------------------------------------------------------------===//
-// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-// Traits for: CFGBlock
-
-template <> struct GraphTraits<clang::CFGBlock* > {
- typedef clang::CFGBlock NodeType;
- typedef clang::CFGBlock::succ_iterator ChildIteratorType;
-
- static NodeType* getEntryNode(clang::CFGBlock* BB)
- { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
-};
-
-template <> struct GraphTraits<const clang::CFGBlock* > {
- typedef const clang::CFGBlock NodeType;
- typedef clang::CFGBlock::const_succ_iterator ChildIteratorType;
-
- static NodeType* getEntryNode(const clang::CFGBlock* BB)
- { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
-};
-
-template <> struct GraphTraits<Inverse<const clang::CFGBlock*> > {
- typedef const clang::CFGBlock NodeType;
- typedef clang::CFGBlock::const_pred_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Inverse<const clang::CFGBlock*> G)
- { return G.Graph; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->pred_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->pred_end(); }
-};
-
-// Traits for: CFG
-
-template <> struct GraphTraits<clang::CFG* >
- : public GraphTraits<clang::CFGBlock* > {
-
- typedef clang::CFG::iterator nodes_iterator;
-
- static NodeType *getEntryNode(clang::CFG* F) { return &F->getEntry(); }
- static nodes_iterator nodes_begin(clang::CFG* F) { return F->begin(); }
- static nodes_iterator nodes_end(clang::CFG* F) { return F->end(); }
-};
-
-template <> struct GraphTraits< const clang::CFG* >
- : public GraphTraits< const clang::CFGBlock* > {
-
- typedef clang::CFG::const_iterator nodes_iterator;
-
- static NodeType *getEntryNode( const clang::CFG* F) { return &F->getEntry(); }
- static nodes_iterator nodes_begin( const clang::CFG* F) { return F->begin(); }
- static nodes_iterator nodes_end( const clang::CFG* F) { return F->end(); }
-};
-
-template <> struct GraphTraits<Inverse<const clang::CFG*> >
- : public GraphTraits<Inverse<const clang::CFGBlock*> > {
-
- typedef clang::CFG::const_iterator nodes_iterator;
-
- static NodeType *getEntryNode(const clang::CFG* F) { return &F->getExit(); }
- static nodes_iterator nodes_begin(const clang::CFG* F) { return F->begin();}
- static nodes_iterator nodes_end(const clang::CFG* F) { return F->end(); }
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
deleted file mode 100644
index b0acc4c1b7a7..000000000000
--- a/clang/include/clang/AST/Decl.h
+++ /dev/null
@@ -1,986 +0,0 @@
-//===--- Decl.h - Classes for representing declarations ---------*- 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 Decl subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECL_H
-#define LLVM_CLANG_AST_DECL_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/Parse/AccessSpecifier.h"
-
-namespace clang {
-class Expr;
-class Stmt;
-class StringLiteral;
-class IdentifierInfo;
-
-/// TranslationUnitDecl - The top declaration context.
-/// FIXME: The TranslationUnit class should probably be modified to serve as
-/// the top decl context. It would have ownership of the top decls so that the
-/// AST is self-contained and easily de/serializable.
-class TranslationUnitDecl : public Decl, public DeclContext {
- TranslationUnitDecl()
- : Decl(TranslationUnit, SourceLocation()),
- DeclContext(TranslationUnit) {}
-public:
- static TranslationUnitDecl *Create(ASTContext &C);
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
- static bool classof(const TranslationUnitDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this TranslationUnitDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a TranslationUnitDecl. Called by Decl::Create.
- static TranslationUnitDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// NamedDecl - This represents a decl with an identifier for a name. Many
-/// decls have names, but not ObjCMethodDecl, @class, etc.
-class NamedDecl : public Decl {
- /// Identifier - The identifier for this declaration (e.g. the name for the
- /// variable, the tag for a struct).
- IdentifierInfo *Identifier;
-public:
- NamedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
- : Decl(DK, L), Identifier(Id) {}
-
- IdentifierInfo *getIdentifier() const { return Identifier; }
- const char *getName() const;
-
- static bool classof(const Decl *D) {
- return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
- }
- static bool classof(const NamedDecl *D) { return true; }
-
-protected:
- void EmitInRec(llvm::Serializer& S) const;
- void ReadInRec(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ScopedDecl - Represent lexically scoped names, used for all ValueDecl's
-/// and TypeDecl's.
-class ScopedDecl : public NamedDecl {
- /// NextDeclarator - If this decl was part of a multi-declarator declaration,
- /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
- ScopedDecl *NextDeclarator;
-
- /// When this decl is in scope while parsing, the Next field contains a
- /// pointer to the shadowed decl of the same name. When the scope is popped,
- /// Decls are relinked onto a containing decl object.
- ///
- ScopedDecl *Next;
-
- DeclContext *DeclCtx;
-
-protected:
- ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, ScopedDecl *PrevDecl)
- : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0), DeclCtx(DC) {}
-
-public:
- DeclContext *getDeclContext() const { return DeclCtx; }
-
- ScopedDecl *getNext() const { return Next; }
- void setNext(ScopedDecl *N) { Next = N; }
-
- /// getNextDeclarator - If this decl was part of a multi-declarator
- /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
- /// declarator. Otherwise it returns null.
- ScopedDecl *getNextDeclarator() { return NextDeclarator; }
- const ScopedDecl *getNextDeclarator() const { return NextDeclarator; }
- void setNextDeclarator(ScopedDecl *N) { NextDeclarator = N; }
-
- // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
- // scoped decl is defined outside the current function or method. This is
- // roughly global variables and functions, but also handles enums (which could
- // be defined inside or outside a function etc).
- bool isDefinedOutsideFunctionOrMethod() const {
- if (getDeclContext())
- return !getDeclContext()->isFunctionOrMethod();
- else
- return true;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast;
- }
- static bool classof(const ScopedDecl *D) { return true; }
-
-protected:
- void EmitInRec(llvm::Serializer& S) const;
- void ReadInRec(llvm::Deserializer& D, ASTContext& C);
-
- void EmitOutRec(llvm::Serializer& S) const;
- void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
-
- friend void Decl::Destroy(ASTContext& C);
-};
-
-/// NamespaceDecl - Represent a C++ namespace.
-class NamespaceDecl : public ScopedDecl, public DeclContext {
- SourceLocation LBracLoc, RBracLoc;
-
- // For extended namespace definitions:
- //
- // namespace A { int x; }
- // namespace A { int y; }
- //
- // there will be one NamespaceDecl for each declaration.
- // NextDeclarator points to the next extended declaration.
- // OrigNamespace points to the original namespace declaration.
- // OrigNamespace of the first namespace decl points to itself.
-
- NamespaceDecl *OrigNamespace;
-
- NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
- : ScopedDecl(Namespace, DC, L, Id, 0), DeclContext(Namespace) {
- OrigNamespace = this;
- }
-public:
- static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id);
-
- virtual void Destroy(ASTContext& C);
-
- NamespaceDecl *getNextNamespace() {
- return cast_or_null<NamespaceDecl>(getNextDeclarator());
- }
- const NamespaceDecl *getNextNamespace() const {
- return cast_or_null<NamespaceDecl>(getNextDeclarator());
- }
- void setNextNamespace(NamespaceDecl *ND) { setNextDeclarator(ND); }
-
- NamespaceDecl *getOriginalNamespace() const {
- return OrigNamespace;
- }
- void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
-
- SourceRange getSourceRange() const {
- return SourceRange(LBracLoc, RBracLoc);
- }
-
- SourceLocation getLBracLoc() const { return LBracLoc; }
- SourceLocation getRBracLoc() const { return RBracLoc; }
- void setLBracLoc(SourceLocation LBrace) { LBracLoc = LBrace; }
- void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Namespace; }
- static bool classof(const NamespaceDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this NamespaceDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a NamespaceDecl. Called by Decl::Create.
- static NamespaceDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ValueDecl - Represent the declaration of a variable (in which case it is
-/// an lvalue) a function (in which case it is a function designator) or
-/// an enum constant.
-class ValueDecl : public ScopedDecl {
- QualType DeclType;
-
-protected:
- ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
- : ScopedDecl(DK, DC, L, Id, PrevDecl), DeclType(T) {}
-public:
- QualType getType() const { return DeclType; }
- void setType(QualType newType) { DeclType = newType; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= ValueFirst && D->getKind() <= ValueLast;
- }
- static bool classof(const ValueDecl *D) { return true; }
-
-protected:
- void EmitInRec(llvm::Serializer& S) const;
- void ReadInRec(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// VarDecl - An instance of this class is created to represent a variable
-/// declaration or definition.
-class VarDecl : public ValueDecl {
-public:
- enum StorageClass {
- None, Auto, Register, Extern, Static, PrivateExtern
- };
-private:
- Stmt *Init;
- // FIXME: This can be packed into the bitfields in Decl.
- unsigned SClass : 3;
- bool ThreadSpecified : 1;
- bool HasCXXDirectInit : 1;
-
- // Move to DeclGroup when it is implemented.
- SourceLocation TypeSpecStartLoc;
- friend class StmtIteratorBase;
-protected:
- VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, StorageClass SC, ScopedDecl *PrevDecl,
- SourceLocation TSSL = SourceLocation())
- : ValueDecl(DK, DC, L, Id, T, PrevDecl), Init(0),
- ThreadSpecified(false), HasCXXDirectInit(false),
- TypeSpecStartLoc(TSSL) { SClass = SC; }
-public:
- static VarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, StorageClass S, ScopedDecl *PrevDecl,
- SourceLocation TypeSpecStartLoc = SourceLocation());
-
- StorageClass getStorageClass() const { return (StorageClass)SClass; }
-
- SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; }
-
- const Expr *getInit() const { return (const Expr*) Init; }
- Expr *getInit() { return (Expr*) Init; }
- void setInit(Expr *I) { Init = (Stmt*) I; }
-
- void setThreadSpecified(bool T) { ThreadSpecified = T; }
- bool isThreadSpecified() const {
- return ThreadSpecified;
- }
-
- void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
-
- /// hasCXXDirectInitializer - If true, the initializer was a direct
- /// initializer, e.g: "int x(1);". The Init expression will be the expression
- /// inside the parens or a "ClassType(a,b,c)" class constructor expression for
- /// class types. Clients can distinguish between "int x(1);" and "int x=1;"
- /// by checking hasCXXDirectInitializer.
- ///
- bool hasCXXDirectInitializer() const {
- return HasCXXDirectInit;
- }
-
- /// hasLocalStorage - Returns true if a variable with function scope
- /// is a non-static local variable.
- bool hasLocalStorage() const {
- if (getStorageClass() == None)
- return !isFileVarDecl();
-
- // Return true for: Auto, Register.
- // Return false for: Extern, Static, PrivateExtern.
-
- return getStorageClass() <= Register;
- }
-
- /// hasGlobalStorage - Returns true for all variables that do not
- /// have local storage. This includs all global variables as well
- /// as static variables declared within a function.
- bool hasGlobalStorage() const { return !hasLocalStorage(); }
-
- /// isBlockVarDecl - Returns true for local variable declarations. Note that
- /// this includes static variables inside of functions.
- ///
- /// void foo() { int x; static int y; extern int z; }
- ///
- bool isBlockVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (DeclContext *DC = getDeclContext())
- return DC->isFunctionOrMethod();
- return false;
- }
-
- /// isFileVarDecl - Returns true for file scoped variable declaration.
- bool isFileVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (isa<TranslationUnitDecl>(getDeclContext()) ||
- isa<NamespaceDecl>(getDeclContext()) )
- return true;
- return false;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= VarFirst && D->getKind() <= VarLast;
- }
- static bool classof(const VarDecl *D) { return true; }
-
-protected:
- void EmitInRec(llvm::Serializer& S) const;
- void ReadInRec(llvm::Deserializer& D, ASTContext& C);
-
- void EmitOutRec(llvm::Serializer& S) const;
- void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
-
- /// EmitImpl - Serialize this VarDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// ReadImpl - Deserialize this VarDecl. Called by subclasses.
- virtual void ReadImpl(llvm::Deserializer& D, ASTContext& C);
-
- /// CreateImpl - Deserialize a VarDecl. Called by Decl::Create.
- static VarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class ImplicitParamDecl : public VarDecl {
-protected:
- ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
- : VarDecl(DK, DC, L, Id, T, VarDecl::None, PrevDecl) {}
-public:
- static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, ScopedDecl *PrevDecl);
- // Implement isa/cast/dyncast/etc.
- static bool classof(const ImplicitParamDecl *D) { return true; }
- static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; }
-};
-
-/// ParmVarDecl - Represent a parameter to a function.
-class ParmVarDecl : public VarDecl {
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// FIXME: Also can be paced into the bitfields in Decl.
- /// in, inout, etc.
- unsigned objcDeclQualifier : 6;
-
- /// Default argument, if any. [C++ Only]
- Expr *DefaultArg;
-
- ParmVarDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, StorageClass S,
- Expr *DefArg, ScopedDecl *PrevDecl)
- : VarDecl(ParmVar, DC, L, Id, T, S, PrevDecl),
- objcDeclQualifier(OBJC_TQ_None), DefaultArg(DefArg) {}
-
-public:
- static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,IdentifierInfo *Id,
- QualType T, StorageClass S, Expr *DefArg,
- ScopedDecl *PrevDecl);
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QTVal)
- { objcDeclQualifier = QTVal; }
-
- const Expr *getDefaultArg() const { return DefaultArg; }
- Expr *getDefaultArg() { return DefaultArg; }
- void setDefaultArg(Expr *defarg) { DefaultArg = defarg; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ParmVar; }
- static bool classof(const ParmVarDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this ParmVarDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a ParmVarDecl. Called by Decl::Create.
- static ParmVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// FunctionDecl - An instance of this class is created to represent a
-/// function declaration or definition.
-///
-/// Since a given function can be declared several times in a program,
-/// there may be several FunctionDecls that correspond to that
-/// function. Only one of those FunctionDecls will be found when
-/// traversing the list of declarations in the context of the
-/// FunctionDecl (e.g., the translation unit); this FunctionDecl
-/// contains all of the information known about the function. Other,
-/// previous declarations of the function are available via the
-/// getPreviousDeclaration() chain.
-class FunctionDecl : public ValueDecl, public DeclContext {
-public:
- enum StorageClass {
- None, Extern, Static, PrivateExtern
- };
-private:
- /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
- /// parameters of this function. This is null if a prototype or if there are
- /// no formals. TODO: we could allocate this space immediately after the
- /// FunctionDecl object to save an allocation like FunctionType does.
- ParmVarDecl **ParamInfo;
-
- Stmt *Body; // Null if a prototype.
-
- /// PreviousDeclaration - A link to the previous declaration of this
- /// same function, NULL if this is the first declaration. For
- /// example, in the following code, the PreviousDeclaration can be
- /// traversed several times to see all three declarations of the
- /// function "f", the last of which is also a definition.
- ///
- /// int f(int x, int y = 1);
- /// int f(int x = 0, int y);
- /// int f(int x, int y) { return x + y; }
- FunctionDecl *PreviousDeclaration;
-
- // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
- unsigned SClass : 2;
- bool IsInline : 1;
- bool IsImplicit : 1;
-
- // Move to DeclGroup when it is implemented.
- SourceLocation TypeSpecStartLoc;
-protected:
- FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S, bool isInline, ScopedDecl *PrevDecl,
- SourceLocation TSSL = SourceLocation())
- : ValueDecl(DK, DC, L, Id, T, PrevDecl),
- DeclContext(DK),
- ParamInfo(0), Body(0), PreviousDeclaration(0),
- SClass(S), IsInline(isInline), IsImplicit(0), TypeSpecStartLoc(TSSL) {}
-
- virtual ~FunctionDecl();
- virtual void Destroy(ASTContext& C);
-
-public:
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S = None, bool isInline = false,
- ScopedDecl *PrevDecl = 0,
- SourceLocation TSStartLoc = SourceLocation());
-
- SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; }
-
- /// getBody - Retrieve the body (definition) of the function. The
- /// function body might be in any of the (re-)declarations of this
- /// function. The variant that accepts a FunctionDecl pointer will
- /// set that function declaration to the actual declaration
- /// containing the body (if there is one).
- Stmt *getBody(const FunctionDecl *&Definition) const;
-
- virtual Stmt *getBody() const {
- const FunctionDecl* Definition;
- return getBody(Definition);
- }
-
- /// isThisDeclarationADefinition - Returns whether this specific
- /// declaration of the function is also a definition. This does not
- /// determine whether the function has been defined (e.g., in a
- /// previous definition); for that information, use getBody.
- bool isThisDeclarationADefinition() const { return Body != 0; }
-
- void setBody(Stmt *B) { Body = B; }
-
- bool isImplicit() { return IsImplicit; }
- void setImplicit() { IsImplicit = true; }
-
- /// getPreviousDeclaration - Return the previous declaration of this
- /// function.
- const FunctionDecl *getPreviousDeclaration() const {
- return PreviousDeclaration;
- }
-
- void setPreviousDeclaration(FunctionDecl * PrevDecl) {
- PreviousDeclaration = PrevDecl;
- }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return getNumParams(); }
- typedef ParmVarDecl **param_iterator;
- typedef ParmVarDecl * const *param_const_iterator;
-
- param_iterator param_begin() { return ParamInfo; }
- param_iterator param_end() {
-
- // Special-case for handling typedefs:
- //
- // typedef void func_t(int x);
- // func_t a;
- //
- // In the case of the FunctionDecl for "a", there are no ParmVarDecls.
-
- return ParamInfo ? ParamInfo+param_size() : 0x0;
- }
-
- param_const_iterator param_begin() const { return ParamInfo; }
-
- param_const_iterator param_end() const {
- return ParamInfo ? ParamInfo+param_size() : 0x0;
- }
-
- unsigned getNumParams() const;
- const ParmVarDecl *getParamDecl(unsigned i) const {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- ParmVarDecl *getParamDecl(unsigned i) {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
-
- /// getMinRequiredArguments - Returns the minimum number of arguments
- /// needed to call this function. This may be fewer than the number of
- /// function parameters, if some of the parameters have default
- /// arguments (in C++).
- unsigned getMinRequiredArguments() const;
-
- QualType getResultType() const {
- return getType()->getAsFunctionType()->getResultType();
- }
- StorageClass getStorageClass() const { return StorageClass(SClass); }
- bool isInline() const { return IsInline; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
- }
- static bool classof(const FunctionDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this FunctionDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a FunctionDecl. Called by Decl::Create.
- static FunctionDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// FieldDecl - An instance of this class is created by Sema::ActOnField to
-/// represent a member of a struct/union/class.
-class FieldDecl : public NamedDecl {
- QualType DeclType;
- Expr *BitWidth;
-protected:
- FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
- Expr *BW = NULL)
- : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {}
- FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW)
- : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {}
-public:
- static FieldDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *BW = NULL);
-
- QualType getType() const { return DeclType; }
-
- bool isBitField() const { return BitWidth != NULL; }
- Expr *getBitWidth() const { return BitWidth; }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
- }
- static bool classof(const FieldDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this FieldDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a FieldDecl. Called by Decl::Create.
- static FieldDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// EnumConstantDecl - An instance of this object exists for each enum constant
-/// that is defined. For example, in "enum X {a,b}", each of a/b are
-/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
-/// TagType for the X EnumDecl.
-class EnumConstantDecl : public ValueDecl {
- Stmt *Init; // an integer constant expression
- llvm::APSInt Val; // The value.
-protected:
- EnumConstantDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *E,
- const llvm::APSInt &V, ScopedDecl *PrevDecl)
- : ValueDecl(EnumConstant, DC, L, Id, T, PrevDecl), Init((Stmt*)E), Val(V) {}
-
- virtual ~EnumConstantDecl() {}
-public:
-
- static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *E,
- const llvm::APSInt &V, ScopedDecl *PrevDecl);
-
- virtual void Destroy(ASTContext& C);
-
- const Expr *getInitExpr() const { return (const Expr*) Init; }
- Expr *getInitExpr() { return (Expr*) Init; }
- const llvm::APSInt &getInitVal() const { return Val; }
-
- void setInitExpr(Expr *E) { Init = (Stmt*) E; }
- void setInitVal(const llvm::APSInt &V) { Val = V; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == EnumConstant; }
- static bool classof(const EnumConstantDecl *D) { return true; }
-
- friend class StmtIteratorBase;
-
-protected:
- /// EmitImpl - Serialize this EnumConstantDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a EnumConstantDecl. Called by Decl::Create.
- static EnumConstantDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// TypeDecl - Represents a declaration of a type.
-///
-class TypeDecl : public ScopedDecl {
- /// TypeForDecl - This indicates the Type object that represents this
- /// TypeDecl. It is a cache maintained by ASTContext::getTypedefType and
- /// ASTContext::getTagDeclType.
- Type *TypeForDecl;
- friend class ASTContext;
-protected:
- TypeDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, ScopedDecl *PrevDecl)
- : ScopedDecl(DK, DC, L, Id, PrevDecl), TypeForDecl(0) {}
-public:
- void setAccess(AccessSpecifier AS) { Access = AS; }
- AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TypeFirst && D->getKind() <= TypeLast;
- }
- static bool classof(const TypeDecl *D) { return true; }
-};
-
-
-class TypedefDecl : public TypeDecl {
- /// UnderlyingType - This is the type the typedef is set to.
- QualType UnderlyingType;
- TypedefDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, ScopedDecl *PD)
- : TypeDecl(Typedef, DC, L, Id, PD), UnderlyingType(T) {}
-
- virtual ~TypedefDecl() {}
-public:
-
- static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,IdentifierInfo *Id,
- QualType T, ScopedDecl *PD);
-
- QualType getUnderlyingType() const { return UnderlyingType; }
- void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Typedef; }
- static bool classof(const TypedefDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this TypedefDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a TypedefDecl. Called by Decl::Create.
- static TypedefDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-
-};
-
-
-/// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl : public TypeDecl {
-public:
- enum TagKind {
- TK_struct,
- TK_union,
- TK_class,
- TK_enum
- };
-
-private:
- /// IsDefinition - True if this is a definition ("struct foo {};"), false if
- /// it is a declaration ("struct foo;").
- bool IsDefinition : 1;
-protected:
- TagDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, ScopedDecl *PrevDecl)
- : TypeDecl(DK, DC, L, Id, PrevDecl) {
- IsDefinition = false;
- }
-public:
-
- /// isDefinition - Return true if this decl has its body specified.
- bool isDefinition() const {
- return IsDefinition;
- }
-
- /// getDefinition - Returns the TagDecl that actually defines this
- /// struct/union/class/enum. When determining whether or not a
- /// struct/union/class/enum is completely defined, one should use this method
- /// as opposed to 'isDefinition'. 'isDefinition' indicates whether or not a
- /// specific TagDecl is defining declaration, not whether or not the
- /// struct/union/class/enum type is defined. This method returns NULL if
- /// there is no TagDecl that defines the struct/union/class/enum.
- TagDecl* getDefinition(ASTContext& C) const;
-
- const char *getKindName() const {
- switch (getTagKind()) {
- default: assert(0 && "Unknown TagKind!");
- case TK_struct: return "struct";
- case TK_union: return "union";
- case TK_class: return "class";
- case TK_enum: return "enum";
- }
- }
-
- TagKind getTagKind() const {
- switch (getKind()) {
- default: assert(0 && "Unknown TagDecl!");
- case Struct: case CXXStruct: return TK_struct;
- case Union: case CXXUnion: return TK_union;
- case Class: case CXXClass: return TK_class;
- case Enum: return TK_enum;
- }
- }
-
- bool isStruct() const { return getKind() == Struct || getKind() == CXXStruct;}
- bool isClass() const { return getKind() == Class || getKind() == CXXClass; }
- bool isUnion() const { return getKind() == Union || getKind() == CXXUnion; }
- bool isEnum() const { return getKind() == Enum; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() >= TagFirst && D->getKind() <= TagLast;
- }
- static bool classof(const TagDecl *D) { return true; }
-protected:
- void setDefinition(bool V) { IsDefinition = V; }
-};
-
-/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
-/// enums.
-class EnumDecl : public TagDecl, public DeclContext {
- // EnumDecl's DeclChain points to a linked list of EnumConstantDecl's which
- // are linked together through their getNextDeclarator pointers.
-
- /// IntegerType - This represent the integer type that the enum corresponds
- /// to for code generation purposes. Note that the enumerator constants may
- /// have a different type than this does.
- QualType IntegerType;
-
- EnumDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, ScopedDecl *PrevDecl)
- : TagDecl(Enum, DC, L, Id, PrevDecl), DeclContext(Enum) {
- IntegerType = QualType();
- }
-public:
- static EnumDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ScopedDecl *PrevDecl);
-
- virtual void Destroy(ASTContext& C);
-
- /// defineElements - When created, EnumDecl correspond to a forward declared
- /// enum. This method is used to mark the decl as being defined, with the
- /// specified list of enums.
- void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
- assert(!isDefinition() && "Cannot redefine enums!");
- setDeclChain(ListHead);
- setDefinition(true);
-
- IntegerType = NewType;
- }
-
- /// getIntegerType - Return the integer type this enum decl corresponds to.
- /// This returns a null qualtype for an enum forward definition.
- QualType getIntegerType() const { return IntegerType; }
-
- /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
- ///
- EnumConstantDecl *getEnumConstantList() {
- return cast_or_null<EnumConstantDecl>(getDeclChain());
- }
- const EnumConstantDecl *getEnumConstantList() const {
- return cast_or_null<const EnumConstantDecl>(getDeclChain());
- }
-
- static bool classof(const Decl *D) { return D->getKind() == Enum; }
- static bool classof(const EnumDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this EnumDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a EnumDecl. Called by Decl::Create.
- static EnumDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// RecordDecl - Represents a struct/union/class. For example:
-/// struct X; // Forward declaration, no "body".
-/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
-/// This decl will be marked invalid if *any* members are invalid.
-///
-class RecordDecl : public TagDecl {
- /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
- /// array member (e.g. int X[]) or if this union contains a struct that does.
- /// If so, this cannot be contained in arrays or other structs as a member.
- bool HasFlexibleArrayMember : 1;
-
- /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
- FieldDecl **Members; // Null if not defined.
- int NumMembers; // -1 if not defined.
-
-protected:
- RecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id);
- virtual ~RecordDecl();
-
-public:
- static RecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- RecordDecl* PrevDecl = 0);
-
- virtual void Destroy(ASTContext& C);
-
- bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
- void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
-
- /// getDefinition - Returns the RecordDecl that actually defines this
- /// struct/union/class. When determining whether or not a struct/union/class
- /// is completely defined, one should use this method as opposed to
- /// 'isDefinition'. 'isDefinition' indicates whether or not a specific
- /// RecordDecl is defining declaration, not whether or not the record
- /// type is defined. This method returns NULL if there is no RecordDecl
- /// that defines the struct/union/tag.
- RecordDecl* getDefinition(ASTContext& C) const {
- return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
- }
-
- /// getNumMembers - Return the number of members, or -1 if this is a forward
- /// definition.
- int getNumMembers() const { return NumMembers; }
- const FieldDecl *getMember(unsigned i) const { return Members[i]; }
- FieldDecl *getMember(unsigned i) { return Members[i]; }
-
- // Iterator access to field members.
- typedef FieldDecl **field_iterator;
- typedef FieldDecl * const *field_const_iterator;
-
- field_iterator field_begin() {
- assert(isDefinition() && "Not a definition!");
- return Members;
- }
- field_iterator field_end() {
- assert(isDefinition() && "Not a definition!");
- return Members + getNumMembers();
- }
-
- field_const_iterator field_begin() const {
- assert(isDefinition() && "Not a definition!");
- return Members;
- }
- field_const_iterator field_end() const {
- assert(isDefinition() && "Not a definition!");
- return Members + getNumMembers();
- }
-
- /// defineBody - When created, RecordDecl's correspond to a forward declared
- /// record. This method is used to mark the decl as being defined, with the
- /// specified contents.
- void defineBody(ASTContext& C, FieldDecl **Members, unsigned numMembers);
-
- /// getMember - If the member doesn't exist, or there are no members, this
- /// function will return 0;
- FieldDecl *getMember(IdentifierInfo *name);
-
- static bool classof(const Decl *D) {
- return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;
- }
- static bool classof(const RecordDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this RecordDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a RecordDecl. Called by Decl::Create.
- static RecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-class FileScopeAsmDecl : public Decl {
- StringLiteral *AsmString;
- FileScopeAsmDecl(SourceLocation L, StringLiteral *asmstring)
- : Decl(FileScopeAsm, L), AsmString(asmstring) {}
-public:
- static FileScopeAsmDecl *Create(ASTContext &C, SourceLocation L,
- StringLiteral *Str);
-
- const StringLiteral *getAsmString() const { return AsmString; }
- StringLiteral *getAsmString() { return AsmString; }
- static bool classof(const Decl *D) {
- return D->getKind() == FileScopeAsm;
- }
- static bool classof(const FileScopeAsmDecl *D) { return true; }
-protected:
- /// EmitImpl - Serialize this FileScopeAsmDecl. Called by Decl::Emit.
- virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a FileScopeAsmDecl. Called by Decl::Create.
- static FileScopeAsmDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// LinkageSpecDecl - This represents a linkage specification. For example:
-/// extern "C" void foo();
-///
-class LinkageSpecDecl : public Decl {
-public:
- /// LanguageIDs - Used to represent the language in a linkage
- /// specification. The values are part of the serialization abi for
- /// ASTs and cannot be changed without altering that abi. To help
- /// ensure a stable abi for this, we choose the DW_LANG_ encodings
- /// from the dwarf standard.
- enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
- lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
-private:
- /// Language - The language for this linkage specification.
- LanguageIDs Language;
- /// D - This is the Decl of the linkage specification.
- Decl *D;
-
- LinkageSpecDecl(SourceLocation L, LanguageIDs lang, Decl *d)
- : Decl(LinkageSpec, L), Language(lang), D(d) {}
-public:
- static LinkageSpecDecl *Create(ASTContext &C, SourceLocation L,
- LanguageIDs Lang, Decl *D);
-
- LanguageIDs getLanguage() const { return Language; }
- const Decl *getDecl() const { return D; }
- Decl *getDecl() { return D; }
-
- static bool classof(const Decl *D) {
- return D->getKind() == LinkageSpec;
- }
- static bool classof(const LinkageSpecDecl *D) { return true; }
-
-protected:
- void EmitInRec(llvm::Serializer& S) const;
- void ReadInRec(llvm::Deserializer& D, ASTContext& C);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
deleted file mode 100644
index d274fd381df1..000000000000
--- a/clang/include/clang/AST/DeclBase.h
+++ /dev/null
@@ -1,403 +0,0 @@
-//===-- DeclBase.h - Base Classes for representing declarations *- 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 Decl and DeclContext interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLBASE_H
-#define LLVM_CLANG_AST_DECLBASE_H
-
-#include "clang/AST/Attr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-class TranslationUnitDecl;
-class NamespaceDecl;
-class ScopedDecl;
-class FunctionDecl;
-class CXXRecordDecl;
-class EnumDecl;
-class ObjCMethodDecl;
-class ObjCInterfaceDecl;
-
-/// Decl - This represents one declaration (or definition), e.g. a variable,
-/// typedef, function, struct, etc.
-///
-class Decl {
-public:
- enum Kind {
- // This lists the concrete classes of Decl in order of the inheritance
- // hierarchy. This allows us to do efficient classof tests based on the
- // enums below. The commented out names are abstract class names.
- // [DeclContext] indicates that the class also inherits from DeclContext.
-
- // Decl
- TranslationUnit, // [DeclContext]
- // NamedDecl
- Field,
- CXXField,
- ObjCIvar,
- ObjCAtDefsField,
- ObjCCategory,
- ObjCCategoryImpl,
- ObjCImplementation,
- ObjCProtocol,
- ObjCProperty,
- // ScopedDecl
- Namespace, // [DeclContext]
- // TypeDecl
- Typedef,
- // TagDecl
- Enum, // [DeclContext]
- // RecordDecl
- Struct,
- Union,
- Class,
- // CXXRecordDecl [DeclContext]
- CXXStruct,
- CXXUnion,
- CXXClass,
- // ValueDecl
- EnumConstant,
- Function, // [DeclContext]
- CXXMethod,
- Var,
- ImplicitParam,
- CXXClassVar,
- ParmVar,
- ObjCInterface, // [DeclContext]
- ObjCCompatibleAlias,
- ObjCMethod, // [DeclContext]
- ObjCClass,
- ObjCForwardProtocol,
- ObjCPropertyImpl,
- LinkageSpec,
- FileScopeAsm,
-
- // For each non-leaf class, we now define a mapping to the first/last member
- // of the class, to allow efficient classof.
- NamedFirst = Field , NamedLast = ParmVar,
- FieldFirst = Field , FieldLast = ObjCAtDefsField,
- ScopedFirst = Namespace , ScopedLast = ParmVar,
- TypeFirst = Typedef , TypeLast = CXXClass,
- TagFirst = Enum , TagLast = CXXClass,
- RecordFirst = Struct , RecordLast = CXXClass,
- CXXRecordFirst = CXXStruct , CXXRecordLast = CXXClass,
- ValueFirst = EnumConstant , ValueLast = ParmVar,
- FunctionFirst = Function , FunctionLast = CXXMethod,
- VarFirst = Var , VarLast = ParmVar
- };
-
- /// IdentifierNamespace - According to C99 6.2.3, there are four 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.
- enum IdentifierNamespace {
- IDNS_Label = 0x1,
- IDNS_Tag = 0x2,
- IDNS_Member = 0x4,
- IDNS_Ordinary = 0x8
- };
-
- /// ObjCDeclQualifier - Qualifier used on types in method declarations
- /// for remote messaging. They are meant for the arguments though and
- /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
- enum ObjCDeclQualifier {
- OBJC_TQ_None = 0x0,
- OBJC_TQ_In = 0x1,
- OBJC_TQ_Inout = 0x2,
- OBJC_TQ_Out = 0x4,
- OBJC_TQ_Bycopy = 0x8,
- OBJC_TQ_Byref = 0x10,
- OBJC_TQ_Oneway = 0x20
- };
-
-private:
- /// Loc - The location that this decl.
- SourceLocation Loc;
-
- /// DeclKind - This indicates which class this is.
- Kind DeclKind : 8;
-
- /// InvalidDecl - This indicates a semantic error occurred.
- unsigned int InvalidDecl : 1;
-
- /// HasAttrs - This indicates whether the decl has attributes or not.
- unsigned int HasAttrs : 1;
-
- protected:
- /// Access - Used by C++ decls for the access specifier.
- // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
- unsigned Access : 2;
- friend class CXXClassMemberWrapper;
-
- Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false) {
- if (Decl::CollectingStats()) addDeclKind(DK);
- }
-
- virtual ~Decl();
-
-public:
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- Kind getKind() const { return DeclKind; }
- const char *getDeclKindName() const;
-
- void addAttr(Attr *attr);
- const Attr *getAttrs() const;
- void swapAttrs(Decl *D);
- void invalidateAttrs();
-
- template<typename T> const T *getAttr() const {
- for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
- if (const T *V = dyn_cast<T>(attr))
- return V;
-
- return 0;
- }
-
- /// setInvalidDecl - Indicates the Decl had a semantic error. This
- /// allows for graceful error recovery.
- void setInvalidDecl() { InvalidDecl = 1; }
- bool isInvalidDecl() const { return (bool) InvalidDecl; }
-
- IdentifierNamespace getIdentifierNamespace() const {
- switch (DeclKind) {
- default: assert(0 && "Unknown decl kind!");
- case ImplicitParam:
- case Typedef:
- case Function:
- case Var:
- case ParmVar:
- case EnumConstant:
- case ObjCInterface:
- case ObjCCompatibleAlias:
- case CXXField:
- case CXXMethod:
- case CXXClassVar:
- return IDNS_Ordinary;
- case Struct:
- case Union:
- case Class:
- case CXXStruct:
- case CXXUnion:
- case CXXClass:
- case Enum:
- return IDNS_Tag;
- case Namespace:
- return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary);
- }
- }
-
- // getBody - If this Decl represents a declaration for a body of code,
- // such as a function or method definition, this method returns the top-level
- // Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody() const { return 0; }
-
- // global temp stats (until we have a per-module visitor)
- static void addDeclKind(Kind k);
- static bool CollectingStats(bool Enable = false);
- static void PrintStats();
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *) { return true; }
-
- /// Emit - Serialize this Decl to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Create - Deserialize a Decl from Bitcode.
- static Decl* Create(llvm::Deserializer& D, ASTContext& C);
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
-protected:
- /// EmitImpl - Provides the subclass-specific serialization logic for
- /// serializing out a decl.
- virtual void EmitImpl(llvm::Serializer& S) const {
- // FIXME: This will eventually be a pure virtual function.
- assert (false && "Not implemented.");
- }
-
- void EmitInRec(llvm::Serializer& S) const;
- void ReadInRec(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// DeclContext - This is used only as base class of specific decl types that
-/// can act as declaration contexts. These decls are:
-///
-/// TranslationUnitDecl
-/// NamespaceDecl
-/// FunctionDecl
-/// CXXRecordDecl
-/// EnumDecl
-/// ObjCMethodDecl
-/// ObjCInterfaceDecl
-///
-class DeclContext {
- /// DeclKind - This indicates which class this is.
- Decl::Kind DeclKind : 8;
-
- /// DeclChain - Linked list of declarations that are defined inside this
- /// declaration context.
- ScopedDecl *DeclChain;
-
- // Used in the CastTo template to get the DeclKind
- // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
- // to avoid 'ambiguous access' compiler errors.
- template<typename T> struct KindTrait {
- static Decl::Kind getKind(const T *D) { return D->getKind(); }
- };
-
- // Used only by the ToDecl and FromDecl methods
- template<typename To, typename From>
- static To *CastTo(const From *D) {
- Decl::Kind DK = KindTrait<From>::getKind(D);
- switch(DK) {
- case Decl::TranslationUnit:
- return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
- case Decl::Namespace:
- return static_cast<NamespaceDecl*>(const_cast<From*>(D));
- case Decl::Enum:
- return static_cast<EnumDecl*>(const_cast<From*>(D));
- case Decl::ObjCMethod:
- return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
- case Decl::ObjCInterface:
- return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
- default:
- if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
- return static_cast<FunctionDecl*>(const_cast<From*>(D));
- if (DK >= Decl::CXXRecordFirst && DK <= Decl::CXXRecordLast)
- return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
-
- assert(false && "a decl that inherits DeclContext isn't handled");
- return 0;
- }
- }
-
-protected:
- DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {}
-
-public:
- /// getParent - Returns the containing DeclContext if this is a ScopedDecl,
- /// else returns NULL.
- DeclContext *getParent() const;
-
- bool isFunctionOrMethod() const {
- switch (DeclKind) {
- case Decl::Function:
- case Decl::CXXMethod:
- case Decl::ObjCMethod:
- return true;
- default:
- return false;
- }
- }
-
- ScopedDecl *getDeclChain() const { return DeclChain; }
- void setDeclChain(ScopedDecl *D) { DeclChain = D; }
-
- /// ToDecl and FromDecl make Decl <-> DeclContext castings.
- /// They are intended to be used by the simplify_type and cast_convert_val
- /// templates.
- static Decl *ToDecl (const DeclContext *D);
- static DeclContext *FromDecl (const Decl *D);
-
- static bool classof(const Decl *D) {
- switch (D->getKind()) {
- case Decl::TranslationUnit:
- case Decl::Namespace:
- case Decl::Enum:
- case Decl::ObjCMethod:
- case Decl::ObjCInterface:
- return true;
- default:
- if (D->getKind() >= Decl::FunctionFirst &&
- D->getKind() <= Decl::FunctionLast)
- return true;
- if (D->getKind() >= Decl::CXXRecordFirst &&
- D->getKind() <= Decl::CXXRecordLast)
- return true;
- return false;
- }
- }
- static bool classof(const DeclContext *D) { return true; }
- static bool classof(const TranslationUnitDecl *D) { return true; }
- static bool classof(const NamespaceDecl *D) { return true; }
- static bool classof(const FunctionDecl *D) { return true; }
- static bool classof(const CXXRecordDecl *D) { return true; }
- static bool classof(const EnumDecl *D) { return true; }
- static bool classof(const ObjCMethodDecl *D) { return true; }
- static bool classof(const ObjCInterfaceDecl *D) { return true; }
-
-private:
- void EmitOutRec(llvm::Serializer& S) const;
- void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
-
- friend class Decl;
-};
-
-template<> struct DeclContext::KindTrait<DeclContext> {
- static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
-};
-
-} // end clang.
-
-namespace llvm {
-/// Implement simplify_type for DeclContext, so that we can dyn_cast from
-/// DeclContext to a specific Decl class.
- template<> struct simplify_type<const ::clang::DeclContext*> {
- typedef ::clang::Decl* SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::DeclContext *Val) {
- return ::clang::DeclContext::ToDecl(Val);
- }
-};
-template<> struct simplify_type< ::clang::DeclContext*>
- : public simplify_type<const ::clang::DeclContext*> {};
-
-template<> struct simplify_type<const ::clang::DeclContext> {
- typedef ::clang::Decl SimpleType;
- static SimpleType &getSimplifiedValue(const ::clang::DeclContext &Val) {
- return *::clang::DeclContext::ToDecl(&Val);
- }
-};
-template<> struct simplify_type< ::clang::DeclContext>
- : public simplify_type<const ::clang::DeclContext> {};
-
-/// Implement cast_convert_val for DeclContext, so that we can dyn_cast from
-/// a Decl class to DeclContext.
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> {
- static ::clang::DeclContext &doit(const FromTy &Val) {
- return *::clang::DeclContext::FromDecl(&Val);
- }
-};
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext,FromTy,FromTy>
- : public cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy>
- {};
-
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> {
- static ::clang::DeclContext *doit(const FromTy *Val) {
- return ::clang::DeclContext::FromDecl(Val);
- }
-};
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext,FromTy*,FromTy*>
- : public cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*>
- {};
-
-} // end namespace llvm
-
-#endif
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
deleted file mode 100644
index dc72267554ea..000000000000
--- a/clang/include/clang/AST/DeclCXX.h
+++ /dev/null
@@ -1,194 +0,0 @@
-//===-- DeclCXX.h - Classes for representing C++ declarations *- 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 C++ Decl subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLCXX_H
-#define LLVM_CLANG_AST_DECLCXX_H
-
-#include "clang/AST/Decl.h"
-
-namespace clang {
-class CXXRecordDecl;
-
-/// CXXFieldDecl - Represents an instance field of a C++ struct/union/class.
-class CXXFieldDecl : public FieldDecl {
- CXXRecordDecl *Parent;
-
- CXXFieldDecl(CXXRecordDecl *RD, SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *BW = NULL)
- : FieldDecl(CXXField, L, Id, T, BW), Parent(RD) {}
-public:
- static CXXFieldDecl *Create(ASTContext &C, CXXRecordDecl *RD,SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *BW = NULL);
-
- void setAccess(AccessSpecifier AS) { Access = AS; }
- AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
- CXXRecordDecl *getParent() const { return Parent; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == CXXField; }
- static bool classof(const CXXFieldDecl *D) { return true; }
-};
-
-/// CXXRecordDecl - Represents a C++ struct/union/class.
-/// The only difference with RecordDecl is that CXXRecordDecl is a DeclContext.
-class CXXRecordDecl : public RecordDecl, public DeclContext {
-protected:
- CXXRecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
- : RecordDecl(DK, DC, L, Id), DeclContext(DK) {
- assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
- }
-public:
- static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- CXXRecordDecl* PrevDecl=0);
-
- const CXXFieldDecl *getMember(unsigned i) const {
- return cast<const CXXFieldDecl>(RecordDecl::getMember(i));
- }
- CXXFieldDecl *getMember(unsigned i) {
- return cast<CXXFieldDecl>(RecordDecl::getMember(i));
- }
-
- /// getMember - If the member doesn't exist, or there are no members, this
- /// function will return 0;
- CXXFieldDecl *getMember(IdentifierInfo *name) {
- return cast_or_null<CXXFieldDecl>(RecordDecl::getMember(name));
- }
-
- static bool classof(const Decl *D) {
- return D->getKind() >= CXXRecordFirst && D->getKind() <= CXXRecordLast;
- }
- static bool classof(const CXXRecordDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this CXXRecordDecl. Called by Decl::Emit.
- // FIXME: Implement this.
- //virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a CXXRecordDecl. Called by Decl::Create.
- // FIXME: Implement this.
- static CXXRecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CXXMethodDecl - Represents a static or instance method of a
-/// struct/union/class.
-class CXXMethodDecl : public FunctionDecl {
-
- CXXMethodDecl(CXXRecordDecl *RD, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- bool isStatic, bool isInline, ScopedDecl *PrevDecl)
- : FunctionDecl(CXXMethod, RD, L, Id, T, (isStatic ? Static : None),
- isInline, PrevDecl) {}
-public:
- static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, bool isStatic = false,
- bool isInline = false, ScopedDecl *PrevDecl = 0);
-
- bool isStatic() const { return getStorageClass() == Static; }
- bool isInstance() const { return !isStatic(); }
-
- void setAccess(AccessSpecifier AS) { Access = AS; }
- AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-
- /// getThisType - Returns the type of 'this' pointer.
- /// Should only be called for instance methods.
- QualType getThisType(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == CXXMethod; }
- static bool classof(const CXXMethodDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this CXXMethodDecl. Called by Decl::Emit.
- // FIXME: Implement this.
- //virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a CXXMethodDecl. Called by Decl::Create.
- // FIXME: Implement this.
- static CXXMethodDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CXXClassVarDecl - Represents a static data member of a struct/union/class.
-class CXXClassVarDecl : public VarDecl {
-
- CXXClassVarDecl(CXXRecordDecl *RD, SourceLocation L,
- IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
- : VarDecl(CXXClassVar, RD, L, Id, T, None, PrevDecl) {}
-public:
- static CXXClassVarDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L,IdentifierInfo *Id,
- QualType T, ScopedDecl *PrevDecl);
-
- void setAccess(AccessSpecifier AS) { Access = AS; }
- AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == CXXClassVar; }
- static bool classof(const CXXClassVarDecl *D) { return true; }
-
-protected:
- /// EmitImpl - Serialize this CXXClassVarDecl. Called by Decl::Emit.
- // FIXME: Implement this.
- //virtual void EmitImpl(llvm::Serializer& S) const;
-
- /// CreateImpl - Deserialize a CXXClassVarDecl. Called by Decl::Create.
- // FIXME: Implement this.
- static CXXClassVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
- friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// CXXClassMemberWrapper - A wrapper class for C++ class member decls.
-/// Common functions like set/getAccess are included here to avoid bloating
-/// the interface of non-C++ specific decl classes, like NamedDecl.
-class CXXClassMemberWrapper {
- Decl *MD;
-
-public:
- CXXClassMemberWrapper(Decl *D) : MD(D) {
- assert(isMember(D) && "Not a C++ class member!");
- }
-
- AccessSpecifier getAccess() const {
- return AccessSpecifier(MD->Access);
- }
-
- void setAccess(AccessSpecifier AS) {
- assert(AS != AS_none && "Access must be specified.");
- MD->Access = AS;
- }
-
- CXXRecordDecl *getParent() const {
- if (ScopedDecl *SD = dyn_cast<ScopedDecl>(MD)) {
- return cast<CXXRecordDecl>(SD->getDeclContext());
- }
- return cast<CXXFieldDecl>(MD)->getParent();
- }
-
- static bool isMember(Decl *D) {
- if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
- return isa<CXXRecordDecl>(SD->getDeclContext());
- }
- return isa<CXXFieldDecl>(D);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/DeclGroup.h b/clang/include/clang/AST/DeclGroup.h
deleted file mode 100644
index 0dac050ad2bb..000000000000
--- a/clang/include/clang/AST/DeclGroup.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//===--- DeclGroup.h - Classes for representing groups of Decls -*- 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 DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLGROUP_H
-#define LLVM_CLANG_AST_DECLGROUP_H
-
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include <cassert>
-
-namespace clang {
-
-class ASTContext;
-class Decl;
-class DeclGroup;
-class DeclGroupIterator;
-
-class DeclGroup {
- // FIXME: Include a TypeSpecifier object.
- unsigned NumDecls;
-
-private:
- DeclGroup() : NumDecls(0) {}
- DeclGroup(unsigned numdecls, Decl** decls);
-
-public:
- static DeclGroup* Create(ASTContext& C, unsigned numdecls, Decl** decls);
- void Destroy(ASTContext& C);
-
- unsigned size() const { return NumDecls; }
- Decl*& operator[](unsigned i) {
- assert (i < NumDecls && "Out-of-bounds access.");
- return *((Decl**) (this+1));
- }
-
- const Decl*& operator[](unsigned i) const {
- assert (i < NumDecls && "Out-of-bounds access.");
- return *((const Decl**) (this+1));
- }
-
- /// Emit - Serialize a DeclGroup to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Deserialize a DeclGroup from Bitcode.
- static DeclGroup* Create(llvm::Deserializer& D, ASTContext& C);
-};
-
-class DeclGroupRef {
-protected:
- enum Kind { DeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
- Decl* D;
-
- Kind getKind() const {
- return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
- }
-
-public:
- DeclGroupRef() : D(0) {}
-
- explicit DeclGroupRef(Decl* d) : D(d) {}
- explicit DeclGroupRef(DeclGroup* dg)
- : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
-
- typedef Decl** iterator;
-
- iterator begin() {
- if (getKind() == DeclKind) return D ? &D : 0;
- DeclGroup& G = *((DeclGroup*) (reinterpret_cast<uintptr_t>(D) & ~Mask));
- return &G[0];
- }
-
- iterator end() {
- if (getKind() == DeclKind) return D ? &D + 1 : 0;
- DeclGroup& G = *((DeclGroup*) (reinterpret_cast<uintptr_t>(D) & ~Mask));
- return &G[0] + G.size();
- }
-
- /// Emit - Serialize a DeclGroupRef to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Deserialize a DeclGroupRef from Bitcode.
- static DeclGroupRef ReadVal(llvm::Deserializer& D);
-};
-
-class DeclGroupOwningRef : public DeclGroupRef {
-public:
- explicit DeclGroupOwningRef(Decl* d) : DeclGroupRef(d) {}
- explicit DeclGroupOwningRef(DeclGroup* dg) : DeclGroupRef(dg) {}
-
- ~DeclGroupOwningRef();
- void Destroy(ASTContext& C);
-
- DeclGroupOwningRef(DeclGroupOwningRef& R)
- : DeclGroupRef(R) { R.D = 0; }
-
- DeclGroupOwningRef& operator=(DeclGroupOwningRef& R) {
- D = R.D;
- R.D = 0;
- return *this;
- }
-
- /// Emit - Serialize a DeclGroupOwningRef to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Deserialize a DeclGroupOwningRef from Bitcode.
- static DeclGroupOwningRef ReadVal(llvm::Deserializer& D, ASTContext& C);
-};
-
-} // end clang namespace
-#endif
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
deleted file mode 100644
index 34e60e62f367..000000000000
--- a/clang/include/clang/AST/DeclObjC.h
+++ /dev/null
@@ -1,1318 +0,0 @@
-//===--- DeclObjC.h - Classes for representing declarations -----*- 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 DeclObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLOBJC_H
-#define LLVM_CLANG_AST_DECLOBJC_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Basic/IdentifierTable.h"
-
-namespace clang {
-class Expr;
-class Stmt;
-class FunctionDecl;
-class AttributeList;
-class ObjCIvarDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
-class ObjCCategoryDecl;
-class ObjCPropertyDecl;
-class ObjCPropertyImplDecl;
-
-
-/// ObjCList - This is a simple template class used to hold various lists of
-/// decls etc, which is heavily used by the ObjC front-end. This only use case
-/// this supports is setting the list all at once and then reading elements out
-/// of it.
-template <typename T>
-class ObjCList {
- /// List is a new[]'d array of pointers to objects that are not owned by this
- /// list.
- T **List;
- unsigned NumElts;
-
- void operator=(const ObjCList &); // DO NOT IMPLEMENT
- ObjCList(const ObjCList&); // DO NOT IMPLEMENT
-public:
- ObjCList() : List(0), NumElts(0) {}
- ~ObjCList() {
- delete[] List;
- }
-
- void set(T* const* InList, unsigned Elts) {
- assert(List == 0 && "Elements already set!");
- List = new T*[Elts];
- NumElts = Elts;
- memcpy(List, InList, sizeof(T*)*Elts);
- }
-
- typedef T* const * iterator;
- iterator begin() const { return List; }
- iterator end() const { return List+NumElts; }
-
- unsigned size() const { return NumElts; }
- bool empty() const { return NumElts == 0; }
-
- T* operator[](unsigned idx) const {
- assert(idx < NumElts && "Invalid access");
- return List[idx];
- }
-};
-
-
-
-/// ObjCMethodDecl - Represents an instance or class method declaration.
-/// ObjC methods can be declared within 4 contexts: class interfaces,
-/// categories, protocols, and class implementations. While C++ member
-/// functions leverage C syntax, Objective-C method syntax is modeled after
-/// Smalltalk (using colons to specify argument types/expressions).
-/// Here are some brief examples:
-///
-/// Setter/getter instance methods:
-/// - (void)setMenu:(NSMenu *)menu;
-/// - (NSMenu *)menu;
-///
-/// Instance method that takes 2 NSView arguments:
-/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
-///
-/// Getter class method:
-/// + (NSMenu *)defaultMenu;
-///
-/// A selector represents a unique name for a method. The selector names for
-/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
-///
-class ObjCMethodDecl : public Decl, public DeclContext {
-public:
- enum ImplementationControl { None, Required, Optional };
-private:
- /// Bitfields must be first fields in this class so they pack with those
- /// declared in class Decl.
- /// instance (true) or class (false) method.
- bool IsInstance : 1;
- bool IsVariadic : 1;
-
- // Synthesized declaration method for a property setter/getter
- bool IsSynthesized : 1;
-
- // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
- /// @required/@optional
- unsigned DeclImplementation : 2;
-
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// in, inout, etc.
- unsigned objcDeclQualifier : 6;
-
- // Context this method is declared in.
- NamedDecl *MethodContext;
-
- // A unigue name for this method.
- Selector SelName;
-
- // Type of this method.
- QualType MethodDeclType;
- /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
- /// parameters of this Method. This is null if there are no formals.
- ParmVarDecl **ParamInfo;
- unsigned NumMethodParams;
-
- /// List of attributes for this method declaration.
- SourceLocation EndLoc; // the location of the ';' or '{'.
-
- // The following are only used for method definitions, null otherwise.
- // FIXME: space savings opportunity, consider a sub-class.
- Stmt *Body;
-
- /// SelfDecl - Decl for the implicit self parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *SelfDecl;
- /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *CmdDecl;
-
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T,
- Decl *contextDecl,
- bool isInstance = true,
- bool isVariadic = false,
- bool isSynthesized = false,
- ImplementationControl impControl = None)
- : Decl(ObjCMethod, beginLoc),
- DeclContext(ObjCMethod),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsSynthesized(isSynthesized),
- DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
- MethodContext(static_cast<NamedDecl*>(contextDecl)),
- SelName(SelInfo), MethodDeclType(T),
- ParamInfo(0), NumMethodParams(0),
- EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
-
- virtual ~ObjCMethodDecl();
-
-public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
- static ObjCMethodDecl *Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc, Selector SelInfo,
- QualType T, Decl *contextDecl,
- bool isInstance = true,
- bool isVariadic = false,
- bool isSynthesized = false,
- ImplementationControl impControl = None);
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); }
- SourceLocation getLocEnd() const { return EndLoc; }
- SourceRange getSourceRange() const {
- return SourceRange(getLocation(), EndLoc);
- }
-
- NamedDecl *getMethodContext() const { return MethodContext; }
-
- ObjCInterfaceDecl *getClassInterface();
- const ObjCInterfaceDecl *getClassInterface() const {
- return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
- }
-
- Selector getSelector() const { return SelName; }
- unsigned getSynthesizedMethodSize() const;
- QualType getResultType() const { return MethodDeclType; }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return NumMethodParams; }
- typedef ParmVarDecl **param_iterator;
- typedef ParmVarDecl * const *param_const_iterator;
- param_iterator param_begin() { return ParamInfo; }
- param_iterator param_end() { return ParamInfo+param_size(); }
- param_const_iterator param_begin() const { return ParamInfo; }
- param_const_iterator param_end() const { return ParamInfo+param_size(); }
-
- unsigned getNumParams() const { return NumMethodParams; }
- ParmVarDecl *getParamDecl(unsigned i) const {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- void setParamDecl(int i, ParmVarDecl *pDecl) {
- ParamInfo[i] = pDecl;
- }
- void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
-
- /// createImplicitParams - Used to lazily create the self and cmd
- /// implict parameters. This must be called prior to using getSelfDecl()
- /// or getCmdDecl(). The call is ignored if the implicit paramters
- /// have already been created.
- void createImplicitParams(ASTContext &Context);
-
- ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
- ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
-
- bool isInstance() const { return IsInstance; }
- bool isVariadic() const { return IsVariadic; }
-
- bool isSynthesized() const { return IsSynthesized; }
-
- // Related to protocols declared in @protocol
- void setDeclImplementation(ImplementationControl ic) {
- DeclImplementation = ic;
- }
- ImplementationControl getImplementationControl() const {
- return ImplementationControl(DeclImplementation);
- }
-
- virtual Stmt *getBody() const { return Body; }
- void setBody(Stmt *B) { Body = B; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
- static bool classof(const ObjCMethodDecl *D) { return true; }
-};
-
-/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
-///
-/// // MostPrimitive declares no super class (not particularly useful).
-/// @interface MostPrimitive
-/// // no instance variables or methods.
-/// @end
-///
-/// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
-/// @interface NSResponder : NSObject <NSCoding>
-/// { // instance variables are represented by ObjCIvarDecl.
-/// id nextResponder; // nextResponder instance variable.
-/// }
-/// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
-/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
-/// @end // to an NSEvent.
-///
-/// Unlike C/C++, forward class declarations are accomplished with @class.
-/// Unlike C/C++, @class allows for a list of classes to be forward declared.
-/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
-/// typically inherit from NSObject (an exception is NSProxy).
-///
-class ObjCInterfaceDecl : public NamedDecl, public DeclContext {
- /// TypeForDecl - This indicates the Type object that represents this
- /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
- Type *TypeForDecl;
- friend class ASTContext;
-
- /// Class's super class.
- ObjCInterfaceDecl *SuperClass;
-
- /// Protocols referenced in interface header declaration
- ObjCList<ObjCProtocolDecl> ReferencedProtocols;
-
- /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
- ObjCIvarDecl **Ivars; // Null if not defined.
- unsigned NumIvars; // 0 if none.
-
- /// instance methods
- ObjCMethodDecl **InstanceMethods; // Null if not defined
- unsigned NumInstanceMethods; // 0 if none.
-
- /// class methods
- ObjCMethodDecl **ClassMethods; // Null if not defined
- unsigned NumClassMethods; // 0 if none
-
- /// List of categories defined for this class.
- ObjCCategoryDecl *CategoryList;
-
- /// class properties
- ObjCPropertyDecl **PropertyDecl; // Null if no property
- unsigned NumPropertyDecl; // 0 if none.
-
- bool ForwardDecl:1; // declared with @class.
- bool InternalInterface:1; // true - no @interface for @implementation
-
- SourceLocation ClassLoc; // location of the class identifier.
- SourceLocation SuperClassLoc; // location of the super class identifier.
- SourceLocation EndLoc; // marks the '>', '}', or identifier.
- SourceLocation AtEndLoc; // marks the end of the entire interface.
-
- ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
- SourceLocation CLoc, bool FD, bool isInternal)
- : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
- TypeForDecl(0), SuperClass(0),
- Ivars(0), NumIvars(0),
- InstanceMethods(0), NumInstanceMethods(0),
- ClassMethods(0), NumClassMethods(0),
- CategoryList(0), PropertyDecl(0), NumPropertyDecl(0),
- ForwardDecl(FD), InternalInterface(isInternal),
- ClassLoc(CLoc) {
- }
-
- virtual ~ObjCInterfaceDecl();
-
-public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
- static ObjCInterfaceDecl *Create(ASTContext &C,
- SourceLocation atLoc,
- IdentifierInfo *Id,
- SourceLocation ClassLoc = SourceLocation(),
- bool ForwardDecl = false,
- bool isInternal = false);
- const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
- return ReferencedProtocols;
- }
-
- ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
- ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
- ObjCIvarDecl *FindIvarDeclaration(IdentifierInfo *IvarId) const;
-
- typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
- protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
-
- typedef ObjCIvarDecl * const *ivar_iterator;
- ivar_iterator ivar_begin() const { return Ivars; }
- ivar_iterator ivar_end() const { return Ivars + ivar_size();}
- unsigned ivar_size() const { return NumIvars; }
- bool ivar_empty() const { return NumIvars == 0; }
-
- unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
- unsigned getNumClassMethods() const { return NumClassMethods; }
-
- typedef ObjCMethodDecl * const * instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods; }
- instmeth_iterator instmeth_end() const {
- return InstanceMethods+NumInstanceMethods;
- }
-
- typedef ObjCMethodDecl * const * classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods; }
- classmeth_iterator classmeth_end() const {
- return ClassMethods+NumClassMethods;
- }
-
- /// addReferencedProtocols - Set the list of protocols that this interface
- /// implements.
- void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) {
- ReferencedProtocols.set(List, NumRPs);
- }
-
- void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
- SourceLocation RBracLoc);
-
- void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
- ObjCMethodDecl **clsMethods, unsigned numClsMembers,
- SourceLocation AtEnd);
-
- void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
-
- void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
-
- void addPropertyMethods(ASTContext &Context,
- ObjCPropertyDecl* Property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods);
-
- typedef ObjCPropertyDecl * const * classprop_iterator;
- classprop_iterator classprop_begin() const { return PropertyDecl; }
- classprop_iterator classprop_end() const {
- return PropertyDecl+NumPropertyDecl;
- }
-
- bool isForwardDecl() const { return ForwardDecl; }
- void setForwardDecl(bool val) { ForwardDecl = val; }
-
- ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
- void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
-
- ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
- void setCategoryList(ObjCCategoryDecl *category) {
- CategoryList = category;
- }
-
- /// isSuperClassOf - Return true if this class is the specified class or is a
- /// super class of the specified interface class.
- bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
- // If RHS is derived from LHS it is OK; else it is not OK.
- while (I != NULL) {
- if (this == I)
- return true;
- I = I->getSuperClass();
- }
- return false;
- }
-
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
- ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
- ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(IVarName, ClassDeclared);
- }
-
-
- // Get the local instance method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
- }
- return 0;
- }
- // Get the local class method declared in this interface.
- ObjCMethodDecl *getClassMethod(Selector Sel) const {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
- }
- return 0;
- }
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
- ObjCMethodDecl *lookupClassMethod(Selector Sel);
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); } // '@'interface
- SourceLocation getLocEnd() const { return EndLoc; }
- void setLocEnd(SourceLocation LE) { EndLoc = LE; };
-
- SourceLocation getClassLoc() const { return ClassLoc; }
- void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
- SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
-
- // We also need to record the @end location.
- SourceLocation getAtEndLoc() const { return AtEndLoc; }
-
- unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
-
- ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
- ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
-
- /// ImplicitInterfaceDecl - check that this is an implicitely declared
- /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
- /// declaration without an @interface declaration.
- bool ImplicitInterfaceDecl() const { return InternalInterface; }
-
- static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
- static bool classof(const ObjCInterfaceDecl *D) { return true; }
-};
-
-/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
-/// instance variables are identical to C. The only exception is Objective-C
-/// supports C++ style access control. For example:
-///
-/// @interface IvarExample : NSObject
-/// {
-/// id defaultToProtected;
-/// @public:
-/// id canBePublic; // same as C++.
-/// @protected:
-/// id canBeProtected; // same as C++.
-/// @package:
-/// id canBePackage; // framework visibility (not available in C++).
-/// }
-///
-class ObjCIvarDecl : public FieldDecl {
-public:
- enum AccessControl {
- None, Private, Protected, Public, Package
- };
-
-private:
- ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
- AccessControl ac, Expr *BW)
- : FieldDecl(ObjCIvar, L, Id, T, BW), DeclAccess(ac) {}
-
-public:
- static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- AccessControl ac, Expr *BW = NULL);
-
- void setAccessControl(AccessControl ac) { DeclAccess = ac; }
-
- AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
-
- AccessControl getCanonicalAccessControl() const {
- return DeclAccess == None ? Protected : AccessControl(DeclAccess);
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
- static bool classof(const ObjCIvarDecl *D) { return true; }
-private:
- // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
- unsigned DeclAccess : 3;
-};
-
-
-/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
-/// @defs(...).
-class ObjCAtDefsFieldDecl : public FieldDecl {
-private:
- ObjCAtDefsFieldDecl(SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *BW)
- : FieldDecl(ObjCAtDefsField, L, Id, T, BW) {}
-
-public:
- static ObjCAtDefsFieldDecl *Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- Expr *BW);
-
- virtual void Destroy(ASTContext& C);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
- static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
-};
-
-/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
-/// declare a pure abstract type (i.e no instance variables are permitted).
-/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
-/// feature with nice semantics and lousy syntax:-). Here is an example:
-///
-/// @protocol NSDraggingInfo <refproto1, refproto2>
-/// - (NSWindow *)draggingDestinationWindow;
-/// - (NSImage *)draggedImage;
-/// @end
-///
-/// This says that NSDraggingInfo requires two methods and requires everything
-/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
-/// well.
-///
-/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
-/// @end
-///
-/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
-/// protocols are in distinct namespaces. For example, Cocoa defines both
-/// an NSObject protocol and class (which isn't allowed in Java). As a result,
-/// protocols are referenced using angle brackets as follows:
-///
-/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
-///
-class ObjCProtocolDecl : public NamedDecl {
- /// Referenced protocols
- ObjCList<ObjCProtocolDecl> ReferencedProtocols;
-
- /// protocol instance methods
- ObjCMethodDecl **InstanceMethods; // Null if not defined
- unsigned NumInstanceMethods; // 0 if none
-
- /// protocol class methods
- ObjCMethodDecl **ClassMethods; // Null if not defined
- unsigned NumClassMethods; // 0 if none
-
- /// protocol properties
- ObjCPropertyDecl **PropertyDecl; // Null if no property
- unsigned NumPropertyDecl; // 0 if none
-
- bool isForwardProtoDecl; // declared with @protocol.
-
- SourceLocation EndLoc; // marks the '>' or identifier.
- SourceLocation AtEndLoc; // marks the end of the entire interface.
-
- ObjCProtocolDecl(SourceLocation L, IdentifierInfo *Id)
- : NamedDecl(ObjCProtocol, L, Id),
- InstanceMethods(0), NumInstanceMethods(0),
- ClassMethods(0), NumClassMethods(0),
- PropertyDecl(0), NumPropertyDecl(0),
- isForwardProtoDecl(true) {
- }
-
- virtual ~ObjCProtocolDecl();
-
-public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
- static ObjCProtocolDecl *Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id);
-
- void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
- ObjCMethodDecl **clsMethods, unsigned numClsMembers,
- SourceLocation AtEndLoc);
-
- const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
- return ReferencedProtocols;
- }
- typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
- protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
-
- /// addReferencedProtocols - Set the list of protocols that this interface
- /// implements.
- void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) {
- ReferencedProtocols.set(List, NumRPs);
- }
-
- unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
- unsigned getNumClassMethods() const { return NumClassMethods; }
-
- ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
-
- unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
-
- ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
- ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
-
- void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
-
- void addPropertyMethods(ASTContext &Context,
- ObjCPropertyDecl* Property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods);
-
- typedef ObjCPropertyDecl * const * classprop_iterator;
- classprop_iterator classprop_begin() const { return PropertyDecl; }
- classprop_iterator classprop_end() const {
- return PropertyDecl+NumPropertyDecl;
- }
-
- typedef ObjCMethodDecl * const * instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods; }
- instmeth_iterator instmeth_end() const {
- return InstanceMethods+NumInstanceMethods;
- }
-
- typedef ObjCMethodDecl * const * classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods; }
- classmeth_iterator classmeth_end() const {
- return ClassMethods+NumClassMethods;
- }
-
- // Get the local instance method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
- }
- return 0;
- }
- // Get the local class method declared in this interface.
- ObjCMethodDecl *getClassMethod(Selector Sel) const {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
- }
- return 0;
- }
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
- ObjCMethodDecl *lookupClassMethod(Selector Sel);
-
- bool isForwardDecl() const { return isForwardProtoDecl; }
- void setForwardDecl(bool val) { isForwardProtoDecl = val; }
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
- SourceLocation getLocEnd() const { return EndLoc; }
- void setLocEnd(SourceLocation LE) { EndLoc = LE; };
-
- // We also need to record the @end location.
- SourceLocation getAtEndLoc() const { return AtEndLoc; }
-
- static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
- static bool classof(const ObjCProtocolDecl *D) { return true; }
-};
-
-/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
-///
-/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
-///
-class ObjCClassDecl : public Decl {
- ObjCInterfaceDecl **ForwardDecls;
- unsigned NumForwardDecls;
-
- ObjCClassDecl(SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts)
- : Decl(ObjCClass, L) {
- if (nElts) {
- ForwardDecls = new ObjCInterfaceDecl*[nElts];
- memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
- } else {
- ForwardDecls = 0;
- }
- NumForwardDecls = nElts;
- }
-
- virtual ~ObjCClassDecl();
-
-public:
-
- /// Destroy - Call destructors and release memory.
- virtual void Destroy(ASTContext& C);
-
- static ObjCClassDecl *Create(ASTContext &C, SourceLocation L,
- ObjCInterfaceDecl **Elts, unsigned nElts);
-
- void setInterfaceDecl(unsigned idx, ObjCInterfaceDecl *OID) {
- assert(idx < NumForwardDecls && "index out of range");
- ForwardDecls[idx] = OID;
- }
- ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; }
- int getNumForwardDecls() const { return NumForwardDecls; }
-
- typedef ObjCInterfaceDecl * const * iterator;
- iterator begin() const { return ForwardDecls; }
- iterator end() const { return ForwardDecls+NumForwardDecls; }
-
- static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
- static bool classof(const ObjCClassDecl *D) { return true; }
-};
-
-/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
-/// For example:
-///
-/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
-///
-class ObjCForwardProtocolDecl : public Decl {
- ObjCProtocolDecl **ReferencedProtocols;
- unsigned NumReferencedProtocols;
-
- ObjCForwardProtocolDecl(SourceLocation L,
- ObjCProtocolDecl **Elts, unsigned nElts)
- : Decl(ObjCForwardProtocol, L) {
- NumReferencedProtocols = nElts;
- if (nElts) {
- ReferencedProtocols = new ObjCProtocolDecl*[nElts];
- memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
- } else {
- ReferencedProtocols = 0;
- }
- }
-
- virtual ~ObjCForwardProtocolDecl();
-
-public:
- static ObjCForwardProtocolDecl *Create(ASTContext &C, SourceLocation L,
- ObjCProtocolDecl **Elts, unsigned Num);
-
-
- void setForwardProtocolDecl(unsigned idx, ObjCProtocolDecl *OID) {
- assert(idx < NumReferencedProtocols && "index out of range");
- ReferencedProtocols[idx] = OID;
- }
-
- unsigned getNumForwardDecls() const { return NumReferencedProtocols; }
-
- ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) {
- assert(idx < NumReferencedProtocols && "index out of range");
- return ReferencedProtocols[idx];
- }
- const ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) const {
- assert(idx < NumReferencedProtocols && "index out of range");
- return ReferencedProtocols[idx];
- }
-
- typedef ObjCProtocolDecl * const * iterator;
- iterator begin() const { return ReferencedProtocols; }
- iterator end() const { return ReferencedProtocols+NumReferencedProtocols; }
-
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCForwardProtocol;
- }
- static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
-};
-
-/// ObjCCategoryDecl - Represents a category declaration. A category allows
-/// you to add methods to an existing class (without subclassing or modifying
-/// the original class interface or implementation:-). Categories don't allow
-/// you to add instance data. The following example adds "myMethod" to all
-/// NSView's within a process:
-///
-/// @interface NSView (MyViewMethods)
-/// - myMethod;
-/// @end
-///
-/// Cateogries also allow you to split the implementation of a class across
-/// several files (a feature more naturally supported in C++).
-///
-/// Categories were originally inspired by dynamic languages such as Common
-/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
-/// don't support this level of dynamism, which is both powerful and dangerous.
-///
-class ObjCCategoryDecl : public NamedDecl {
- /// Interface belonging to this category
- ObjCInterfaceDecl *ClassInterface;
-
- /// referenced protocols in this category.
- ObjCList<ObjCProtocolDecl> ReferencedProtocols;
-
- /// category instance methods
- ObjCMethodDecl **InstanceMethods; // Null if not defined
- unsigned NumInstanceMethods; // 0 if none
-
- /// category class methods
- ObjCMethodDecl **ClassMethods; // Null if not defined
- unsigned NumClassMethods; // 0 if not defined
-
- /// Next category belonging to this class
- ObjCCategoryDecl *NextClassCategory;
-
- /// category properties
- ObjCPropertyDecl **PropertyDecl; // Null if no property
- unsigned NumPropertyDecl; // 0 if none
-
- SourceLocation EndLoc; // marks the '>' or identifier.
- SourceLocation AtEndLoc; // marks the end of the entire interface.
-
- ObjCCategoryDecl(SourceLocation L, IdentifierInfo *Id)
- : NamedDecl(ObjCCategory, L, Id),
- ClassInterface(0),
- InstanceMethods(0), NumInstanceMethods(0),
- ClassMethods(0), NumClassMethods(0),
- NextClassCategory(0), PropertyDecl(0), NumPropertyDecl(0) {
- }
-public:
-
- static ObjCCategoryDecl *Create(ASTContext &C,
- SourceLocation L, IdentifierInfo *Id);
-
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
- void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
-
- /// addReferencedProtocols - Set the list of protocols that this interface
- /// implements.
- void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) {
- ReferencedProtocols.set(List, NumRPs);
- }
-
- const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
- return ReferencedProtocols;
- }
-
- typedef ObjCProtocolDecl * const * protocol_iterator;
- protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
-
-
- unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
- unsigned getNumClassMethods() const { return NumClassMethods; }
-
- unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
-
- ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
-
- void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
-
- void addPropertyMethods(ASTContext &Context,
- ObjCPropertyDecl* Property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods);
-
- ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
-
- typedef ObjCPropertyDecl * const * classprop_iterator;
- classprop_iterator classprop_begin() const { return PropertyDecl; }
- classprop_iterator classprop_end() const {
- return PropertyDecl+NumPropertyDecl;
- }
-
- typedef ObjCMethodDecl * const * instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods; }
- instmeth_iterator instmeth_end() const {
- return InstanceMethods+NumInstanceMethods;
- }
-
- typedef ObjCMethodDecl * const * classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods; }
- classmeth_iterator classmeth_end() const {
- return ClassMethods+NumClassMethods;
- }
-
- // Get the local instance method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
- }
- return 0;
- }
- // Get the local class method declared in this interface.
- ObjCMethodDecl *getClassMethod(Selector Sel) const {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I) {
- if ((*I)->getSelector() == Sel)
- return *I;
- }
- return 0;
- }
-
- void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
- ObjCMethodDecl **clsMethods, unsigned numClsMembers,
- SourceLocation AtEndLoc);
-
- ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
- void insertNextClassCategory() {
- NextClassCategory = ClassInterface->getCategoryList();
- ClassInterface->setCategoryList(this);
- }
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); } // '@'interface
- SourceLocation getLocEnd() const { return EndLoc; }
- void setLocEnd(SourceLocation LE) { EndLoc = LE; };
-
- // We also need to record the @end location.
- SourceLocation getAtEndLoc() const { return AtEndLoc; }
-
- static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
- static bool classof(const ObjCCategoryDecl *D) { return true; }
-};
-
-/// ObjCCategoryImplDecl - An object of this class encapsulates a category
-/// @implementation declaration. If a category class has declaration of a
-/// property, its implementation must be specified in the category's
-/// @implementation declaration. Example:
-/// @interface I @end
-/// @interface I(CATEGORY)
-/// @property int p1, d1;
-/// @end
-/// @implementation I(CATEGORY)
-/// @dynamic p1,d1;
-/// @end
-///
-class ObjCCategoryImplDecl : public NamedDecl {
- /// Class interface for this category implementation
- ObjCInterfaceDecl *ClassInterface;
-
- /// implemented instance methods
- llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
-
- /// implemented class methods
- llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
-
- /// Property Implementations in this category
- llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
-
- SourceLocation EndLoc;
-
- ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface)
- : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
-public:
- static ObjCCategoryImplDecl *Create(ASTContext &C,
- SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface);
-
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
-
- unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
- unsigned getNumClassMethods() const { return ClassMethods.size(); }
-
- void addInstanceMethod(ObjCMethodDecl *method) {
- InstanceMethods.push_back(method);
- }
- void addClassMethod(ObjCMethodDecl *method) {
- ClassMethods.push_back(method);
- }
- // Get the instance method definition for this implementation.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
-
- // Get the class method definition for this implementation.
- ObjCMethodDecl *getClassMethod(Selector Sel) const;
-
- void addPropertyImplementation(ObjCPropertyImplDecl *property) {
- PropertyImplementations.push_back(property);
- }
-
- unsigned getNumPropertyImplementations() const
- { return PropertyImplementations.size(); }
-
-
- typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
- propimpl_iterator;
- propimpl_iterator propimpl_begin() const {
- return PropertyImplementations.begin();
- }
- propimpl_iterator propimpl_end() const {
- return PropertyImplementations.end();
- }
-
- typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
- instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
- instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
-
- typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
- classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
- classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
-
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); }
- SourceLocation getLocEnd() const { return EndLoc; }
- void setLocEnd(SourceLocation LE) { EndLoc = LE; };
-
- static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
- static bool classof(const ObjCCategoryImplDecl *D) { return true; }
-};
-
-/// ObjCImplementationDecl - Represents a class definition - this is where
-/// method definitions are specified. For example:
-///
-/// @implementation MyClass
-/// - (void)myMethod { /* do something */ }
-/// @end
-///
-/// Typically, instance variables are specified in the class interface,
-/// *not* in the implemenentation. Nevertheless (for legacy reasons), we
-/// allow instance variables to be specified in the implementation. When
-/// specified, they need to be *identical* to the interface. Now that we
-/// have support for non-fragile ivars in ObjC 2.0, we can consider removing
-/// the legacy semantics and allow developers to move private ivar declarations
-/// from the class interface to the class implementation (but I digress:-)
-///
-class ObjCImplementationDecl : public NamedDecl {
- /// Class interface for this implementation
- ObjCInterfaceDecl *ClassInterface;
-
- /// Implementation Class's super class.
- ObjCInterfaceDecl *SuperClass;
-
- /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
- ObjCIvarDecl **Ivars; // Null if not specified
- unsigned NumIvars; // 0 if none.
-
- /// implemented instance methods
- llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
-
- /// implemented class methods
- llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
-
- /// Propertys' being implemented
- llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
-
- SourceLocation EndLoc;
-
- ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl)
- : NamedDecl(ObjCImplementation, L, Id),
- ClassInterface(classInterface), SuperClass(superDecl),
- Ivars(0), NumIvars(0) {}
-public:
- static ObjCImplementationDecl *Create(ASTContext &C,
- SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl);
-
-
- void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars,
- unsigned numIvars);
-
- void addInstanceMethod(ObjCMethodDecl *method) {
- InstanceMethods.push_back(method);
- }
- void addClassMethod(ObjCMethodDecl *method) {
- ClassMethods.push_back(method);
- }
-
- void addPropertyImplementation(ObjCPropertyImplDecl *property) {
- PropertyImplementations.push_back(property);
- }
- typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
- propimpl_iterator;
- propimpl_iterator propimpl_begin() const {
- return PropertyImplementations.begin();
- }
- propimpl_iterator propimpl_end() const {
- return PropertyImplementations.end();
- }
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); }
- SourceLocation getLocEnd() const { return EndLoc; }
- void setLocEnd(SourceLocation LE) { EndLoc = LE; };
-
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
- ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
-
- void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
-
- unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
- unsigned getNumClassMethods() const { return ClassMethods.size(); }
-
- unsigned getNumPropertyImplementations() const
- { return PropertyImplementations.size(); }
-
- typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
- instmeth_iterator;
- instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
- instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
-
- typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
- classmeth_iterator;
- classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
- classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
-
- // Get the instance method definition for this implementation.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
-
- // Get the class method definition for this implementation.
- ObjCMethodDecl *getClassMethod(Selector Sel) const;
-
- typedef ObjCIvarDecl * const *ivar_iterator;
- ivar_iterator ivar_begin() const { return Ivars; }
- ivar_iterator ivar_end() const { return Ivars+NumIvars; }
- unsigned ivar_size() const { return NumIvars; }
- bool ivar_empty() const { return NumIvars == 0; }
-
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCImplementation;
- }
- static bool classof(const ObjCImplementationDecl *D) { return true; }
-};
-
-/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
-/// declared as @compatibility_alias alias class.
-class ObjCCompatibleAliasDecl : public NamedDecl {
- /// Class that this is an alias of.
- ObjCInterfaceDecl *AliasedClass;
-
- ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass)
- : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {}
-public:
- static ObjCCompatibleAliasDecl *Create(ASTContext &C,
- SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass);
-
- const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
- ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
-
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCCompatibleAlias;
- }
- static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
-
-};
-
-/// ObjCPropertyDecl - Represents one property declaration in an interface.
-/// For example:
-/// @property (assign, readwrite) int MyProperty;
-///
-class ObjCPropertyDecl : public NamedDecl {
-public:
- enum PropertyAttributeKind {
- OBJC_PR_noattr = 0x00,
- OBJC_PR_readonly = 0x01,
- OBJC_PR_getter = 0x02,
- OBJC_PR_assign = 0x04,
- OBJC_PR_readwrite = 0x08,
- OBJC_PR_retain = 0x10,
- OBJC_PR_copy = 0x20,
- OBJC_PR_nonatomic = 0x40,
- OBJC_PR_setter = 0x80
- };
-
- enum SetterKind { Assign, Retain, Copy };
- enum PropertyControl { None, Required, Optional };
-private:
- QualType DeclType;
- unsigned PropertyAttributes : 8;
-
- // @required/@optional
- unsigned PropertyImplementation : 2;
-
- Selector GetterName; // getter name of NULL if no getter
- Selector SetterName; // setter name of NULL if no setter
-
- ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
- ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
-
- ObjCPropertyDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
- : NamedDecl(ObjCProperty, L, Id), DeclType(T),
- PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
- GetterName(Selector()),
- SetterName(Selector()),
- GetterMethodDecl(0), SetterMethodDecl(0) {}
-public:
- static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- PropertyControl propControl = None);
- QualType getType() const { return DeclType; }
-
- PropertyAttributeKind getPropertyAttributes() const {
- return PropertyAttributeKind(PropertyAttributes);
- }
- void setPropertyAttributes(PropertyAttributeKind PRVal) {
- PropertyAttributes |= PRVal;
- }
-
- // Helper methods for accessing attributes.
-
- /// isReadOnly - Return true iff the property has a setter.
- bool isReadOnly() const {
- return (PropertyAttributes & OBJC_PR_readonly);
- }
-
- /// getSetterKind - Return the method used for doing assignment in
- /// the property setter. This is only valid if the property has been
- /// defined to have a setter.
- SetterKind getSetterKind() const {
- if (PropertyAttributes & OBJC_PR_retain)
- return Retain;
- if (PropertyAttributes & OBJC_PR_copy)
- return Copy;
- return Assign;
- }
-
- Selector getGetterName() const { return GetterName; }
- void setGetterName(Selector Sel) { GetterName = Sel; }
-
- Selector getSetterName() const { return SetterName; }
- void setSetterName(Selector Sel) { SetterName = Sel; }
-
- ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
- void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
-
- ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
- void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
-
- // Related to @optional/@required declared in @protocol
- void setPropertyImplementation(PropertyControl pc) {
- PropertyImplementation = pc;
- }
- PropertyControl getPropertyImplementation() const {
- return PropertyControl(PropertyImplementation);
- }
-
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCProperty;
- }
- static bool classof(const ObjCPropertyDecl *D) { return true; }
-};
-
-/// ObjCPropertyImplDecl - Represents implementation declaration of a property
-/// in a class or category implementation block. For example:
-/// @synthesize prop1 = ivar1;
-///
-class ObjCPropertyImplDecl : public Decl {
-public:
- enum Kind {
- Synthesize,
- Dynamic
- };
-private:
- SourceLocation AtLoc; // location of @synthesize or @dynamic
- /// Property declaration being implemented
- ObjCPropertyDecl *PropertyDecl;
-
- /// Null for @dynamic. Required for @synthesize.
- ObjCIvarDecl *PropertyIvarDecl;
-
- ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl)
- : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(property),
- PropertyIvarDecl(ivarDecl) {
- assert (PK == Dynamic || PropertyIvarDecl);
- }
-
-public:
- static ObjCPropertyImplDecl *Create(ASTContext &C, SourceLocation atLoc,
- SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl);
-
- ObjCPropertyDecl *getPropertyDecl() const {
- return PropertyDecl;
- }
-
- Kind getPropertyImplementation() const {
- return PropertyIvarDecl ? Synthesize : Dynamic;
- }
-
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
-
- static bool classof(const Decl *D) {
- return D->getKind() == ObjCPropertyImpl;
- }
- static bool classof(const ObjCPropertyImplDecl *D) { return true; }
-};
-
-} // end namespace clang
-#endif
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
deleted file mode 100644
index 2b42424803db..000000000000
--- a/clang/include/clang/AST/Expr.h
+++ /dev/null
@@ -1,1575 +0,0 @@
-//===--- Expr.h - Classes for representing expressions ----------*- 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 Expr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPR_H
-#define LLVM_CLANG_AST_EXPR_H
-
-#include "clang/AST/Stmt.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallVector.h"
-#include <vector>
-
-namespace clang {
- class ASTContext;
- class APValue;
- class Decl;
- class IdentifierInfo;
- class ParmVarDecl;
- class ValueDecl;
-
-/// Expr - This represents one expression. Note that Expr's are subclasses of
-/// Stmt. This allows an expression to be transparently used any place a Stmt
-/// is required.
-///
-class Expr : public Stmt {
- QualType TR;
-protected:
- Expr(StmtClass SC, QualType T) : Stmt(SC), TR(T) {}
-public:
- QualType getType() const { return TR; }
- void setType(QualType t) { TR = t; }
-
- /// SourceLocation tokens are not useful in isolation - they are low level
- /// value objects created/interpreted by SourceManager. We assume AST
- /// clients will have a pointer to the respective SourceManager.
- virtual SourceRange getSourceRange() const = 0;
-
- /// getExprLoc - Return the preferred location for the arrow when diagnosing
- /// a problem with a generic expression.
- virtual SourceLocation getExprLoc() const { return getLocStart(); }
-
- /// hasLocalSideEffect - Return true if this immediate expression has side
- /// effects, not counting any sub-expressions.
- bool hasLocalSideEffect() const;
-
- /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
- /// incomplete type other than void. Nonarray expressions that can be lvalues:
- /// - name, where name must be a variable
- /// - e[i]
- /// - (e), where e must be an lvalue
- /// - e.name, where e must be an lvalue
- /// - e->name
- /// - *e, the type of e cannot be a function type
- /// - string-constant
- /// - reference type [C++ [expr]]
- ///
- enum isLvalueResult {
- LV_Valid,
- LV_NotObjectType,
- LV_IncompleteVoidType,
- LV_DuplicateVectorComponents,
- LV_InvalidExpression
- };
- isLvalueResult isLvalue(ASTContext &Ctx) const;
-
- /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
- /// does not have an incomplete type, does not have a const-qualified type,
- /// and if it is a structure or union, does not have any member (including,
- /// recursively, any member or element of all contained aggregates or unions)
- /// with a const-qualified type.
- enum isModifiableLvalueResult {
- MLV_Valid,
- MLV_NotObjectType,
- MLV_IncompleteVoidType,
- MLV_DuplicateVectorComponents,
- MLV_InvalidExpression,
- MLV_IncompleteType,
- MLV_ConstQualified,
- MLV_ArrayType,
- MLV_NotBlockQualified
- };
- isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx) const;
-
- bool isNullPointerConstant(ASTContext &Ctx) const;
-
- /// getIntegerConstantExprValue() - Return the value of an integer
- /// constant expression. The expression must be a valid integer
- /// constant expression as determined by isIntegerConstantExpr.
- llvm::APSInt getIntegerConstantExprValue(ASTContext &Ctx) const {
- llvm::APSInt X;
- bool success = isIntegerConstantExpr(X, Ctx);
- success = success;
- assert(success && "Illegal argument to getIntegerConstantExpr");
- return X;
- }
-
- /// isIntegerConstantExpr - Return true if this expression is a valid integer
- /// constant expression, and, if so, return its value in Result. If not a
- /// valid i-c-e, return false and fill in Loc (if specified) with the location
- /// of the invalid expression.
- bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
- SourceLocation *Loc = 0,
- bool isEvaluated = true) const;
- bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const {
- llvm::APSInt X;
- return isIntegerConstantExpr(X, Ctx, Loc);
- }
- /// isConstantExpr - Return true if this expression is a valid constant expr.
- bool isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const;
-
- /// tryEvaluate - Return true if this is a constant which we can fold using
- /// any crazy technique (that has nothing to do with language standards) that
- /// we want to. If this function returns true, it returns the folded constant
- /// in Result.
- bool tryEvaluate(APValue& Result, ASTContext &Ctx) const;
-
- /// isEvaluatable - Call tryEvaluate to see if this expression can be constant
- /// folded, but discard the result.
- bool isEvaluatable(ASTContext &Ctx) const;
-
- /// hasGlobalStorage - Return true if this expression has static storage
- /// duration. This means that the address of this expression is a link-time
- /// constant.
- bool hasGlobalStorage() const;
-
- /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
- /// its subexpression. If that subexpression is also a ParenExpr,
- /// then this method recursively returns its subexpression, and so forth.
- /// Otherwise, the method returns the current Expr.
- Expr* IgnoreParens();
-
- /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
- /// or CastExprs or ImplicitCastExprs, returning their operand.
- Expr *IgnoreParenCasts();
-
- const Expr* IgnoreParens() const {
- return const_cast<Expr*>(this)->IgnoreParens();
- }
- const Expr *IgnoreParenCasts() const {
- return const_cast<Expr*>(this)->IgnoreParenCasts();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstExprConstant &&
- T->getStmtClass() <= lastExprConstant;
- }
- static bool classof(const Expr *) { return true; }
-
- static inline Expr* Create(llvm::Deserializer& D, ASTContext& C) {
- return cast<Expr>(Stmt::Create(D, C));
- }
-};
-
-//===----------------------------------------------------------------------===//
-// ExprIterator - Iterators for iterating over Stmt* arrays that contain
-// only Expr*. This is needed because AST nodes use Stmt* arrays to store
-// references to children (to be compatible with StmtIterator).
-//===----------------------------------------------------------------------===//
-
-class ExprIterator {
- Stmt** I;
-public:
- ExprIterator(Stmt** i) : I(i) {}
- ExprIterator() : I(0) {}
- ExprIterator& operator++() { ++I; return *this; }
- ExprIterator operator-(size_t i) { return I-i; }
- ExprIterator operator+(size_t i) { return I+i; }
- Expr* operator[](size_t idx) { return cast<Expr>(I[idx]); }
- // FIXME: Verify that this will correctly return a signed distance.
- signed operator-(const ExprIterator& R) const { return I - R.I; }
- Expr* operator*() const { return cast<Expr>(*I); }
- Expr* operator->() const { return cast<Expr>(*I); }
- bool operator==(const ExprIterator& R) const { return I == R.I; }
- bool operator!=(const ExprIterator& R) const { return I != R.I; }
- bool operator>(const ExprIterator& R) const { return I > R.I; }
- bool operator>=(const ExprIterator& R) const { return I >= R.I; }
-};
-
-class ConstExprIterator {
- Stmt* const * I;
-public:
- ConstExprIterator(Stmt* const* i) : I(i) {}
- ConstExprIterator() : I(0) {}
- ConstExprIterator& operator++() { ++I; return *this; }
- ConstExprIterator operator+(size_t i) { return I+i; }
- ConstExprIterator operator-(size_t i) { return I-i; }
- Expr * operator[](size_t idx) const { return cast<Expr>(I[idx]); }
- signed operator-(const ConstExprIterator& R) const { return I - R.I; }
- Expr * operator*() const { return cast<Expr>(*I); }
- Expr * operator->() const { return cast<Expr>(*I); }
- bool operator==(const ConstExprIterator& R) const { return I == R.I; }
- bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
- bool operator>(const ConstExprIterator& R) const { return I > R.I; }
- bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
-};
-
-
-//===----------------------------------------------------------------------===//
-// Primary Expressions.
-//===----------------------------------------------------------------------===//
-
-/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
-/// enum, etc.
-class DeclRefExpr : public Expr {
- ValueDecl *D;
- SourceLocation Loc;
-
-protected:
- DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
- Expr(SC, t), D(d), Loc(l) {}
-
-public:
- DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) :
- Expr(DeclRefExprClass, t), D(d), Loc(l) {}
-
- ValueDecl *getDecl() { return D; }
- const ValueDecl *getDecl() const { return D; }
- SourceLocation getLocation() const { return Loc; }
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass ||
- T->getStmtClass() == CXXConditionDeclExprClass;
- }
- static bool classof(const DeclRefExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static DeclRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
-class PredefinedExpr : public Expr {
-public:
- enum IdentType {
- Func,
- Function,
- PrettyFunction,
- CXXThis,
- ObjCSuper // super
- };
-
-private:
- SourceLocation Loc;
- IdentType Type;
-public:
- PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
- : Expr(PredefinedExprClass, type), Loc(l), Type(IT) {}
-
- IdentType getIdentType() const { return Type; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PredefinedExprClass;
- }
- static bool classof(const PredefinedExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static PredefinedExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class IntegerLiteral : public Expr {
- llvm::APInt Value;
- SourceLocation Loc;
-public:
- // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
- // or UnsignedLongLongTy
- IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l)
- : Expr(IntegerLiteralClass, type), Value(V), Loc(l) {
- assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
- }
- const llvm::APInt &getValue() const { return Value; }
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IntegerLiteralClass;
- }
- static bool classof(const IntegerLiteral *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static IntegerLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class CharacterLiteral : public Expr {
- unsigned Value;
- SourceLocation Loc;
- bool IsWide;
-public:
- // type should be IntTy
- CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l)
- : Expr(CharacterLiteralClass, type), Value(value), Loc(l), IsWide(iswide) {
- }
- SourceLocation getLoc() const { return Loc; }
- bool isWide() const { return IsWide; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- unsigned getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CharacterLiteralClass;
- }
- static bool classof(const CharacterLiteral *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CharacterLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class FloatingLiteral : public Expr {
- llvm::APFloat Value;
- bool IsExact : 1;
- SourceLocation Loc;
-public:
- FloatingLiteral(const llvm::APFloat &V, bool* isexact,
- QualType Type, SourceLocation L)
- : Expr(FloatingLiteralClass, Type), Value(V), IsExact(*isexact), Loc(L) {}
-
- const llvm::APFloat &getValue() const { return Value; }
-
- bool isExact() const { return IsExact; }
-
- /// getValueAsApproximateDouble - This returns the value as an inaccurate
- /// double. Note that this may cause loss of precision, but is useful for
- /// debugging dumps, etc.
- double getValueAsApproximateDouble() const;
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FloatingLiteralClass;
- }
- static bool classof(const FloatingLiteral *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static FloatingLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ImaginaryLiteral - We support imaginary integer and floating point literals,
-/// like "1.0i". We represent these as a wrapper around FloatingLiteral and
-/// IntegerLiteral classes. Instances of this class always have a Complex type
-/// whose element type matches the subexpression.
-///
-class ImaginaryLiteral : public Expr {
- Stmt *Val;
-public:
- ImaginaryLiteral(Expr *val, QualType Ty)
- : Expr(ImaginaryLiteralClass, Ty), Val(val) {}
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
-
- virtual SourceRange getSourceRange() const { return Val->getSourceRange(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImaginaryLiteralClass;
- }
- static bool classof(const ImaginaryLiteral *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ImaginaryLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// StringLiteral - This represents a string literal expression, e.g. "foo"
-/// or L"bar" (wide strings). The actual string is returned by getStrData()
-/// is NOT null-terminated, and the length of the string is determined by
-/// calling getByteLength(). The C type for a string is always a
-/// ConstantArrayType.
-class StringLiteral : public Expr {
- const char *StrData;
- unsigned ByteLength;
- bool IsWide;
- // if the StringLiteral was composed using token pasting, both locations
- // are needed. If not (the common case), firstTokLoc == lastTokLoc.
- // FIXME: if space becomes an issue, we should create a sub-class.
- SourceLocation firstTokLoc, lastTokLoc;
-public:
- StringLiteral(const char *strData, unsigned byteLength, bool Wide,
- QualType t, SourceLocation b, SourceLocation e);
- virtual ~StringLiteral();
-
- const char *getStrData() const { return StrData; }
- unsigned getByteLength() const { return ByteLength; }
- bool isWide() const { return IsWide; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(firstTokLoc,lastTokLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == StringLiteralClass;
- }
- static bool classof(const StringLiteral *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static StringLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
-/// AST node is only formed if full location information is requested.
-class ParenExpr : public Expr {
- SourceLocation L, R;
- Stmt *Val;
-public:
- ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
- : Expr(ParenExprClass, val->getType()), L(l), R(r), Val(val) {}
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- virtual SourceRange getSourceRange() const { return SourceRange(L, R); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ParenExprClass;
- }
- static bool classof(const ParenExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ParenExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// UnaryOperator - This represents the unary-expression's (except sizeof of
-/// types), the postinc/postdec operators from postfix-expression, and various
-/// extensions.
-///
-/// Notes on various nodes:
-///
-/// Real/Imag - These return the real/imag part of a complex operand. If
-/// applied to a non-complex value, the former returns its operand and the
-/// later returns zero in the type of the operand.
-///
-/// __builtin_offsetof(type, a.b[10]) is represented as a unary operator whose
-/// subexpression is a compound literal with the various MemberExpr and
-/// ArraySubscriptExpr's applied to it.
-///
-class UnaryOperator : public Expr {
-public:
- // Note that additions to this should also update the StmtVisitor class.
- enum Opcode {
- PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators
- PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators.
- AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators.
- Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators.
- Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators.
- SizeOf, AlignOf, // [C99 6.5.3.4] Sizeof (expr, not type) operator.
- Real, Imag, // "__real expr"/"__imag expr" Extension.
- Extension, // __extension__ marker.
- OffsetOf // __builtin_offsetof
- };
-private:
- Stmt *Val;
- Opcode Opc;
- SourceLocation Loc;
-public:
-
- UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
- : Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
-
- Opcode getOpcode() const { return Opc; }
- Expr *getSubExpr() const { return cast<Expr>(Val); }
-
- /// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return Loc; }
-
- /// isPostfix - Return true if this is a postfix operation, like x++.
- static bool isPostfix(Opcode Op);
-
- /// isPostfix - Return true if this is a prefix operation, like --x.
- static bool isPrefix(Opcode Op);
-
- bool isPrefix() const { return isPrefix(Opc); }
- bool isPostfix() const { return isPostfix(Opc); }
- bool isIncrementOp() const {return Opc==PreInc || Opc==PostInc; }
- bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
- bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; }
- bool isOffsetOfOp() const { return Opc == OffsetOf; }
- static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "sizeof" or "[pre]++"
- static const char *getOpcodeStr(Opcode Op);
-
- virtual SourceRange getSourceRange() const {
- if (isPostfix())
- return SourceRange(Val->getLocStart(), Loc);
- else
- return SourceRange(Loc, Val->getLocEnd());
- }
- virtual SourceLocation getExprLoc() const { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryOperatorClass;
- }
- static bool classof(const UnaryOperator *) { return true; }
-
- int64_t evaluateOffsetOf(ASTContext& C) const;
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static UnaryOperator* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of
-/// *types*. sizeof(expr) is handled by UnaryOperator.
-class SizeOfAlignOfTypeExpr : public Expr {
- bool isSizeof; // true if sizeof, false if alignof.
- QualType Ty;
- SourceLocation OpLoc, RParenLoc;
-public:
- SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType,
- SourceLocation op, SourceLocation rp) :
- Expr(SizeOfAlignOfTypeExprClass, resultType),
- isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {}
-
- virtual void Destroy(ASTContext& C);
-
- bool isSizeOf() const { return isSizeof; }
- QualType getArgumentType() const { return Ty; }
-
- SourceLocation getOperatorLoc() const { return OpLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(OpLoc, RParenLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfAlignOfTypeExprClass;
- }
- static bool classof(const SizeOfAlignOfTypeExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static SizeOfAlignOfTypeExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-//===----------------------------------------------------------------------===//
-// Postfix Operators.
-//===----------------------------------------------------------------------===//
-
-/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
-class ArraySubscriptExpr : public Expr {
- enum { LHS, RHS, END_EXPR=2 };
- Stmt* SubExprs[END_EXPR];
- SourceLocation RBracketLoc;
-public:
- ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
- SourceLocation rbracketloc)
- : Expr(ArraySubscriptExprClass, t), RBracketLoc(rbracketloc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// An array access can be written A[4] or 4[A] (both are equivalent).
- /// - getBase() and getIdx() always present the normalized view: A[4].
- /// In this case getBase() returns "A" and getIdx() returns "4".
- /// - getLHS() and getRHS() present the syntactic view. e.g. for
- /// 4[A] getLHS() returns "4".
- /// Note: Because vector element access is also written A[4] we must
- /// predicate the format conversion in getBase and getIdx only on the
- /// the type of the RHS, as it is possible for the LHS to be a vector of
- /// integer type
- Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
- const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
-
- Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
- const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
-
- Expr *getBase() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
- }
-
- const Expr *getBase() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
- }
-
- Expr *getIdx() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
- }
-
- const Expr *getIdx() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getLHS()->getLocStart(), RBracketLoc);
- }
-
- virtual SourceLocation getExprLoc() const { return RBracketLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArraySubscriptExprClass;
- }
- static bool classof(const ArraySubscriptExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ArraySubscriptExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// CallExpr - [C99 6.5.2.2] Function Calls.
-///
-class CallExpr : public Expr {
- enum { FN=0, ARGS_START=1 };
- Stmt **SubExprs;
- unsigned NumArgs;
- SourceLocation RParenLoc;
-
- // This version of the ctor is for deserialization.
- CallExpr(Stmt** subexprs, unsigned numargs, QualType t,
- SourceLocation rparenloc)
- : Expr(CallExprClass,t), SubExprs(subexprs),
- NumArgs(numargs), RParenLoc(rparenloc) {}
-
-public:
- CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
- SourceLocation rparenloc);
- ~CallExpr() {
- delete [] SubExprs;
- }
-
- const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
- Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
- void setCallee(Expr *F) { SubExprs[FN] = F; }
-
- /// getNumArgs - Return the number of actual arguments to this call.
- ///
- unsigned getNumArgs() const { return NumArgs; }
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+ARGS_START]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+ARGS_START]);
- }
- /// setArg - Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+ARGS_START] = ArgExpr;
- }
-
- /// setNumArgs - This changes the number of arguments present in this call.
- /// Any orphaned expressions are deleted by this, and any new operands are set
- /// to null.
- void setNumArgs(unsigned NumArgs);
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- arg_iterator arg_begin() { return SubExprs+ARGS_START; }
- arg_iterator arg_end() { return SubExprs+ARGS_START+getNumArgs(); }
- const_arg_iterator arg_begin() const { return SubExprs+ARGS_START; }
- const_arg_iterator arg_end() const { return SubExprs+ARGS_START+getNumArgs();}
-
- /// getNumCommas - Return the number of commas that must have been present in
- /// this function call.
- unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
-
- /// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
- /// not, return 0.
- unsigned isBuiltinCall() const;
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getCallee()->getLocStart(), RParenLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CallExprClass;
- }
- static bool classof(const CallExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CallExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// MemberExpr - [C99 6.5.2.3] Structure and Union Members.
-///
-class MemberExpr : public Expr {
- Stmt *Base;
- FieldDecl *MemberDecl;
- SourceLocation MemberLoc;
- bool IsArrow; // True if this is "X->F", false if this is "X.F".
-public:
- MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l,
- QualType ty)
- : Expr(MemberExprClass, ty),
- Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {}
-
- Expr *getBase() const { return cast<Expr>(Base); }
- FieldDecl *getMemberDecl() const { return MemberDecl; }
- bool isArrow() const { return IsArrow; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getBase()->getLocStart(), MemberLoc);
- }
-
- virtual SourceLocation getExprLoc() const { return MemberLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MemberExprClass;
- }
- static bool classof(const MemberExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static MemberExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CompoundLiteralExpr - [C99 6.5.2.5]
-///
-class CompoundLiteralExpr : public Expr {
- /// LParenLoc - If non-null, this is the location of the left paren in a
- /// compound literal like "(int){4}". This can be null if this is a
- /// synthesized compound expression.
- SourceLocation LParenLoc;
- Stmt *Init;
- bool FileScope;
-public:
- CompoundLiteralExpr(SourceLocation lparenloc, QualType ty, Expr *init,
- bool fileScope)
- : Expr(CompoundLiteralExprClass, ty), LParenLoc(lparenloc), Init(init),
- FileScope(fileScope) {}
-
- const Expr *getInitializer() const { return cast<Expr>(Init); }
- Expr *getInitializer() { return cast<Expr>(Init); }
-
- bool isFileScope() const { return FileScope; }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- // FIXME: Init should never be null.
- if (!Init)
- return SourceRange();
- if (LParenLoc.isInvalid())
- return Init->getSourceRange();
- return SourceRange(LParenLoc, Init->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundLiteralExprClass;
- }
- static bool classof(const CompoundLiteralExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CompoundLiteralExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CastExpr - Base class for Cast Operators (explicit, implicit, etc.).
-/// Classes that derive from CastExpr are:
-///
-/// ImplicitCastExpr
-/// ExplicitCastExpr
-///
-class CastExpr : public Expr {
- Stmt *Op;
-protected:
- CastExpr(StmtClass SC, QualType ty, Expr *op) :
- Expr(SC, ty), Op(op) {}
-
-public:
- Expr *getSubExpr() { return cast<Expr>(Op); }
- const Expr *getSubExpr() const { return cast<Expr>(Op); }
-
- static bool classof(const Stmt *T) {
- switch (T->getStmtClass()) {
- case ImplicitCastExprClass:
- case ExplicitCastExprClass:
- case CXXFunctionalCastExprClass:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const CastExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// ImplicitCastExpr - Allows us to explicitly represent implicit type
-/// conversions. For example: converting T[]->T*, void f()->void (*f)(),
-/// float->double, short->int, etc.
-///
-class ImplicitCastExpr : public CastExpr {
-public:
- ImplicitCastExpr(QualType ty, Expr *op) :
- CastExpr(ImplicitCastExprClass, ty, op) {}
-
- virtual SourceRange getSourceRange() const {
- return getSubExpr()->getSourceRange();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImplicitCastExprClass;
- }
- static bool classof(const ImplicitCastExpr *) { return true; }
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ImplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ExplicitCastExpr - [C99 6.5.4] Cast Operators.
-///
-class ExplicitCastExpr : public CastExpr {
- SourceLocation Loc; // the location of the left paren
-public:
- ExplicitCastExpr(QualType ty, Expr *op, SourceLocation l) :
- CastExpr(ExplicitCastExprClass, ty, op), Loc(l) {}
-
- SourceLocation getLParenLoc() const { return Loc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExplicitCastExprClass;
- }
- static bool classof(const ExplicitCastExpr *) { return true; }
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ExplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class BinaryOperator : public Expr {
-public:
- enum Opcode {
- // Operators listed in order of precedence.
- // Note that additions to this should also update the StmtVisitor class.
- Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators.
- Add, Sub, // [C99 6.5.6] Additive operators.
- Shl, Shr, // [C99 6.5.7] Bitwise shift operators.
- LT, GT, LE, GE, // [C99 6.5.8] Relational operators.
- EQ, NE, // [C99 6.5.9] Equality operators.
- And, // [C99 6.5.10] Bitwise AND operator.
- Xor, // [C99 6.5.11] Bitwise XOR operator.
- Or, // [C99 6.5.12] Bitwise OR operator.
- LAnd, // [C99 6.5.13] Logical AND operator.
- LOr, // [C99 6.5.14] Logical OR operator.
- Assign, MulAssign,// [C99 6.5.16] Assignment operators.
- DivAssign, RemAssign,
- AddAssign, SubAssign,
- ShlAssign, ShrAssign,
- AndAssign, XorAssign,
- OrAssign,
- Comma // [C99 6.5.17] Comma operator.
- };
-private:
- enum { LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- Opcode Opc;
- SourceLocation OpLoc;
-public:
-
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- SourceLocation opLoc)
- : Expr(BinaryOperatorClass, ResTy), Opc(opc), OpLoc(opLoc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- assert(!isCompoundAssignmentOp() &&
- "Use ArithAssignBinaryOperator for compound assignments");
- }
-
- SourceLocation getOperatorLoc() const { return OpLoc; }
- Opcode getOpcode() const { return Opc; }
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- virtual SourceRange getSourceRange() const {
- return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd());
- }
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "<<=".
- static const char *getOpcodeStr(Opcode Op);
-
- /// predicates to categorize the respective opcodes.
- bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
- bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
- bool isShiftOp() const { return Opc == Shl || Opc == Shr; }
- bool isBitwiseOp() const { return Opc >= And && Opc <= Or; }
-
- static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
- bool isRelationalOp() const { return isRelationalOp(Opc); }
-
- static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; }
- bool isEqualityOp() const { return isEqualityOp(Opc); }
-
- static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; }
- bool isLogicalOp() const { return isLogicalOp(Opc); }
-
- bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
- bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
- bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == BinaryOperatorClass ||
- S->getStmtClass() == CompoundAssignOperatorClass;
- }
- static bool classof(const BinaryOperator *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static BinaryOperator* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
-protected:
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- SourceLocation oploc, bool dead)
- : Expr(CompoundAssignOperatorClass, ResTy), Opc(opc), OpLoc(oploc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-};
-
-/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
-/// track of the type the operation is performed in. Due to the semantics of
-/// these operators, the operands are promoted, the aritmetic performed, an
-/// implicit conversion back to the result type done, then the assignment takes
-/// place. This captures the intermediate type which the computation is done
-/// in.
-class CompoundAssignOperator : public BinaryOperator {
- QualType ComputationType;
-public:
- CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc,
- QualType ResType, QualType CompType,
- SourceLocation OpLoc)
- : BinaryOperator(lhs, rhs, opc, ResType, OpLoc, true),
- ComputationType(CompType) {
- assert(isCompoundAssignmentOp() &&
- "Only should be used for compound assignments");
- }
-
- QualType getComputationType() const { return ComputationType; }
-
- static bool classof(const CompoundAssignOperator *) { return true; }
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CompoundAssignOperatorClass;
- }
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CompoundAssignOperator* CreateImpl(llvm::Deserializer& D,
- ASTContext& C);
-};
-
-/// ConditionalOperator - The ?: operator. Note that LHS may be null when the
-/// GNU "missing LHS" extension is in use.
-///
-class ConditionalOperator : public Expr {
- enum { COND, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
-public:
- ConditionalOperator(Expr *cond, Expr *lhs, Expr *rhs, QualType t)
- : Expr(ConditionalOperatorClass, t) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- // getCond - Return the expression representing the condition for
- // the ?: operator.
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
-
- // getTrueExpr - Return the subexpression representing the value of the ?:
- // expression if the condition evaluates to true. In most cases this value
- // will be the same as getLHS() except a GCC extension allows the left
- // subexpression to be omitted, and instead of the condition be returned.
- // e.g: x ?: y is shorthand for x ? x : y, except that the expression "x"
- // is only evaluated once.
- Expr *getTrueExpr() const {
- return cast<Expr>(SubExprs[LHS] ? SubExprs[LHS] : SubExprs[COND]);
- }
-
- // getTrueExpr - Return the subexpression representing the value of the ?:
- // expression if the condition evaluates to false. This is the same as getRHS.
- Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
-
- Expr *getLHS() const { return cast_or_null<Expr>(SubExprs[LHS]); }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConditionalOperatorClass;
- }
- static bool classof(const ConditionalOperator *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ConditionalOperator* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// AddrLabelExpr - The GNU address of label extension, representing &&label.
-class AddrLabelExpr : public Expr {
- SourceLocation AmpAmpLoc, LabelLoc;
- LabelStmt *Label;
-public:
- AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L,
- QualType t)
- : Expr(AddrLabelExprClass, t), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AmpAmpLoc, LabelLoc);
- }
-
- LabelStmt *getLabel() const { return Label; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AddrLabelExprClass;
- }
- static bool classof(const AddrLabelExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static AddrLabelExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
-/// The StmtExpr contains a single CompoundStmt node, which it evaluates and
-/// takes the value of the last subexpression.
-class StmtExpr : public Expr {
- Stmt *SubStmt;
- SourceLocation LParenLoc, RParenLoc;
-public:
- StmtExpr(CompoundStmt *substmt, QualType T,
- SourceLocation lp, SourceLocation rp) :
- Expr(StmtExprClass, T), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
-
- CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
- const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(LParenLoc, RParenLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == StmtExprClass;
- }
- static bool classof(const StmtExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static StmtExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// TypesCompatibleExpr - GNU builtin-in function __builtin_type_compatible_p.
-/// This AST node represents a function that returns 1 if two *types* (not
-/// expressions) are compatible. The result of this built-in function can be
-/// used in integer constant expressions.
-class TypesCompatibleExpr : public Expr {
- QualType Type1;
- QualType Type2;
- SourceLocation BuiltinLoc, RParenLoc;
-public:
- TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc,
- QualType t1, QualType t2, SourceLocation RP) :
- Expr(TypesCompatibleExprClass, ReturnType), Type1(t1), Type2(t2),
- BuiltinLoc(BLoc), RParenLoc(RP) {}
-
- QualType getArgType1() const { return Type1; }
- QualType getArgType2() const { return Type2; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypesCompatibleExprClass;
- }
- static bool classof(const TypesCompatibleExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// ShuffleVectorExpr - clang-specific builtin-in function
-/// __builtin_shufflevector.
-/// This AST node represents a operator that does a constant
-/// shuffle, similar to LLVM's shufflevector instruction. It takes
-/// two vectors and a variable number of constant indices,
-/// and returns the appropriately shuffled vector.
-class ShuffleVectorExpr : public Expr {
- SourceLocation BuiltinLoc, RParenLoc;
-
- // SubExprs - the list of values passed to the __builtin_shufflevector
- // function. The first two are vectors, and the rest are constant
- // indices. The number of values in this list is always
- // 2+the number of indices in the vector type.
- Stmt **SubExprs;
- unsigned NumExprs;
-
-public:
- ShuffleVectorExpr(Expr **args, unsigned nexpr,
- QualType Type, SourceLocation BLoc,
- SourceLocation RP) :
- Expr(ShuffleVectorExprClass, Type), BuiltinLoc(BLoc),
- RParenLoc(RP), NumExprs(nexpr) {
-
- SubExprs = new Stmt*[nexpr];
- for (unsigned i = 0; i < nexpr; i++)
- SubExprs[i] = args[i];
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ShuffleVectorExprClass;
- }
- static bool classof(const ShuffleVectorExpr *) { return true; }
-
- ~ShuffleVectorExpr() {
- delete [] SubExprs;
- }
-
- /// getNumSubExprs - Return the size of the SubExprs array. This includes the
- /// constant expression, the actual arguments passed in, and the function
- /// pointers.
- unsigned getNumSubExprs() const { return NumExprs; }
-
- /// getExpr - Return the Expr at the specified index.
- Expr *getExpr(unsigned Index) {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
- const Expr *getExpr(unsigned Index) const {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
-
- unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) {
- assert((N < NumExprs - 2) && "Shuffle idx out of range!");
- return getExpr(N+2)->getIntegerConstantExprValue(Ctx).getZExtValue();
- }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
-/// This AST node is similar to the conditional operator (?:) in C, with
-/// the following exceptions:
-/// - the test expression much be a constant expression.
-/// - the expression returned has it's type unaltered by promotion rules.
-/// - does not evaluate the expression that was not chosen.
-class ChooseExpr : public Expr {
- enum { COND, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
- SourceLocation BuiltinLoc, RParenLoc;
-public:
- ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t,
- SourceLocation RP)
- : Expr(ChooseExprClass, t),
- BuiltinLoc(BLoc), RParenLoc(RP) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// isConditionTrue - Return true if the condition is true. This is always
- /// statically knowable for a well-formed choosexpr.
- bool isConditionTrue(ASTContext &C) const;
-
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ChooseExprClass;
- }
- static bool classof(const ChooseExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// OverloadExpr - Clang builtin function __builtin_overload.
-/// This AST node provides a way to overload functions in C.
-///
-/// The first argument is required to be a constant expression, for the number
-/// of arguments passed to each candidate function.
-///
-/// The next N arguments, where N is the value of the constant expression,
-/// are the values to be passed as arguments.
-///
-/// The rest of the arguments are values of pointer to function type, which
-/// are the candidate functions for overloading.
-///
-/// The result is a equivalent to a CallExpr taking N arguments to the
-/// candidate function whose parameter types match the types of the N arguments.
-///
-/// example: float Z = __builtin_overload(2, X, Y, modf, mod, modl);
-/// If X and Y are long doubles, Z will assigned the result of modl(X, Y);
-/// If X and Y are floats, Z will be assigned the result of modf(X, Y);
-class OverloadExpr : public Expr {
- // SubExprs - the list of values passed to the __builtin_overload function.
- // SubExpr[0] is a constant expression
- // SubExpr[1-N] are the parameters to pass to the matching function call
- // SubExpr[N-...] are the candidate functions, of type pointer to function.
- Stmt **SubExprs;
-
- // NumExprs - the size of the SubExprs array
- unsigned NumExprs;
-
- // The index of the matching candidate function
- unsigned FnIndex;
-
- SourceLocation BuiltinLoc;
- SourceLocation RParenLoc;
-public:
- OverloadExpr(Expr **args, unsigned nexprs, unsigned idx, QualType t,
- SourceLocation bloc, SourceLocation rploc)
- : Expr(OverloadExprClass, t), NumExprs(nexprs), FnIndex(idx),
- BuiltinLoc(bloc), RParenLoc(rploc) {
- SubExprs = new Stmt*[nexprs];
- for (unsigned i = 0; i != nexprs; ++i)
- SubExprs[i] = args[i];
- }
- ~OverloadExpr() {
- delete [] SubExprs;
- }
-
- /// arg_begin - Return a pointer to the list of arguments that will be passed
- /// to the matching candidate function, skipping over the initial constant
- /// expression.
- typedef ConstExprIterator const_arg_iterator;
- const_arg_iterator arg_begin() const { return &SubExprs[0]+1; }
- const_arg_iterator arg_end(ASTContext& Ctx) const {
- return &SubExprs[0]+1+getNumArgs(Ctx);
- }
-
- /// getNumArgs - Return the number of arguments to pass to the candidate
- /// functions.
- unsigned getNumArgs(ASTContext &Ctx) const {
- return getExpr(0)->getIntegerConstantExprValue(Ctx).getZExtValue();
- }
-
- /// getNumSubExprs - Return the size of the SubExprs array. This includes the
- /// constant expression, the actual arguments passed in, and the function
- /// pointers.
- unsigned getNumSubExprs() const { return NumExprs; }
-
- /// getExpr - Return the Expr at the specified index.
- Expr *getExpr(unsigned Index) const {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
-
- /// getFn - Return the matching candidate function for this OverloadExpr.
- Expr *getFn() const { return cast<Expr>(SubExprs[FnIndex]); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OverloadExprClass;
- }
- static bool classof(const OverloadExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// VAArgExpr, used for the builtin function __builtin_va_start.
-class VAArgExpr : public Expr {
- Stmt *Val;
- SourceLocation BuiltinLoc, RParenLoc;
-public:
- VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc)
- : Expr(VAArgExprClass, t),
- Val(e),
- BuiltinLoc(BLoc),
- RParenLoc(RPLoc) { }
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- virtual SourceRange getSourceRange() const {
- return SourceRange(BuiltinLoc, RParenLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == VAArgExprClass;
- }
- static bool classof(const VAArgExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// InitListExpr - used for struct and array initializers, such as:
-/// struct foo x = { 1, { 2, 3 } };
-///
-/// Because C is somewhat loose with braces, the AST does not necessarily
-/// directly model the C source. Instead, the semantic analyzer aims to make
-/// the InitListExprs match up with the type of the decl being initialized. We
-/// have the following exceptions:
-///
-/// 1. Elements at the end of the list may be dropped from the initializer.
-/// These elements are defined to be initialized to zero. For example:
-/// int x[20] = { 1 };
-/// 2. Initializers may have excess initializers which are to be ignored by the
-/// compiler. For example:
-/// int x[1] = { 1, 2 };
-/// 3. Redundant InitListExprs may be present around scalar elements. These
-/// always have a single element whose type is the same as the InitListExpr.
-/// this can only happen for Type::isScalarType() types.
-/// int x = { 1 }; int y[2] = { {1}, {2} };
-///
-class InitListExpr : public Expr {
- std::vector<Stmt *> InitExprs;
- SourceLocation LBraceLoc, RBraceLoc;
-public:
- InitListExpr(SourceLocation lbraceloc, Expr **initexprs, unsigned numinits,
- SourceLocation rbraceloc);
-
- unsigned getNumInits() const { return InitExprs.size(); }
-
- const Expr* getInit(unsigned Init) const {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return cast<Expr>(InitExprs[Init]);
- }
-
- Expr* getInit(unsigned Init) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return cast<Expr>(InitExprs[Init]);
- }
-
- void setInit(unsigned Init, Expr *expr) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- InitExprs[Init] = expr;
- }
-
- // Dynamic removal/addition (for constructing implicit InitExpr's).
- void removeInit(unsigned Init) {
- InitExprs.erase(InitExprs.begin()+Init);
- }
- void addInit(unsigned Init, Expr *expr) {
- InitExprs.insert(InitExprs.begin()+Init, expr);
- }
-
- // Explicit InitListExpr's originate from source code (and have valid source
- // locations). Implicit InitListExpr's are created by the semantic analyzer.
- bool isExplicit() {
- return LBraceLoc.isValid() && RBraceLoc.isValid();
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(LBraceLoc, RBraceLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == InitListExprClass;
- }
- static bool classof(const InitListExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static InitListExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-
-private:
- // Used by serializer.
- InitListExpr() : Expr(InitListExprClass, QualType()) {}
-};
-
-//===----------------------------------------------------------------------===//
-// Clang Extensions
-//===----------------------------------------------------------------------===//
-
-
-/// ExtVectorElementExpr - This represents access to specific elements of a
-/// vector, and may occur on the left hand side or right hand side. For example
-/// the following is legal: "V.xy = V.zw" if V is a 4 element extended vector.
-///
-class ExtVectorElementExpr : public Expr {
- Stmt *Base;
- IdentifierInfo &Accessor;
- SourceLocation AccessorLoc;
-public:
- ExtVectorElementExpr(QualType ty, Expr *base, IdentifierInfo &accessor,
- SourceLocation loc)
- : Expr(ExtVectorElementExprClass, ty),
- Base(base), Accessor(accessor), AccessorLoc(loc) {}
-
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
-
- IdentifierInfo &getAccessor() const { return Accessor; }
-
- /// getNumElements - Get the number of components being selected.
- unsigned getNumElements() const;
-
- /// containsDuplicateElements - Return true if any element access is
- /// repeated.
- bool containsDuplicateElements() const;
-
- /// getEncodedElementAccess - Encode the elements accessed into an llvm
- /// aggregate Constant of ConstantInt(s).
- void getEncodedElementAccess(llvm::SmallVectorImpl<unsigned> &Elts) const;
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getBase()->getLocStart(), AccessorLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExtVectorElementExprClass;
- }
- static bool classof(const ExtVectorElementExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-
-/// BlockExpr - Represent a block literal with a syntax:
-/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
-class BlockExpr : public Expr {
- SourceLocation CaretLocation;
- llvm::SmallVector<ParmVarDecl*, 8> Args;
- Stmt *Body;
-public:
- BlockExpr(SourceLocation caretloc, QualType ty, ParmVarDecl **args,
- unsigned numargs, CompoundStmt *body) : Expr(BlockExprClass, ty),
- CaretLocation(caretloc), Args(args, args+numargs), Body(body) {}
-
- SourceLocation getCaretLocation() const { return CaretLocation; }
-
- /// getFunctionType - Return the underlying function type for this block.
- const FunctionType *getFunctionType() const;
-
- const CompoundStmt *getBody() const { return cast<CompoundStmt>(Body); }
- CompoundStmt *getBody() { return cast<CompoundStmt>(Body); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getCaretLocation(), Body->getLocEnd());
- }
-
- /// arg_iterator - Iterate over the ParmVarDecl's for the arguments to this
- /// block.
- typedef llvm::SmallVector<ParmVarDecl*, 8>::const_iterator arg_iterator;
- bool arg_empty() const { return Args.empty(); }
- arg_iterator arg_begin() const { return Args.begin(); }
- arg_iterator arg_end() const { return Args.end(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BlockExprClass;
- }
- static bool classof(const BlockExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static BlockExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// BlockDeclRefExpr - A reference to a declared variable, function,
-/// enum, etc.
-class BlockDeclRefExpr : public Expr {
- ValueDecl *D;
- SourceLocation Loc;
- bool IsByRef;
-public:
- BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef) :
- Expr(BlockDeclRefExprClass, t), D(d), Loc(l), IsByRef(ByRef) {}
-
- ValueDecl *getDecl() { return D; }
- const ValueDecl *getDecl() const { return D; }
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- bool isByRef() const { return IsByRef; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BlockDeclRefExprClass;
- }
- static bool classof(const BlockDeclRefExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static BlockDeclRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
deleted file mode 100644
index 915c9e000f33..000000000000
--- a/clang/include/clang/AST/ExprCXX.h
+++ /dev/null
@@ -1,276 +0,0 @@
-//===--- ExprCXX.h - Classes for representing expressions -------*- 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 Expr interface and subclasses for C++ expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPRCXX_H
-#define LLVM_CLANG_AST_EXPRCXX_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/Decl.h"
-
-namespace clang {
-
-//===--------------------------------------------------------------------===//
-// C++ Expressions.
-//===--------------------------------------------------------------------===//
-
-/// CXXCastExpr - [C++ 5.2.7, 5.2.9, 5.2.10, 5.2.11] C++ Cast Operators.
-///
-class CXXCastExpr : public Expr {
-public:
- enum Opcode {
- DynamicCast,
- StaticCast,
- ReinterpretCast,
- ConstCast
- };
-private:
- QualType Ty;
- Opcode Opc;
- Stmt *Op;
- SourceLocation Loc; // the location of the casting op
-public:
- CXXCastExpr(Opcode op, QualType ty, Expr *expr, SourceLocation l)
- : Expr(CXXCastExprClass, ty), Ty(ty), Opc(op), Op(expr), Loc(l) {}
-
- QualType getDestType() const { return Ty; }
- Expr *getSubExpr() const { return cast<Expr>(Op); }
-
- Opcode getOpcode() const { return Opc; }
-
- /// getOpcodeStr - Turn an Opcode enum value into the string it represents,
- /// e.g. "reinterpret_cast".
- static const char *getOpcodeStr(Opcode Op) {
- // FIXME: move out of line.
- switch (Op) {
- default: assert(0 && "Not a C++ cast expression");
- case CXXCastExpr::ConstCast: return "const_cast";
- case CXXCastExpr::DynamicCast: return "dynamic_cast";
- case CXXCastExpr::ReinterpretCast: return "reinterpret_cast";
- case CXXCastExpr::StaticCast: return "static_cast";
- }
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXCastExprClass;
- }
- static bool classof(const CXXCastExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal.
-///
-class CXXBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-public:
- CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(CXXBoolLiteralExprClass, Ty), Value(val), Loc(l) {}
-
- bool getValue() const { return Value; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBoolLiteralExprClass;
- }
- static bool classof(const CXXBoolLiteralExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// CXXThrowExpr - [C++ 15] C++ Throw Expression. This handles
-/// 'throw' and 'throw' assignment-expression. When
-/// assignment-expression isn't present, Op will be null.
-///
-class CXXThrowExpr : public Expr {
- Stmt *Op;
- SourceLocation ThrowLoc;
-public:
- // Ty is the void type which is used as the result type of the
- // exepression. The l is the location of the throw keyword. expr
- // can by null, if the optional expression to throw isn't present.
- CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
- Expr(CXXThrowExprClass, Ty), Op(expr), ThrowLoc(l) {}
- const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
- Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
-
- virtual SourceRange getSourceRange() const {
- if (getSubExpr() == 0)
- return SourceRange(ThrowLoc, ThrowLoc);
- return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThrowExprClass;
- }
- static bool classof(const CXXThrowExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// CXXDefaultArgExpr - C++ [dcl.fct.default]. This wraps up a
-/// function call argument that was created from the corresponding
-/// parameter's default argument, when the call did not explicitly
-/// supply arguments for all of the parameters.
-class CXXDefaultArgExpr : public Expr {
- ParmVarDecl *Param;
-public:
- // Param is the parameter whose default argument is used by this
- // expression.
- explicit CXXDefaultArgExpr(ParmVarDecl *param)
- : Expr(CXXDefaultArgExprClass, param->getDefaultArg()->getType()),
- Param(param) { }
-
- // Retrieve the parameter that the argument was created from.
- const ParmVarDecl *getParam() const { return Param; }
- ParmVarDecl *getParam() { return Param; }
-
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const { return Param->getDefaultArg(); }
- Expr *getExpr() { return Param->getDefaultArg(); }
-
- virtual SourceRange getSourceRange() const {
- // Default argument expressions have no representation in the
- // source, so they have an empty source range.
- return SourceRange();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultArgExprClass;
- }
- static bool classof(const CXXDefaultArgExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- // Serialization
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CXXDefaultArgExpr* CreateImpl(llvm::Deserializer& D,
- ASTContext& C);
-};
-
-/// CXXFunctionalCastExpr - [C++ 5.2.3p1] Explicit type conversion
-/// (functional notation).
-/// Example: "x = int(0.5);"
-///
-class CXXFunctionalCastExpr : public CastExpr {
- SourceLocation TyBeginLoc;
- SourceLocation RParenLoc;
-public:
- CXXFunctionalCastExpr(QualType ty, SourceLocation tyBeginLoc, Expr *castExpr,
- SourceLocation rParenLoc) :
- CastExpr(CXXFunctionalCastExprClass, ty, castExpr),
- TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
-
- SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(TyBeginLoc, RParenLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFunctionalCastExprClass;
- }
- static bool classof(const CXXFunctionalCastExpr *) { return true; }
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CXXFunctionalCastExpr *
- CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
-/// Expression "T()" which creates a value-initialized Rvalue of non-class
-/// type T.
-///
-class CXXZeroInitValueExpr : public Expr {
- SourceLocation TyBeginLoc;
- SourceLocation RParenLoc;
-
-public:
- CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
- SourceLocation rParenLoc ) :
- Expr(CXXZeroInitValueExprClass, ty),
- TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
-
- SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(TyBeginLoc, RParenLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXZeroInitValueExprClass;
- }
- static bool classof(const CXXZeroInitValueExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CXXZeroInitValueExpr *
- CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CXXConditionDeclExpr - Condition declaration of a if/switch/while/for
-/// statement, e.g: "if (int x = f()) {...}".
-/// The main difference with DeclRefExpr is that CXXConditionDeclExpr owns the
-/// decl that it references.
-///
-class CXXConditionDeclExpr : public DeclRefExpr {
-public:
- CXXConditionDeclExpr(SourceLocation startLoc,
- SourceLocation eqLoc, VarDecl *var)
- : DeclRefExpr(CXXConditionDeclExprClass, var, var->getType(), startLoc) {}
-
- virtual void Destroy(ASTContext& Ctx);
-
- SourceLocation getStartLoc() const { return getLocation(); }
-
- VarDecl *getVarDecl() { return cast<VarDecl>(getDecl()); }
- const VarDecl *getVarDecl() const { return cast<VarDecl>(getDecl()); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getStartLoc(), getVarDecl()->getInit()->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConditionDeclExprClass;
- }
- static bool classof(const CXXConditionDeclExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- // FIXME: Implement these.
- //virtual void EmitImpl(llvm::Serializer& S) const;
- //static CXXConditionDeclExpr *
- // CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
deleted file mode 100644
index 32c799673397..000000000000
--- a/clang/include/clang/AST/ExprObjC.h
+++ /dev/null
@@ -1,418 +0,0 @@
-//===--- ExprObjC.h - Classes for representing ObjC expressions -*- 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 ExprObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPROBJC_H
-#define LLVM_CLANG_AST_EXPROBJC_H
-
-#include "clang/AST/Expr.h"
-#include "clang/Basic/IdentifierTable.h"
-
-namespace clang {
- class IdentifierInfo;
- class ASTContext;
- class ObjCMethodDecl;
- class ObjCPropertyDecl;
-
-/// ObjCStringLiteral, used for Objective-C string literals
-/// i.e. @"foo".
-class ObjCStringLiteral : public Expr {
- StringLiteral *String;
- SourceLocation AtLoc;
-public:
- ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
- : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {}
-
- StringLiteral* getString() { return String; }
-
- const StringLiteral* getString() const { return String; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtLoc, String->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCStringLiteralClass;
- }
- static bool classof(const ObjCStringLiteral *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCStringLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCEncodeExpr, used for @encode in Objective-C.
-class ObjCEncodeExpr : public Expr {
- QualType EncType;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCEncodeExpr(QualType T, QualType ET,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {}
-
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtLoc, RParenLoc);
- }
-
- QualType getEncodedType() const { return EncType; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCEncodeExprClass;
- }
- static bool classof(const ObjCEncodeExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCEncodeExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCSelectorExpr used for @selector in Objective-C.
-class ObjCSelectorExpr : public Expr {
- Selector SelName;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCSelectorExpr(QualType T, Selector selInfo,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCSelectorExprClass, T), SelName(selInfo),
- AtLoc(at), RParenLoc(rp) {}
-
- Selector getSelector() const { return SelName; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtLoc, RParenLoc);
- }
-
- /// getNumArgs - Return the number of actual arguments to this call.
- unsigned getNumArgs() const { return SelName.getNumArgs(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSelectorExprClass;
- }
- static bool classof(const ObjCSelectorExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCSelectorExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCProtocolExpr used for protocol in Objective-C.
-class ObjCProtocolExpr : public Expr {
- ObjCProtocolDecl *Protocol;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCProtocolExprClass, T), Protocol(protocol),
- AtLoc(at), RParenLoc(rp) {}
-
- ObjCProtocolDecl *getProtocol() const { return Protocol; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtLoc, RParenLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCProtocolExprClass;
- }
- static bool classof(const ObjCProtocolExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
-/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
-class ObjCIvarRefExpr : public Expr {
- class ObjCIvarDecl *D;
- SourceLocation Loc;
- Stmt *Base;
- bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
- bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
-
-public:
- ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, Expr *base=0,
- bool arrow = false, bool freeIvar = false) :
- Expr(ObjCIvarRefExprClass, t), D(d), Loc(l), Base(base), IsArrow(arrow),
- IsFreeIvar(freeIvar) {}
-
- ObjCIvarDecl *getDecl() { return D; }
- const ObjCIvarDecl *getDecl() const { return D; }
- virtual SourceRange getSourceRange() const {
- return isFreeIvar() ? SourceRange(Loc)
- : SourceRange(getBase()->getLocStart(), Loc);
- }
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
- void setBase(Expr * base) { Base = base; }
- bool isArrow() const { return IsArrow; }
- bool isFreeIvar() const { return IsFreeIvar; }
-
- SourceLocation getLocation() const { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCIvarRefExprClass;
- }
- static bool classof(const ObjCIvarRefExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCIvarRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
-/// property. Note that dot-syntax can also be used to access
-/// "implicit" properties (i.e. methods following the property naming
-/// convention). Additionally, sema is not yet smart enough to know if
-/// a property reference is to a getter or a setter, so the expr must
-/// have access to both methods.
-///
-// FIXME: Consider splitting these into separate Expr classes.
-class ObjCPropertyRefExpr : public Expr {
-public:
- enum Kind {
- PropertyRef, // This expressions references a declared property.
- MethodRef // This expressions references methods.
- };
-
-private:
- // A dot-syntax reference via methods must always have a getter. We
- // avoid storing the kind explicitly by relying on this invariant
- // and assuming this is a MethodRef iff Getter is non-null. Setter
- // can be null in situations which access a read-only property.
- union {
- ObjCPropertyDecl *AsProperty;
- struct {
- ObjCMethodDecl *Setter;
- ObjCMethodDecl *Getter;
- } AsMethod;
- } Referent;
- SourceLocation Loc;
- Stmt *Base;
-
-public:
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t), Loc(l), Base(base) {
- Referent.AsMethod.Getter = Referent.AsMethod.Setter = NULL;
- Referent.AsProperty = PD;
- }
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType t,
- SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t), Loc(l), Base(base) {
- Referent.AsMethod.Getter = Getter;
- Referent.AsMethod.Setter = Setter;
- }
-
- Kind getKind() const {
- return Referent.AsMethod.Getter ? MethodRef : PropertyRef;
- }
-
- ObjCPropertyDecl *getProperty() const {
- assert(getKind() == PropertyRef &&
- "Cannot get property from an ObjCPropertyRefExpr using methods");
- return Referent.AsProperty;
- }
- ObjCMethodDecl *getGetterMethod() const {
- assert(getKind() == MethodRef &&
- "Cannot get method from an ObjCPropertyRefExpr using a property");
- return Referent.AsMethod.Getter;
- }
- ObjCMethodDecl *getSetterMethod() const {
- assert(getKind() == MethodRef &&
- "Cannot get method from an ObjCPropertyRefExpr using a property");
- return Referent.AsMethod.Setter;
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getBase()->getLocStart(), Loc);
- }
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
- void setBase(Expr * base) { Base = base; }
-
- SourceLocation getLocation() const { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCPropertyRefExprClass;
- }
- static bool classof(const ObjCPropertyRefExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCPropertyRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class ObjCMessageExpr : public Expr {
- // SubExprs - The receiver and arguments of the message expression.
- Stmt **SubExprs;
-
- // NumArgs - The number of arguments (not including the receiver) to the
- // message expression.
- unsigned NumArgs;
-
- // A unigue name for this message.
- Selector SelName;
-
- // A method prototype for this message (optional).
- // FIXME: Since method decls contain the selector, and most messages have a
- // prototype, consider devising a scheme for unifying SelName/MethodProto.
- ObjCMethodDecl *MethodProto;
-
- SourceLocation LBracloc, RBracloc;
-
- // Constants for indexing into SubExprs.
- enum { RECEIVER=0, ARGS_START=1 };
-
- // Bit-swizziling flags.
- enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
- unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
-
- // constructor used during deserialization
- ObjCMessageExpr(Selector selInfo, QualType retType,
- SourceLocation LBrac, SourceLocation RBrac,
- Stmt **subexprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType), SubExprs(subexprs),
- NumArgs(nargs), SelName(selInfo), MethodProto(NULL),
- LBracloc(LBrac), RBracloc(RBrac) {}
-
-public:
- /// This constructor is used to represent class messages where the
- /// ObjCInterfaceDecl* of the receiver is not known.
- ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
- QualType retType, ObjCMethodDecl *methDecl,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned NumArgs);
-
- /// This constructor is used to represent class messages where the
- /// ObjCInterfaceDecl* of the receiver is known.
- // FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
- QualType retType, ObjCMethodDecl *methDecl,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned NumArgs);
-
- // constructor for instance messages.
- ObjCMessageExpr(Expr *receiver, Selector selInfo,
- QualType retType, ObjCMethodDecl *methDecl,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned NumArgs);
-
- ~ObjCMessageExpr() {
- delete [] SubExprs;
- }
-
- /// getReceiver - Returns the receiver of the message expression.
- /// This can be NULL if the message is for class methods. For
- /// class methods, use getClassName.
- /// FIXME: need to handle/detect 'super' usage within a class method.
- Expr *getReceiver() {
- uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
- }
- const Expr *getReceiver() const {
- return const_cast<ObjCMessageExpr*>(this)->getReceiver();
- }
-
- Selector getSelector() const { return SelName; }
-
- const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
- ObjCMethodDecl *getMethodDecl() { return MethodProto; }
-
- typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
-
- /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
- /// and IdentifierInfo* of the invoked class. Both can be NULL if this
- /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none
- /// was available when this ObjCMessageExpr object was constructed.
- ClassInfo getClassInfo() const;
-
- /// getClassName - For class methods, this returns the invoked class,
- /// and returns NULL otherwise. For instance methods, use getReceiver.
- IdentifierInfo *getClassName() const {
- return getClassInfo().second;
- }
-
-
- /// getNumArgs - Return the number of actual arguments to this call.
- unsigned getNumArgs() const { return NumArgs; }
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+ARGS_START]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+ARGS_START]);
- }
- /// setArg - Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+ARGS_START] = ArgExpr;
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(LBracloc, RBracloc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCMessageExprClass;
- }
- static bool classof(const ObjCMessageExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
- arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; }
- const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
- const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
-
- // Serialization.
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/PPCBuiltins.def b/clang/include/clang/AST/PPCBuiltins.def
deleted file mode 100644
index b8c791286e55..000000000000
--- a/clang/include/clang/AST/PPCBuiltins.def
+++ /dev/null
@@ -1,24 +0,0 @@
-//===--- PPCBuiltins.def - PowerPC Builtin function database ----*- 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 PowerPC-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
-// adding stuff on demand.
-
-// The format of this database matches clang/AST/Builtins.def.
-
-// This is just a placeholder, the types and attributes are wrong.
-BUILTIN(__builtin_altivec_abs_v4sf , "ii" , "nc")
-// FIXME: Obviously incomplete.
-
-#undef BUILTIN
diff --git a/clang/include/clang/AST/ParentMap.h b/clang/include/clang/AST/ParentMap.h
deleted file mode 100644
index 7443f915733c..000000000000
--- a/clang/include/clang/AST/ParentMap.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- 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 ParentMap class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARENTMAP_H
-#define LLVM_CLANG_PARENTMAP_H
-
-namespace clang {
-class Stmt;
-
-class ParentMap {
- void* Impl;
-public:
- ParentMap(Stmt* ASTRoot);
- ~ParentMap();
-
- Stmt* getParent(Stmt*) const;
-
- bool hasParent(Stmt* S) const {
- return !getParent(S);
- }
-
- bool isSubExpr(Stmt *S) const;
-};
-
-} // end clang namespace
-#endif
diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h
deleted file mode 100644
index f43b59f69304..000000000000
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- 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 PrinterHelper interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
-#define LLVM_CLANG_AST_PRETTY_PRINTER_H
-
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-
-class Stmt;
-
-class PrinterHelper {
-public:
- virtual ~PrinterHelper();
- virtual bool handledStmt(Stmt* E, llvm::raw_ostream& OS) = 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/RecordLayout.h b/clang/include/clang/AST/RecordLayout.h
deleted file mode 100644
index 1b72017cd3e0..000000000000
--- a/clang/include/clang/AST/RecordLayout.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===--- RecordLayout.h - Layout information for a struct/union -*- 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 RecordLayout interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
-#define LLVM_CLANG_AST_LAYOUTINFO_H
-
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
- class ASTContext;
- class RecordDecl;
-
-/// ASTRecordLayout -
-/// This class contains layout information for one RecordDecl,
-/// which is a struct/union/class. The decl represented must be a definition,
-/// not a forward declaration.
-/// This class is also used to contain layout informaiton for one
-/// ObjCInterfaceDecl. FIXME - Find appropriate name.
-/// These objects are managed by ASTContext.
-class ASTRecordLayout {
- uint64_t Size; // Size of record in bits.
- unsigned Alignment; // Alignment of record in bits.
- unsigned FieldCount; // Number of fields
- uint64_t *FieldOffsets;
- friend class ASTContext;
-
- ASTRecordLayout(uint64_t S = 0, unsigned A = 8)
- : Size(S), Alignment(A), FieldCount(0) {}
- ~ASTRecordLayout() {
- delete [] FieldOffsets;
- }
-
- /// Initialize record layout. N is the number of fields in this record.
- void InitializeLayout(unsigned N) {
- FieldCount = N;
- FieldOffsets = new uint64_t[N];
- }
-
- /// Finalize record layout. Adjust record size based on the alignment.
- void FinalizeLayout() {
- // Finally, round the size of the record up to the alignment of the
- // record itself.
- Size = (Size + (Alignment-1)) & ~(Alignment-1);
- }
-
- void SetFieldOffset(unsigned FieldNo, uint64_t Offset) {
- assert (FieldNo < FieldCount && "Invalid Field No");
- FieldOffsets[FieldNo] = Offset;
- }
-
- void SetAlignment(unsigned A) { Alignment = A; }
-
- /// LayoutField - Field layout.
- void LayoutField(const FieldDecl *FD, unsigned FieldNo,
- bool IsUnion, bool StructIsPacked,
- ASTContext &Context);
-
- ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
- void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
-public:
-
- unsigned getAlignment() const { return Alignment; }
- uint64_t getSize() const { return Size; }
-
- uint64_t getFieldOffset(unsigned FieldNo) const {
- assert (FieldNo < FieldCount && "Invalid Field No");
- return FieldOffsets[FieldNo];
- }
-
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
deleted file mode 100644
index 1111bd31e1aa..000000000000
--- a/clang/include/clang/AST/Stmt.h
+++ /dev/null
@@ -1,1133 +0,0 @@
-//===--- Stmt.h - Classes for representing statements -----------*- 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 Stmt interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMT_H
-#define LLVM_CLANG_AST_STMT_H
-
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/AST/StmtIterator.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include <string>
-
-using llvm::dyn_cast_or_null;
-
-namespace clang {
- class ASTContext;
- class Expr;
- class Decl;
- class ScopedDecl;
- class IdentifierInfo;
- class SourceManager;
- class StringLiteral;
- class SwitchStmt;
- class PrinterHelper;
-
-/// Stmt - This represents one statement.
-///
-class Stmt {
-public:
- enum StmtClass {
-#define STMT(N, CLASS, PARENT) CLASS##Class = N,
-#define FIRST_STMT(N) firstStmtConstant = N,
-#define LAST_STMT(N) lastStmtConstant = N,
-#define FIRST_EXPR(N) firstExprConstant = N,
-#define LAST_EXPR(N) lastExprConstant = N
-#include "clang/AST/StmtNodes.def"
-};
-private:
- const StmtClass sClass;
-
-protected:
- /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
- /// recursively release child AST nodes.
- void DestroyChildren(ASTContext& Ctx);
-
-public:
- Stmt(StmtClass SC) : sClass(SC) {
- if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
- }
- virtual ~Stmt() {}
-
- virtual void Destroy(ASTContext& Ctx);
-
- StmtClass getStmtClass() const { return sClass; }
- const char *getStmtClassName() const;
-
- /// SourceLocation tokens are not useful in isolation - they are low level
- /// value objects created/interpreted by SourceManager. We assume AST
- /// clients will have a pointer to the respective SourceManager.
- virtual SourceRange getSourceRange() const = 0;
- SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
- SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
-
- // global temp stats (until we have a per-module visitor)
- static void addStmtClass(const StmtClass s);
- static bool CollectingStats(bool enable=false);
- static void PrintStats();
-
- /// dump - This does a local dump of the specified AST fragment. It dumps the
- /// specified node and a few nodes underneath it, but not the whole subtree.
- /// This is useful in a debugger.
- void dump() const;
- void dump(SourceManager &SM) const;
-
- /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
- void dumpAll() const;
- void dumpAll(SourceManager &SM) const;
-
- /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
- /// back to its original source language syntax.
- void dumpPretty() const;
- void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL) const;
-
- /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
- /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
- void viewAST() const;
-
- // Implement isa<T> support.
- static bool classof(const Stmt *) { return true; }
-
- /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
- /// contain implicit control-flow in the order their subexpressions
- /// are evaluated. This predicate returns true if this statement has
- /// such implicit control-flow. Such statements are also specially handled
- /// within CFGs.
- bool hasImplicitControlFlow() const;
-
- /// Child Iterators: All subclasses must implement child_begin and child_end
- /// to permit easy iteration over the substatements/subexpessions of an
- /// AST node. This permits easy iteration over all nodes in the AST.
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
-
- virtual child_iterator child_begin() = 0;
- virtual child_iterator child_end() = 0;
-
- const_child_iterator child_begin() const {
- return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
- }
-
- const_child_iterator child_end() const {
- return const_child_iterator(const_cast<Stmt*>(this)->child_end());
- }
-
- void Emit(llvm::Serializer& S) const;
- static Stmt* Create(llvm::Deserializer& D, ASTContext& C);
-
- virtual void EmitImpl(llvm::Serializer& S) const {
- // This method will eventually be a pure-virtual function.
- assert (false && "Not implemented.");
- }
-};
-
-/// DeclStmt - Adaptor class for mixing declarations with statements and
-/// expressions. For example, CompoundStmt mixes statements, expressions
-/// and declarations (variables, types). Another example is ForStmt, where
-/// the first statement can be an expression or a declaration.
-///
-class DeclStmt : public Stmt {
-protected:
- ScopedDecl *TheDecl;
- SourceLocation StartLoc, EndLoc;
-public:
- DeclStmt(ScopedDecl *D, SourceLocation startLoc, SourceLocation endLoc)
- : Stmt(DeclStmtClass), TheDecl(D), StartLoc(startLoc), EndLoc(endLoc) {}
-
- virtual void Destroy(ASTContext& Ctx);
-
- // hasSolitaryDecl - This method returns true if this DeclStmt refers
- // to a single Decl.
- bool hasSolitaryDecl() const;
-
- const ScopedDecl* getSolitaryDecl() const {
- assert (hasSolitaryDecl() &&
- "Caller assumes this DeclStmt points to one Decl*");
- return TheDecl;
- }
-
- ScopedDecl* getSolitaryDecl() {
- assert (hasSolitaryDecl() &&
- "Caller assumes this DeclStmt points to one Decl*");
- return TheDecl;
- }
-
- SourceLocation getStartLoc() const { return StartLoc; }
- SourceLocation getEndLoc() const { return EndLoc; }
- virtual SourceRange getSourceRange() const {
- return SourceRange(StartLoc, EndLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclStmtClass;
- }
- static bool classof(const DeclStmt *) { return true; }
-
- // Iterators over subexpressions.
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- // Iterators over the decls.
- class decl_iterator {
- ScopedDecl* D;
- public:
- decl_iterator(ScopedDecl *d) : D(d) {}
- bool operator==(const decl_iterator& I) const { return D == I.D; }
- bool operator!=(const decl_iterator& I) const { return D != I.D; }
- ScopedDecl* operator*() const { return D; }
- decl_iterator& operator++();
- };
-
- virtual decl_iterator decl_begin() { return TheDecl; }
- virtual decl_iterator decl_end() { return 0; }
-
- class const_decl_iterator {
- decl_iterator Impl;
- public:
- const_decl_iterator(const ScopedDecl *d)
- : Impl(const_cast<ScopedDecl*>(d)) {}
-
- bool operator==(const const_decl_iterator& I) const {
- return Impl == I.Impl;
- }
- bool operator!=(const const_decl_iterator& I) const {
- return Impl != I.Impl;
- }
- const ScopedDecl* operator*() const {
- return *Impl;
- }
- const_decl_iterator& operator++() {
- ++Impl; return *this;
- }
- };
-
- const_decl_iterator decl_begin() const { return TheDecl; }
- const_decl_iterator decl_end() const { return 0; }
-
- // Serialization.
- virtual void EmitImpl(llvm::Serializer& S) const;
- static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// NullStmt - This is the null statement ";": C99 6.8.3p3.
-///
-class NullStmt : public Stmt {
- SourceLocation SemiLoc;
-public:
- NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
-
- SourceLocation getSemiLoc() const { return SemiLoc; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == NullStmtClass;
- }
- static bool classof(const NullStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CompoundStmt - This represents a group of statements like { stmt stmt }.
-///
-class CompoundStmt : public Stmt {
- llvm::SmallVector<Stmt*, 16> Body;
- SourceLocation LBracLoc, RBracLoc;
-public:
- CompoundStmt(Stmt **StmtStart, unsigned NumStmts,
- SourceLocation LB, SourceLocation RB)
- : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts),
- LBracLoc(LB), RBracLoc(RB) {}
-
- bool body_empty() const { return Body.empty(); }
-
- typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
- body_iterator body_begin() { return Body.begin(); }
- body_iterator body_end() { return Body.end(); }
- Stmt *body_back() { return Body.back(); }
-
- typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
- const_body_iterator body_begin() const { return Body.begin(); }
- const_body_iterator body_end() const { return Body.end(); }
- const Stmt *body_back() const { return Body.back(); }
-
- typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator;
- reverse_body_iterator body_rbegin() { return Body.rbegin(); }
- reverse_body_iterator body_rend() { return Body.rend(); }
-
- typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator
- const_reverse_body_iterator;
- const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); }
- const_reverse_body_iterator body_rend() const { return Body.rend(); }
-
- void push_back(Stmt *S) { Body.push_back(S); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(LBracLoc, RBracLoc);
- }
-
- SourceLocation getLBracLoc() const { return LBracLoc; }
- SourceLocation getRBracLoc() const { return RBracLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundStmtClass;
- }
- static bool classof(const CompoundStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-// SwitchCase is the base class for CaseStmt and DefaultStmt,
-class SwitchCase : public Stmt {
-protected:
- // A pointer to the following CaseStmt or DefaultStmt class,
- // used by SwitchStmt.
- SwitchCase *NextSwitchCase;
-
- SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
-
-public:
- const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
-
- SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
-
- void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
-
- virtual Stmt* v_getSubStmt() = 0;
- Stmt *getSubStmt() { return v_getSubStmt(); }
-
- virtual SourceRange getSourceRange() const { return SourceRange(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass ||
- T->getStmtClass() == DefaultStmtClass;
- }
- static bool classof(const SwitchCase *) { return true; }
-};
-
-class CaseStmt : public SwitchCase {
- enum { SUBSTMT, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
- // GNU "case 1 ... 4" extension
- SourceLocation CaseLoc;
-public:
- CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc)
- : SwitchCase(CaseStmtClass) {
- SubExprs[SUBSTMT] = substmt;
- SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
- SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
- CaseLoc = caseLoc;
- }
-
- SourceLocation getCaseLoc() const { return CaseLoc; }
-
- Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
- Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
- Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
- virtual Stmt* v_getSubStmt() { return getSubStmt(); }
- const Expr *getLHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[LHS]);
- }
- const Expr *getRHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[RHS]);
- }
- const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
-
- void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
- void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
- void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
-
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass;
- }
- static bool classof(const CaseStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class DefaultStmt : public SwitchCase {
- Stmt* SubStmt;
- SourceLocation DefaultLoc;
-public:
- DefaultStmt(SourceLocation DL, Stmt *substmt) :
- SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
-
- Stmt *getSubStmt() { return SubStmt; }
- virtual Stmt* v_getSubStmt() { return getSubStmt(); }
- const Stmt *getSubStmt() const { return SubStmt; }
-
- SourceLocation getDefaultLoc() const { return DefaultLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(DefaultLoc, SubStmt->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DefaultStmtClass;
- }
- static bool classof(const DefaultStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-class LabelStmt : public Stmt {
- IdentifierInfo *Label;
- Stmt *SubStmt;
- SourceLocation IdentLoc;
-public:
- LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
- : Stmt(LabelStmtClass), Label(label),
- SubStmt(substmt), IdentLoc(IL) {}
-
- SourceLocation getIdentLoc() const { return IdentLoc; }
- IdentifierInfo *getID() const { return Label; }
- const char *getName() const;
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
-
- void setIdentLoc(SourceLocation L) { IdentLoc = L; }
- void setSubStmt(Stmt *SS) { SubStmt = SS; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(IdentLoc, SubStmt->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LabelStmtClass;
- }
- static bool classof(const LabelStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// IfStmt - This represents an if/then/else.
-///
-class IfStmt : public Stmt {
- enum { COND, THEN, ELSE, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- SourceLocation IfLoc;
-public:
- IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
- : Stmt(IfStmtClass) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[THEN] = then;
- SubExprs[ELSE] = elsev;
- IfLoc = IL;
- }
-
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Stmt *getThen() const { return SubExprs[THEN]; }
- const Stmt *getElse() const { return SubExprs[ELSE]; }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Stmt *getThen() { return SubExprs[THEN]; }
- Stmt *getElse() { return SubExprs[ELSE]; }
-
- virtual SourceRange getSourceRange() const {
- if (SubExprs[ELSE])
- return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
- else
- return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IfStmtClass;
- }
- static bool classof(const IfStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// SwitchStmt - This represents a 'switch' stmt.
-///
-class SwitchStmt : public Stmt {
- enum { COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- // This points to a linked list of case and default statements.
- SwitchCase *FirstCase;
- SourceLocation SwitchLoc;
-public:
- SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = NULL;
- }
-
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Stmt *getBody() const { return SubExprs[BODY]; }
- const SwitchCase *getSwitchCaseList() const { return FirstCase; }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- Stmt *getBody() { return SubExprs[BODY]; }
- SwitchCase *getSwitchCaseList() { return FirstCase; }
-
- void setBody(Stmt *S, SourceLocation SL) {
- SubExprs[BODY] = S;
- SwitchLoc = SL;
- }
- void addSwitchCase(SwitchCase *SC) {
- if (FirstCase)
- SC->setNextSwitchCase(FirstCase);
-
- FirstCase = SC;
- }
- virtual SourceRange getSourceRange() const {
- return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SwitchStmtClass;
- }
- static bool classof(const SwitchStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// WhileStmt - This represents a 'while' stmt.
-///
-class WhileStmt : public Stmt {
- enum { COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- SourceLocation WhileLoc;
-public:
- WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = body;
- WhileLoc = WL;
- }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == WhileStmtClass;
- }
- static bool classof(const WhileStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// DoStmt - This represents a 'do/while' stmt.
-///
-class DoStmt : public Stmt {
- enum { COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- SourceLocation DoLoc;
-public:
- DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
- : Stmt(DoStmtClass), DoLoc(DL) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = body;
- DoLoc = DL;
- }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DoStmtClass;
- }
- static bool classof(const DoStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
-/// the init/cond/inc parts of the ForStmt will be null if they were not
-/// specified in the source.
-///
-class ForStmt : public Stmt {
- enum { INIT, COND, INC, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
- SourceLocation ForLoc;
-public:
- ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
- : Stmt(ForStmtClass) {
- SubExprs[INIT] = Init;
- SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
- SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
- SubExprs[BODY] = Body;
- ForLoc = FL;
- }
-
- Stmt *getInit() { return SubExprs[INIT]; }
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const Stmt *getInit() const { return SubExprs[INIT]; }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ForStmtClass;
- }
- static bool classof(const ForStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// GotoStmt - This represents a direct goto.
-///
-class GotoStmt : public Stmt {
- LabelStmt *Label;
- SourceLocation GotoLoc;
- SourceLocation LabelLoc;
-public:
- GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
- : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
-
- LabelStmt *getLabel() const { return Label; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(GotoLoc, LabelLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GotoStmtClass;
- }
- static bool classof(const GotoStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// IndirectGotoStmt - This represents an indirect goto.
-///
-class IndirectGotoStmt : public Stmt {
- Stmt *Target;
- // FIXME: Add location information (e.g. SourceLocation objects).
- // When doing so, update the serialization routines.
-public:
- IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
- Target((Stmt*)target){}
-
- Expr *getTarget();
- const Expr *getTarget() const;
-
- virtual SourceRange getSourceRange() const { return SourceRange(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IndirectGotoStmtClass;
- }
- static bool classof(const IndirectGotoStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// ContinueStmt - This represents a continue.
-///
-class ContinueStmt : public Stmt {
- SourceLocation ContinueLoc;
-public:
- ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(ContinueLoc);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ContinueStmtClass;
- }
- static bool classof(const ContinueStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// BreakStmt - This represents a break.
-///
-class BreakStmt : public Stmt {
- SourceLocation BreakLoc;
-public:
- BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
-
- virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BreakStmtClass;
- }
- static bool classof(const BreakStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-
-/// ReturnStmt - This represents a return, optionally of an expression:
-/// return;
-/// return 4;
-///
-/// Note that GCC allows return with no argument in a function declared to
-/// return a value, and it allows returning a value in functions declared to
-/// return void. We explicitly model this in the AST, which means you can't
-/// depend on the return type of the function and the presence of an argument.
-///
-class ReturnStmt : public Stmt {
- Stmt *RetExpr;
- SourceLocation RetLoc;
-public:
- ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
- RetExpr((Stmt*) E), RetLoc(RL) {}
-
- const Expr *getRetValue() const;
- Expr *getRetValue();
-
- virtual SourceRange getSourceRange() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ReturnStmtClass;
- }
- static bool classof(const ReturnStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// AsmStmt - This represents a GNU inline-assembly statement extension.
-///
-class AsmStmt : public Stmt {
- SourceLocation AsmLoc, RParenLoc;
- StringLiteral *AsmStr;
-
- bool IsSimple;
- bool IsVolatile;
-
- unsigned NumOutputs;
- unsigned NumInputs;
-
- llvm::SmallVector<std::string, 4> Names;
- llvm::SmallVector<StringLiteral*, 4> Constraints;
- llvm::SmallVector<Expr*, 4> Exprs;
-
- llvm::SmallVector<StringLiteral*, 4> Clobbers;
-public:
- AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
- unsigned numoutputs, unsigned numinputs,
- std::string *names, StringLiteral **constraints,
- Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc);
-
- bool isVolatile() const { return IsVolatile; }
- bool isSimple() const { return IsSimple; }
-
- unsigned getNumOutputs() const { return NumOutputs; }
- const std::string &getOutputName(unsigned i) const
- { return Names[i]; }
- const StringLiteral *getOutputConstraint(unsigned i) const
- { return Constraints[i]; }
- StringLiteral *getOutputConstraint(unsigned i)
- { return Constraints[i]; }
- const Expr *getOutputExpr(unsigned i) const { return Exprs[i]; }
- Expr *getOutputExpr(unsigned i) { return Exprs[i]; }
-
- unsigned getNumInputs() const { return NumInputs; }
- const std::string &getInputName(unsigned i) const
- { return Names[i + NumOutputs]; }
- StringLiteral *getInputConstraint(unsigned i)
- { return Constraints[i + NumOutputs]; }
- const StringLiteral *getInputConstraint(unsigned i) const
- { return Constraints[i + NumOutputs]; }
- Expr *getInputExpr(unsigned i) { return Exprs[i + NumOutputs]; }
- const Expr *getInputExpr(unsigned i) const { return Exprs[i + NumOutputs]; }
-
- const StringLiteral *getAsmString() const { return AsmStr; }
- StringLiteral *getAsmString() { return AsmStr; }
-
- unsigned getNumClobbers() const { return Clobbers.size(); }
- StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
- const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AsmLoc, RParenLoc);
- }
-
- static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
- static bool classof(const AsmStmt *) { return true; }
-
- // Input expr iterators.
-
- typedef Expr* const * inputs_iterator;
- typedef const Expr* const* const_inputs_iterator;
-
- inputs_iterator begin_inputs() { return &Exprs[0] + NumOutputs; }
- inputs_iterator end_inputs() { return begin_inputs() + NumInputs; }
-
- const_inputs_iterator begin_inputs() const { return &Exprs[0] + NumOutputs; }
- const_inputs_iterator end_inputs() const { return begin_inputs() + NumInputs;}
-
- // Output expr iterators.
-
- typedef Expr* const * outputs_iterator;
- typedef const Expr* const* const_outputs_iterator;
-
- outputs_iterator begin_outputs() { return &Exprs[0]; }
- outputs_iterator end_outputs() { return begin_outputs() + NumOutputs; }
-
- const_outputs_iterator begin_outputs() const { return &Exprs[0]; }
- const_outputs_iterator end_outputs() const {
- return begin_outputs() + NumOutputs;
- }
-
- // Child iterators
-
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
-/// represented as 'for (element 'in' collection-expression)' stmt.
-///
-class ObjCForCollectionStmt : public Stmt {
- enum { ELEM, COLLECTION, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
- SourceLocation ForLoc;
- SourceLocation RParenLoc;
-public:
- ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
- SourceLocation FCL, SourceLocation RPL);
-
- Stmt *getElement() { return SubExprs[ELEM]; }
- Expr *getCollection() {
- return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
- }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const Stmt *getElement() const { return SubExprs[ELEM]; }
- const Expr *getCollection() const {
- return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
- }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCForCollectionStmtClass;
- }
- static bool classof(const ObjCForCollectionStmt *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
-class ObjCAtCatchStmt : public Stmt {
-private:
- enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR };
- Stmt *SubExprs[END_EXPR];
- SourceLocation AtCatchLoc, RParenLoc;
-
- // Used by deserialization.
- ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
- : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
-
-public:
- ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
- Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList);
-
- const Stmt *getCatchBody() const { return SubExprs[BODY]; }
- Stmt *getCatchBody() { return SubExprs[BODY]; }
-
- const ObjCAtCatchStmt *getNextCatchStmt() const {
- return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
- }
- ObjCAtCatchStmt *getNextCatchStmt() {
- return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
- }
-
- const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; }
- Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
- }
-
- bool hasEllipsis() const { return getCatchParamStmt() == 0; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtCatchStmtClass;
- }
- static bool classof(const ObjCAtCatchStmt *) { return true; }
-
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
-class ObjCAtFinallyStmt : public Stmt {
- Stmt *AtFinallyStmt;
- SourceLocation AtFinallyLoc;
-public:
- ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
- : Stmt(ObjCAtFinallyStmtClass),
- AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
-
- const Stmt *getFinallyBody () const { return AtFinallyStmt; }
- Stmt *getFinallyBody () { return AtFinallyStmt; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtFinallyStmtClass;
- }
- static bool classof(const ObjCAtFinallyStmt *) { return true; }
-
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCAtTryStmt - This represent objective-c's over-all
-/// @try ... @catch ... @finally statement.
-class ObjCAtTryStmt : public Stmt {
-private:
- enum { TRY, CATCH, FINALLY, END_EXPR };
- Stmt* SubStmts[END_EXPR];
-
- SourceLocation AtTryLoc;
-public:
- ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt *atCatchStmt,
- Stmt *atFinallyStmt)
- : Stmt(ObjCAtTryStmtClass) {
- SubStmts[TRY] = atTryStmt;
- SubStmts[CATCH] = atCatchStmt;
- SubStmts[FINALLY] = atFinallyStmt;
- AtTryLoc = atTryLoc;
- }
-
- const Stmt *getTryBody() const { return SubStmts[TRY]; }
- Stmt *getTryBody() { return SubStmts[TRY]; }
- const ObjCAtCatchStmt *getCatchStmts() const {
- return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
- }
- ObjCAtCatchStmt *getCatchStmts() {
- return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
- }
- const ObjCAtFinallyStmt *getFinallyStmt() const {
- return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
- }
- ObjCAtFinallyStmt *getFinallyStmt() {
- return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
- }
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtTryStmtClass;
- }
- static bool classof(const ObjCAtTryStmt *) { return true; }
-
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
-/// Example: @synchronized (sem) {
-/// do-something;
-/// }
-///
-class ObjCAtSynchronizedStmt : public Stmt {
-private:
- enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
- Stmt* SubStmts[END_EXPR];
- SourceLocation AtSynchronizedLoc;
-
-public:
- ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
- Stmt *synchBody)
- : Stmt(ObjCAtSynchronizedStmtClass) {
- SubStmts[SYNC_EXPR] = synchExpr;
- SubStmts[SYNC_BODY] = synchBody;
- AtSynchronizedLoc = atSynchronizedLoc;
- }
-
- const CompoundStmt *getSynchBody() const {
- return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
- }
- CompoundStmt *getSynchBody() {
- return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
- }
-
- const Expr *getSynchExpr() const {
- return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
- }
- Expr *getSynchExpr() {
- return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
- }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
- }
- static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
-
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D,
- ASTContext& C);
-};
-
-/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
-class ObjCAtThrowStmt : public Stmt {
- Stmt *Throw;
- SourceLocation AtThrowLoc;
-public:
- ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
- : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
- AtThrowLoc = atThrowLoc;
- }
-
- const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
- Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
-
- virtual SourceRange getSourceRange() const {
- if (Throw)
- return SourceRange(AtThrowLoc, Throw->getLocEnd());
- else
- return SourceRange(AtThrowLoc);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtThrowStmtClass;
- }
- static bool classof(const ObjCAtThrowStmt *) { return true; }
-
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/StmtGraphTraits.h b/clang/include/clang/AST/StmtGraphTraits.h
deleted file mode 100644
index 1bfac6a9587e..000000000000
--- a/clang/include/clang/AST/StmtGraphTraits.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- 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 a template specialization of llvm::GraphTraits to
-// treat ASTs (Stmt*) as graphs
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
-#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
-
-#include "clang/AST/Stmt.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-
-namespace llvm {
-
-//template <typename T> struct GraphTraits;
-
-
-template <> struct GraphTraits<clang::Stmt*> {
- typedef clang::Stmt NodeType;
- typedef clang::Stmt::child_iterator ChildIteratorType;
- typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
-
- static NodeType* getEntryNode(clang::Stmt* S) { return S; }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- if (N) return N->child_begin();
- else return ChildIteratorType();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- if (N) return N->child_end();
- else return ChildIteratorType();
- }
-
- static nodes_iterator nodes_begin(clang::Stmt* S) {
- return df_begin(S);
- }
-
- static nodes_iterator nodes_end(clang::Stmt* S) {
- return df_end(S);
- }
-};
-
-
-template <> struct GraphTraits<const clang::Stmt*> {
- typedef const clang::Stmt NodeType;
- typedef clang::Stmt::const_child_iterator ChildIteratorType;
- typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
-
- static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- if (N) return N->child_begin();
- else return ChildIteratorType();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- if (N) return N->child_end();
- else return ChildIteratorType();
- }
-
- static nodes_iterator nodes_begin(const clang::Stmt* S) {
- return df_begin(S);
- }
-
- static nodes_iterator nodes_end(const clang::Stmt* S) {
- return df_end(S);
- }
-};
-
-
-} // end namespace llvm
-
-#endif
diff --git a/clang/include/clang/AST/StmtIterator.h b/clang/include/clang/AST/StmtIterator.h
deleted file mode 100644
index c652ef207111..000000000000
--- a/clang/include/clang/AST/StmtIterator.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- StmtIterator.h - Iterators for Statements ------------------------===//
-//
-// 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 StmtIterator and ConstStmtIterator classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMT_ITR_H
-#define LLVM_CLANG_AST_STMT_ITR_H
-
-#include "llvm/ADT/iterator.h"
-#include <cassert>
-
-namespace clang {
-
-class Stmt;
-class ScopedDecl;
-class VariableArrayType;
-
-class StmtIteratorBase {
-protected:
- enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, Flags = 0x3 };
-
- union { Stmt** stmt; ScopedDecl* decl; };
- uintptr_t RawVAPtr;
-
- bool inDecl() const {
- return RawVAPtr & DeclMode ? true : false;
- }
-
- bool inSizeOfTypeVA() const {
- return RawVAPtr & SizeOfTypeVAMode ? true : false;
- }
-
- VariableArrayType* getVAPtr() const {
- return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags);
- }
-
- void setVAPtr(VariableArrayType* P) {
- assert (inDecl() || inSizeOfTypeVA());
- RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
- }
-
- void NextDecl(bool ImmediateAdvance = true);
- void NextVA();
-
- Stmt*& GetDeclExpr() const;
-
- StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {}
- StmtIteratorBase(ScopedDecl* d);
- StmtIteratorBase(VariableArrayType* t);
- StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {}
-};
-
-
-template <typename DERIVED, typename REFERENCE>
-class StmtIteratorImpl : public StmtIteratorBase,
- public std::iterator<std::forward_iterator_tag,
- REFERENCE, ptrdiff_t,
- REFERENCE, REFERENCE> {
-protected:
- StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
-public:
- StmtIteratorImpl() {}
- StmtIteratorImpl(Stmt** s) : StmtIteratorBase(s) {}
- StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {}
- StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {}
-
- DERIVED& operator++() {
- if (inDecl()) {
- if (getVAPtr()) NextVA();
- else NextDecl();
- }
- else if (inSizeOfTypeVA())
- NextVA();
- else
- ++stmt;
-
- return static_cast<DERIVED&>(*this);
- }
-
- DERIVED operator++(int) {
- DERIVED tmp = static_cast<DERIVED&>(*this);
- operator++();
- return tmp;
- }
-
- bool operator==(const DERIVED& RHS) const {
- return stmt == RHS.stmt && RawVAPtr == RHS.RawVAPtr;
- }
-
- bool operator!=(const DERIVED& RHS) const {
- return stmt != RHS.stmt || RawVAPtr != RHS.RawVAPtr;
- }
-
- REFERENCE operator*() const {
- return (REFERENCE) (inDecl() || inSizeOfTypeVA() ? GetDeclExpr() : *stmt);
- }
-
- REFERENCE operator->() const { return operator*(); }
-};
-
-struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
- explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
-
- StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
-
- StmtIterator(VariableArrayType* t):StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
- StmtIterator(ScopedDecl* D) : StmtIteratorImpl<StmtIterator,Stmt*&>(D) {}
-};
-
-struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
- const Stmt*> {
- explicit ConstStmtIterator() :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
-
- ConstStmtIterator(const StmtIterator& RHS) :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def
deleted file mode 100644
index ed8861ba9967..000000000000
--- a/clang/include/clang/AST/StmtNodes.def
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- StmtNodes.def - Metadata about Stmt AST nodes -----------*- 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 AST Node info database.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FIRST_STMT
-#define FIRST_STMT(n)
-#define LAST_STMT(n)
-#endif
-
-#ifndef FIRST_EXPR
-#define FIRST_EXPR(n)
-#define LAST_EXPR(n)
-#endif
-
-// Normal Statements.
-FIRST_STMT(1)
-STMT( 1, NullStmt , Stmt)
-STMT( 2, CompoundStmt , Stmt)
-STMT( 3, CaseStmt , SwitchCase)
-STMT( 4, DefaultStmt , SwitchCase)
-STMT( 5, LabelStmt , Stmt)
-STMT( 6, IfStmt , Stmt)
-STMT( 7, SwitchStmt , Stmt)
-STMT( 8, WhileStmt , Stmt)
-STMT( 9, DoStmt , Stmt)
-STMT(10, ForStmt , Stmt)
-STMT(11, GotoStmt , Stmt)
-STMT(12, IndirectGotoStmt, Stmt)
-STMT(13, ContinueStmt , Stmt)
-STMT(14, BreakStmt , Stmt)
-STMT(15, ReturnStmt , Stmt)
-STMT(16, DeclStmt , Stmt)
-STMT(17, SwitchCase , Stmt)
-
-// GNU Stmt Extensions
-STMT(18, AsmStmt , Stmt)
-
-// Obj-C statements
-STMT(19, ObjCAtTryStmt , Stmt)
-STMT(20, ObjCAtCatchStmt , Stmt)
-STMT(21, ObjCAtFinallyStmt , Stmt)
-STMT(22, ObjCAtThrowStmt , Stmt)
-STMT(23, ObjCAtSynchronizedStmt , Stmt)
-// Obj-C2 statements
-STMT(24, ObjCForCollectionStmt, Stmt)
-
-LAST_STMT(23)
-
-FIRST_EXPR(31)
-// Expressions.
-STMT(31, Expr , Stmt)
-STMT(32, PredefinedExpr , Expr)
-STMT(33, DeclRefExpr , Expr)
-STMT(34, IntegerLiteral , Expr)
-STMT(35, FloatingLiteral , Expr)
-STMT(36, ImaginaryLiteral , Expr)
-STMT(37, StringLiteral , Expr)
-STMT(38, CharacterLiteral , Expr)
-STMT(39, ParenExpr , Expr)
-STMT(40, UnaryOperator , Expr)
-STMT(41, SizeOfAlignOfTypeExpr , Expr)
-STMT(42, ArraySubscriptExpr , Expr)
-STMT(43, CallExpr , Expr)
-STMT(44, MemberExpr , Expr)
-STMT(45, CastExpr , Expr)
-STMT(46, BinaryOperator , Expr)
-STMT(47, CompoundAssignOperator, BinaryOperator)
-STMT(48, ConditionalOperator , Expr)
-STMT(49, ImplicitCastExpr , CastExpr)
-STMT(50, ExplicitCastExpr , CastExpr)
-STMT(51, CompoundLiteralExpr , Expr)
-STMT(52, ExtVectorElementExpr , Expr)
-STMT(53, InitListExpr , Expr)
-STMT(54, VAArgExpr , Expr)
-
-// GNU Extensions.
-STMT(55, AddrLabelExpr , Expr)
-STMT(56, StmtExpr , Expr)
-STMT(57, TypesCompatibleExpr , Expr)
-STMT(58, ChooseExpr , Expr)
-
-// C++ Expressions.
-STMT(60, CXXCastExpr , Expr)
-STMT(61, CXXBoolLiteralExpr , Expr)
-STMT(62, CXXThrowExpr , Expr)
-STMT(63, CXXDefaultArgExpr , Expr)
-STMT(64, CXXFunctionalCastExpr, CastExpr)
-STMT(65, CXXZeroInitValueExpr , Expr)
-STMT(66, CXXConditionDeclExpr , DeclRefExpr)
-
-// Obj-C Expressions.
-STMT(70, ObjCStringLiteral , Expr)
-STMT(71, ObjCEncodeExpr , Expr)
-STMT(72, ObjCMessageExpr , Expr)
-STMT(73, ObjCSelectorExpr , Expr)
-STMT(74, ObjCProtocolExpr , Expr)
-STMT(75, ObjCIvarRefExpr , Expr)
-STMT(76, ObjCPropertyRefExpr , Expr)
-
-// Clang Extensions.
-STMT(77, OverloadExpr , Expr)
-STMT(78, ShuffleVectorExpr , Expr)
-STMT(79, BlockExpr , Expr)
-STMT(80, BlockDeclRefExpr , Expr)
-
-LAST_EXPR(80)
-
-#undef STMT
-#undef FIRST_STMT
-#undef LAST_STMT
-#undef FIRST_EXPR
-#undef LAST_EXPR
diff --git a/clang/include/clang/AST/StmtVisitor.h b/clang/include/clang/AST/StmtVisitor.h
deleted file mode 100644
index fb1e4d120272..000000000000
--- a/clang/include/clang/AST/StmtVisitor.h
+++ /dev/null
@@ -1,174 +0,0 @@
-//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- 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 StmtVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTVISITOR_H
-#define LLVM_CLANG_AST_STMTVISITOR_H
-
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-
-namespace clang {
-
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<CLASS*>(S))
-
-/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
-/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
-template<typename ImplClass, typename RetTy=void>
-class StmtVisitor {
-public:
- RetTy Visit(Stmt *S) {
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
- default: assert(0 && "Unknown binary operator!");
- case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator);
- case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator);
- case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator);
- case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator);
- case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator);
- case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator);
- case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator);
-
- case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator);
- case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator);
- case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator);
- case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator);
- case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator);
- case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator);
-
- case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator);
- case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator);
- case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator);
- case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator);
- case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator);
- case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator);
- case BinaryOperator::MulAssign:
- DISPATCH(BinMulAssign, CompoundAssignOperator);
- case BinaryOperator::DivAssign:
- DISPATCH(BinDivAssign, CompoundAssignOperator);
- case BinaryOperator::RemAssign:
- DISPATCH(BinRemAssign, CompoundAssignOperator);
- case BinaryOperator::AddAssign:
- DISPATCH(BinAddAssign, CompoundAssignOperator);
- case BinaryOperator::SubAssign:
- DISPATCH(BinSubAssign, CompoundAssignOperator);
- case BinaryOperator::ShlAssign:
- DISPATCH(BinShlAssign, CompoundAssignOperator);
- case BinaryOperator::ShrAssign:
- DISPATCH(BinShrAssign, CompoundAssignOperator);
- case BinaryOperator::AndAssign:
- DISPATCH(BinAndAssign, CompoundAssignOperator);
- case BinaryOperator::OrAssign:
- DISPATCH(BinOrAssign, CompoundAssignOperator);
- case BinaryOperator::XorAssign:
- DISPATCH(BinXorAssign, CompoundAssignOperator);
- case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator);
- }
- } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
- default: assert(0 && "Unknown unary operator!");
- case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
- case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
- case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
- case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
- case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
- case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator);
- case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator);
- case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator);
- case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator);
- case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator);
- case UnaryOperator::SizeOf: DISPATCH(UnarySizeOf, UnaryOperator);
- case UnaryOperator::AlignOf: DISPATCH(UnaryAlignOf, UnaryOperator);
- case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator);
- case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator);
- case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator);
- case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator);
- }
- }
-
- // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
- switch (S->getStmtClass()) {
- default: assert(0 && "Unknown stmt kind!");
-#define STMT(N, CLASS, PARENT) \
- case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
-#include "clang/AST/StmtNodes.def"
- }
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on VisitExpr or whatever else is the superclass.
-#define STMT(N, CLASS, PARENT) \
- RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); }
-#include "clang/AST/StmtNodes.def"
-
- // If the implementation doesn't implement binary operator methods, fall back
- // on VisitBinaryOperator.
-#define BINOP_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(BinaryOperator *S) { \
- DISPATCH(BinaryOperator, BinaryOperator); \
- }
- BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
- BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
- BINOP_FALLBACK(Shr)
-
- BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
- BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
- BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
- BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
-
- BINOP_FALLBACK(Assign)
- BINOP_FALLBACK(Comma)
-#undef BINOP_FALLBACK
-
- // If the implementation doesn't implement compound assignment operator
- // methods, fall back on VisitCompoundAssignOperator.
-#define CAO_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(CompoundAssignOperator *S) { \
- DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
- }
- CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
- CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
- CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
- CAO_FALLBACK(XorAssign)
-#undef CAO_FALLBACK
-
- // If the implementation doesn't implement unary operator methods, fall back
- // on VisitUnaryOperator.
-#define UNARYOP_FALLBACK(NAME) \
- RetTy VisitUnary ## NAME(UnaryOperator *S) { \
- DISPATCH(UnaryOperator, UnaryOperator); \
- }
- UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
- UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
- UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
-
- UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
- UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
- UNARYOP_FALLBACK(SizeOf) UNARYOP_FALLBACK(AlignOf)
- UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
- UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
-#undef UNARYOP_FALLBACK
-
- // Base case, ignore it. :)
- RetTy VisitStmt(Stmt *Node) { return RetTy(); }
-};
-
-#undef DISPATCH
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/TargetBuiltins.h b/clang/include/clang/AST/TargetBuiltins.h
deleted file mode 100644
index d425a9b8ecad..000000000000
--- a/clang/include/clang/AST/TargetBuiltins.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===--- TargetBuiltins.h - Target specific builtin IDs -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TARGET_BUILTINS_H
-#define LLVM_CLANG_AST_TARGET_BUILTINS_H
-
-#include "clang/AST/Builtins.h"
-#undef PPC
-
-namespace clang {
- /// X86 builtins
- namespace X86 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "X86Builtins.def"
- LastTSBuiltin
- };
- }
-
- /// PPC builtins
- namespace PPC {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "PPCBuiltins.def"
- LastTSBuiltin
- };
- }
-} // end namespace clang.
-
-#endif
diff --git a/clang/include/clang/AST/TranslationUnit.h b/clang/include/clang/AST/TranslationUnit.h
deleted file mode 100644
index 2153a0b1ebfc..000000000000
--- a/clang/include/clang/AST/TranslationUnit.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===--- TranslationUnit.h - Abstraction for Translation Units -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-// FIXME: This should eventually be moved out of the driver, or replaced
-// with its eventual successor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TRANSLATION_UNIT_H
-#define LLVM_CLANG_TRANSLATION_UNIT_H
-
-#include "clang/AST/ASTContext.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include "llvm/System/Path.h"
-#include <vector>
-#include <string>
-
-namespace clang {
-
-class FileManager;
-class SourceManager;
-class TargetInfo;
-class IdentifierTable;
-class SelectorTable;
-class ASTContext;
-class Decl;
-class FileEntry;
-
-class TranslationUnit {
- ASTContext* Context;
- std::vector<Decl*> TopLevelDecls;
- bool OwnsMetaData;
- bool OwnsDecls;
-
- // The default ctor is only invoked during deserialization.
- explicit TranslationUnit() : Context(NULL), OwnsMetaData(true),
- OwnsDecls(true) {}
-
-public:
- explicit TranslationUnit(ASTContext& Ctx)
- : Context(&Ctx), OwnsMetaData(false), OwnsDecls(true) {}
-
- void SetOwnsDecls(bool val) { OwnsDecls = val; }
-
- ~TranslationUnit();
-
- const std::string& getSourceFile() const;
-
- /// Emit - Emit the translation unit to an arbitray bitcode stream.
- void Emit(llvm::Serializer& S) const;
-
- /// Create - Reconsititute a translation unit from a bitcode stream.
- static TranslationUnit* Create(llvm::Deserializer& D, FileManager& FMgr);
-
- // Accessors
- const LangOptions& getLangOptions() const { return Context->getLangOptions();}
-
- ASTContext& getContext() { return *Context; }
- const ASTContext& getContext() const { return *Context; }
-
- /// AddTopLevelDecl - Add a top-level declaration to the translation unit.
- /// Ownership of the Decl is transfered to the TranslationUnit object.
- void AddTopLevelDecl(Decl* d) {
- TopLevelDecls.push_back(d);
- }
-
- typedef std::vector<Decl*>::iterator iterator;
- iterator begin() { return TopLevelDecls.begin(); }
- iterator end() { return TopLevelDecls.end(); }
-
- typedef std::vector<Decl*>::const_iterator const_iterator;
- const_iterator begin() const { return TopLevelDecls.begin(); }
- const_iterator end() const { return TopLevelDecls.end(); }
-};
-
-/// EmitASTBitcodeFile - Emit a translation unit to a bitcode file.
-bool EmitASTBitcodeFile(const TranslationUnit& TU,
- const llvm::sys::Path& Filename);
-
-bool EmitASTBitcodeFile(const TranslationUnit* TU,
- const llvm::sys::Path& Filename);
-
-/// EmitASTBitcodeStream - Emit a translation unit to a std::ostream.
-bool EmitASTBitcodeStream(const TranslationUnit& TU,
- std::ostream& Stream);
-
-bool EmitASTBitcodeStream(const TranslationUnit* TU,
- std::ostream& Stream);
-
-/// EmitASTBitcodeBuffer - Emit a translation unit to a buffer.
-bool EmitASTBitcodeBuffer(const TranslationUnit& TU,
- std::vector<unsigned char>& Buffer);
-
-bool EmitASTBitcodeBuffer(const TranslationUnit* TU,
- std::vector<unsigned char>& Buffer);
-
-/// ReadASTBitcodeFile - Reconsitute a translation unit from a bitcode file.
-TranslationUnit* ReadASTBitcodeFile(const llvm::sys::Path& Filename,
- FileManager& FMgr);
-
-/// ReadASTBitcodeBuffer - Reconsitute a translation unit from a buffer.
-TranslationUnit* ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer,
- FileManager& FMgr);
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
deleted file mode 100644
index 81417f0da6c4..000000000000
--- a/clang/include/clang/AST/Type.h
+++ /dev/null
@@ -1,1412 +0,0 @@
-//===--- Type.h - C Language Family Type Representation ---------*- 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 Type interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPE_H
-#define LLVM_CLANG_AST_TYPE_H
-
-#include "llvm/Support/Casting.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-
-using llvm::isa;
-using llvm::cast;
-using llvm::cast_or_null;
-using llvm::dyn_cast;
-using llvm::dyn_cast_or_null;
-
-namespace clang {
- class ASTContext;
- class Type;
- class TypedefDecl;
- class TagDecl;
- class RecordDecl;
- class CXXRecordDecl;
- class EnumDecl;
- class FieldDecl;
- class ObjCInterfaceDecl;
- class ObjCProtocolDecl;
- class ObjCMethodDecl;
- class Expr;
- class Stmt;
- class SourceLocation;
- class PointerLikeType;
- class PointerType;
- class BlockPointerType;
- class ReferenceType;
- class VectorType;
- class ArrayType;
- class ConstantArrayType;
- class VariableArrayType;
- class IncompleteArrayType;
- class RecordType;
- class EnumType;
- class ComplexType;
- class TagType;
- class TypedefType;
- class FunctionType;
- class FunctionTypeProto;
- class ExtVectorType;
- class BuiltinType;
- class ObjCInterfaceType;
- class ObjCQualifiedIdType;
- class ObjCQualifiedInterfaceType;
- class StmtIteratorBase;
-
-/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
-/// their own: instead each reference to a type stores the qualifiers. This
-/// greatly reduces the number of nodes we need to allocate for types (for
-/// example we only need one for 'int', 'const int', 'volatile int',
-/// 'const volatile int', etc).
-///
-/// As an added efficiency bonus, instead of making this a pair, we just store
-/// the three bits we care about in the low bits of the pointer. To handle the
-/// packing/unpacking, we make QualType be a simple wrapper class that acts like
-/// a smart pointer.
-class QualType {
- uintptr_t ThePtr;
-public:
- enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
- Const = 0x1,
- Restrict = 0x2,
- Volatile = 0x4,
- CVRFlags = Const|Restrict|Volatile
- };
-
- QualType() : ThePtr(0) {}
-
- QualType(Type *Ptr, unsigned Quals) {
- assert((Quals & ~CVRFlags) == 0 && "Invalid type qualifiers!");
- ThePtr = reinterpret_cast<uintptr_t>(Ptr);
- assert((ThePtr & CVRFlags) == 0 && "Type pointer not 8-byte aligned?");
- ThePtr |= Quals;
- }
-
- QualType(const Type *Ptr, unsigned Quals) {
- assert((Quals & ~CVRFlags) == 0 && "Invalid type qualifiers!");
- ThePtr = reinterpret_cast<uintptr_t>(Ptr);
- assert((ThePtr & CVRFlags) == 0 && "Type pointer not 8-byte aligned?");
- ThePtr |= Quals;
- }
-
- static QualType getFromOpaquePtr(void *Ptr) {
- QualType T;
- T.ThePtr = reinterpret_cast<uintptr_t>(Ptr);
- return T;
- }
-
- unsigned getCVRQualifiers() const {
- return ThePtr & CVRFlags;
- }
- Type *getTypePtr() const {
- return reinterpret_cast<Type*>(ThePtr & ~CVRFlags);
- }
-
- void *getAsOpaquePtr() const {
- return reinterpret_cast<void*>(ThePtr);
- }
-
- Type &operator*() const {
- return *getTypePtr();
- }
-
- Type *operator->() const {
- return getTypePtr();
- }
-
- /// isNull - Return true if this QualType doesn't point to a type yet.
- bool isNull() const {
- return ThePtr == 0;
- }
-
- bool isConstQualified() const {
- return (ThePtr & Const) ? true : false;
- }
- bool isVolatileQualified() const {
- return (ThePtr & Volatile) ? true : false;
- }
- bool isRestrictQualified() const {
- return (ThePtr & Restrict) ? true : false;
- }
-
- bool isConstant(ASTContext& Ctx) const;
-
- /// addConst/addVolatile/addRestrict - add the specified type qual to this
- /// QualType.
- void addConst() { ThePtr |= Const; }
- void addVolatile() { ThePtr |= Volatile; }
- void addRestrict() { ThePtr |= Restrict; }
-
- void removeConst() { ThePtr &= ~Const; }
- void removeVolatile() { ThePtr &= ~Volatile; }
- void removeRestrict() { ThePtr &= ~Restrict; }
-
- QualType getQualifiedType(unsigned TQs) const {
- return QualType(getTypePtr(), TQs);
- }
- QualType getWithAdditionalQualifiers(unsigned TQs) const {
- return QualType(getTypePtr(), TQs|getCVRQualifiers());
- }
-
- inline QualType getUnqualifiedType() const;
-
- /// operator==/!= - Indicate whether the specified types and qualifiers are
- /// identical.
- bool operator==(const QualType &RHS) const {
- return ThePtr == RHS.ThePtr;
- }
- bool operator!=(const QualType &RHS) const {
- return ThePtr != RHS.ThePtr;
- }
- std::string getAsString() const {
- std::string S;
- getAsStringInternal(S);
- return S;
- }
- void getAsStringInternal(std::string &Str) const;
-
- void dump(const char *s) const;
- void dump() const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(getAsOpaquePtr());
- }
-
-public:
-
- /// getAddressSpace - Return the address space of this type.
- inline unsigned getAddressSpace() const;
-
- /// Emit - Serialize a QualType to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Deserialize a QualType from Bitcode.
- static QualType ReadVal(llvm::Deserializer& D);
-
- void ReadBackpatch(llvm::Deserializer& D);
-};
-
-} // end clang.
-
-namespace llvm {
-/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
-/// to a specific Type class.
-template<> struct simplify_type<const ::clang::QualType> {
- typedef ::clang::Type* SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
- return Val.getTypePtr();
- }
-};
-template<> struct simplify_type< ::clang::QualType>
- : public simplify_type<const ::clang::QualType> {};
-
-} // end namespace llvm
-
-namespace clang {
-
-/// Type - This is the base class of the type hierarchy. A central concept
-/// with types is that each type always has a canonical type. A canonical type
-/// is the type with any typedef names stripped out of it or the types it
-/// references. For example, consider:
-///
-/// typedef int foo;
-/// typedef foo* bar;
-/// 'int *' 'foo *' 'bar'
-///
-/// There will be a Type object created for 'int'. Since int is canonical, its
-/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a
-/// TypeNameType). Its CanonicalType pointer points to the 'int' Type. Next
-/// there is a PointerType that represents 'int*', which, like 'int', is
-/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical
-/// type is 'int*', and there is a TypeNameType for 'bar', whose canonical type
-/// is also 'int*'.
-///
-/// Non-canonical types are useful for emitting diagnostics, without losing
-/// information about typedefs being used. Canonical types are useful for type
-/// comparisons (they allow by-pointer equality tests) and useful for reasoning
-/// about whether something has a particular form (e.g. is a function type),
-/// because they implicitly, recursively, strip all typedefs out of a type.
-///
-/// Types, once created, are immutable.
-///
-class Type {
-public:
- enum TypeClass {
- Builtin, Complex, Pointer, Reference,
- ConstantArray, VariableArray, IncompleteArray,
- Vector, ExtVector,
- FunctionNoProto, FunctionProto,
- TypeName, Tagged, ASQual,
- ObjCInterface, ObjCQualifiedInterface,
- ObjCQualifiedId,
- TypeOfExp, TypeOfTyp, // GNU typeof extension.
- BlockPointer // C extension
- };
-private:
- QualType CanonicalType;
-
- /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
- /// Note that this should stay at the end of the ivars for Type so that
- /// subclasses can pack their bitfields into the same word.
- unsigned TC : 5;
-protected:
- // silence VC++ warning C4355: 'this' : used in base member initializer list
- Type *this_() { return this; }
- Type(TypeClass tc, QualType Canonical)
- : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
- TC(tc) {}
- virtual ~Type() {};
- virtual void Destroy(ASTContext& C);
- friend class ASTContext;
-
- void EmitTypeInternal(llvm::Serializer& S) const;
- void ReadTypeInternal(llvm::Deserializer& D);
-
-public:
- TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
-
- bool isCanonical() const { return CanonicalType.getTypePtr() == this; }
-
- /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
- /// object types, function types, and incomplete types.
-
- /// isObjectType - types that fully describe objects. An object is a region
- /// of memory that can be examined and stored into (H&S).
- bool isObjectType() const;
-
- /// isIncompleteType - Return true if this is an incomplete type.
- /// A type that can describe objects, but which lacks information needed to
- /// determine its size (e.g. void, or a fwd declared struct). Clients of this
- /// routine will need to determine if the size is actually required.
- bool isIncompleteType() const;
-
- /// isIncompleteOrObjectType - Return true if this is an incomplete or object
- /// type, in other words, not a function type.
- bool isIncompleteOrObjectType() const {
- return !isFunctionType();
- }
-
- /// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
- /// types that have a non-constant expression. This does not include "[]".
- bool isVariablyModifiedType() const;
-
- /// Helper methods to distinguish type categories. All type predicates
- /// operate on the canonical type, ignoring typedefs and qualifiers.
-
- /// isIntegerType() does *not* include complex integers (a GCC extension).
- /// isComplexIntegerType() can be used to test for complex integers.
- bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
- bool isEnumeralType() const;
- bool isBooleanType() const;
- bool isCharType() const;
- bool isWideCharType() const;
- bool isIntegralType() const;
-
- /// Floating point categories.
- bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
- /// isComplexType() does *not* include complex integers (a GCC extension).
- /// isComplexIntegerType() can be used to test for complex integers.
- bool isComplexType() const; // C99 6.2.5p11 (complex)
- bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int.
- bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
- bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
- bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
- bool isVoidType() const; // C99 6.2.5p19
- bool isDerivedType() const; // C99 6.2.5p20
- bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
- bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures)
-
- // Type Predicates: Check to see if this type is structurally the specified
- // type, ignoring typedefs and qualifiers.
- bool isFunctionType() const;
- bool isPointerLikeType() const; // Pointer or Reference.
- bool isPointerType() const;
- bool isBlockPointerType() const;
- bool isReferenceType() const;
- bool isFunctionPointerType() const;
- bool isArrayType() const;
- bool isConstantArrayType() const;
- bool isIncompleteArrayType() const;
- bool isVariableArrayType() const;
- bool isRecordType() const;
- bool isClassType() const;
- bool isStructureType() const;
- bool isUnionType() const;
- bool isComplexIntegerType() const; // GCC _Complex integer type.
- bool isVectorType() const; // GCC vector type.
- bool isExtVectorType() const; // Extended vector type.
- bool isObjCInterfaceType() const; // NSString or NSString<foo>
- bool isObjCQualifiedInterfaceType() const; // NSString<foo>
- bool isObjCQualifiedIdType() const; // id<foo>
-
- // Type Checking Functions: Check to see if this type is structurally the
- // specified type, ignoring typedefs and qualifiers, and return a pointer to
- // the best type we can.
- const BuiltinType *getAsBuiltinType() const;
- const FunctionType *getAsFunctionType() const;
- const FunctionTypeProto *getAsFunctionTypeProto() const;
- const PointerLikeType *getAsPointerLikeType() const; // Pointer or Reference.
- const PointerType *getAsPointerType() const;
- const BlockPointerType *getAsBlockPointerType() const;
- const ReferenceType *getAsReferenceType() const;
- const RecordType *getAsRecordType() const;
- const RecordType *getAsStructureType() const;
- /// NOTE: getAsArrayType* are methods on ASTContext.
- const TypedefType *getAsTypedefType() const;
- const RecordType *getAsUnionType() const;
- const EnumType *getAsEnumType() const;
- const VectorType *getAsVectorType() const; // GCC vector type.
- const ComplexType *getAsComplexType() const;
- const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
- const ExtVectorType *getAsExtVectorType() const; // Extended vector type.
- const ObjCInterfaceType *getAsObjCInterfaceType() const;
- const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const;
- const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
-
- /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
- /// interface, return the interface type, otherwise return null.
- const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
-
- /// getArrayElementTypeNoTypeQual - If this is an array type, return the
- /// element type of the array, potentially with type qualifiers missing.
- /// This method should never be used when type qualifiers are meaningful.
- const Type *getArrayElementTypeNoTypeQual() const;
-
-
-
- /// 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
- /// to getting the canonical type, but it doesn't remove *all* typedefs. For
- /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
- /// concrete.
- QualType getDesugaredType() const;
-
- /// More type predicates useful for type checking/promotion
- bool isPromotableIntegerType() const; // C99 6.3.1.1p2
-
- /// isSignedIntegerType - Return true if this is an integer type that is
- /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
- /// an enum decl which has a signed representation, or a vector of signed
- /// integer element type.
- bool isSignedIntegerType() const;
-
- /// isUnsignedIntegerType - Return true if this is an integer type that is
- /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
- /// decl which has an unsigned representation, or a vector of unsigned integer
- /// element type.
- bool isUnsignedIntegerType() const;
-
- /// isConstantSizeType - Return true if this is not a variable sized type,
- /// according to the rules of C99 6.7.5p3. It is not legal to call this on
- /// incomplete types.
- bool isConstantSizeType() const;
-
- QualType getCanonicalTypeInternal() const { return CanonicalType; }
- void dump() const;
- virtual void getAsStringInternal(std::string &InnerString) const = 0;
- static bool classof(const Type *) { return true; }
-
-protected:
- /// Emit - Emit a Type to bitcode. Used by ASTContext.
- void Emit(llvm::Serializer& S) const;
-
- /// Create - Construct a Type from bitcode. Used by ASTContext.
- static void Create(ASTContext& Context, unsigned i, llvm::Deserializer& S);
-
- /// EmitImpl - Subclasses must implement this method in order to
- /// be serialized.
- virtual void EmitImpl(llvm::Serializer& S) const;
-};
-
-/// ASQualType - TR18037 (C embedded extensions) 6.2.5p26
-/// This supports address space qualified types.
-///
-class ASQualType : public Type, public llvm::FoldingSetNode {
- /// BaseType - This is the underlying type that this qualifies. All CVR
- /// qualifiers are stored on the QualType that references this type, so we
- /// can't have any here.
- Type *BaseType;
- /// Address Space ID - The address space ID this type is qualified with.
- unsigned AddressSpace;
- ASQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace) :
- Type(ASQual, CanonicalPtr), BaseType(Base), AddressSpace(AddrSpace) {
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- Type *getBaseType() const { return BaseType; }
- unsigned getAddressSpace() const { return AddressSpace; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getBaseType(), AddressSpace);
- }
- static void Profile(llvm::FoldingSetNodeID &ID, Type *Base,
- unsigned AddrSpace) {
- ID.AddPointer(Base);
- ID.AddInteger(AddrSpace);
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == ASQual; }
- static bool classof(const ASQualType *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-
-/// BuiltinType - This class is used for builtin types like 'int'. Builtin
-/// types are always canonical and have a literal name field.
-class BuiltinType : public Type {
-public:
- enum Kind {
- Void,
-
- Bool, // This is bool and/or _Bool.
- Char_U, // This is 'char' for targets where char is unsigned.
- UChar, // This is explicitly qualified unsigned char.
- UShort,
- UInt,
- ULong,
- ULongLong,
-
- Char_S, // This is 'char' for targets where char is signed.
- SChar, // This is explicitly qualified signed char.
- WChar, // This is 'wchar_t' for C++.
- Short,
- Int,
- Long,
- LongLong,
-
- Float, Double, LongDouble
- };
-private:
- Kind TypeKind;
-public:
- BuiltinType(Kind K) : Type(Builtin, QualType()), TypeKind(K) {}
-
- Kind getKind() const { return TypeKind; }
- const char *getName() const;
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
- static bool classof(const BuiltinType *) { return true; }
-};
-
-/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex
-/// types (_Complex float etc) as well as the GCC integer complex extensions.
-///
-class ComplexType : public Type, public llvm::FoldingSetNode {
- QualType ElementType;
- ComplexType(QualType Element, QualType CanonicalPtr) :
- Type(Complex, CanonicalPtr), ElementType(Element) {
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- QualType getElementType() const { return ElementType; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
- ID.AddPointer(Element.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
- static bool classof(const ComplexType *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// PointerLikeType - Common base class for pointers and references.
-/// FIXME: Add more documentation on this classes design point. For example,
-/// should BlockPointerType inherit from it? Is the concept of a PointerLikeType
-/// in the C++ standard?
-///
-class PointerLikeType : public Type {
- QualType PointeeType;
-protected:
- PointerLikeType(TypeClass K, QualType Pointee, QualType CanonicalPtr) :
- Type(K, CanonicalPtr), PointeeType(Pointee) {
- }
-public:
-
- QualType getPointeeType() const { return PointeeType; }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Pointer || T->getTypeClass() == Reference;
- }
- static bool classof(const PointerLikeType *) { return true; }
-};
-
-/// PointerType - C99 6.7.5.1 - Pointer Declarators.
-///
-class PointerType : public PointerLikeType, public llvm::FoldingSetNode {
- PointerType(QualType Pointee, QualType CanonicalPtr) :
- PointerLikeType(Pointer, Pointee, CanonicalPtr) {
- }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
- static bool classof(const PointerType *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// BlockPointerType - pointer to a block type.
-/// This type is to represent types syntactically represented as
-/// "void (^)(int)", etc. Pointee is required to always be a function type.
-/// FIXME: Should BlockPointerType inherit from PointerLikeType? It could
-/// simplfy some type checking code, however PointerLikeType doesn't appear
-/// to be used by the type checker.
-///
-class BlockPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType; // Block is some kind of pointer type
- BlockPointerType(QualType Pointee, QualType CanonicalCls) :
- Type(BlockPointer, CanonicalCls), PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
-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;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == BlockPointer;
- }
- static bool classof(const BlockPointerType *) { return true; }
-
- protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// ReferenceType - C++ 8.3.2 - Reference Declarators.
-///
-class ReferenceType : public PointerLikeType, public llvm::FoldingSetNode {
- ReferenceType(QualType Referencee, QualType CanonicalRef) :
- PointerLikeType(Reference, Referencee, CanonicalRef) {
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
- ID.AddPointer(Referencee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Reference; }
- static bool classof(const ReferenceType *) { return true; }
-};
-
-/// ArrayType - C99 6.7.5.2 - Array Declarators.
-///
-class ArrayType : public Type, public llvm::FoldingSetNode {
-public:
- /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
- /// an array with a static size (e.g. int X[static 4]), or with a star size
- /// (e.g. int X[*]). 'static' is only allowed on function parameters.
- enum ArraySizeModifier {
- Normal, Static, Star
- };
-private:
- /// ElementType - The element type of the array.
- QualType ElementType;
-
- // NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
- /// NOTE: These fields are packed into the bitfields space in the Type class.
- unsigned SizeModifier : 2;
-
- /// IndexTypeQuals - Capture qualifiers in declarations like:
- /// 'int X[static restrict 4]'. For function parameters only.
- unsigned IndexTypeQuals : 3;
-
-protected:
- ArrayType(TypeClass tc, QualType et, QualType can,
- ArraySizeModifier sm, unsigned tq)
- : Type(tc, can), ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- QualType getElementType() const { return ElementType; }
- ArraySizeModifier getSizeModifier() const {
- return ArraySizeModifier(SizeModifier);
- }
- unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == VariableArray ||
- T->getTypeClass() == IncompleteArray;
- }
- static bool classof(const ArrayType *) { return true; }
-};
-
-/// ConstantArrayType - This class represents C arrays with a specified constant
-/// size. For example 'int A[100]' has ConstantArrayType where the element type
-/// is 'int' and the size is 100.
-class ConstantArrayType : public ArrayType {
- llvm::APInt Size; // Allows us to unique the type.
-
- ConstantArrayType(QualType et, QualType can, llvm::APInt sz,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(ConstantArray, et, can, sm, tq), Size(sz) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- const llvm::APInt &getSize() const { return Size; }
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getSize());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
- llvm::APInt ArraySize) {
- ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(ArraySize.getZExtValue());
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray;
- }
- static bool classof(const ConstantArrayType *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
- friend class Type;
-};
-
-/// IncompleteArrayType - This class represents C arrays with an unspecified
-/// size. For example 'int A[]' has an IncompleteArrayType where the element
-/// type is 'int' and the size is unspecified.
-class IncompleteArrayType : public ArrayType {
- IncompleteArrayType(QualType et, QualType can,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(IncompleteArray, et, can, sm, tq) {}
- friend class ASTContext; // ASTContext creates these.
-public:
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == IncompleteArray;
- }
- static bool classof(const IncompleteArrayType *) { return true; }
-
- friend class StmtIteratorBase;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ET) {
- ID.AddPointer(ET.getAsOpaquePtr());
- }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// VariableArrayType - This class represents C arrays with a specified size
-/// which is not an integer-constant-expression. For example, 'int s[x+foo()]'.
-/// Since the size expression is an arbitrary expression, we store it as such.
-///
-/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
-/// should not be: two lexically equivalent variable array types could mean
-/// different things, for example, these variables do not have the same type
-/// dynamically:
-///
-/// void foo(int x) {
-/// int Y[x];
-/// ++x;
-/// int Z[x];
-/// }
-///
-class VariableArrayType : public ArrayType {
- /// SizeExpr - An assignment expression. VLA's are only permitted within
- /// a function block.
- Stmt *SizeExpr;
-
- VariableArrayType(QualType et, QualType can, Expr *e,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(VariableArray, et, can, sm, tq), SizeExpr((Stmt*) e) {}
- friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
-
-public:
- Expr *getSizeExpr() const {
- // We use C-style casts instead of cast<> here because we do not wish
- // to have a dependency of Type.h on Stmt.h/Expr.h.
- return (Expr*) SizeExpr;
- }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == VariableArray;
- }
- static bool classof(const VariableArrayType *) { return true; }
-
- friend class StmtIteratorBase;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert (0 && "Cannnot unique VariableArrayTypes.");
- }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// VectorType - GCC generic vector type. This type is created using
-/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes. Since the constructor takes the number of vector elements, the
-/// client is responsible for converting the size into the number of elements.
-class VectorType : public Type, public llvm::FoldingSetNode {
-protected:
- /// ElementType - The element type of the vector.
- QualType ElementType;
-
- /// NumElements - The number of elements in the vector.
- unsigned NumElements;
-
- VectorType(QualType vecType, unsigned nElements, QualType canonType) :
- Type(Vector, canonType), ElementType(vecType), NumElements(nElements) {}
- VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType) : Type(tc, canonType), ElementType(vecType),
- NumElements(nElements) {}
- friend class ASTContext; // ASTContext creates these.
-public:
-
- QualType getElementType() const { return ElementType; }
- unsigned getNumElements() const { return NumElements; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(), getTypeClass());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
- unsigned NumElements, TypeClass TypeClass) {
- ID.AddPointer(ElementType.getAsOpaquePtr());
- ID.AddInteger(NumElements);
- ID.AddInteger(TypeClass);
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
- }
- static bool classof(const VectorType *) { return true; }
-};
-
-/// ExtVectorType - Extended vector type. This type is created using
-/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
-/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
-/// class enables syntactic extensions, like Vector Components for accessing
-/// points, colors, and textures (modeled after OpenGL Shading Language).
-class ExtVectorType : public VectorType {
- ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- static int getPointAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case 'x': return 0;
- case 'y': return 1;
- case 'z': return 2;
- case 'w': return 3;
- }
- }
- static int getColorAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case 'r': return 0;
- case 'g': return 1;
- case 'b': return 2;
- case 'a': return 3;
- }
- }
- static int getTextureAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case 's': return 0;
- case 't': return 1;
- case 'p': return 2;
- case 'q': return 3;
- }
- };
-
- static int getAccessorIdx(char c) {
- if (int idx = getPointAccessorIdx(c)+1) return idx-1;
- if (int idx = getColorAccessorIdx(c)+1) return idx-1;
- return getTextureAccessorIdx(c);
- }
-
- bool isAccessorWithinNumElements(char c) const {
- if (int idx = getAccessorIdx(c)+1)
- return unsigned(idx-1) < NumElements;
- return false;
- }
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ExtVector;
- }
- static bool classof(const ExtVectorType *) { return true; }
-};
-
-/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
-/// class of FunctionTypeNoProto and FunctionTypeProto.
-///
-class FunctionType : public Type {
- /// SubClassData - This field is owned by the subclass, put here to pack
- /// tightly with the ivars in Type.
- bool SubClassData : 1;
-
- // The type returned by the function.
- QualType ResultType;
-protected:
- FunctionType(TypeClass tc, QualType res, bool SubclassInfo,QualType Canonical)
- : Type(tc, Canonical), SubClassData(SubclassInfo), ResultType(res) {}
- bool getSubClassData() const { return SubClassData; }
-public:
-
- QualType getResultType() const { return ResultType; }
-
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionNoProto ||
- T->getTypeClass() == FunctionProto;
- }
- static bool classof(const FunctionType *) { return true; }
-};
-
-/// FunctionTypeNoProto - Represents a K&R-style 'int foo()' function, which has
-/// no information available about its arguments.
-class FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode {
- FunctionTypeNoProto(QualType Result, QualType Canonical)
- : FunctionType(FunctionNoProto, Result, false, Canonical) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- // No additional state past what FunctionType provides.
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getResultType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType) {
- ID.AddPointer(ResultType.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionNoProto;
- }
- static bool classof(const FunctionTypeNoProto *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// FunctionTypeProto - Represents a prototype with argument type info, e.g.
-/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
-/// arguments, not as having a single void argument.
-class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
- FunctionTypeProto(QualType Result, const QualType *ArgArray, unsigned numArgs,
- bool isVariadic, QualType Canonical)
- : FunctionType(FunctionProto, Result, isVariadic, Canonical),
- NumArgs(numArgs) {
- // Fill in the trailing argument array.
- QualType *ArgInfo = reinterpret_cast<QualType *>(this+1);;
- for (unsigned i = 0; i != numArgs; ++i)
- ArgInfo[i] = ArgArray[i];
- }
-
- /// NumArgs - The number of arguments this function has, not counting '...'.
- unsigned NumArgs;
-
- /// ArgInfo - There is an variable size array after the class in memory that
- /// holds the argument types.
-
- friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
-
-public:
- unsigned getNumArgs() const { return NumArgs; }
- QualType getArgType(unsigned i) const {
- assert(i < NumArgs && "Invalid argument number!");
- return arg_type_begin()[i];
- }
-
- bool isVariadic() const { return getSubClassData(); }
-
- typedef const QualType *arg_type_iterator;
- arg_type_iterator arg_type_begin() const {
- return reinterpret_cast<const QualType *>(this+1);
- }
- arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionProto;
- }
- static bool classof(const FunctionTypeProto *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
- arg_type_iterator ArgTys, unsigned NumArgs,
- bool isVariadic);
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-
-class TypedefType : public Type {
- TypedefDecl *Decl;
-protected:
- TypedefType(TypeClass tc, TypedefDecl *D, QualType can)
- : Type(tc, can), Decl(D) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- TypedefDecl *getDecl() const { return Decl; }
-
- /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
- /// potentially looking through *all* consequtive typedefs. This returns the
- /// sum of the type qualifiers, so if you have:
- /// typedef const int A;
- /// typedef volatile A B;
- /// looking through the typedefs for B will give you "const volatile A".
- QualType LookThroughTypedefs() const;
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == TypeName; }
- static bool classof(const TypedefType *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D);
- friend class Type;
-};
-
-/// TypeOfExpr (GCC extension).
-class TypeOfExpr : public Type {
- Expr *TOExpr;
- TypeOfExpr(Expr *E, QualType can) : Type(TypeOfExp, can), TOExpr(E) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- Expr *getUnderlyingExpr() const { return TOExpr; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExp; }
- static bool classof(const TypeOfExpr *) { return true; }
-};
-
-/// TypeOfType (GCC extension).
-class TypeOfType : public Type {
- QualType TOType;
- TypeOfType(QualType T, QualType can) : Type(TypeOfTyp, can), TOType(T) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- QualType getUnderlyingType() const { return TOType; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOfTyp; }
- static bool classof(const TypeOfType *) { return true; }
-};
-
-class TagType : public Type {
- TagDecl *decl;
- friend class ASTContext;
-
-protected:
- TagType(TagDecl *D, QualType can) : Type(Tagged, can), decl(D) {}
-
-public:
- TagDecl *getDecl() const { return decl; }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == Tagged; }
- static bool classof(const TagType *) { return true; }
-
-protected:
- virtual void EmitImpl(llvm::Serializer& S) const;
- static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
- friend class Type;
-};
-
-/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
-/// to detect TagType objects of structs/unions/classes.
-class RecordType : public TagType {
-protected:
- explicit RecordType(RecordDecl *D) : TagType(cast<TagDecl>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- RecordDecl *getDecl() const {
- return reinterpret_cast<RecordDecl*>(TagType::getDecl());
- }
-
- // FIXME: This predicate is a helper to QualType/Type. It needs to
- // recursively check all fields for const-ness. If any field is declared
- // const, it needs to return false.
- bool hasConstFields() const { return false; }
-
- // FIXME: RecordType needs to check when it is created that all fields are in
- // the same address space, and return that.
- unsigned getAddressSpace() const { return 0; }
-
- static bool classof(const TagType *T);
- static bool classof(const Type *T) {
- return isa<TagType>(T) && classof(cast<TagType>(T));
- }
- static bool classof(const RecordType *) { return true; }
-};
-
-/// CXXRecordType - This is a helper class that allows the use of
-/// isa/cast/dyncast to detect TagType objects of C++ structs/unions/classes.
-class CXXRecordType : public RecordType {
- explicit CXXRecordType(CXXRecordDecl *D)
- : RecordType(reinterpret_cast<RecordDecl*>(D)) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- CXXRecordDecl *getDecl() const {
- return reinterpret_cast<CXXRecordDecl*>(RecordType::getDecl());
- }
-
- static bool classof(const TagType *T);
- static bool classof(const Type *T) {
- return isa<TagType>(T) && classof(cast<TagType>(T));
- }
- static bool classof(const CXXRecordType *) { return true; }
-};
-
-/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
-/// to detect TagType objects of enums.
-class EnumType : public TagType {
- explicit EnumType(EnumDecl *D) : TagType(cast<TagDecl>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- EnumDecl *getDecl() const {
- return reinterpret_cast<EnumDecl*>(TagType::getDecl());
- }
-
- static bool classof(const TagType *T);
- static bool classof(const Type *T) {
- return isa<TagType>(T) && classof(cast<TagType>(T));
- }
- static bool classof(const EnumType *) { return true; }
-};
-
-
-
-/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
-/// object oriented design. They basically correspond to C++ classes. There
-/// are two kinds of interface types, normal interfaces like "NSString" and
-/// qualified interfaces, which are qualified with a protocol list like
-/// "NSString<NSCopyable, NSAmazing>". Qualified interface types are instances
-/// of ObjCQualifiedInterfaceType, which is a subclass of ObjCInterfaceType.
-class ObjCInterfaceType : public Type {
- ObjCInterfaceDecl *Decl;
-protected:
- ObjCInterfaceType(TypeClass tc, ObjCInterfaceDecl *D) :
- Type(tc, QualType()), Decl(D) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- ObjCInterfaceDecl *getDecl() const { return Decl; }
-
- /// qual_iterator and friends: this provides access to the (potentially empty)
- /// list of protocols qualifying this interface. If this is an instance of
- /// ObjCQualifiedInterfaceType it returns the list, otherwise it returns an
- /// empty list if there are no qualifying protocols.
- typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
- inline qual_iterator qual_begin() const;
- inline qual_iterator qual_end() const;
- bool qual_empty() const { return getTypeClass() != ObjCQualifiedInterface; }
-
- /// getNumProtocols - Return the number of qualifying protocols in this
- /// interface type, or 0 if there are none.
- inline unsigned getNumProtocols() const;
-
- /// getProtocol - Return the specified qualifying protocol.
- inline ObjCProtocolDecl *getProtocol(unsigned i) const;
-
-
- virtual void getAsStringInternal(std::string &InnerString) const;
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCInterface ||
- T->getTypeClass() == ObjCQualifiedInterface;
- }
- static bool classof(const ObjCInterfaceType *) { return true; }
-};
-
-/// ObjCQualifiedInterfaceType - This class represents interface types
-/// conforming to a list of protocols, such as INTF<Proto1, Proto2, Proto1>.
-///
-/// Duplicate protocols are removed and protocol list is canonicalized to be in
-/// alphabetical order.
-class ObjCQualifiedInterfaceType : public ObjCInterfaceType,
- public llvm::FoldingSetNode {
-
- // List of protocols for this protocol conforming object type
- // List is sorted on protocol name. No protocol is enterred more than once.
- llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
-
- ObjCQualifiedInterfaceType(ObjCInterfaceDecl *D,
- ObjCProtocolDecl **Protos, unsigned NumP) :
- ObjCInterfaceType(ObjCQualifiedInterface, D),
- Protocols(Protos, Protos+NumP) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- ObjCProtocolDecl *getProtocol(unsigned i) const {
- return Protocols[i];
- }
- unsigned getNumProtocols() const {
- return Protocols.size();
- }
-
- qual_iterator qual_begin() const { return Protocols.begin(); }
- qual_iterator qual_end() const { return Protocols.end(); }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCQualifiedInterface;
- }
- static bool classof(const ObjCQualifiedInterfaceType *) { return true; }
-};
-
-inline ObjCInterfaceType::qual_iterator ObjCInterfaceType::qual_begin() const {
- if (const ObjCQualifiedInterfaceType *QIT =
- dyn_cast<ObjCQualifiedInterfaceType>(this))
- return QIT->qual_begin();
- return 0;
-}
-inline ObjCInterfaceType::qual_iterator ObjCInterfaceType::qual_end() const {
- if (const ObjCQualifiedInterfaceType *QIT =
- dyn_cast<ObjCQualifiedInterfaceType>(this))
- return QIT->qual_end();
- return 0;
-}
-
-/// getNumProtocols - Return the number of qualifying protocols in this
-/// interface type, or 0 if there are none.
-inline unsigned ObjCInterfaceType::getNumProtocols() const {
- if (const ObjCQualifiedInterfaceType *QIT =
- dyn_cast<ObjCQualifiedInterfaceType>(this))
- return QIT->getNumProtocols();
- return 0;
-}
-
-/// getProtocol - Return the specified qualifying protocol.
-inline ObjCProtocolDecl *ObjCInterfaceType::getProtocol(unsigned i) const {
- return cast<ObjCQualifiedInterfaceType>(this)->getProtocol(i);
-}
-
-
-
-/// ObjCQualifiedIdType - to represent id<protocol-list>.
-///
-/// Duplicate protocols are removed and protocol list is canonicalized to be in
-/// alphabetical order.
-class ObjCQualifiedIdType : public Type,
- public llvm::FoldingSetNode {
- // List of protocols for this protocol conforming 'id' type
- // List is sorted on protocol name. No protocol is enterred more than once.
- llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
-
- ObjCQualifiedIdType(ObjCProtocolDecl **Protos, unsigned NumP)
- : Type(ObjCQualifiedId, QualType()/*these are always canonical*/),
- Protocols(Protos, Protos+NumP) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- ObjCProtocolDecl *getProtocols(unsigned i) const {
- return Protocols[i];
- }
- unsigned getNumProtocols() const {
- return Protocols.size();
- }
- ObjCProtocolDecl **getReferencedProtocols() {
- return &Protocols[0];
- }
-
- typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator;
- qual_iterator qual_begin() const { return Protocols.begin(); }
- qual_iterator qual_end() const { return Protocols.end(); }
-
- virtual void getAsStringInternal(std::string &InnerString) const;
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCQualifiedId;
- }
- static bool classof(const ObjCQualifiedIdType *) { return true; }
-
-};
-
-
-// Inline function definitions.
-
-/// getUnqualifiedType - Return the type without any qualifiers.
-inline QualType QualType::getUnqualifiedType() const {
- Type *TP = getTypePtr();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(TP))
- TP = ASQT->getBaseType();
- return QualType(TP, 0);
-}
-
-/// getAddressSpace - Return the address space of this type.
-inline unsigned QualType::getAddressSpace() const {
- QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
- return AT->getElementType().getAddressSpace();
- if (const RecordType *RT = dyn_cast<RecordType>(CT))
- return RT->getAddressSpace();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CT))
- return ASQT->getAddressSpace();
- return 0;
-}
-
-inline const TypedefType* Type::getAsTypedefType() const {
- return dyn_cast<TypedefType>(this);
-}
-inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
- if (const PointerType *PT = getAsPointerType())
- return PT->getPointeeType()->getAsObjCInterfaceType();
- 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());
-}
-inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isBlockPointerType() const {
- return isa<BlockPointerType>(CanonicalType);
-}
-inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isPointerLikeType() const {
- return isa<PointerLikeType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isFunctionPointerType() const {
- if (const PointerType* T = getAsPointerType())
- return T->getPointeeType()->isFunctionType();
- else
- return false;
-}
-inline bool Type::isArrayType() const {
- return isa<ArrayType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isConstantArrayType() const {
- return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isVariableArrayType() const {
- return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isRecordType() const {
- return isa<RecordType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isVectorType() const {
- return isa<VectorType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isExtVectorType() const {
- return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isObjCInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isObjCQualifiedInterfaceType() const {
- return isa<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isObjCQualifiedIdType() const {
- return isa<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
-}
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/AST/X86Builtins.def b/clang/include/clang/AST/X86Builtins.def
deleted file mode 100644
index 057ff91f12c3..000000000000
--- a/clang/include/clang/AST/X86Builtins.def
+++ /dev/null
@@ -1,465 +0,0 @@
-//===--- X86Builtins.def - X86 Builtin function database --------*- 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 X86-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
-// adding stuff on demand.
-
-// The format of this database matches clang/AST/Builtins.def.
-
-// FIXME: In GCC, these builtins are defined depending on whether support for
-// MMX/SSE/etc is turned on. We should do this too.
-
-// FIXME: Ideally we would be able to pull this information from what
-// LLVM already knows about X86 builtins. We need to match the LLVM
-// definition anyway, since code generation will lower to the
-// intrinsic if one exists.
-
-BUILTIN(__builtin_ia32_emms , "v", "")
-
-// FIXME: Are these nothrow/const?
-
-// SSE intrinsics.
-BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_comile, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_comige, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "")
-BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "")
-BUILTIN(__builtin_ia32_addps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_subps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_mulps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_divps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_addss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_subss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_mulss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_divss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpeqps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpltps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpleps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpgtps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpgeps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpunordps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpneqps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnltps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnleps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngtps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngeps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpordps, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpeqss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpltss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpless, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpunordss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpneqss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnltss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnless, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngtss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngess, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpordss, "V4iV4fV4f", "")
-BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_andps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_andnps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_orps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_xorps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_movss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_movhlps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_movlhps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_unpckhps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_unpcklps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_addpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_subpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_mulpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_divpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_addsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_subsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_mulsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_divsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpeqpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpltpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmplepd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpgtpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpgepd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpunordpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpneqpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnltpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnlepd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpngtpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpngepd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpordpd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpeqsd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpltsd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmplesd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpunordsd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpneqsd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnltsd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnlesd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpordsd, "V4iV2dV2d", "")
-BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_andpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_andnpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_orpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_xorpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_movsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_unpckhpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_unpcklpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_paddb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_paddw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_paddd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_paddq128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_psubb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_psubw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_psubd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_psubq128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pmullw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pand128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_pandn128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_por128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_pxor128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pcmpeqb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pcmpeqw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pcmpeqd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_pcmpgtb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pcmpgtw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pcmpgtd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_punpckhbw128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_punpckhwd128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_punpckhdq128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_punpckhqdq128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_punpcklbw128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_punpcklwd128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_punpckldq128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_punpcklqdq128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_packsswb128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_packssdw128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_packuswb128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pmaddubsw128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "")
-BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "")
-BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "")
-BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "")
-BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "")
-BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "")
-BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "")
-BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "")
-BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "")
-BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "")
-BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "")
-BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "")
-BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "")
-BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "")
-BUILTIN(__builtin_ia32_pshufw, "V4sV4si", "")
-BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "")
-BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "")
-BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "")
-BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "")
-BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "")
-BUILTIN(__builtin_ia32_stmxcsr, "Ui", "")
-BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "")
-BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
-BUILTIN(__builtin_ia32_cvtsi2ss, "V4fV4fi", "")
-BUILTIN(__builtin_ia32_cvtsi642ss, "V4fV4fLLi", "")
-BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "")
-BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "")
-BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
-BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "")
-BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "")
-BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "")
-BUILTIN(__builtin_ia32_loadups, "V4ffC*", "")
-BUILTIN(__builtin_ia32_storeups, "vf*V4f", "")
-BUILTIN(__builtin_ia32_loadhps, "V4fV4fV2i*", "")
-BUILTIN(__builtin_ia32_loadlps, "V4fV4fV2i*", "")
-BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "")
-BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "")
-BUILTIN(__builtin_ia32_movmskps, "iV4f", "")
-BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "")
-BUILTIN(__builtin_ia32_movntps, "vf*V4f", "")
-// FIXME: the prototype for __builtin_ia32_movntq changed across different
-// versions of GCC. Until we can replace GCC's xmmintrin.h, this is hacked to
-// be a vararg builtin instead of taking V1LLi like it should. This loses some
-// type checking but makes us compatible with old version of GCC's xmmintrin.h
-// file.
-BUILTIN(__builtin_ia32_movntq, "vV1LLi*.", "")
-BUILTIN(__builtin_ia32_sfence, "v", "")
-BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "")
-BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "")
-BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "")
-BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "")
-BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "")
-BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "")
-BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "")
-BUILTIN(__builtin_ia32_shufps, "V4fV4fV4fi", "")
-BUILTIN(__builtin_ia32_femms, "v", "")
-BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "")
-BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "")
-BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "")
-BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "")
-BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "")
-BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "")
-BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "")
-BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "")
-BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "")
-BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "")
-BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "")
-BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "")
-BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "")
-BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "")
-BUILTIN(__builtin_ia32_loadupd, "V2ddC*", "")
-BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "")
-BUILTIN(__builtin_ia32_loadhpd, "V2dV2ddC*", "")
-BUILTIN(__builtin_ia32_loadlpd, "V2dV2ddC*", "")
-BUILTIN(__builtin_ia32_movmskpd, "iV2d", "")
-BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "")
-BUILTIN(__builtin_ia32_movnti, "vi*i", "")
-BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "")
-BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "")
-BUILTIN(__builtin_ia32_pshufd, "V4iV4ii", "")
-BUILTIN(__builtin_ia32_pshuflw, "V8sV8si", "")
-BUILTIN(__builtin_ia32_pshufhw, "V8sV8si", "")
-BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "")
-BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "")
-BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "")
-BUILTIN(__builtin_ia32_shufpd, "V2dV2dV2di", "")
-BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "")
-BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "")
-BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "")
-BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "")
-BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "")
-BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "")
-BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "")
-BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "")
-BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "")
-BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "")
-BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "")
-BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "")
-BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "")
-BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "")
-BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "")
-BUILTIN(__builtin_ia32_cvtsi2sd, "V2dV2di", "")
-BUILTIN(__builtin_ia32_cvtsi642sd, "V2dV2dLLi", "")
-BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "")
-BUILTIN(__builtin_ia32_cvtss2sd, "V2dV2dV4f", "")
-BUILTIN(__builtin_ia32_clflush, "vvC*", "")
-BUILTIN(__builtin_ia32_lfence, "v", "")
-BUILTIN(__builtin_ia32_mfence, "v", "")
-BUILTIN(__builtin_ia32_loaddqu, "V16ccC*", "")
-BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "")
-BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "")
-BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "")
-BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "")
-BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "")
-BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "")
-BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "")
-BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "")
-BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "")
-BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "")
-BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "")
-BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "")
-BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "")
-BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "")
-BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "")
-BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "")
-BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "")
-BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "")
-BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "")
-BUILTIN(__builtin_ia32_pmaddwd128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
-BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
-BUILTIN(__builtin_ia32_movshdup, "V4fV4f", "")
-BUILTIN(__builtin_ia32_movsldup, "V4fV4f", "")
-BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
-BUILTIN(__builtin_ia32_palignr128, "V2LLiV2LLiV2LLii", "")
-BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLiV1LLis", "")
-BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "")
-BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "")
-BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "")
-BUILTIN(__builtin_ia32_vec_ext_v2df, "dV2di", "")
-BUILTIN(__builtin_ia32_vec_ext_v2di, "LLiV2LLii", "")
-BUILTIN(__builtin_ia32_vec_ext_v4sf, "fV4fi", "")
-BUILTIN(__builtin_ia32_vec_ext_v4si, "iV4ii", "")
-BUILTIN(__builtin_ia32_vec_ext_v8hi, "UsV8si", "")
-BUILTIN(__builtin_ia32_vec_ext_v4hi, "sV4si", "")
-BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "")
-BUILTIN(__builtin_ia32_vec_set_v8hi, "V8sV8ssi", "")
-BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssi", "")
-
-BUILTIN(__builtin_ia32_movqv4si, "V4iV4i", "")
-BUILTIN(__builtin_ia32_loadlv4si, "V4iV2i*", "")
-BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
-
-BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8si", "")
-BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2di", "")
-BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fi", "")
-BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "")
-BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "")
-BUILTIN(__builtin_ia32_pmovsxbd128, "V4iV16c", "")
-BUILTIN(__builtin_ia32_pmovsxbq128, "V2LLiV16c", "")
-BUILTIN(__builtin_ia32_pmovsxbw128, "V8sV16c", "")
-BUILTIN(__builtin_ia32_pmovsxdq128, "V2LLiV4i", "")
-BUILTIN(__builtin_ia32_pmovsxwd128, "V4iV8s", "")
-BUILTIN(__builtin_ia32_pmovsxwq128, "V2LLiV8s", "")
-BUILTIN(__builtin_ia32_pmovzxbd128, "V4iV16c", "")
-BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "")
-BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "")
-BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "")
-BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "")
-BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "")
-BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "")
-BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "")
-BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
-BUILTIN(__builtin_ia32_roundss, "V4fV4fi", "")
-BUILTIN(__builtin_ia32_roundsd, "V2dV2di", "")
-BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")
-
-
-#undef BUILTIN
diff --git a/clang/include/clang/Analysis/Analyses/LiveVariables.h b/clang/include/clang/Analysis/Analyses/LiveVariables.h
deleted file mode 100644
index 6571c73ab723..000000000000
--- a/clang/include/clang/Analysis/Analyses/LiveVariables.h
+++ /dev/null
@@ -1,119 +0,0 @@
-//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Live Variables analysis for source-level CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIVEVARIABLES_H
-#define LLVM_CLANG_LIVEVARIABLES_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Analysis/Support/ExprDeclBitVector.h"
-#include "clang/Analysis/FlowSensitive/DataflowValues.h"
-
-namespace clang {
-
-class Stmt;
-class DeclRefExpr;
-class SourceManager;
-
-struct LiveVariables_ValueTypes {
-
- struct ObserverTy;
-
- // We keep dataflow state for declarations and block-level expressions;
- typedef ExprDeclBitVector_Types::ValTy ValTy;
-
- // We need to keep track of both declarations and CFGBlock-level expressions,
- // (so that we don't explore such expressions twice). We also want
- // to compute liveness information for block-level expressions, since these
- // act as "temporary" values.
-
- struct AnalysisDataTy : public ExprDeclBitVector_Types::AnalysisDataTy {
- ObserverTy* Observer;
- ValTy AlwaysLive;
-
- AnalysisDataTy() : Observer(NULL) {}
- };
-
- //===-----------------------------------------------------===//
- // ObserverTy - Observer for uninitialized values queries.
- //===-----------------------------------------------------===//
-
- struct ObserverTy {
- virtual ~ObserverTy() {}
-
- /// ObserveStmt - A callback invoked right before invoking the
- /// liveness transfer function on the given statement.
- virtual void ObserveStmt(Stmt* S, const AnalysisDataTy& AD,
- const ValTy& V) {}
-
- virtual void ObserverKill(DeclRefExpr* DR) {}
- };
-};
-
-class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
- dataflow::backward_analysis_tag> {
-
-
-public:
- typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
-
- LiveVariables(CFG& cfg);
-
- /// IsLive - Return true if a variable is live at beginning of a
- /// specified block.
- bool isLive(const CFGBlock* B, const VarDecl* D) const;
-
- /// IsLive - Returns true if a variable is live at the beginning of the
- /// the statement. This query only works if liveness information
- /// has been recorded at the statement level (see runOnAllBlocks), and
- /// only returns liveness information for block-level expressions.
- bool isLive(const Stmt* S, const VarDecl* D) const;
-
- /// IsLive - Returns true the block-level expression "value" is live
- /// before the given block-level expression (see runOnAllBlocks).
- bool isLive(const Stmt* Loc, const Stmt* StmtVal) const;
-
- /// IsLive - Return true if a variable is live according to the
- /// provided livness bitvector.
- bool isLive(const ValTy& V, const VarDecl* D) const;
-
- /// dumpLiveness - Print to stderr the liveness information encoded
- /// by a specified bitvector.
- void dumpLiveness(const ValTy& V, SourceManager& M) const;
-
- /// dumpBlockLiveness - Print to stderr the liveness information
- /// associated with each basic block.
- void dumpBlockLiveness(SourceManager& M) const;
-
- /// getNumDecls - Return the number of variables (declarations) that
- /// whose liveness status is being tracked by the dataflow
- /// analysis.
- unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); }
-
- /// IntializeValues - This routine can perform extra initialization, but
- /// for LiveVariables this does nothing since all that logic is in
- /// the constructor.
- void InitializeValues(const CFG& cfg) {}
-
- void runOnCFG(CFG& cfg);
-
- /// runOnAllBlocks - Propagate the dataflow values once for each block,
- /// starting from the current dataflow values. 'recordStmtValues' indicates
- /// whether the method should store dataflow values per each individual
- /// block-level expression.
- void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs,
- bool recordStmtValues=false);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/Analyses/UninitializedValues.h b/clang/include/clang/Analysis/Analyses/UninitializedValues.h
deleted file mode 100644
index ea7bd1477943..000000000000
--- a/clang/include/clang/Analysis/Analyses/UninitializedValues.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===- UninitializedValues.h - unintialized values analysis ----*- C++ --*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the interface for the Unintialized Values analysis,
-// a flow-sensitive analysis that detects when variable values are unintialized.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_UNITVALS_H
-#define LLVM_CLANG_UNITVALS_H
-
-#include "clang/Analysis/Support/ExprDeclBitVector.h"
-#include "clang/Analysis/FlowSensitive/DataflowValues.h"
-
-namespace clang {
-
- class BlockVarDecl;
- class Expr;
- class DeclRefExpr;
- class VarDecl;
-
-/// UninitializedValues_ValueTypes - Utility class to wrap type declarations
-/// for dataflow values and dataflow analysis state for the
-/// Unitialized Values analysis.
-class UninitializedValues_ValueTypes {
-public:
-
- struct ObserverTy;
-
- struct AnalysisDataTy : public ExprDeclBitVector_Types::AnalysisDataTy {
- AnalysisDataTy() : Observer(NULL), FullUninitTaint(true) {}
- virtual ~AnalysisDataTy() {};
-
- ObserverTy* Observer;
- bool FullUninitTaint;
- };
-
- typedef ExprDeclBitVector_Types::ValTy ValTy;
-
- //===--------------------------------------------------------------------===//
- // ObserverTy - Observer for querying DeclRefExprs that use an uninitalized
- // value.
- //===--------------------------------------------------------------------===//
-
- struct ObserverTy {
- virtual ~ObserverTy();
- virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
- DeclRefExpr* DR, VarDecl* VD) = 0;
- };
-};
-
-/// UninitializedValues - Objects of this class encapsulate dataflow analysis
-/// information regarding what variable declarations in a function are
-/// potentially unintialized.
-class UninitializedValues :
- public DataflowValues<UninitializedValues_ValueTypes> {
-public:
- typedef UninitializedValues_ValueTypes::ObserverTy ObserverTy;
-
- UninitializedValues(CFG &cfg) { getAnalysisData().setCFG(&cfg); }
-
- /// IntializeValues - Create initial dataflow values and meta data for
- /// a given CFG. This is intended to be called by the dataflow solver.
- void InitializeValues(const CFG& cfg);
-};
-
-} // end namespace clang
-#endif
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h
deleted file mode 100644
index 0ed4c8667f16..000000000000
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ /dev/null
@@ -1,311 +0,0 @@
-//===--- DataflowSolver.h - Skeleton Dataflow Analysis Code -----*- 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 skeleton code for implementing dataflow analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-
-#include "clang/AST/CFG.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "functional" // STL
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-/// DataflowWorkListTy - Data structure representing the worklist used for
-/// dataflow algorithms.
-//===----------------------------------------------------------------------===//
-
-class DataflowWorkListTy {
- typedef llvm::SmallPtrSet<const CFGBlock*,20> BlockSet;
- BlockSet wlist;
-public:
- /// enqueue - Add a block to the worklist. Blocks already on the
- /// worklist are not added a second time.
- void enqueue(const CFGBlock* B) { wlist.insert(B); }
-
- /// dequeue - Remove a block from the worklist.
- const CFGBlock* dequeue() {
- assert (!wlist.empty());
- const CFGBlock* B = *wlist.begin();
- wlist.erase(B);
- return B;
- }
-
- /// isEmpty - Return true if the worklist is empty.
- bool isEmpty() const { return wlist.empty(); }
-};
-
-//===----------------------------------------------------------------------===//
-// BlockItrTraits - Traits classes that allow transparent iteration
-// over successors/predecessors of a block depending on the direction
-// of our dataflow analysis.
-//===----------------------------------------------------------------------===//
-
-namespace dataflow {
-template<typename Tag> struct ItrTraits {};
-
-template <> struct ItrTraits<forward_analysis_tag> {
- typedef CFGBlock::const_pred_iterator PrevBItr;
- typedef CFGBlock::const_succ_iterator NextBItr;
- typedef CFGBlock::const_iterator StmtItr;
-
- static PrevBItr PrevBegin(const CFGBlock* B) { return B->pred_begin(); }
- static PrevBItr PrevEnd(const CFGBlock* B) { return B->pred_end(); }
-
- static NextBItr NextBegin(const CFGBlock* B) { return B->succ_begin(); }
- static NextBItr NextEnd(const CFGBlock* B) { return B->succ_end(); }
-
- static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); }
- static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); }
-
- static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) {
- return BlockEdge(Prev, B);
- }
-
- static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) {
- return BlockEdge(B, Next);
- }
-};
-
-template <> struct ItrTraits<backward_analysis_tag> {
- typedef CFGBlock::const_succ_iterator PrevBItr;
- typedef CFGBlock::const_pred_iterator NextBItr;
- typedef CFGBlock::const_reverse_iterator StmtItr;
-
- static PrevBItr PrevBegin(const CFGBlock* B) { return B->succ_begin(); }
- static PrevBItr PrevEnd(const CFGBlock* B) { return B->succ_end(); }
-
- static NextBItr NextBegin(const CFGBlock* B) { return B->pred_begin(); }
- static NextBItr NextEnd(const CFGBlock* B) { return B->pred_end(); }
-
- static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); }
- static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); }
-
- static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) {
- return BlockEdge(B, Prev);
- }
-
- static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) {
- return BlockEdge(Next, B);
- }
-};
-} // end namespace dataflow
-
-//===----------------------------------------------------------------------===//
-/// DataflowSolverTy - Generic dataflow solver.
-//===----------------------------------------------------------------------===//
-
-template <typename _DFValuesTy, // Usually a subclass of DataflowValues
- typename _TransferFuncsTy,
- typename _MergeOperatorTy,
- typename _Equal = std::equal_to<typename _DFValuesTy::ValTy> >
-class DataflowSolver {
-
- //===----------------------------------------------------===//
- // Type declarations.
- //===----------------------------------------------------===//
-
-public:
- typedef _DFValuesTy DFValuesTy;
- typedef _TransferFuncsTy TransferFuncsTy;
- typedef _MergeOperatorTy MergeOperatorTy;
-
- typedef typename _DFValuesTy::AnalysisDirTag AnalysisDirTag;
- typedef typename _DFValuesTy::ValTy ValTy;
- typedef typename _DFValuesTy::EdgeDataMapTy EdgeDataMapTy;
- typedef typename _DFValuesTy::BlockDataMapTy BlockDataMapTy;
-
- typedef dataflow::ItrTraits<AnalysisDirTag> ItrTraits;
- typedef typename ItrTraits::NextBItr NextBItr;
- typedef typename ItrTraits::PrevBItr PrevBItr;
- typedef typename ItrTraits::StmtItr StmtItr;
-
- //===----------------------------------------------------===//
- // External interface: constructing and running the solver.
- //===----------------------------------------------------===//
-
-public:
- DataflowSolver(DFValuesTy& d) : D(d), TF(d.getAnalysisData()) {}
- ~DataflowSolver() {}
-
- /// runOnCFG - Computes dataflow values for all blocks in a CFG.
- void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
- // Set initial dataflow values and boundary conditions.
- D.InitializeValues(cfg);
- // Solve the dataflow equations. This will populate D.EdgeDataMap
- // with dataflow values.
- SolveDataflowEquations(cfg, recordStmtValues);
- }
-
- /// runOnBlock - Computes dataflow values for a given block. This
- /// should usually be invoked only after previously computing
- /// dataflow values using runOnCFG, as runOnBlock is intended to
- /// only be used for querying the dataflow values within a block
- /// with and Observer object.
- void runOnBlock(const CFGBlock* B, bool recordStmtValues) {
- BlockDataMapTy& M = D.getBlockDataMap();
- typename BlockDataMapTy::iterator I = M.find(B);
-
- if (I != M.end()) {
- TF.getVal().copyValues(I->second);
- ProcessBlock(B, recordStmtValues, AnalysisDirTag());
- }
- }
-
- void runOnBlock(const CFGBlock& B, bool recordStmtValues) {
- runOnBlock(&B, recordStmtValues);
- }
- void runOnBlock(CFG::iterator& I, bool recordStmtValues) {
- runOnBlock(*I, recordStmtValues);
- }
- void runOnBlock(CFG::const_iterator& I, bool recordStmtValues) {
- runOnBlock(*I, recordStmtValues);
- }
-
- void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
- for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
- runOnBlock(I, recordStmtValues);
- }
-
- //===----------------------------------------------------===//
- // Internal solver logic.
- //===----------------------------------------------------===//
-
-private:
-
- /// SolveDataflowEquations - Perform the actual worklist algorithm
- /// to compute dataflow values.
- void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
- // Enqueue all blocks to ensure the dataflow values are computed
- // for every block. Not all blocks are guaranteed to reach the exit block.
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
- WorkList.enqueue(&*I);
-
- while (!WorkList.isEmpty()) {
- const CFGBlock* B = WorkList.dequeue();
- ProcessMerge(cfg,B);
- ProcessBlock(B, recordStmtValues, AnalysisDirTag());
- UpdateEdges(cfg,B,TF.getVal());
- }
- }
-
- void ResetValues(CFG& cfg, ValTy& V, const CFGBlock* B,
- dataflow::forward_analysis_tag){
-
- if (B == &cfg.getEntry())
- TF.SetTopValue(V);
- else
- V.resetValues(D.getAnalysisData());
- }
-
- void ResetValues(CFG& cfg, ValTy& V, const CFGBlock* B,
- dataflow::backward_analysis_tag){
-
- if (B == &cfg.getExit())
- TF.SetTopValue(V);
- else
- V.resetValues(D.getAnalysisData());
- }
-
- void ProcessMerge(CFG& cfg, const CFGBlock* B) {
-
- ValTy& V = TF.getVal();
- ResetValues(cfg, V, B, AnalysisDirTag());
-
- // Merge dataflow values from all predecessors of this block.
- MergeOperatorTy Merge;
-
- EdgeDataMapTy& M = D.getEdgeDataMap();
- bool firstMerge = true;
-
- for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
-
- typename EdgeDataMapTy::iterator EI =
- M.find(ItrTraits::PrevEdge(B, *I));
-
- if (EI != M.end()) {
- if (firstMerge) {
- firstMerge = false;
- V.copyValues(EI->second);
- }
- else Merge(V,EI->second);
- }
- }
-
- // Set the data for the block.
- D.getBlockDataMap()[B].copyValues(V);
- }
-
- /// ProcessBlock - Process the transfer functions for a given block.
- void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
- dataflow::forward_analysis_tag) {
-
- for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
- ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
-
- TF.VisitTerminator(const_cast<CFGBlock*>(B));
- }
-
- void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
- dataflow::backward_analysis_tag) {
-
- TF.VisitTerminator(const_cast<CFGBlock*>(B));
-
- for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
- ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
- }
-
- void ProcessStmt(const Stmt* S, bool record, dataflow::forward_analysis_tag) {
- if (record) D.getStmtDataMap()[S] = TF.getVal();
- TF.BlockStmt_Visit(const_cast<Stmt*>(S));
- }
-
- void ProcessStmt(const Stmt* S, bool record, dataflow::backward_analysis_tag){
- TF.BlockStmt_Visit(const_cast<Stmt*>(S));
- if (record) D.getStmtDataMap()[S] = TF.getVal();
- }
-
- /// UpdateEdges - After processing the transfer functions for a
- /// block, update the dataflow value associated with the block's
- /// outgoing/incoming edges (depending on whether we do a
- // forward/backward analysis respectively)
- void UpdateEdges(CFG& cfg, const CFGBlock* B, ValTy& V) {
- for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I)
- UpdateEdgeValue(ItrTraits::NextEdge(B, *I),V,*I);
- }
-
- /// UpdateEdgeValue - Update the value associated with a given edge.
- void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock* TargetBlock) {
-
- EdgeDataMapTy& M = D.getEdgeDataMap();
- typename EdgeDataMapTy::iterator I = M.find(E);
-
- if (I == M.end()) { // First computed value for this edge?
- M[E].copyValues(V);
- WorkList.enqueue(TargetBlock);
- }
- else if (!_Equal()(V,I->second)) {
- I->second.copyValues(V);
- WorkList.enqueue(TargetBlock);
- }
- }
-
-private:
- DFValuesTy& D;
- DataflowWorkListTy WorkList;
- TransferFuncsTy TF;
-};
-
-} // end namespace clang
-#endif
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
deleted file mode 100644
index d6427a5cab47..000000000000
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//===--- DataflowValues.h - Data structure for dataflow values --*- 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 a skeleton data structure for encapsulating the dataflow
-// values for a CFG. Typically this is subclassed to provide methods for
-// computing these values from a CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
-#define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
-
-#include "clang/AST/CFG.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "llvm/ADT/DenseMap.h"
-
-//===----------------------------------------------------------------------===//
-/// Dataflow Directional Tag Classes. These are used for tag dispatching
-/// within the dataflow solver/transfer functions to determine what direction
-/// a dataflow analysis flows.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-namespace dataflow {
- struct forward_analysis_tag {};
- struct backward_analysis_tag {};
-} // end namespace dataflow
-
-//===----------------------------------------------------------------------===//
-/// DataflowValues. Container class to store dataflow values for a CFG.
-//===----------------------------------------------------------------------===//
-
-template <typename ValueTypes,
- typename _AnalysisDirTag = dataflow::forward_analysis_tag >
-class DataflowValues {
-
- //===--------------------------------------------------------------------===//
- // Type declarations.
- //===--------------------------------------------------------------------===//
-
-public:
- typedef typename ValueTypes::ValTy ValTy;
- typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy;
- typedef _AnalysisDirTag AnalysisDirTag;
- typedef llvm::DenseMap<ProgramPoint, ValTy> EdgeDataMapTy;
- typedef llvm::DenseMap<const CFGBlock*, ValTy> BlockDataMapTy;
- typedef llvm::DenseMap<const Stmt*, ValTy> StmtDataMapTy;
-
- //===--------------------------------------------------------------------===//
- // Predicates.
- //===--------------------------------------------------------------------===//
-
-public:
- /// isForwardAnalysis - Returns true if the dataflow values are computed
- /// from a forward analysis.
- bool isForwardAnalysis() { return isForwardAnalysis(AnalysisDirTag()); }
-
- /// isBackwardAnalysis - Returns true if the dataflow values are computed
- /// from a backward analysis.
- bool isBackwardAnalysis() { return !isForwardAnalysis(); }
-
-private:
- bool isForwardAnalysis(dataflow::forward_analysis_tag) { return true; }
- bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; }
-
- //===--------------------------------------------------------------------===//
- // Initialization and accessors methods.
- //===--------------------------------------------------------------------===//
-
-public:
- DataflowValues() : StmtDataMap(NULL) {}
- ~DataflowValues() { delete StmtDataMap; }
-
- /// InitializeValues - Invoked by the solver to initialize state needed for
- /// dataflow analysis. This method is usually specialized by subclasses.
- void InitializeValues(const CFG& cfg) {};
-
-
- /// getEdgeData - Retrieves the dataflow values associated with a
- /// CFG edge.
- ValTy& getEdgeData(const BlockEdge& E) {
- typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
- assert (I != EdgeDataMap.end() && "No data associated with Edge.");
- return I->second;
- }
-
- const ValTy& getEdgeData(const BlockEdge& E) const {
- return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
- }
-
- /// getBlockData - Retrieves the dataflow values associated with a
- /// specified CFGBlock. If the dataflow analysis is a forward analysis,
- /// this data is associated with the END of the block. If the analysis
- /// is a backwards analysis, it is associated with the ENTRY of the block.
- ValTy& getBlockData(const CFGBlock* B) {
- typename BlockDataMapTy::iterator I = BlockDataMap.find(B);
- assert (I != BlockDataMap.end() && "No data associated with block.");
- return I->second;
- }
-
- const ValTy& getBlockData(const CFGBlock* B) const {
- return const_cast<DataflowValues*>(this)->getBlockData(B);
- }
-
- /// getStmtData - Retrieves the dataflow values associated with a
- /// specified Stmt. If the dataflow analysis is a forward analysis,
- /// this data corresponds to the point immediately before a Stmt.
- /// If the analysis is a backwards analysis, it is associated with
- /// the point after a Stmt. This data is only computed for block-level
- /// expressions, and only when requested when the analysis is executed.
- ValTy& getStmtData(const Stmt* S) {
- assert (StmtDataMap && "Dataflow values were not computed for statements.");
- typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
- assert (I != StmtDataMap->end() && "No data associated with statement.");
- return I->second;
- }
-
- const ValTy& getStmtData(const Stmt* S) const {
- return const_cast<DataflowValues*>(this)->getStmtData(S);
- }
-
- /// getEdgeDataMap - Retrieves the internal map between CFG edges and
- /// dataflow values. Usually used by a dataflow solver to compute
- /// values for blocks.
- EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; }
- const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; }
-
- /// getBlockDataMap - Retrieves the internal map between CFGBlocks and
- /// dataflow values. If the dataflow analysis operates in the forward
- /// direction, the values correspond to the dataflow values at the start
- /// of the block. Otherwise, for a backward analysis, the values correpsond
- /// to the dataflow values at the end of the block.
- BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
- const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
-
- /// getStmtDataMap - Retrieves the internal map between Stmts and
- /// dataflow values.
- StmtDataMapTy& getStmtDataMap() {
- if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
- return *StmtDataMap;
- }
-
- const StmtDataMapTy& getStmtDataMap() const {
- return const_cast<DataflowValues*>(this)->getStmtDataMap();
- }
-
- /// getAnalysisData - Retrieves the meta data associated with a
- /// dataflow analysis for analyzing a particular CFG.
- /// This is typically consumed by transfer function code (via the solver).
- /// This can also be used by subclasses to interpret the dataflow values.
- AnalysisDataTy& getAnalysisData() { return AnalysisData; }
- const AnalysisDataTy& getAnalysisData() const { return AnalysisData; }
-
- //===--------------------------------------------------------------------===//
- // Internal data.
- //===--------------------------------------------------------------------===//
-
-protected:
- EdgeDataMapTy EdgeDataMap;
- BlockDataMapTy BlockDataMap;
- StmtDataMapTy* StmtDataMap;
- AnalysisDataTy AnalysisData;
-};
-
-} // end namespace clang
-#endif
diff --git a/clang/include/clang/Analysis/LocalCheckers.h b/clang/include/clang/Analysis/LocalCheckers.h
deleted file mode 100644
index 23610f9a2d97..000000000000
--- a/clang/include/clang/Analysis/LocalCheckers.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- 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 interface to call a set of intra-procedural (local)
-// checkers that use flow/path-sensitive analyses to find bugs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
-#define LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
-
-namespace clang {
-
-class CFG;
-class Decl;
-class Diagnostic;
-class ASTContext;
-class PathDiagnosticClient;
-class GRTransferFuncs;
-class BugType;
-class LangOptions;
-class ParentMap;
-class LiveVariables;
-class BugReporter;
-class ObjCImplementationDecl;
-class LangOptions;
-class GRExprEngine;
-
-void CheckDeadStores(LiveVariables& L, BugReporter& BR);
-
-void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
- bool FullUninitTaint=false);
-
-GRTransferFuncs* MakeGRSimpleValsTF();
-GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
- const LangOptions& lopts);
-
-void CheckObjCDealloc(ObjCImplementationDecl* D, const LangOptions& L,
- BugReporter& BR);
-
-void CheckObjCInstMethSignature(ObjCImplementationDecl* ID, BugReporter& BR);
-void CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR);
-
-void RegisterAppleChecks(GRExprEngine& Eng);
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h
deleted file mode 100644
index e266ee8518ff..000000000000
--- a/clang/include/clang/Analysis/PathDiagnostic.h
+++ /dev/null
@@ -1,213 +0,0 @@
-//===--- PathDiagnostic.h - Path-Specific Diagnostic Handling ---*- 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 PathDiagnostic-related interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
-#define LLVM_CLANG_PATH_DIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/OwningPtr.h"
-
-#include <vector>
-#include <list>
-#include <string>
-#include <algorithm>
-
-namespace clang {
-
-class PathDiagnosticPiece {
-public:
- enum DisplayHint { Above, Below };
-
-private:
- FullSourceLoc Pos;
- std::string str;
- DisplayHint Hint;
- std::vector<SourceRange> ranges;
-
-public:
-
- PathDiagnosticPiece(FullSourceLoc pos, const std::string& s,
- DisplayHint hint = Above)
- : Pos(pos), str(s), Hint(hint) {}
-
- PathDiagnosticPiece(FullSourceLoc pos, const char* s,
- DisplayHint hint = Above)
- : Pos(pos), str(s), Hint(hint) {}
-
- const std::string& getString() const { return str; }
-
- DisplayHint getDisplayHint() const { return Hint; }
-
- void addRange(SourceRange R) {
- ranges.push_back(R);
- }
-
- void addRange(SourceLocation B, SourceLocation E) {
- ranges.push_back(SourceRange(B,E));
- }
-
- typedef const SourceRange* range_iterator;
-
- range_iterator ranges_begin() const {
- return ranges.empty() ? NULL : &ranges[0];
- }
-
- range_iterator ranges_end() const {
- return ranges_begin() + ranges.size();
- }
-
- const SourceManager& getSourceManager() const {
- return Pos.getManager();
- }
-
- FullSourceLoc getLocation() const { return Pos; }
-};
-
-class PathDiagnostic {
- std::list<PathDiagnosticPiece*> path;
- unsigned Size;
- std::string Desc;
- std::string Category;
- std::vector<std::string> OtherDesc;
-
-public:
- PathDiagnostic() : Size(0) {}
-
- PathDiagnostic(const char* desc, const char* category)
- : Size(0), Desc(desc), Category(category) {}
-
- PathDiagnostic(const std::string& desc, const std::string& category)
- : Size(0), Desc(desc), Category(category) {}
-
- ~PathDiagnostic();
-
- const std::string& getDescription() const { return Desc; }
- const std::string& getCategory() const { return Category; }
-
- typedef std::vector<std::string>::const_iterator meta_iterator;
- meta_iterator meta_begin() const { return OtherDesc.begin(); }
- meta_iterator meta_end() const { return OtherDesc.end(); }
- void addMeta(const std::string& s) { OtherDesc.push_back(s); }
- void addMeta(const char* s) { OtherDesc.push_back(s); }
-
- void push_front(PathDiagnosticPiece* piece) {
- path.push_front(piece);
- ++Size;
- }
-
- void push_back(PathDiagnosticPiece* piece) {
- path.push_back(piece);
- ++Size;
- }
-
- PathDiagnosticPiece* back() {
- return path.back();
- }
-
- const PathDiagnosticPiece* back() const {
- return path.back();
- }
-
- unsigned size() const { return Size; }
- bool empty() const { return Size == 0; }
-
- class iterator {
- public:
- typedef std::list<PathDiagnosticPiece*>::iterator ImplTy;
-
- typedef PathDiagnosticPiece value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- private:
- ImplTy I;
-
- public:
- iterator(const ImplTy& i) : I(i) {}
-
- bool operator==(const iterator& X) const { return I == X.I; }
- bool operator!=(const iterator& X) const { return I != X.I; }
-
- PathDiagnosticPiece& operator*() const { return **I; }
- PathDiagnosticPiece* operator->() const { return *I; }
-
- iterator& operator++() { ++I; return *this; }
- iterator& operator--() { --I; return *this; }
- };
-
- class const_iterator {
- public:
- typedef std::list<PathDiagnosticPiece*>::const_iterator ImplTy;
-
- typedef const PathDiagnosticPiece value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- private:
- ImplTy I;
-
- public:
- const_iterator(const ImplTy& i) : I(i) {}
-
- bool operator==(const const_iterator& X) const { return I == X.I; }
- bool operator!=(const const_iterator& X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
-
- const_iterator& operator++() { ++I; return *this; }
- const_iterator& operator--() { --I; return *this; }
- };
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-
- // forward iterator creation methods.
-
- iterator begin() { return path.begin(); }
- iterator end() { return path.end(); }
-
- const_iterator begin() const { return path.begin(); }
- const_iterator end() const { return path.end(); }
-
- // reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-};
-
-class PathDiagnosticClient : public DiagnosticClient {
-public:
- PathDiagnosticClient() {}
- virtual ~PathDiagnosticClient() {}
-
- virtual void HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level DiagLevel,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges);
-
- virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
-};
-
-} //end clang namespace
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h
deleted file mode 100644
index 29957a7996f9..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
-// of APSInt objects and symbolic constraints used by GRExprEngine
-// and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
-#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
-
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/APSInt.h"
-
-namespace llvm {
- class BumpPtrAllocator;
-}
-
-namespace clang {
-
-class RVal;
-
-class BasicValueFactory {
- typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
- APSIntSetTy;
-
- typedef llvm::FoldingSet<SymIntConstraint>
- SymIntCSetTy;
-
-
- ASTContext& Ctx;
- llvm::BumpPtrAllocator& BPAlloc;
-
- APSIntSetTy APSIntSet;
- SymIntCSetTy SymIntCSet;
- void* PersistentRVals;
- void* PersistentRValPairs;
-
-public:
- BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
- : Ctx(ctx), BPAlloc(Alloc), PersistentRVals(0), PersistentRValPairs(0) {}
-
- ~BasicValueFactory();
-
- ASTContext& getContext() const { return Ctx; }
-
- const llvm::APSInt& getValue(const llvm::APSInt& X);
- const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
- const llvm::APSInt& getValue(uint64_t X, QualType T);
-
- inline const llvm::APSInt& getZeroWithPtrWidth() {
- return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), true);
- }
-
- inline const llvm::APSInt& getTruthValue(bool b) {
- return getValue(b ? 1 : 0, Ctx.getTypeSize(Ctx.IntTy), false);
- }
-
- const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
- const llvm::APSInt& V);
-
- const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1,
- const llvm::APSInt& V2);
-
- const std::pair<RVal, uintptr_t>&
- getPersistentRValWithData(const RVal& V, uintptr_t Data);
-
- const std::pair<RVal, RVal>&
- getPersistentRValPair(const RVal& V1, const RVal& V2);
-
- const RVal* getPersistentRVal(RVal X);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h
deleted file mode 100644
index bf9aa00fdb11..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h
+++ /dev/null
@@ -1,352 +0,0 @@
-// BugReporter.h - Generate PathDiagnostics ----------*- 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 BugReporter, a utility class for generating
-// PathDiagnostics for analyses based on GRState.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
-#define LLVM_CLANG_ANALYSIS_BUGREPORTER
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include <vector>
-#include <list>
-
-namespace clang {
-
-class PathDiagnostic;
-class PathDiagnosticPiece;
-class PathDiagnosticClient;
-class ASTContext;
-class Diagnostic;
-class BugReporter;
-class GRExprEngine;
-class GRState;
-class Stmt;
-class BugReport;
-class ParentMap;
-
-class BugType {
-public:
- BugType() {}
- virtual ~BugType();
-
- virtual const char* getName() const = 0;
- virtual const char* getDescription() const { return getName(); }
- virtual const char* getCategory() const { return ""; }
-
- virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
- return std::pair<const char**, const char**>(0, 0);
- }
-
- virtual void EmitWarnings(BugReporter& BR) {}
- virtual void GetErrorNodes(std::vector<ExplodedNode<GRState>*>& Nodes) {}
-
- virtual bool isCached(BugReport& R) = 0;
-};
-
-class BugTypeCacheLocation : public BugType {
- llvm::SmallSet<ProgramPoint,10> CachedErrors;
-public:
- BugTypeCacheLocation() {}
- virtual ~BugTypeCacheLocation() {}
- virtual bool isCached(BugReport& R);
- bool isCached(ProgramPoint P);
-};
-
-
-class BugReport {
- BugType& Desc;
- ExplodedNode<GRState> *EndNode;
- SourceRange R;
-public:
- BugReport(BugType& D, ExplodedNode<GRState> *n) : Desc(D), EndNode(n) {}
- virtual ~BugReport();
-
- const BugType& getBugType() const { return Desc; }
- BugType& getBugType() { return Desc; }
-
- ExplodedNode<GRState>* getEndNode() const { return EndNode; }
-
- Stmt* getStmt(BugReporter& BR) const;
-
- const char* getName() const { return getBugType().getName(); }
-
- virtual const char* getDescription() const {
- return getBugType().getDescription();
- }
-
- virtual const char* getCategory() const {
- return getBugType().getCategory();
- }
-
- virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
- return getBugType().getExtraDescriptiveText();
- }
-
- virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
- ExplodedNode<GRState>* N);
-
- virtual FullSourceLoc getLocation(SourceManager& Mgr);
-
- virtual void getRanges(BugReporter& BR,const SourceRange*& beg,
- const SourceRange*& end);
-
- virtual PathDiagnosticPiece* VisitNode(ExplodedNode<GRState>* N,
- ExplodedNode<GRState>* PrevN,
- ExplodedGraph<GRState>& G,
- BugReporter& BR);
-};
-
-class RangedBugReport : public BugReport {
- std::vector<SourceRange> Ranges;
- const char* desc;
-public:
- RangedBugReport(BugType& D, ExplodedNode<GRState> *n,
- const char* description = 0)
- : BugReport(D, n), desc(description) {}
-
- virtual ~RangedBugReport();
-
- virtual const char* getDescription() const {
- return desc ? desc : BugReport::getDescription();
- }
-
- void addRange(SourceRange R) { Ranges.push_back(R); }
-
-
- virtual void getRanges(BugReporter& BR,const SourceRange*& beg,
- const SourceRange*& end) {
-
- if (Ranges.empty()) {
- beg = NULL;
- end = NULL;
- }
- else {
- beg = &Ranges[0];
- end = beg + Ranges.size();
- }
- }
-};
-
-class BugReporterData {
-public:
- virtual ~BugReporterData();
- virtual Diagnostic& getDiagnostic() = 0;
- virtual PathDiagnosticClient* getPathDiagnosticClient() = 0;
- virtual ASTContext& getContext() = 0;
- virtual SourceManager& getSourceManager() = 0;
- virtual CFG* getCFG() = 0;
- virtual ParentMap& getParentMap() = 0;
- virtual LiveVariables* getLiveVariables() = 0;
-};
-
-class BugReporter {
-public:
- enum Kind { BaseBRKind, GRBugReporterKind };
-
-protected:
- Kind kind;
- BugReporterData& D;
-
- BugReporter(BugReporterData& d, Kind k) : kind(k), D(d) {}
-
-public:
- BugReporter(BugReporterData& d) : kind(BaseBRKind), D(d) {}
- virtual ~BugReporter();
-
- Kind getKind() const { return kind; }
-
- Diagnostic& getDiagnostic() {
- return D.getDiagnostic();
- }
-
- PathDiagnosticClient* getPathDiagnosticClient() {
- return D.getPathDiagnosticClient();
- }
-
- ASTContext& getContext() {
- return D.getContext();
- }
-
- SourceManager& getSourceManager() {
- return D.getSourceManager();
- }
-
- CFG* getCFG() {
- return D.getCFG();
- }
-
- ParentMap& getParentMap() {
- return D.getParentMap();
- }
-
- LiveVariables* getLiveVariables() {
- return D.getLiveVariables();
- }
-
- virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R) {}
-
- void EmitWarning(BugReport& R);
-
- void EmitBasicReport(const char* BugName, const char* BugStr,
- SourceLocation Loc,
- SourceRange* RangeBeg, unsigned NumRanges);
-
- void EmitBasicReport(const char* BugName, const char* BugCategory,
- const char* BugStr, SourceLocation Loc,
- SourceRange* RangeBeg, unsigned NumRanges);
-
-
- void EmitBasicReport(const char* BugName, const char* BugStr,
- SourceLocation Loc) {
- EmitBasicReport(BugName, BugStr, Loc, 0, 0);
- }
-
- void EmitBasicReport(const char* BugName, const char* BugCategory,
- const char* BugStr, SourceLocation Loc) {
- EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0);
- }
-
- void EmitBasicReport(const char* BugName, const char* BugStr,
- SourceLocation Loc, SourceRange R) {
- EmitBasicReport(BugName, BugStr, Loc, &R, 1);
- }
-
- void EmitBasicReport(const char* BugName, const char* Category,
- const char* BugStr, SourceLocation Loc, SourceRange R) {
- EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1);
- }
-
- static bool classof(const BugReporter* R) { return true; }
-};
-
-class GRBugReporter : public BugReporter {
- GRExprEngine& Eng;
- llvm::SmallSet<SymbolID, 10> NotableSymbols;
-public:
-
- GRBugReporter(BugReporterData& d, GRExprEngine& eng)
- : BugReporter(d, GRBugReporterKind), Eng(eng) {}
-
- virtual ~GRBugReporter();
-
- /// getEngine - Return the analysis engine used to analyze a given
- /// function or method.
- GRExprEngine& getEngine() {
- return Eng;
- }
-
- /// getGraph - Get the exploded graph created by the analysis engine
- /// for the analyzed method or function.
- ExplodedGraph<GRState>& getGraph();
-
- /// getStateManager - Return the state manager used by the analysis
- /// engine.
- GRStateManager& getStateManager();
-
- virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
-
- void addNotableSymbol(SymbolID Sym) {
- NotableSymbols.insert(Sym);
- }
-
- bool isNotable(SymbolID Sym) const {
- return (bool) NotableSymbols.count(Sym);
- }
-
- /// classof - Used by isa<>, cast<>, and dyn_cast<>.
- static bool classof(const BugReporter* R) {
- return R->getKind() == GRBugReporterKind;
- }
-};
-
-
-class DiagBugReport : public RangedBugReport {
- std::list<std::string> Strs;
- FullSourceLoc L;
- const char* description;
-public:
- DiagBugReport(const char* desc, BugType& D, FullSourceLoc l) :
- RangedBugReport(D, NULL), L(l), description(desc) {}
-
- virtual ~DiagBugReport() {}
- virtual FullSourceLoc getLocation(SourceManager&) { return L; }
-
- virtual const char* getDescription() const {
- return description;
- }
-
- void addString(const std::string& s) { Strs.push_back(s); }
-
- typedef std::list<std::string>::const_iterator str_iterator;
- str_iterator str_begin() const { return Strs.begin(); }
- str_iterator str_end() const { return Strs.end(); }
-};
-
-class DiagCollector : public DiagnosticClient {
- std::list<DiagBugReport> Reports;
- BugType& D;
-public:
- DiagCollector(BugType& d) : D(d) {}
-
- virtual ~DiagCollector() {}
-
- virtual void HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level DiagLevel,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges) {
-
- // FIXME: Use a map from diag::kind to BugType, instead of having just
- // one BugType.
-
- Reports.push_back(DiagBugReport(Diags.getDescription(ID), D, Pos));
- DiagBugReport& R = Reports.back();
-
- for ( ; NumRanges ; --NumRanges, ++Ranges)
- R.addRange(*Ranges);
-
- for ( ; NumStrs ; --NumStrs, ++Strs)
- R.addString(*Strs);
- }
-
- // Iterators.
-
- typedef std::list<DiagBugReport>::iterator iterator;
- iterator begin() { return Reports.begin(); }
- iterator end() { return Reports.end(); }
-};
-
-class SimpleBugType : public BugTypeCacheLocation {
- const char* name;
- const char* category;
- const char* desc;
-public:
- SimpleBugType(const char* n) : name(n), category(""), desc(0) {}
- SimpleBugType(const char* n, const char* c, const char* d)
- : name(n), category(c), desc(d) {}
-
- virtual const char* getName() const { return name; }
- virtual const char* getDescription() const { return desc ? desc : name; }
- virtual const char* getCategory() const { return category; }
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h b/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h
deleted file mode 100644
index 25c9260a72c3..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the interface to manage constraints on symbolic values.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
-#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
-
-// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place.
-#include "clang/Analysis/PathSensitive/Store.h"
-
-namespace llvm {
-class APSInt;
-}
-
-namespace clang {
-
-class GRState;
-class GRStateManager;
-class RVal;
-class SymbolID;
-
-class ConstraintManager {
-public:
- virtual ~ConstraintManager();
- virtual const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
- bool& isFeasible) = 0;
-
- virtual const GRState* AddNE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) = 0;
- virtual const llvm::APSInt* getSymVal(const GRState* St, SymbolID sym) = 0;
-
- virtual bool isEqual(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) const = 0;
-
- virtual const GRState* RemoveDeadBindings(const GRState* St,
- StoreManager::LiveSymbolsTy& LSymbols,
- StoreManager::DeadSymbolsTy& DSymbols) = 0;
-
- virtual void print(const GRState* St, std::ostream& Out,
- const char* nl, const char *sep) = 0;
-};
-
-ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr);
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/Environment.h b/clang/include/clang/Analysis/PathSensitive/Environment.h
deleted file mode 100644
index 8e1b97a3bec4..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/Environment.h
+++ /dev/null
@@ -1,150 +0,0 @@
-//== Environment.h - Map from Expr* to Locations/Values ---------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the Environment and EnvironmentManager classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
-#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
-
-// For using typedefs in StoreManager. Should find a better place for these
-// typedefs.
-#include "clang/Analysis/PathSensitive/Store.h"
-
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "clang/Analysis/PathSensitive/RValues.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/FoldingSet.h"
-
-namespace clang {
-
-class EnvironmentManager;
-class BasicValueFactory;
-class LiveVariables;
-
-class Environment : public llvm::FoldingSetNode {
-private:
-
- friend class EnvironmentManager;
-
- // Type definitions.
- typedef llvm::ImmutableMap<Expr*,RVal> BindingsTy;
-
- // Data.
- BindingsTy SubExprBindings;
- BindingsTy BlkExprBindings;
-
- Environment(BindingsTy seb, BindingsTy beb)
- : SubExprBindings(seb), BlkExprBindings(beb) {}
-
-public:
-
- typedef BindingsTy::iterator seb_iterator;
- seb_iterator seb_begin() const { return SubExprBindings.begin(); }
- seb_iterator seb_end() const { return SubExprBindings.end(); }
-
- typedef BindingsTy::iterator beb_iterator;
- beb_iterator beb_begin() const { return BlkExprBindings.begin(); }
- beb_iterator beb_end() const { return BlkExprBindings.end(); }
-
- RVal LookupSubExpr(Expr* E) const {
- const RVal* X = SubExprBindings.lookup(E);
- return X ? *X : UnknownVal();
- }
-
- RVal LookupBlkExpr(Expr* E) const {
- const RVal* X = BlkExprBindings.lookup(E);
- return X ? *X : UnknownVal();
- }
-
- RVal LookupExpr(Expr* E) const {
- const RVal* X = SubExprBindings.lookup(E);
- if (X) return *X;
- X = BlkExprBindings.lookup(E);
- return X ? *X : UnknownVal();
- }
-
- RVal GetRVal(Expr* Ex, BasicValueFactory& BasicVals) const;
- RVal GetBlkExprRVal(Expr* Ex, BasicValueFactory& BasicVals) const;
-
- /// Profile - Profile the contents of an Environment object for use
- /// in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
- E->SubExprBindings.Profile(ID);
- E->BlkExprBindings.Profile(ID);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- bool operator==(const Environment& RHS) const {
- return SubExprBindings == RHS.SubExprBindings &&
- BlkExprBindings == RHS.BlkExprBindings;
- }
-};
-
-class EnvironmentManager {
-private:
- typedef Environment::BindingsTy::Factory FactoryTy;
- FactoryTy F;
-
-public:
-
- EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
- ~EnvironmentManager() {}
-
- /// RemoveBlkExpr - Return a new environment object with the same bindings as
- /// the provided environment except with any bindings for the provided Expr*
- /// removed. This method only removes bindings for block-level expressions.
- /// Using this method on a non-block level expression will return the
- /// same environment object.
- Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
- return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E));
- }
-
- Environment RemoveSubExpr(const Environment& Env, Expr* E) {
- return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings);
- }
-
- Environment AddBlkExpr(const Environment& Env, Expr* E, RVal V) {
- return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V));
- }
-
- Environment AddSubExpr(const Environment& Env, Expr* E, RVal V) {
- return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings);
- }
-
- /// RemoveSubExprBindings - Return a new environment object with
- /// the same bindings as the provided environment except with all the
- /// subexpression bindings removed.
- Environment RemoveSubExprBindings(const Environment& Env) {
- return Environment(F.GetEmptyMap(), Env.BlkExprBindings);
- }
-
- Environment getInitialEnvironment() {
- return Environment(F.GetEmptyMap(), F.GetEmptyMap());
- }
-
- Environment SetRVal(const Environment& Env, Expr* E, RVal V,
- bool isBlkExpr, bool Invalidate);
-
- Environment RemoveDeadBindings(Environment Env, Stmt* Loc,
- const LiveVariables& Liveness,
- llvm::SmallVectorImpl<const MemRegion*>& DRoots,
- StoreManager::LiveSymbolsTy& LSymbols);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h
deleted file mode 100644
index 3406d178dd7d..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h
+++ /dev/null
@@ -1,525 +0,0 @@
-//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- 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 template classes ExplodedNode and ExplodedGraph,
-// which represent a path-sensitive, intra-procedural "exploded graph."
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
-#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
-
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/AST/Decl.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/Support/Casting.h"
-
-namespace clang {
-
-class GRCoreEngineImpl;
-class ExplodedNodeImpl;
-class CFG;
-class ASTContext;
-
-class GRStmtNodeBuilderImpl;
-class GRBranchNodeBuilderImpl;
-class GRIndirectGotoNodeBuilderImpl;
-class GRSwitchNodeBuilderImpl;
-class GREndPathNodebuilderImpl;
-
-class ExplodedNodeImpl : public llvm::FoldingSetNode {
-protected:
- friend class ExplodedGraphImpl;
- friend class GRCoreEngineImpl;
- friend class GRStmtNodeBuilderImpl;
- friend class GRBranchNodeBuilderImpl;
- friend class GRIndirectGotoNodeBuilderImpl;
- friend class GRSwitchNodeBuilderImpl;
- friend class GREndPathNodeBuilderImpl;
-
- class NodeGroup {
- enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 };
- uintptr_t P;
-
- unsigned getKind() const {
- return P & 0x1;
- }
-
- void* getPtr() const {
- assert (!getFlag());
- return reinterpret_cast<void*>(P & ~Mask);
- }
-
- ExplodedNodeImpl* getNode() const {
- return reinterpret_cast<ExplodedNodeImpl*>(getPtr());
- }
-
- public:
- NodeGroup() : P(0) {}
-
- ~NodeGroup();
-
- ExplodedNodeImpl** begin() const;
-
- ExplodedNodeImpl** end() const;
-
- unsigned size() const;
-
- bool empty() const { return size() == 0; }
-
- void addNode(ExplodedNodeImpl* N);
-
- void setFlag() {
- assert (P == 0);
- P = AuxFlag;
- }
-
- bool getFlag() const {
- return P & AuxFlag ? true : false;
- }
- };
-
- /// Location - The program location (within a function body) associated
- /// with this node.
- const ProgramPoint Location;
-
- /// State - The state associated with this node.
- const void* State;
-
- /// Preds - The predecessors of this node.
- NodeGroup Preds;
-
- /// Succs - The successors of this node.
- NodeGroup Succs;
-
- /// Construct a ExplodedNodeImpl with the provided location and state.
- explicit ExplodedNodeImpl(const ProgramPoint& loc, const void* state)
- : Location(loc), State(state) {}
-
- /// addPredeccessor - Adds a predecessor to the current node, and
- /// in tandem add this node as a successor of the other node.
- void addPredecessor(ExplodedNodeImpl* V);
-
-public:
-
- /// getLocation - Returns the edge associated with the given node.
- ProgramPoint getLocation() const { return Location; }
-
- unsigned succ_size() const { return Succs.size(); }
- unsigned pred_size() const { return Preds.size(); }
- bool succ_empty() const { return Succs.empty(); }
- bool pred_empty() const { return Preds.empty(); }
-
- bool isSink() const { return Succs.getFlag(); }
- void markAsSink() { Succs.setFlag(); }
-
- // For debugging.
-
-public:
-
- class Auditor {
- public:
- virtual ~Auditor();
- virtual void AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst) = 0;
- };
-
- static void SetAuditor(Auditor* A);
-};
-
-
-template <typename StateTy>
-struct GRTrait {
- static inline void Profile(llvm::FoldingSetNodeID& ID, const StateTy* St) {
- St->Profile(ID);
- }
-};
-
-
-template <typename StateTy>
-class ExplodedNode : public ExplodedNodeImpl {
-public:
- /// Construct a ExplodedNodeImpl with the given node ID, program edge,
- /// and state.
- explicit ExplodedNode(const ProgramPoint& loc, const StateTy* St)
- : ExplodedNodeImpl(loc, St) {}
-
- /// getState - Returns the state associated with the node.
- inline const StateTy* getState() const {
- return static_cast<const StateTy*>(State);
- }
-
- // Profiling (for FoldingSet).
-
- static inline void Profile(llvm::FoldingSetNodeID& ID,
- const ProgramPoint& Loc,
- const StateTy* state) {
- ID.Add(Loc);
- GRTrait<StateTy>::Profile(ID, state);
- }
-
- inline void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, getLocation(), getState());
- }
-
- void addPredecessor(ExplodedNode* V) {
- ExplodedNodeImpl::addPredecessor(V);
- }
-
- // Iterators over successor and predecessor vertices.
- typedef ExplodedNode** succ_iterator;
- typedef const ExplodedNode** const_succ_iterator;
- typedef ExplodedNode** pred_iterator;
- typedef const ExplodedNode** const_pred_iterator;
-
- pred_iterator pred_begin() { return (ExplodedNode**) Preds.begin(); }
- pred_iterator pred_end() { return (ExplodedNode**) Preds.end(); }
-
- const_pred_iterator pred_begin() const {
- return const_cast<ExplodedNode*>(this)->pred_begin();
- }
- const_pred_iterator pred_end() const {
- return const_cast<ExplodedNode*>(this)->pred_end();
- }
-
- succ_iterator succ_begin() { return (ExplodedNode**) Succs.begin(); }
- succ_iterator succ_end() { return (ExplodedNode**) Succs.end(); }
-
- const_succ_iterator succ_begin() const {
- return const_cast<ExplodedNode*>(this)->succ_begin();
- }
- const_succ_iterator succ_end() const {
- return const_cast<ExplodedNode*>(this)->succ_end();
- }
-};
-
-
-class ExplodedGraphImpl {
-protected:
- friend class GRCoreEngineImpl;
- friend class GRStmtNodeBuilderImpl;
- friend class GRBranchNodeBuilderImpl;
- friend class GRIndirectGotoNodeBuilderImpl;
- friend class GRSwitchNodeBuilderImpl;
- friend class GREndPathNodeBuilderImpl;
-
- // Type definitions.
- typedef llvm::SmallVector<ExplodedNodeImpl*,2> RootsTy;
- typedef llvm::SmallVector<ExplodedNodeImpl*,10> EndNodesTy;
-
- /// Roots - The roots of the simulation graph. Usually there will be only
- /// one, but clients are free to establish multiple subgraphs within a single
- /// SimulGraph. Moreover, these subgraphs can often merge when paths from
- /// different roots reach the same state at the same program location.
- RootsTy Roots;
-
- /// EndNodes - The nodes in the simulation graph which have been
- /// specially marked as the endpoint of an abstract simulation path.
- EndNodesTy EndNodes;
-
- /// Allocator - BumpPtrAllocator to create nodes.
- llvm::BumpPtrAllocator Allocator;
-
- /// cfg - The CFG associated with this analysis graph.
- CFG& cfg;
-
- /// CodeDecl - The declaration containing the code being analyzed. This
- /// can be a FunctionDecl or and ObjCMethodDecl.
- Decl& CodeDecl;
-
- /// Ctx - The ASTContext used to "interpret" CodeDecl.
- ASTContext& Ctx;
-
- /// NumNodes - The number of nodes in the graph.
- unsigned NumNodes;
-
- /// getNodeImpl - Retrieve the node associated with a (Location,State)
- /// pair, where 'State' is represented as an opaque void*. This method
- /// is intended to be used only by GRCoreEngineImpl.
- virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
- const void* State,
- bool* IsNew) = 0;
-
- virtual ExplodedGraphImpl* MakeEmptyGraph() const = 0;
-
- /// addRoot - Add an untyped node to the set of roots.
- ExplodedNodeImpl* addRoot(ExplodedNodeImpl* V) {
- Roots.push_back(V);
- return V;
- }
-
- /// addEndOfPath - Add an untyped node to the set of EOP nodes.
- ExplodedNodeImpl* addEndOfPath(ExplodedNodeImpl* V) {
- EndNodes.push_back(V);
- return V;
- }
-
- // ctor.
- ExplodedGraphImpl(CFG& c, Decl& cd, ASTContext& ctx)
- : cfg(c), CodeDecl(cd), Ctx(ctx), NumNodes(0) {}
-
-public:
- virtual ~ExplodedGraphImpl() {}
-
- unsigned num_roots() const { return Roots.size(); }
- unsigned num_eops() const { return EndNodes.size(); }
-
- bool empty() const { return NumNodes == 0; }
- unsigned size() const { return NumNodes; }
-
- llvm::BumpPtrAllocator& getAllocator() { return Allocator; }
- CFG& getCFG() { return cfg; }
- ASTContext& getContext() { return Ctx; }
-
- Decl& getCodeDecl() { return CodeDecl; }
- const Decl& getCodeDecl() const { return CodeDecl; }
-
- const FunctionDecl* getFunctionDecl() const {
- return llvm::dyn_cast<FunctionDecl>(&CodeDecl);
- }
-
- ExplodedGraphImpl* Trim(ExplodedNodeImpl** NBeg,
- ExplodedNodeImpl** NEnd) const;
-
-};
-
-template <typename STATE>
-class ExplodedGraph : public ExplodedGraphImpl {
-public:
- typedef STATE StateTy;
- typedef ExplodedNode<StateTy> NodeTy;
- typedef llvm::FoldingSet<NodeTy> AllNodesTy;
-
-protected:
- /// Nodes - The nodes in the graph.
- AllNodesTy Nodes;
-
-protected:
- virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
- const void* State,
- bool* IsNew) {
-
- return getNode(L, static_cast<const StateTy*>(State), IsNew);
- }
-
- virtual ExplodedGraphImpl* MakeEmptyGraph() const {
- return new ExplodedGraph(cfg, CodeDecl, Ctx);
- }
-
-public:
- ExplodedGraph(CFG& c, Decl& cd, ASTContext& ctx)
- : ExplodedGraphImpl(c, cd, ctx) {}
-
- /// getNode - Retrieve the node associated with a (Location,State) pair,
- /// where the 'Location' is a ProgramPoint in the CFG. If no node for
- /// this pair exists, it is created. IsNew is set to true if
- /// the node was freshly created.
- NodeTy* getNode(const ProgramPoint& L, const StateTy* State,
- bool* IsNew = NULL) {
-
- // Profile 'State' to determine if we already have an existing node.
- llvm::FoldingSetNodeID profile;
- void* InsertPos = 0;
-
- NodeTy::Profile(profile, L, State);
- NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
-
- if (!V) {
- // Allocate a new node.
- V = (NodeTy*) Allocator.Allocate<NodeTy>();
- new (V) NodeTy(L, State);
-
- // Insert the node into the node set and return it.
- Nodes.InsertNode(V, InsertPos);
-
- ++NumNodes;
-
- if (IsNew) *IsNew = true;
- }
- else
- if (IsNew) *IsNew = false;
-
- return V;
- }
-
- // Iterators.
- typedef NodeTy** roots_iterator;
- typedef const NodeTy** const_roots_iterator;
- typedef NodeTy** eop_iterator;
- typedef const NodeTy** const_eop_iterator;
- typedef typename AllNodesTy::iterator node_iterator;
- typedef typename AllNodesTy::const_iterator const_node_iterator;
-
- node_iterator nodes_begin() {
- return Nodes.begin();
- }
-
- node_iterator nodes_end() {
- return Nodes.end();
- }
-
- const_node_iterator nodes_begin() const {
- return Nodes.begin();
- }
-
- const_node_iterator nodes_end() const {
- return Nodes.end();
- }
-
- roots_iterator roots_begin() {
- return reinterpret_cast<roots_iterator>(Roots.begin());
- }
-
- roots_iterator roots_end() {
- return reinterpret_cast<roots_iterator>(Roots.end());
- }
-
- const_roots_iterator roots_begin() const {
- return const_cast<ExplodedGraph>(this)->roots_begin();
- }
-
- const_roots_iterator roots_end() const {
- return const_cast<ExplodedGraph>(this)->roots_end();
- }
-
- eop_iterator eop_begin() {
- return reinterpret_cast<eop_iterator>(EndNodes.begin());
- }
-
- eop_iterator eop_end() {
- return reinterpret_cast<eop_iterator>(EndNodes.end());
- }
-
- const_eop_iterator eop_begin() const {
- return const_cast<ExplodedGraph>(this)->eop_begin();
- }
-
- const_eop_iterator eop_end() const {
- return const_cast<ExplodedGraph>(this)->eop_end();
- }
-
- // Utility.
-
- ExplodedGraph* Trim(NodeTy** NBeg, NodeTy** NEnd) const {
-
- if (NBeg == NEnd)
- return NULL;
-
- assert (NBeg < NEnd);
-
- ExplodedNodeImpl** NBegImpl = (ExplodedNodeImpl**) NBeg;
- ExplodedNodeImpl** NEndImpl = (ExplodedNodeImpl**) NEnd;
-
- return static_cast<ExplodedGraph*>(ExplodedGraphImpl::Trim(NBegImpl,
- NEndImpl));
- }
-};
-
-
-template <typename StateTy>
-class ExplodedNodeSet {
-
- typedef ExplodedNode<StateTy> NodeTy;
- typedef llvm::SmallPtrSet<NodeTy*,5> ImplTy;
- ImplTy Impl;
-
-public:
- ExplodedNodeSet(NodeTy* N) {
- assert (N && !static_cast<ExplodedNodeImpl*>(N)->isSink());
- Impl.insert(N);
- }
-
- ExplodedNodeSet() {}
-
- inline void Add(NodeTy* N) {
- if (N && !static_cast<ExplodedNodeImpl*>(N)->isSink()) Impl.insert(N);
- }
-
- typedef typename ImplTy::iterator iterator;
- typedef typename ImplTy::const_iterator const_iterator;
-
- inline unsigned size() const { return Impl.size(); }
- inline bool empty() const { return Impl.empty(); }
-
- inline void clear() { Impl.clear(); }
-
- inline iterator begin() { return Impl.begin(); }
- inline iterator end() { return Impl.end(); }
-
- inline const_iterator begin() const { return Impl.begin(); }
- inline const_iterator end() const { return Impl.end(); }
-};
-
-} // end clang namespace
-
-// GraphTraits
-
-namespace llvm {
- template<typename StateTy>
- struct GraphTraits<clang::ExplodedNode<StateTy>*> {
- typedef clang::ExplodedNode<StateTy> NodeType;
- typedef typename NodeType::succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
-
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
-
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
-
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
- };
-
- template<typename StateTy>
- struct GraphTraits<const clang::ExplodedNode<StateTy>*> {
- typedef const clang::ExplodedNode<StateTy> NodeType;
- typedef typename NodeType::succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
-
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
-
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
-
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
- };
-
-} // end llvm namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRAuditor.h b/clang/include/clang/Analysis/PathSensitive/GRAuditor.h
deleted file mode 100644
index eca591d4af0e..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRAuditor.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//==- GRAuditor.h - Observers of the creation of ExplodedNodes------*- 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 GRAuditor and its primary subclasses, an interface
-// to audit the creation of ExplodedNodes. This interface can be used
-// to implement simple checkers that do not mutate analysis state but
-// instead operate by perfoming simple logical checks at key monitoring
-// locations (e.g., function calls).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRAUDITOR
-#define LLVM_CLANG_ANALYSIS_GRAUDITOR
-
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-
-namespace clang {
-
-template <typename STATE>
-class GRAuditor {
-public:
- typedef ExplodedNode<STATE> NodeTy;
- typedef typename STATE::ManagerTy ManagerTy;
-
- virtual ~GRAuditor() {}
- virtual bool Audit(NodeTy* N, ManagerTy& M) = 0;
-};
-
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRBlockCounter.h b/clang/include/clang/Analysis/PathSensitive/GRBlockCounter.h
deleted file mode 100644
index b4fd2704b81a..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRBlockCounter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//==- GRBlockCounter.h - ADT for counting block visits -------------*- 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 GRBlockCounter, an abstract data type used to count
-// the number of times a given block has been visited along a path
-// analyzed by GRCoreEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
-#define LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
-
-namespace llvm {
- class BumpPtrAllocator;
-}
-
-namespace clang {
-
-class GRBlockCounter {
- void* Data;
-
- GRBlockCounter(void* D) : Data(D) {}
-
-public:
- GRBlockCounter() : Data(0) {}
-
- unsigned getNumVisited(unsigned BlockID) const;
-
- class Factory {
- void* F;
- public:
- Factory(llvm::BumpPtrAllocator& Alloc);
- ~Factory();
-
- GRBlockCounter GetEmptyCounter();
- GRBlockCounter IncrementCount(GRBlockCounter BC, unsigned BlockID);
- };
-
- friend class Factory;
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h
deleted file mode 100644
index 74311249b32d..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ /dev/null
@@ -1,639 +0,0 @@
-//==- GRCoreEngine.h - Path-Sensitive Dataflow Engine ------------------*- 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 a generic engine for intraprocedural, path-sensitive,
-// dataflow analysis via graph reachability.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRENGINE
-#define LLVM_CLANG_ANALYSIS_GRENGINE
-
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/GRWorkList.h"
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
-#include "clang/Analysis/PathSensitive/GRAuditor.h"
-#include "llvm/ADT/OwningPtr.h"
-
-namespace clang {
-
-class GRStmtNodeBuilderImpl;
-class GRBranchNodeBuilderImpl;
-class GRIndirectGotoNodeBuilderImpl;
-class GRSwitchNodeBuilderImpl;
-class GREndPathNodeBuilderImpl;
-class GRWorkList;
-
-//===----------------------------------------------------------------------===//
-/// GRCoreEngineImpl - Implements the core logic of the graph-reachability
-/// analysis. It traverses the CFG and generates the ExplodedGraph.
-/// Program "states" are treated as opaque void pointers.
-/// The template class GRCoreEngine (which subclasses GRCoreEngineImpl)
-/// provides the matching component to the engine that knows the actual types
-/// for states. Note that this engine only dispatches to transfer functions
-/// at the statement and block-level. The analyses themselves must implement
-/// any transfer function logic and the sub-expression level (if any).
-class GRCoreEngineImpl {
-protected:
- friend class GRStmtNodeBuilderImpl;
- friend class GRBranchNodeBuilderImpl;
- friend class GRIndirectGotoNodeBuilderImpl;
- friend class GRSwitchNodeBuilderImpl;
- friend class GREndPathNodeBuilderImpl;
-
- /// G - The simulation graph. Each node is a (location,state) pair.
- llvm::OwningPtr<ExplodedGraphImpl> G;
-
- /// WList - A set of queued nodes that need to be processed by the
- /// worklist algorithm. It is up to the implementation of WList to decide
- /// the order that nodes are processed.
- GRWorkList* WList;
-
- /// BCounterFactory - A factory object for created GRBlockCounter objects.
- /// These are used to record for key nodes in the ExplodedGraph the
- /// number of times different CFGBlocks have been visited along a path.
- GRBlockCounter::Factory BCounterFactory;
-
- void GenerateNode(const ProgramPoint& Loc, const void* State,
- ExplodedNodeImpl* Pred);
-
- /// getInitialState - Gets the void* representing the initial 'state'
- /// of the analysis. This is simply a wrapper (implemented
- /// in GRCoreEngine) that performs type erasure on the initial
- /// state returned by the checker object.
- virtual const void* getInitialState() = 0;
-
- void HandleBlockEdge(const BlockEdge& E, ExplodedNodeImpl* Pred);
- void HandleBlockEntrance(const BlockEntrance& E, ExplodedNodeImpl* Pred);
- void HandleBlockExit(CFGBlock* B, ExplodedNodeImpl* Pred);
- void HandlePostStmt(const PostStmt& S, CFGBlock* B,
- unsigned StmtIdx, ExplodedNodeImpl *Pred);
-
- void HandleBranch(Expr* Cond, Stmt* Term, CFGBlock* B,
- ExplodedNodeImpl* Pred);
-
- virtual void ProcessEndPath(GREndPathNodeBuilderImpl& Builder) = 0;
-
- virtual bool ProcessBlockEntrance(CFGBlock* Blk, const void* State,
- GRBlockCounter BC) = 0;
-
- virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0;
-
- virtual void ProcessBranch(Expr* Condition, Stmt* Terminator,
- GRBranchNodeBuilderImpl& Builder) = 0;
-
- virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& Builder) = 0;
-
- virtual void ProcessSwitch(GRSwitchNodeBuilderImpl& Builder) = 0;
-
-private:
- GRCoreEngineImpl(const GRCoreEngineImpl&); // Do not implement.
- GRCoreEngineImpl& operator=(const GRCoreEngineImpl&);
-
-protected:
- GRCoreEngineImpl(ExplodedGraphImpl* g, GRWorkList* wl)
- : G(g), WList(wl), BCounterFactory(g->getAllocator()) {}
-
-public:
- /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
- /// steps. Returns true if there is still simulation state on the worklist.
- bool ExecuteWorkList(unsigned Steps);
-
- virtual ~GRCoreEngineImpl();
-
- CFG& getCFG() { return G->getCFG(); }
-};
-
-class GRStmtNodeBuilderImpl {
- GRCoreEngineImpl& Eng;
- CFGBlock& B;
- const unsigned Idx;
- ExplodedNodeImpl* Pred;
- ExplodedNodeImpl* LastNode;
-
- typedef llvm::SmallPtrSet<ExplodedNodeImpl*,5> DeferredTy;
- DeferredTy Deferred;
-
- void GenerateAutoTransition(ExplodedNodeImpl* N);
-
-public:
- GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
- ExplodedNodeImpl* N, GRCoreEngineImpl* e);
-
- ~GRStmtNodeBuilderImpl();
-
- ExplodedNodeImpl* getBasePredecessor() const { return Pred; }
-
- ExplodedNodeImpl* getLastNode() const {
- return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL;
- }
-
- GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
-
- unsigned getCurrentBlockCount() const {
- return getBlockCounter().getNumVisited(B.getBlockID());
- }
-
- ExplodedNodeImpl*
- generateNodeImpl(Stmt* S, const void* State, ExplodedNodeImpl* Pred,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind);
-
- ExplodedNodeImpl*
- generateNodeImpl(Stmt* S, const void* State,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
- ExplodedNodeImpl* N = getLastNode();
- assert (N && "Predecessor of new node is infeasible.");
- return generateNodeImpl(S, State, N, K);
- }
-
- /// getStmt - Return the current block-level expression associated with
- /// this builder.
- Stmt* getStmt() const { return B[Idx]; }
-
- /// getBlock - Return the CFGBlock associated with the block-level expression
- /// of this builder.
- CFGBlock* getBlock() const { return &B; }
-};
-
-
-template<typename STATE>
-class GRStmtNodeBuilder {
-public:
- typedef STATE StateTy;
- typedef typename StateTy::ManagerTy StateManagerTy;
- typedef ExplodedNode<StateTy> NodeTy;
-
-private:
- GRStmtNodeBuilderImpl& NB;
- StateManagerTy& Mgr;
- const StateTy* CleanedState;
- GRAuditor<StateTy>* Auditor;
-
-public:
- GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb, StateManagerTy& mgr) :
- NB(nb), Mgr(mgr), Auditor(0), PurgingDeadSymbols(false),
- BuildSinks(false), HasGeneratedNode(false),
- PointKind(ProgramPoint::PostStmtKind) {
-
- CleanedState = getLastNode()->getState();
- }
-
- void setAuditor(GRAuditor<StateTy>* A) {
- Auditor = A;
- }
-
- NodeTy* getLastNode() const {
- return static_cast<NodeTy*>(NB.getLastNode());
- }
-
- NodeTy* generateNode(Stmt* S, const StateTy* St, NodeTy* Pred,
- ProgramPoint::Kind K) {
- HasGeneratedNode = true;
- if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind;
- return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred, K));
- }
-
- NodeTy* generateNode(Stmt* S, const StateTy* St, NodeTy* Pred) {
- return generateNode(S, St, Pred, PointKind);
- }
-
- NodeTy* generateNode(Stmt* S, const StateTy* St, ProgramPoint::Kind K) {
- HasGeneratedNode = true;
- if (PurgingDeadSymbols) K = ProgramPoint::PostPurgeDeadSymbolsKind;
- return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, K));
- }
-
- NodeTy* generateNode(Stmt* S, const StateTy* St) {
- return generateNode(S, St, PointKind);
- }
-
-
- GRBlockCounter getBlockCounter() const {
- return NB.getBlockCounter();
- }
-
- unsigned getCurrentBlockCount() const {
- return NB.getCurrentBlockCount();
- }
-
- const StateTy* GetState(NodeTy* Pred) const {
- if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
- return CleanedState;
- else
- return Pred->getState();
- }
-
- void SetCleanedState(const StateTy* St) {
- CleanedState = St;
- }
-
- NodeTy* MakeNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
- NodeTy* Pred, const StateTy* St,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
-
- const StateTy* PredState = GetState(Pred);
-
- // If the state hasn't changed, don't generate a new node.
- if (!BuildSinks && St == PredState && Auditor == 0) {
- Dst.Add(Pred);
- return NULL;
- }
-
- NodeTy* N = generateNode(S, St, Pred, K);
-
- if (N) {
- if (BuildSinks)
- N->markAsSink();
- else {
- if (Auditor && Auditor->Audit(N, Mgr))
- N->markAsSink();
-
- Dst.Add(N);
- }
- }
-
- return N;
- }
-
- NodeTy* MakeSinkNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
- NodeTy* Pred, const StateTy* St) {
- bool Tmp = BuildSinks;
- BuildSinks = true;
- NodeTy* N = MakeNode(Dst, S, Pred, St);
- BuildSinks = Tmp;
- return N;
- }
-
- bool PurgingDeadSymbols;
- bool BuildSinks;
- bool HasGeneratedNode;
- ProgramPoint::Kind PointKind;
-};
-
-class GRBranchNodeBuilderImpl {
- GRCoreEngineImpl& Eng;
- CFGBlock* Src;
- CFGBlock* DstT;
- CFGBlock* DstF;
- ExplodedNodeImpl* Pred;
-
- typedef llvm::SmallVector<ExplodedNodeImpl*,3> DeferredTy;
- DeferredTy Deferred;
-
- bool GeneratedTrue;
- bool GeneratedFalse;
-
-public:
- GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
- ExplodedNodeImpl* pred, GRCoreEngineImpl* e)
- : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
- GeneratedTrue(false), GeneratedFalse(false) {}
-
- ~GRBranchNodeBuilderImpl();
-
- ExplodedNodeImpl* getPredecessor() const { return Pred; }
- const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
- GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
-
- ExplodedNodeImpl* generateNodeImpl(const void* State, bool branch);
-
- CFGBlock* getTargetBlock(bool branch) const {
- return branch ? DstT : DstF;
- }
-
- void markInfeasible(bool branch) {
- if (branch) GeneratedTrue = true;
- else GeneratedFalse = true;
- }
-};
-
-template<typename STATE>
-class GRBranchNodeBuilder {
- typedef STATE StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
- typedef typename GraphTy::NodeTy NodeTy;
-
- GRBranchNodeBuilderImpl& NB;
-
-public:
- GRBranchNodeBuilder(GRBranchNodeBuilderImpl& nb) : NB(nb) {}
-
- const GraphTy& getGraph() const {
- return static_cast<const GraphTy&>(NB.getGraph());
- }
-
- NodeTy* getPredecessor() const {
- return static_cast<NodeTy*>(NB.getPredecessor());
- }
-
- const StateTy* getState() const {
- return getPredecessor()->getState();
- }
-
- NodeTy* generateNode(const StateTy* St, bool branch) {
- return static_cast<NodeTy*>(NB.generateNodeImpl(St, branch));
- }
-
- GRBlockCounter getBlockCounter() const {
- return NB.getBlockCounter();
- }
-
- CFGBlock* getTargetBlock(bool branch) const {
- return NB.getTargetBlock(branch);
- }
-
- void markInfeasible(bool branch) {
- NB.markInfeasible(branch);
- }
-};
-
-class GRIndirectGotoNodeBuilderImpl {
- GRCoreEngineImpl& Eng;
- CFGBlock* Src;
- CFGBlock& DispatchBlock;
- Expr* E;
- ExplodedNodeImpl* Pred;
-public:
- GRIndirectGotoNodeBuilderImpl(ExplodedNodeImpl* pred, CFGBlock* src,
- Expr* e, CFGBlock* dispatch,
- GRCoreEngineImpl* eng)
- : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
-
-
- class Iterator {
- CFGBlock::succ_iterator I;
-
- friend class GRIndirectGotoNodeBuilderImpl;
- Iterator(CFGBlock::succ_iterator i) : I(i) {}
- public:
-
- Iterator& operator++() { ++I; return *this; }
- bool operator!=(const Iterator& X) const { return I != X.I; }
-
- LabelStmt* getLabel() const {
- return llvm::cast<LabelStmt>((*I)->getLabel());
- }
-
- CFGBlock* getBlock() const {
- return *I;
- }
- };
-
- Iterator begin() { return Iterator(DispatchBlock.succ_begin()); }
- Iterator end() { return Iterator(DispatchBlock.succ_end()); }
-
- ExplodedNodeImpl* generateNodeImpl(const Iterator& I, const void* State,
- bool isSink);
-
- Expr* getTarget() const { return E; }
- const void* getState() const { return Pred->State; }
-};
-
-template<typename STATE>
-class GRIndirectGotoNodeBuilder {
- typedef STATE StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
- typedef typename GraphTy::NodeTy NodeTy;
-
- GRIndirectGotoNodeBuilderImpl& NB;
-
-public:
- GRIndirectGotoNodeBuilder(GRIndirectGotoNodeBuilderImpl& nb) : NB(nb) {}
-
- typedef GRIndirectGotoNodeBuilderImpl::Iterator iterator;
-
- iterator begin() { return NB.begin(); }
- iterator end() { return NB.end(); }
-
- Expr* getTarget() const { return NB.getTarget(); }
-
- NodeTy* generateNode(const iterator& I, const StateTy* St, bool isSink=false){
- return static_cast<NodeTy*>(NB.generateNodeImpl(I, St, isSink));
- }
-
- const StateTy* getState() const {
- return static_cast<const StateTy*>(NB.getState());
- }
-};
-
-class GRSwitchNodeBuilderImpl {
- GRCoreEngineImpl& Eng;
- CFGBlock* Src;
- Expr* Condition;
- ExplodedNodeImpl* Pred;
-public:
- GRSwitchNodeBuilderImpl(ExplodedNodeImpl* pred, CFGBlock* src,
- Expr* condition, GRCoreEngineImpl* eng)
- : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
-
- class Iterator {
- CFGBlock::succ_reverse_iterator I;
-
- friend class GRSwitchNodeBuilderImpl;
- Iterator(CFGBlock::succ_reverse_iterator i) : I(i) {}
- public:
-
- Iterator& operator++() { ++I; return *this; }
- bool operator!=(const Iterator& X) const { return I != X.I; }
-
- CaseStmt* getCase() const {
- return llvm::cast<CaseStmt>((*I)->getLabel());
- }
-
- CFGBlock* getBlock() const {
- return *I;
- }
- };
-
- Iterator begin() { return Iterator(Src->succ_rbegin()+1); }
- Iterator end() { return Iterator(Src->succ_rend()); }
-
- ExplodedNodeImpl* generateCaseStmtNodeImpl(const Iterator& I,
- const void* State);
-
- ExplodedNodeImpl* generateDefaultCaseNodeImpl(const void* State,
- bool isSink);
-
- Expr* getCondition() const { return Condition; }
- const void* getState() const { return Pred->State; }
-};
-
-template<typename STATE>
-class GRSwitchNodeBuilder {
- typedef STATE StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
- typedef typename GraphTy::NodeTy NodeTy;
-
- GRSwitchNodeBuilderImpl& NB;
-
-public:
- GRSwitchNodeBuilder(GRSwitchNodeBuilderImpl& nb) : NB(nb) {}
-
- typedef GRSwitchNodeBuilderImpl::Iterator iterator;
-
- iterator begin() { return NB.begin(); }
- iterator end() { return NB.end(); }
-
- Expr* getCondition() const { return NB.getCondition(); }
-
- NodeTy* generateCaseStmtNode(const iterator& I, const StateTy* St) {
- return static_cast<NodeTy*>(NB.generateCaseStmtNodeImpl(I, St));
- }
-
- NodeTy* generateDefaultCaseNode(const StateTy* St, bool isSink = false) {
- return static_cast<NodeTy*>(NB.generateDefaultCaseNodeImpl(St, isSink));
- }
-
- const StateTy* getState() const {
- return static_cast<const StateTy*>(NB.getState());
- }
-};
-
-
-class GREndPathNodeBuilderImpl {
- GRCoreEngineImpl& Eng;
- CFGBlock& B;
- ExplodedNodeImpl* Pred;
- bool HasGeneratedNode;
-
-public:
- GREndPathNodeBuilderImpl(CFGBlock* b, ExplodedNodeImpl* N,
- GRCoreEngineImpl* e)
- : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
-
- ~GREndPathNodeBuilderImpl();
-
- ExplodedNodeImpl* getPredecessor() const { return Pred; }
-
- GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
-
- unsigned getCurrentBlockCount() const {
- return getBlockCounter().getNumVisited(B.getBlockID());
- }
-
- ExplodedNodeImpl* generateNodeImpl(const void* State);
-
- CFGBlock* getBlock() const { return &B; }
-};
-
-
-template<typename STATE>
-class GREndPathNodeBuilder {
- typedef STATE StateTy;
- typedef ExplodedNode<StateTy> NodeTy;
-
- GREndPathNodeBuilderImpl& NB;
-
-public:
- GREndPathNodeBuilder(GREndPathNodeBuilderImpl& nb) : NB(nb) {}
-
- NodeTy* getPredecessor() const {
- return static_cast<NodeTy*>(NB.getPredecessor());
- }
-
- GRBlockCounter getBlockCounter() const {
- return NB.getBlockCounter();
- }
-
- unsigned getCurrentBlockCount() const {
- return NB.getCurrentBlockCount();
- }
-
- const StateTy* getState() const {
- return getPredecessor()->getState();
- }
-
- NodeTy* MakeNode(const StateTy* St) {
- return static_cast<NodeTy*>(NB.generateNodeImpl(St));
- }
-};
-
-
-template<typename SUBENGINE>
-class GRCoreEngine : public GRCoreEngineImpl {
-public:
- typedef SUBENGINE SubEngineTy;
- typedef typename SubEngineTy::StateTy StateTy;
- typedef typename StateTy::ManagerTy StateManagerTy;
- typedef ExplodedGraph<StateTy> GraphTy;
- typedef typename GraphTy::NodeTy NodeTy;
-
-protected:
- SubEngineTy& SubEngine;
-
- virtual const void* getInitialState() {
- return SubEngine.getInitialState();
- }
-
- virtual void ProcessEndPath(GREndPathNodeBuilderImpl& BuilderImpl) {
- GREndPathNodeBuilder<StateTy> Builder(BuilderImpl);
- SubEngine.ProcessEndPath(Builder);
- }
-
- virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& BuilderImpl) {
- GRStmtNodeBuilder<StateTy> Builder(BuilderImpl,SubEngine.getStateManager());
- SubEngine.ProcessStmt(S, Builder);
- }
-
- virtual bool ProcessBlockEntrance(CFGBlock* Blk, const void* State,
- GRBlockCounter BC) {
- return SubEngine.ProcessBlockEntrance(Blk,
- static_cast<const StateTy*>(State),
- BC);
- }
-
- virtual void ProcessBranch(Expr* Condition, Stmt* Terminator,
- GRBranchNodeBuilderImpl& BuilderImpl) {
- GRBranchNodeBuilder<StateTy> Builder(BuilderImpl);
- SubEngine.ProcessBranch(Condition, Terminator, Builder);
- }
-
- virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& BuilderImpl) {
- GRIndirectGotoNodeBuilder<StateTy> Builder(BuilderImpl);
- SubEngine.ProcessIndirectGoto(Builder);
- }
-
- virtual void ProcessSwitch(GRSwitchNodeBuilderImpl& BuilderImpl) {
- GRSwitchNodeBuilder<StateTy> Builder(BuilderImpl);
- SubEngine.ProcessSwitch(Builder);
- }
-
-public:
- /// Construct a GRCoreEngine object to analyze the provided CFG using
- /// a DFS exploration of the exploded graph.
- GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, SubEngineTy& subengine)
- : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), GRWorkList::MakeDFS()),
- SubEngine(subengine) {}
-
- /// Construct a GRCoreEngine object to analyze the provided CFG and to
- /// use the provided worklist object to execute the worklist algorithm.
- /// The GRCoreEngine object assumes ownership of 'wlist'.
- GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRWorkList* wlist,
- SubEngineTy& subengine)
- : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), wlist),
- SubEngine(subengine) {}
-
- virtual ~GRCoreEngine() {}
-
- /// getGraph - Returns the exploded graph.
- GraphTy& getGraph() {
- return *static_cast<GraphTy*>(G.get());
- }
-
- /// takeGraph - Returns the exploded graph. Ownership of the graph is
- /// transfered to the caller.
- GraphTy* takeGraph() {
- return static_cast<GraphTy*>(G.take());
- }
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h
deleted file mode 100644
index 0bcc13781f8f..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ /dev/null
@@ -1,645 +0,0 @@
-//===-- GRExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- 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 a meta-engine for path-sensitive dataflow analysis that
-// is built on GREngine, but provides the boilerplate to execute transfer
-// functions and build the ExplodedGraph at the expression level.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
-#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
-
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/ExprObjC.h"
-
-namespace clang {
-
- class BugType;
- class PathDiagnosticClient;
- class Diagnostic;
- class BugReporterData;
-
-class GRExprEngine {
-
-public:
- typedef GRState StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
- typedef GraphTy::NodeTy NodeTy;
-
- // Builders.
- typedef GRStmtNodeBuilder<StateTy> StmtNodeBuilder;
- typedef GRBranchNodeBuilder<StateTy> BranchNodeBuilder;
- typedef GRIndirectGotoNodeBuilder<StateTy> IndirectGotoNodeBuilder;
- typedef GRSwitchNodeBuilder<StateTy> SwitchNodeBuilder;
- typedef GREndPathNodeBuilder<StateTy> EndPathNodeBuilder;
- typedef ExplodedNodeSet<StateTy> NodeSet;
-
-
-protected:
- GRCoreEngine<GRExprEngine> CoreEngine;
-
- /// G - the simulation graph.
- GraphTy& G;
-
- /// Liveness - live-variables information the ValueDecl* and block-level
- /// Expr* in the CFG. Used to prune out dead state.
- LiveVariables& Liveness;
-
- /// DeadSymbols - A scratch set used to record the set of symbols that
- /// were just marked dead by a call to GRStateManager::RemoveDeadBindings.
- GRStateManager::DeadSymbolsTy DeadSymbols;
-
- /// Builder - The current GRStmtNodeBuilder which is used when building the
- /// nodes for a given statement.
- StmtNodeBuilder* Builder;
-
- /// StateMgr - Object that manages the data for all created states.
- GRStateManager StateMgr;
-
- /// BugTypes - Objects used for reporting bugs.
- typedef std::vector<BugType*> BugTypeSet;
- BugTypeSet BugTypes;
-
- /// SymMgr - Object that manages the symbol information.
- SymbolManager& SymMgr;
-
- /// EntryNode - The immediate predecessor node.
- NodeTy* EntryNode;
-
- /// CleanedState - The state for EntryNode "cleaned" of all dead
- /// variables and symbols (as determined by a liveness analysis).
- const GRState* CleanedState;
-
- /// CurrentStmt - The current block-level statement.
- Stmt* CurrentStmt;
-
- // Obj-C Class Identifiers.
- IdentifierInfo* NSExceptionII;
-
- // Obj-C Selectors.
- Selector* NSExceptionInstanceRaiseSelectors;
- Selector RaiseSel;
-
- llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
-
-public:
- typedef llvm::SmallPtrSet<NodeTy*,2> UndefBranchesTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> BadCallsTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> UndefReceiversTy;
- typedef llvm::DenseMap<NodeTy*, Expr*> UndefArgsTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;
- typedef llvm::SmallPtrSet<NodeTy*,2> RetsStackAddrTy;
-
-protected:
-
- /// RetsStackAddr - Nodes in the ExplodedGraph that result from returning
- /// the address of a stack variable.
- RetsStackAddrTy RetsStackAddr;
-
- /// UndefBranches - Nodes in the ExplodedGraph that result from
- /// taking a branch based on an undefined value.
- UndefBranchesTy UndefBranches;
-
- /// UndefStores - Sinks in the ExplodedGraph that result from
- /// making a store to an undefined lvalue.
- UndefStoresTy UndefStores;
-
- /// NoReturnCalls - Sinks in the ExplodedGraph that result from
- // calling a function with the attribute "noreturn".
- NoReturnCallsTy NoReturnCalls;
-
- /// ImplicitNullDeref - Nodes in the ExplodedGraph that result from
- /// taking a dereference on a symbolic pointer that MAY be NULL.
- BadDerefTy ImplicitNullDeref;
-
- /// ExplicitNullDeref - Nodes in the ExplodedGraph that result from
- /// taking a dereference on a symbolic pointer that MUST be NULL.
- BadDerefTy ExplicitNullDeref;
-
- /// UnitDeref - Nodes in the ExplodedGraph that result from
- /// taking a dereference on an undefined value.
- BadDerefTy UndefDeref;
-
- /// ImplicitBadDivides - Nodes in the ExplodedGraph that result from
- /// evaluating a divide or modulo operation where the denominator
- /// MAY be zero.
- BadDividesTy ImplicitBadDivides;
-
- /// ExplicitBadDivides - Nodes in the ExplodedGraph that result from
- /// evaluating a divide or modulo operation where the denominator
- /// MUST be zero or undefined.
- BadDividesTy ExplicitBadDivides;
-
- /// UndefResults - Nodes in the ExplodedGraph where the operands are defined
- /// by the result is not. Excludes divide-by-zero errors.
- UndefResultsTy UndefResults;
-
- /// BadCalls - Nodes in the ExplodedGraph resulting from calls to function
- /// pointers that are NULL (or other constants) or Undefined.
- BadCallsTy BadCalls;
-
- /// UndefReceiver - Nodes in the ExplodedGraph resulting from message
- /// ObjC message expressions where the receiver is undefined (uninitialized).
- UndefReceiversTy UndefReceivers;
-
- /// UndefArg - Nodes in the ExplodedGraph resulting from calls to functions
- /// where a pass-by-value argument has an undefined value.
- UndefArgsTy UndefArgs;
-
- /// MsgExprUndefArgs - Nodes in the ExplodedGraph resulting from
- /// message expressions where a pass-by-value argument has an undefined
- /// value.
- UndefArgsTy MsgExprUndefArgs;
-
-public:
- GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L);
- ~GRExprEngine();
-
- void ExecuteWorkList(unsigned Steps = 150000) {
- CoreEngine.ExecuteWorkList(Steps);
- }
-
- /// getContext - Return the ASTContext associated with this analysis.
- ASTContext& getContext() const { return G.getContext(); }
-
- /// getCFG - Returns the CFG associated with this analysis.
- CFG& getCFG() { return G.getCFG(); }
-
- GRTransferFuncs& getTF() { return *StateMgr.TF; }
-
- /// setTransferFunctions
- void setTransferFunctions(GRTransferFuncs* tf);
-
- void setTransferFunctions(GRTransferFuncs& tf) {
- setTransferFunctions(&tf);
- }
-
- /// ViewGraph - Visualize the ExplodedGraph created by executing the
- /// simulation.
- void ViewGraph(bool trim = false);
-
- void ViewGraph(NodeTy** Beg, NodeTy** End);
-
- /// getLiveness - Returned computed live-variables information for the
- /// analyzed function.
- const LiveVariables& getLiveness() const { return Liveness; }
- LiveVariables& getLiveness() { return Liveness; }
-
- /// getInitialState - Return the initial state used for the root vertex
- /// in the ExplodedGraph.
- const GRState* getInitialState();
-
- GraphTy& getGraph() { return G; }
- const GraphTy& getGraph() const { return G; }
-
- typedef BugTypeSet::iterator bug_type_iterator;
- typedef BugTypeSet::const_iterator const_bug_type_iterator;
-
- bug_type_iterator bug_types_begin() { return BugTypes.begin(); }
- bug_type_iterator bug_types_end() { return BugTypes.end(); }
-
- const_bug_type_iterator bug_types_begin() const { return BugTypes.begin(); }
- const_bug_type_iterator bug_types_end() const { return BugTypes.end(); }
-
- /// Register - Register a BugType with the analyzer engine. A registered
- /// BugType object will have its 'EmitWarnings' method called when the
- /// the analyzer finishes analyzing a method or function.
- void Register(BugType* B) {
- BugTypes.push_back(B);
- }
-
- void RegisterInternalChecks();
-
- void EmitWarnings(BugReporterData& BRData);
-
- bool isRetStackAddr(const NodeTy* N) const {
- return N->isSink() && RetsStackAddr.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isUndefControlFlow(const NodeTy* N) const {
- return N->isSink() && UndefBranches.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isUndefStore(const NodeTy* N) const {
- return N->isSink() && UndefStores.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isImplicitNullDeref(const NodeTy* N) const {
- return N->isSink() && ImplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isExplicitNullDeref(const NodeTy* N) const {
- return N->isSink() && ExplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isUndefDeref(const NodeTy* N) const {
- return N->isSink() && UndefDeref.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isImplicitBadDivide(const NodeTy* N) const {
- return N->isSink() && ImplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isExplicitBadDivide(const NodeTy* N) const {
- return N->isSink() && ExplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isNoReturnCall(const NodeTy* N) const {
- return N->isSink() && NoReturnCalls.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isUndefResult(const NodeTy* N) const {
- return N->isSink() && UndefResults.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isBadCall(const NodeTy* N) const {
- return N->isSink() && BadCalls.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- bool isUndefArg(const NodeTy* N) const {
- return N->isSink() &&
- (UndefArgs.find(const_cast<NodeTy*>(N)) != UndefArgs.end() ||
- MsgExprUndefArgs.find(const_cast<NodeTy*>(N)) != MsgExprUndefArgs.end());
- }
-
- bool isUndefReceiver(const NodeTy* N) const {
- return N->isSink() && UndefReceivers.count(const_cast<NodeTy*>(N)) != 0;
- }
-
- typedef RetsStackAddrTy::iterator ret_stackaddr_iterator;
- ret_stackaddr_iterator ret_stackaddr_begin() { return RetsStackAddr.begin(); }
- ret_stackaddr_iterator ret_stackaddr_end() { return RetsStackAddr.end(); }
-
- typedef UndefBranchesTy::iterator undef_branch_iterator;
- undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
- undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }
-
- typedef BadDerefTy::iterator null_deref_iterator;
- null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); }
- null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); }
-
- null_deref_iterator implicit_null_derefs_begin() {
- return ImplicitNullDeref.begin();
- }
- null_deref_iterator implicit_null_derefs_end() {
- return ImplicitNullDeref.end();
- }
-
- typedef BadDerefTy::iterator undef_deref_iterator;
- undef_deref_iterator undef_derefs_begin() { return UndefDeref.begin(); }
- undef_deref_iterator undef_derefs_end() { return UndefDeref.end(); }
-
- typedef BadDividesTy::iterator bad_divide_iterator;
-
- bad_divide_iterator explicit_bad_divides_begin() {
- return ExplicitBadDivides.begin();
- }
-
- bad_divide_iterator explicit_bad_divides_end() {
- return ExplicitBadDivides.end();
- }
-
- bad_divide_iterator implicit_bad_divides_begin() {
- return ImplicitBadDivides.begin();
- }
-
- bad_divide_iterator implicit_bad_divides_end() {
- return ImplicitBadDivides.end();
- }
-
- typedef UndefResultsTy::iterator undef_result_iterator;
- undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
- undef_result_iterator undef_results_end() { return UndefResults.end(); }
-
- typedef BadCallsTy::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 undef_arg_begin() { return UndefArgs.begin(); }
- undef_arg_iterator undef_arg_end() { return UndefArgs.end(); }
-
- undef_arg_iterator msg_expr_undef_arg_begin() {
- return MsgExprUndefArgs.begin();
- }
- undef_arg_iterator msg_expr_undef_arg_end() {
- return MsgExprUndefArgs.end();
- }
-
- typedef UndefReceiversTy::iterator undef_receivers_iterator;
-
- undef_receivers_iterator undef_receivers_begin() {
- return UndefReceivers.begin();
- }
-
- undef_receivers_iterator undef_receivers_end() {
- return UndefReceivers.end();
- }
-
- void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
-
- /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
- /// nodes by processing the 'effects' of a block-level statement.
- void ProcessStmt(Stmt* S, StmtNodeBuilder& builder);
-
- /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
- /// a CFGBlock. This method returns true if the analysis should continue
- /// exploring the given path, and false otherwise.
- bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
- GRBlockCounter BC);
-
- /// ProcessBranch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a branch condition.
- void ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder);
-
- /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a computed goto jump.
- void ProcessIndirectGoto(IndirectGotoNodeBuilder& builder);
-
- /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a switch statement.
- void ProcessSwitch(SwitchNodeBuilder& builder);
-
- /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
- /// nodes when the control reaches the end of a function.
- void ProcessEndPath(EndPathNodeBuilder& builder) {
- getTF().EvalEndPath(*this, builder);
- }
-
- GRStateManager& getStateManager() { return StateMgr; }
- const GRStateManager& getStateManger() const { return StateMgr; }
-
- BasicValueFactory& getBasicVals() {
- return StateMgr.getBasicVals();
- }
- const BasicValueFactory& getBasicVals() const {
- return StateMgr.getBasicVals();
- }
-
- SymbolManager& getSymbolManager() { return SymMgr; }
- const SymbolManager& getSymbolManager() const { return SymMgr; }
-
-protected:
-
- const GRState* GetState(NodeTy* N) {
- return N == EntryNode ? CleanedState : N->getState();
- }
-
-public:
-
- const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V) {
- return StateMgr.SetRVal(St, Ex, V);
- }
-
- const GRState* SetRVal(const GRState* St, const Expr* Ex, RVal V) {
- return SetRVal(St, const_cast<Expr*>(Ex), V);
- }
-
- LVal getLVal(VarDecl* V) {
- return getStateManager().getLVal(V);
- }
-
-protected:
-
- const GRState* SetBlkExprRVal(const GRState* St, Expr* Ex, RVal V) {
- return StateMgr.SetRVal(St, Ex, V, true, false);
- }
-
- const GRState* SetRVal(const GRState* St, LVal LV, RVal V) {
- return StateMgr.SetRVal(St, LV, V);
- }
-
- RVal GetRVal(const GRState* St, Expr* Ex) {
- return StateMgr.GetRVal(St, Ex);
- }
-
- RVal GetRVal(const GRState* St, const Expr* Ex) {
- return GetRVal(St, const_cast<Expr*>(Ex));
- }
-
- RVal GetBlkExprRVal(const GRState* St, Expr* Ex) {
- return StateMgr.GetBlkExprRVal(St, Ex);
- }
-
- RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
- return StateMgr.GetRVal(St, LV, T);
- }
-
- inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
- return NonLVal::MakeVal(getBasicVals(), X, Ex->getType());
- }
-
- /// Assume - Create new state by assuming that a given expression
- /// is true or false.
- const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
- bool& isFeasible) {
- return StateMgr.Assume(St, Cond, Assumption, isFeasible);
- }
-
- const GRState* Assume(const GRState* St, LVal Cond, bool Assumption,
- bool& isFeasible) {
- return StateMgr.Assume(St, Cond, Assumption, isFeasible);
- }
-
- NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
- assert (Builder && "GRStmtNodeBuilder not present.");
- return Builder->MakeNode(Dst, S, Pred, St, K);
- }
-
- /// Visit - Transfer function logic for all statements. Dispatches to
- /// other functions that handle specific kinds of statements.
- void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitLVal - Similar to Visit, but the specified expression is assummed
- /// to be evaluated under the context where it evaluates to an LVal. For
- /// example, if Ex is a DeclRefExpr, under Visit Ex would evaluate to the
- /// value bound to Ex in the symbolic state, while under VisitLVal it would
- /// evaluate to an LVal representing the location of the referred Decl.
- void VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitArraySubscriptExpr - Transfer function for array accesses.
- void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, NodeTy* Pred,
- NodeSet& Dst, bool asLVal);
-
- /// VisitAsmStmt - Transfer function logic for inline asm.
- void VisitAsmStmt(AsmStmt* A, NodeTy* Pred, NodeSet& Dst);
-
- void VisitAsmStmtHelperOutputs(AsmStmt* A,
- AsmStmt::outputs_iterator I,
- AsmStmt::outputs_iterator E,
- NodeTy* Pred, NodeSet& Dst);
-
- void VisitAsmStmtHelperInputs(AsmStmt* A,
- AsmStmt::inputs_iterator I,
- AsmStmt::inputs_iterator E,
- NodeTy* Pred, NodeSet& Dst);
-
- /// VisitBinaryOperator - Transfer function logic for binary operators.
- void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
-
-
- /// VisitCall - Transfer function for function calls.
- void VisitCall(CallExpr* CE, NodeTy* Pred,
- CallExpr::arg_iterator AI, CallExpr::arg_iterator AE,
- NodeSet& Dst);
-
- /// VisitCast - Transfer function logic for all casts (implicit and explicit).
- void VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
- void VisitDeclRefExpr(DeclRefExpr* DR, NodeTy* Pred, NodeSet& Dst,
- bool asLval);
-
- /// VisitDeclStmt - Transfer function logic for DeclStmts.
- void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
- void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitLogicalExpr - Transfer function logic for '&&', '||'
- void VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitMemberExpr - Transfer function for member expressions.
- void VisitMemberExpr(MemberExpr* M, NodeTy* Pred, NodeSet& Dst, bool asLVal);
-
- /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
- void VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred, NodeSet& Dst);
-
- void VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
- ObjCMessageExpr::arg_iterator I,
- ObjCMessageExpr::arg_iterator E,
- NodeTy* Pred, NodeSet& Dst);
-
- void VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, NodeTy* Pred,
- NodeSet& Dst);
-
- /// VisitReturnStmt - Transfer function logic for return statements.
- void VisitReturnStmt(ReturnStmt* R, NodeTy* Pred, NodeSet& Dst);
-
- /// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type).
- void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex, NodeTy* Pred,
- NodeSet& Dst);
-
- /// VisitUnaryOperator - Transfer function logic for unary operators.
- void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst,
- bool asLVal);
-
- bool CheckDivideZero(Expr* Ex, const GRState* St, NodeTy* Pred,
- RVal Denom);
-
- RVal EvalCast(RVal X, QualType CastT) {
- if (X.isUnknownOrUndef())
- return X;
-
- if (isa<LVal>(X))
- return getTF().EvalCast(*this, cast<LVal>(X), CastT);
- else
- return getTF().EvalCast(*this, cast<NonLVal>(X), CastT);
- }
-
- RVal EvalMinus(UnaryOperator* U, RVal X) {
- return X.isValid() ? getTF().EvalMinus(*this, U, cast<NonLVal>(X)) : X;
- }
-
- RVal EvalComplement(RVal X) {
- return X.isValid() ? getTF().EvalComplement(*this, cast<NonLVal>(X)) : X;
- }
-
- RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, NonLVal R) {
- return R.isValid() ? getTF().DetermEvalBinOpNN(getStateManager(), Op, L, R)
- : R;
- }
-
- RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, RVal R) {
- return R.isValid() ? getTF().DetermEvalBinOpNN(getStateManager(), Op, L,
- cast<NonLVal>(R)) : R;
- }
-
- void EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
- BinaryOperator::Opcode Op, NonLVal L, NonLVal R,
- ExplodedNode<GRState>* Pred);
-
- void EvalBinOp(GRStateSet& OStates, const GRState* St, Expr* Ex,
- BinaryOperator::Opcode Op, NonLVal L, NonLVal R);
-
- RVal EvalBinOp(BinaryOperator::Opcode Op, RVal L, RVal R) {
-
- if (L.isUndef() || R.isUndef())
- return UndefinedVal();
-
- if (L.isUnknown() || R.isUnknown())
- return UnknownVal();
-
- if (isa<LVal>(L)) {
- if (isa<LVal>(R))
- return getTF().EvalBinOp(*this, Op, cast<LVal>(L), cast<LVal>(R));
- else
- return getTF().EvalBinOp(*this, Op, cast<LVal>(L), cast<NonLVal>(R));
- }
-
- if (isa<LVal>(R)) {
- // Support pointer arithmetic where the increment/decrement operand
- // is on the left and the pointer on the right.
-
- assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
-
- // Commute the operands.
- return getTF().EvalBinOp(*this, Op, cast<LVal>(R),
- cast<NonLVal>(L));
- }
- else
- return getTF().DetermEvalBinOpNN(getStateManager(), Op, cast<NonLVal>(L),
- cast<NonLVal>(R));
- }
-
-
- void EvalCall(NodeSet& Dst, CallExpr* CE, RVal L, NodeTy* Pred) {
- assert (Builder && "GRStmtNodeBuilder must be defined.");
- getTF().EvalCall(Dst, *this, *Builder, CE, L, Pred);
- }
-
- void EvalObjCMessageExpr(NodeSet& Dst, ObjCMessageExpr* ME, NodeTy* Pred) {
- assert (Builder && "GRStmtNodeBuilder must be defined.");
- getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
- }
-
- void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, const GRState* St,
- RVal TargetLV, RVal Val);
-
- void EvalStore(NodeSet& Dst, Expr* E, Expr* StoreE, NodeTy* Pred,
- const GRState* St, RVal TargetLV, RVal Val);
-
- // FIXME: The "CheckOnly" option exists only because Array and Field
- // loads aren't fully implemented. Eventually this option will go away.
-
- void EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
- const GRState* St, RVal location, bool CheckOnly = false);
-
- const GRState* EvalLocation(Expr* Ex, NodeTy* Pred,
- const GRState* St, RVal location,
- bool isLoad = false);
-
- void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred);
-
- const GRState* MarkBranch(const GRState* St, Stmt* Terminator, bool branchTaken);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h b/clang/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
deleted file mode 100644
index 66b2fb1ae8c8..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// GRCheckAPI.h - Simple API checks based on GRAuditor ------------*- 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 interface for building simple, path-sensitive checks
-// that are stateless and only emit warnings at errors that occur at
-// CallExpr or ObjCMessageExpr.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS
-#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
-
-#include "clang/Analysis/PathSensitive/GRAuditor.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-
-namespace clang {
-
-class Diagnostic;
-class BugReporter;
-class ASTContext;
-class GRExprEngine;
-class PathDiagnosticClient;
-template <typename T> class ExplodedGraph;
-
-
-class GRSimpleAPICheck : public GRAuditor<GRState> {
-public:
- GRSimpleAPICheck() {}
- virtual ~GRSimpleAPICheck() {}
- virtual void EmitWarnings(BugReporter& BR) = 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h
deleted file mode 100644
index 54731b27b8c0..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRState.h
+++ /dev/null
@@ -1,584 +0,0 @@
-//== GRState*h - Path-Sens. "State" for tracking valuues -----*- 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 SymbolID, ExprBindKey, and GRState*
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
-#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
-
-// FIXME: Reduce the number of includes.
-
-#include "clang/Analysis/PathSensitive/Environment.h"
-#include "clang/Analysis/PathSensitive/Store.h"
-#include "clang/Analysis/PathSensitive/ConstraintManager.h"
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-#include "clang/Analysis/PathSensitive/RValues.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Streams.h"
-
-#include <functional>
-
-namespace clang {
-
-class GRStateManager;
-class GRTransferFuncs;
-
-//===----------------------------------------------------------------------===//
-// GRStateTrait - Traits used by the Generic Data Map of a GRState.
-//===----------------------------------------------------------------------===//
-
-template <typename T> struct GRStatePartialTrait;
-
-template <typename T> struct GRStateTrait {
- typedef typename T::data_type data_type;
- static inline void* GDMIndex() { return &T::TagInt; }
- static inline void* MakeVoidPtr(data_type D) { return (void*) D; }
- static inline data_type MakeData(void* const* P) {
- return P ? (data_type) *P : (data_type) 0;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to RVals.
-//===----------------------------------------------------------------------===//
-
-/// GRState - This class encapsulates the actual data values for
-/// for a "state" in our symbolic value tracking. It is intended to be
-/// used as a functional object; that is once it is created and made
-/// "persistent" in a FoldingSet its values will never change.
-class GRState : public llvm::FoldingSetNode {
-public:
- // Typedefs.
- typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
- typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
-
- typedef GRStateManager ManagerTy;
-
-private:
- void operator=(const GRState& R) const;
-
- friend class GRStateManager;
-
- Environment Env;
- Store St;
-
- // FIXME: Make these private.
-public:
- GenericDataMap GDM;
-
-public:
-
- /// This ctor is used when creating the first GRState object.
- GRState(const Environment& env, Store st, GenericDataMap gdm)
- : Env(env),
- St(st),
- GDM(gdm) {}
-
- /// Copy ctor - We must explicitly define this or else the "Next" ptr
- /// in FoldingSetNode will also get copied.
- GRState(const GRState& RHS)
- : llvm::FoldingSetNode(),
- Env(RHS.Env),
- St(RHS.St),
- GDM(RHS.GDM) {}
-
- /// getEnvironment - Return the environment associated with this state.
- /// The environment is the mapping from expressions to values.
- const Environment& getEnvironment() const { return Env; }
-
- /// getStore - Return the store associated with this state. The store
- /// is a mapping from locations to values.
- Store getStore() const { return St; }
-
- /// getGDM - Return the generic data map associated with this state.
- GenericDataMap getGDM() const { return GDM; }
-
- /// Profile - Profile the contents of a GRState object for use
- /// in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
- V->Env.Profile(ID);
- ID.AddPointer(V->St);
- V->GDM.Profile(ID);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- RVal LookupExpr(Expr* E) const {
- return Env.LookupExpr(E);
- }
-
- // Iterators.
- typedef Environment::seb_iterator seb_iterator;
- seb_iterator seb_begin() const { return Env.seb_begin(); }
- seb_iterator seb_end() const { return Env.beb_end(); }
-
- typedef Environment::beb_iterator beb_iterator;
- beb_iterator beb_begin() const { return Env.beb_begin(); }
- beb_iterator beb_end() const { return Env.beb_end(); }
-
- // Trait based GDM dispatch.
- void* const* FindGDM(void* K) const;
-
- template <typename T>
- typename GRStateTrait<T>::data_type
- get() const {
- return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex()));
- }
-
- template<typename T>
- typename GRStateTrait<T>::lookup_type
- get(typename GRStateTrait<T>::key_type key) const {
- void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
- return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key);
- }
-
- // State pretty-printing.
- class Printer {
- public:
- virtual ~Printer() {}
- virtual void Print(std::ostream& Out, const GRState* state,
- const char* nl, const char* sep) = 0;
- };
-
- void print(std::ostream& Out, StoreManager& StoreMgr,
- ConstraintManager& ConstraintMgr,
- Printer **Beg = 0, Printer **End = 0,
- const char* nl = "\n", const char *sep = "") const;
-
- // Tags used for the Generic Data Map.
- struct NullDerefTag {
- static int TagInt;
- typedef const RVal* data_type;
- };
-};
-
-template<> struct GRTrait<GRState*> {
- static inline void* toPtr(GRState* St) { return (void*) St; }
- static inline GRState* toState(void* P) { return (GRState*) P; }
- static inline void Profile(llvm::FoldingSetNodeID& profile, GRState* St) {
- // At this point states have already been uniqued. Just
- // add the pointer.
- profile.AddPointer(St);
- }
-};
-
-
-class GRStateSet {
- typedef llvm::SmallPtrSet<const GRState*,5> ImplTy;
- ImplTy Impl;
-public:
- GRStateSet() {}
-
- inline void Add(const GRState* St) {
- Impl.insert(St);
- }
-
- typedef ImplTy::const_iterator iterator;
-
- inline unsigned size() const { return Impl.size(); }
- inline bool empty() const { return Impl.empty(); }
-
- inline iterator begin() const { return Impl.begin(); }
- inline iterator end() const { return Impl.end(); }
-
- class AutoPopulate {
- GRStateSet& S;
- unsigned StartSize;
- const GRState* St;
- public:
- AutoPopulate(GRStateSet& s, const GRState* st)
- : S(s), StartSize(S.size()), St(st) {}
-
- ~AutoPopulate() {
- if (StartSize == S.size())
- S.Add(St);
- }
- };
-};
-
-//===----------------------------------------------------------------------===//
-// GRStateManager - Factory object for GRStates.
-//===----------------------------------------------------------------------===//
-
-class GRStateRef;
-
-class GRStateManager {
- friend class GRExprEngine;
- friend class GRStateRef;
-
-private:
- EnvironmentManager EnvMgr;
- llvm::OwningPtr<StoreManager> StMgr;
- llvm::OwningPtr<ConstraintManager> ConstraintMgr;
- GRState::IntSetTy::Factory ISetFactory;
-
- GRState::GenericDataMap::Factory GDMFactory;
-
- typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
- GDMContextsTy GDMContexts;
-
- /// Printers - A set of printer objects used for pretty-printing a GRState.
- /// GRStateManager owns these objects.
- std::vector<GRState::Printer*> Printers;
-
- /// StateSet - FoldingSet containing all the states created for analyzing
- /// a particular function. This is used to unique states.
- llvm::FoldingSet<GRState> StateSet;
-
- /// ValueMgr - Object that manages the data for all created RVals.
- BasicValueFactory BasicVals;
-
- /// SymMgr - Object that manages the symbol information.
- SymbolManager SymMgr;
-
- /// Alloc - A BumpPtrAllocator to allocate states.
- llvm::BumpPtrAllocator& Alloc;
-
- /// CurrentStmt - The block-level statement currently being visited. This
- /// is set by GRExprEngine.
- Stmt* CurrentStmt;
-
- /// cfg - The CFG for the analyzed function/method.
- CFG& cfg;
-
- /// TF - Object that represents a bundle of transfer functions
- /// for manipulating and creating RVals.
- GRTransferFuncs* TF;
-
- /// Liveness - live-variables information of the ValueDecl* and block-level
- /// Expr* in the CFG. Used to get initial store and prune out dead state.
- LiveVariables& Liveness;
-
-private:
-
- Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
- return EnvMgr.RemoveBlkExpr(Env, E);
- }
-
- // FIXME: Remove when we do lazy initializaton of variable bindings.
-// const GRState* BindVar(const GRState* St, VarDecl* D, RVal V) {
-// return SetRVal(St, getLVal(D), V);
-// }
-
-public:
-
- typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&);
- typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
-
- GRStateManager(ASTContext& Ctx,
- StoreManagerCreator CreateStoreManager,
- ConstraintManagerCreator CreateConstraintManager,
- llvm::BumpPtrAllocator& alloc, CFG& c, LiveVariables& L)
- : EnvMgr(alloc),
- ISetFactory(alloc),
- GDMFactory(alloc),
- BasicVals(Ctx, alloc),
- SymMgr(alloc),
- Alloc(alloc),
- cfg(c),
- Liveness(L) {
- StMgr.reset((*CreateStoreManager)(*this));
- ConstraintMgr.reset((*CreateConstraintManager)(*this));
- }
-
- ~GRStateManager();
-
- const GRState* getInitialState();
-
- ASTContext& getContext() { return BasicVals.getContext(); }
- BasicValueFactory& getBasicVals() { return BasicVals; }
- const BasicValueFactory& getBasicVals() const { return BasicVals; }
- SymbolManager& getSymbolManager() { return SymMgr; }
- LiveVariables& getLiveVariables() { return Liveness; }
- llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
- MemRegionManager& getRegionManager() { return StMgr->getRegionManager(); }
-
- typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
-
- const GRState* AddDecl(const GRState* St, const VarDecl* VD, Expr* Ex,
- unsigned Count);
-
- const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
- const LiveVariables& Liveness,
- DeadSymbolsTy& DeadSyms);
-
- const GRState* RemoveSubExprBindings(const GRState* St) {
- GRState NewSt = *St;
- NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
- return getPersistentState(NewSt);
- }
-
-
- // Utility methods for getting regions.
-
- VarRegion* getRegion(const VarDecl* D) {
- return getRegionManager().getVarRegion(D);
- }
-
- LVal getLVal(const VarDecl* D) {
- return StMgr->getLVal(D);
- }
-
- // Methods that query & manipulate the Environment.
-
- RVal GetRVal(const GRState* St, Expr* Ex) {
- return St->getEnvironment().GetRVal(Ex, BasicVals);
- }
-
- RVal GetBlkExprRVal(const GRState* St, Expr* Ex) {
- return St->getEnvironment().GetBlkExprRVal(Ex, BasicVals);
- }
-
- const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V,
- bool isBlkExpr, bool Invalidate) {
-
- const Environment& OldEnv = St->getEnvironment();
- Environment NewEnv = EnvMgr.SetRVal(OldEnv, Ex, V, isBlkExpr, Invalidate);
-
- if (NewEnv == OldEnv)
- return St;
-
- GRState NewSt = *St;
- NewSt.Env = NewEnv;
- return getPersistentState(NewSt);
- }
-
- const GRState* SetRVal(const GRState* St, Expr* Ex, RVal V,
- bool Invalidate = true) {
-
- bool isBlkExpr = false;
-
- if (Ex == CurrentStmt) {
- // FIXME: Should this just be an assertion? When would we want to set
- // the value of a block-level expression if it wasn't CurrentStmt?
- isBlkExpr = cfg.isBlkExpr(Ex);
-
- if (!isBlkExpr)
- return St;
- }
-
- return SetRVal(St, Ex, V, isBlkExpr, Invalidate);
- }
-
- // Methods that manipulate the GDM.
- const GRState* addGDM(const GRState* St, void* Key, void* Data);
-
- // Methods that query or create regions.
- bool hasStackStorage(const MemRegion* R) {
- return getRegionManager().hasStackStorage(R);
- }
-
- // Methods that query & manipulate the Store.
-
- void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) {
- StMgr->iterBindings(state->getStore(), F);
- }
-
-
- RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
- return StMgr->GetRVal(St->getStore(), LV, T);
- }
-
- void SetRVal(GRState& St, LVal LV, RVal V) {
- St.St = StMgr->SetRVal(St.St, LV, V);
- }
-
- const GRState* SetRVal(const GRState* St, LVal LV, RVal V);
-
- void Unbind(GRState& St, LVal LV) {
- St.St = StMgr->Remove(St.St, LV);
- }
-
- const GRState* Unbind(const GRState* St, LVal LV);
-
- const GRState* getPersistentState(GRState& Impl);
-
- bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V);
- bool isEqual(const GRState* state, Expr* Ex, uint64_t);
-
- // Trait based GDM dispatch.
- template <typename T>
- const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) {
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(D));
- }
-
- template<typename T>
- const GRState* set(const GRState* st,
- typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type V,
- typename GRStateTrait<T>::context_type C) {
-
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
- }
-
- template <typename T>
- const GRState* remove(const GRState* st,
- typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::context_type C) {
-
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
- }
-
-
- void* FindGDMContext(void* index,
- void* (*CreateContext)(llvm::BumpPtrAllocator&),
- void (*DeleteContext)(void*));
-
- template <typename T>
- typename GRStateTrait<T>::context_type get_context() {
- void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::CreateContext,
- GRStateTrait<T>::DeleteContext);
-
- return GRStateTrait<T>::MakeContext(p);
- }
-
- const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
- bool& isFeasible) {
- return ConstraintMgr->Assume(St, Cond, Assumption, isFeasible);
- }
-
- const GRState* AddNE(const GRState* St, SymbolID sym, const llvm::APSInt& V) {
- return ConstraintMgr->AddNE(St, sym, V);
- }
-
- const llvm::APSInt* getSymVal(const GRState* St, SymbolID sym) {
- return ConstraintMgr->getSymVal(St, sym);
- }
-};
-
-//===----------------------------------------------------------------------===//
-// GRStateRef - A "fat" reference to GRState that also bundles GRStateManager.
-//===----------------------------------------------------------------------===//
-
-class GRStateRef {
- const GRState* St;
- GRStateManager* Mgr;
-public:
- GRStateRef(const GRState* st, GRStateManager& mgr) : St(st), Mgr(&mgr) {}
-
- const GRState* getState() const { return St; }
- operator const GRState*() const { return St; }
- GRStateManager& getManager() const { return *Mgr; }
-
- RVal GetRVal(Expr* Ex) {
- return Mgr->GetRVal(St, Ex);
- }
-
- RVal GetBlkExprRVal(Expr* Ex) {
- return Mgr->GetBlkExprRVal(St, Ex);
- }
-
- RVal GetRVal(LVal LV, QualType T = QualType()) {
- return Mgr->GetRVal(St, LV, T);
- }
-
- GRStateRef SetRVal(Expr* Ex, RVal V, bool isBlkExpr, bool Invalidate) {
- return GRStateRef(Mgr->SetRVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
- }
-
- GRStateRef SetRVal(Expr* Ex, RVal V, bool Invalidate = true) {
- return GRStateRef(Mgr->SetRVal(St, Ex, V, Invalidate), *Mgr);
- }
-
- GRStateRef SetRVal(LVal LV, RVal V) {
- GRState StImpl = *St;
- Mgr->SetRVal(StImpl, LV, V);
- return GRStateRef(Mgr->getPersistentState(StImpl), *Mgr);
- }
-
- GRStateRef Unbind(LVal LV) {
- return GRStateRef(Mgr->Unbind(St, LV), *Mgr);
- }
-
- GRStateRef AddNE(SymbolID sym, const llvm::APSInt& V) {
- return GRStateRef(Mgr->AddNE(St, sym, V), *Mgr);
- }
-
- // Trait based GDM dispatch.
- template<typename T>
- typename GRStateTrait<T>::data_type get() const {
- return St->get<T>();
- }
-
- template<typename T>
- typename GRStateTrait<T>::lookup_type
- get(typename GRStateTrait<T>::key_type key) const {
- return St->get<T>(key);
- }
-
- template<typename T>
- GRStateRef set(typename GRStateTrait<T>::data_type D) {
- return GRStateRef(Mgr->set<T>(St, D), *Mgr);
- }
-
- template <typename T>
- typename GRStateTrait<T>::context_type get_context() {
- return Mgr->get_context<T>();
- }
-
- template<typename T>
- GRStateRef set(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type E,
- typename GRStateTrait<T>::context_type C) {
- return GRStateRef(Mgr->set<T>(St, K, E, C), *Mgr);
- }
-
- template<typename T>
- GRStateRef set(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type E) {
- return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr);
- }
-
- template<typename T>
- GRStateRef remove(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::context_type C) {
- return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr);
- }
-
- template<typename T>
- GRStateRef remove(typename GRStateTrait<T>::key_type K) {
- return GRStateRef(Mgr->remove<T>(St, K, get_context<T>()), *Mgr);
- }
-
- // Pretty-printing.
- void print(std::ostream& Out, const char* nl = "\n",
- const char *sep = "") const;
-
- void printStdErr() const;
-
- void printDOT(std::ostream& Out) const;
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRStateTrait.h b/clang/include/clang/Analysis/PathSensitive/GRStateTrait.h
deleted file mode 100644
index 9409aafaa583..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRStateTrait.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//==- GRStateTrait.h - Partial implementations of GRStateTrait -----*- 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 partial implementations of template specializations of
-// the class GRStateTrait<>. GRStateTrait<> is used by GRState to implement
-// set/get methods for mapulating a GRState's generic data map.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
-#define LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
-
-namespace llvm {
- class BumpPtrAllocator;
- template <typename K, typename D, typename I> class ImmutableMap;
-}
-
-namespace clang {
- template <typename T> struct GRStatePartialTrait;
-
- template <typename Key, typename Data, typename Info>
- struct GRStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
- typedef llvm::ImmutableMap<Key,Data,Info> data_type;
- typedef typename data_type::Factory& context_type;
- typedef Key key_type;
- typedef Data value_type;
- typedef const value_type* lookup_type;
-
- static inline data_type MakeData(void* const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
- }
- static inline void* MakeVoidPtr(data_type B) {
- return B.getRoot();
- }
- static lookup_type Lookup(data_type B, key_type K) {
- return B.lookup(K);
- }
- static data_type Set(data_type B, key_type K, value_type E,context_type F){
- return F.Add(B, K, E);
- }
-
- static data_type Remove(data_type B, key_type K, context_type F) {
- return F.Remove(B, K);
- }
-
- static inline context_type MakeContext(void* p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void* Ctx) {
- delete (typename data_type::Factory*) Ctx;
- }
- };
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
deleted file mode 100644
index ad12328edafe..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ /dev/null
@@ -1,132 +0,0 @@
-//== GRTransferFuncs.h - Path-Sens. Transfer Functions Interface -*- 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 GRTransferFuncs, which provides a base-class that
-// defines an interface for transfer functions used by GRExprEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRTF
-#define LLVM_CLANG_ANALYSIS_GRTF
-
-#include "clang/Analysis/PathSensitive/RValues.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include <vector>
-
-namespace clang {
-
- class GRExprEngine;
- class ObjCMessageExpr;
-
-class GRTransferFuncs {
-
- friend class GRExprEngine;
-
-protected:
-
-
- virtual RVal DetermEvalBinOpNN(GRStateManager& StateMgr,
- BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R) {
- return UnknownVal();
- }
-
-
-public:
- GRTransferFuncs() {}
- virtual ~GRTransferFuncs() {}
-
- virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
- virtual void RegisterChecks(GRExprEngine& Eng);
-
- // Casts.
-
- virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT) =0;
- virtual RVal EvalCast(GRExprEngine& Engine, LVal V, QualType CastT) = 0;
-
- // Unary Operators.
-
- virtual RVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLVal X) = 0;
-
- virtual RVal EvalComplement(GRExprEngine& Engine, NonLVal X) = 0;
-
- // Binary Operators.
- virtual void EvalBinOpNN(GRStateSet& OStates, GRStateManager& StateMgr,
- const GRState* St, Expr* Ex,
- BinaryOperator::Opcode Op, NonLVal L, NonLVal R);
-
- virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
- LVal L, LVal R) = 0;
-
- // Pointer arithmetic.
-
- virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
- LVal L, NonLVal R) = 0;
-
- // Calls.
-
- virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<GRState>* Pred) {}
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<GRState>* Pred) {}
-
- // Stores.
-
- /// EvalStore - Evaluate the effects of a store, creating a new node
- /// the represents the effect of binding 'Val' to the location 'TargetLV'.
- // TargetLV is guaranteed to either be an UnknownVal or an LVal.
- virtual void EvalStore(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* E, ExplodedNode<GRState>* Pred,
- const GRState* St, RVal TargetLV, RVal Val);
-
-
- // End-of-path and dead symbol notification.
-
- virtual void EvalEndPath(GRExprEngine& Engine,
- GREndPathNodeBuilder<GRState>& Builder) {}
-
-
- virtual void EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ExplodedNode<GRState>* Pred,
- Stmt* S,
- const GRState* St,
- const GRStateManager::DeadSymbolsTy& Dead) {}
-
- // Return statements.
- virtual void EvalReturn(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ReturnStmt* S,
- ExplodedNode<GRState>* Pred) {}
-
- // Assumptions.
-
- virtual const GRState* EvalAssume(GRStateManager& VMgr,
- const GRState* St,
- RVal Cond, bool Assumption,
- bool& isFeasible) {
- return St;
- }
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRWorkList.h b/clang/include/clang/Analysis/PathSensitive/GRWorkList.h
deleted file mode 100644
index 69178fb9cce3..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRWorkList.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//==- GRWorkList.h - Worklist class used by GRCoreEngine -----------*- 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 GRWorkList, a pure virtual class that represents an opaque
-// worklist used by GRCoreEngine to explore the reachability state space.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
-#define LLVM_CLANG_ANALYSIS_GRWORKLIST
-
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
-
-namespace clang {
-
-class ExplodedNodeImpl;
-
-class GRWorkListUnit {
- ExplodedNodeImpl* Node;
- GRBlockCounter Counter;
- CFGBlock* Block;
- unsigned BlockIdx;
-
-public:
- GRWorkListUnit(ExplodedNodeImpl* N, GRBlockCounter C,
- CFGBlock* B, unsigned idx)
- : Node(N),
- Counter(C),
- Block(B),
- BlockIdx(idx) {}
-
- explicit GRWorkListUnit(ExplodedNodeImpl* N, GRBlockCounter C)
- : Node(N),
- Counter(C),
- Block(NULL),
- BlockIdx(0) {}
-
- ExplodedNodeImpl* getNode() const { return Node; }
- GRBlockCounter getBlockCounter() const { return Counter; }
- CFGBlock* getBlock() const { return Block; }
- unsigned getIndex() const { return BlockIdx; }
-};
-
-class GRWorkList {
- GRBlockCounter CurrentCounter;
-public:
- virtual ~GRWorkList();
- virtual bool hasWork() const = 0;
-
- virtual void Enqueue(const GRWorkListUnit& U) = 0;
-
- void Enqueue(ExplodedNodeImpl* N, CFGBlock& B, unsigned idx) {
- Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
- }
-
- void Enqueue(ExplodedNodeImpl* N) {
- Enqueue(GRWorkListUnit(N, CurrentCounter));
- }
-
- virtual GRWorkListUnit Dequeue() = 0;
-
- void setBlockCounter(GRBlockCounter C) { CurrentCounter = C; }
- GRBlockCounter getBlockCounter() const { return CurrentCounter; }
-
- static GRWorkList* MakeDFS();
-};
-} // end clang namespace
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/MemRegion.h b/clang/include/clang/Analysis/PathSensitive/MemRegion.h
deleted file mode 100644
index 79705613ab9f..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/MemRegion.h
+++ /dev/null
@@ -1,267 +0,0 @@
-//== MemRegion.h - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a
-// partially-typed abstraction of memory useful for path-sensitive dataflow
-// analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H
-#define LLVM_CLANG_ANALYSIS_MEMREGION_H
-
-#include "llvm/Support/Casting.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include <string>
-
-namespace llvm { class raw_ostream; }
-
-namespace clang {
-
-class MemRegionManager;
-
-
-/// MemRegion - The root abstract class for all memory regions.
-class MemRegion : public llvm::FoldingSetNode {
-public:
- enum Kind { MemSpaceRegionKind,
- // Typed regions.
- BEG_TYPED_REGIONS,
- VarRegionKind, FieldRegionKind, ObjCIvarRegionKind,
- AnonTypedRegionKind,
- END_TYPED_REGIONS };
-private:
- const Kind kind;
-
-protected:
- MemRegion(Kind k) : kind(k) {}
- virtual ~MemRegion();
-
-public:
- // virtual MemExtent getExtent(MemRegionManager& mrm) const = 0;
- virtual const MemRegion* getSuperRegion() const = 0;
- virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
-
- std::string getString() const;
- virtual void print(llvm::raw_ostream& os) const;
-
- Kind getKind() const { return kind; }
- static bool classof(const MemRegion*) { return true; }
-};
-
-/// MemSpaceRegion - A memory region that represents and "memory space";
-/// for example, the set of global variables, the stack frame, etc.
-class MemSpaceRegion : public MemRegion {
- friend class MemRegionManager;
- MemSpaceRegion() : MemRegion(MemSpaceRegionKind) {}
-
-public:
- //RegionExtent getExtent() const { return UndefinedExtent(); }
-
- const MemRegion* getSuperRegion() const {
- return 0;
- }
-
- //static void ProfileRegion(llvm::FoldingSetNodeID& ID);
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == MemSpaceRegionKind;
- }
-};
-
-/// TypedRegion - An abstract class representing regions that are typed.
-class TypedRegion : public MemRegion {
-protected:
- const MemRegion* superRegion;
-
- TypedRegion(const MemRegion* sReg, Kind k)
- : MemRegion(k), superRegion(sReg) {};
-
-public:
- virtual QualType getType() const = 0;
-
- // MemExtent getExtent(MemRegionManager& mrm) const;
- const MemRegion* getSuperRegion() const {
- return superRegion;
- }
-
- static bool classof(const MemRegion* R) {
- unsigned k = R->getKind();
- return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS;
- }
-};
-
-/// AnonTypedRegion - An "anonymous" region that simply types a chunk
-/// of memory.
-class AnonTypedRegion : public TypedRegion {
- QualType T;
-
- friend class MemRegionManager;
-
- AnonTypedRegion(QualType t, MemRegion* sreg)
- : TypedRegion(sreg, AnonTypedRegionKind), T(t) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
- const MemRegion* superRegion);
-
-public:
- QualType getType() const { return T; }
-
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == AnonTypedRegionKind;
- }
-};
-
-class DeclRegion : public TypedRegion {
-protected:
- const Decl* D;
-
- DeclRegion(const Decl* d, MemRegion* sReg, Kind k)
- : TypedRegion(sReg, k), D(d) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
- const MemRegion* superRegion, Kind k);
-
-public:
- void Profile(llvm::FoldingSetNodeID& ID) const;
-};
-
-class VarRegion : public DeclRegion {
- friend class MemRegionManager;
-
- VarRegion(const VarDecl* vd, MemRegion* sReg)
- : DeclRegion(vd, sReg, VarRegionKind) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, VarDecl* VD,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
- }
-
-public:
- const VarDecl* getDecl() const { return cast<VarDecl>(D); }
- QualType getType() const { return getDecl()->getType(); }
-
- void print(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == VarRegionKind;
- }
-};
-
-class FieldRegion : public DeclRegion {
- friend class MemRegionManager;
-
- FieldRegion(const FieldDecl* fd, MemRegion* sReg)
- : DeclRegion(fd, sReg, FieldRegionKind) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, FieldDecl* FD,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
- }
-
-public:
- const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
- QualType getType() const { return getDecl()->getType(); }
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == FieldRegionKind;
- }
-};
-
-class ObjCIvarRegion : public DeclRegion {
-
- friend class MemRegionManager;
-
- ObjCIvarRegion(const ObjCIvarDecl* ivd, MemRegion* sReg)
- : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, ObjCIvarDecl* ivd,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
- }
-
-public:
- const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
- QualType getType() const { return getDecl()->getType(); }
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == ObjCIvarRegionKind;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// MemRegionManager - Factory object for creating regions.
-//===----------------------------------------------------------------------===//
-
-class MemRegionManager {
- llvm::BumpPtrAllocator& A;
- llvm::FoldingSet<MemRegion> Regions;
-
- MemSpaceRegion* globals;
- MemSpaceRegion* stack;
- MemSpaceRegion* heap;
-
-public:
- MemRegionManager(llvm::BumpPtrAllocator& a)
- : A(a), globals(0), stack(0), heap(0) {}
-
- ~MemRegionManager() {}
-
- /// getStackRegion - Retrieve the memory region associated with the
- /// current stack frame.
- MemSpaceRegion* getStackRegion();
-
- /// getGlobalsRegion - Retrieve the memory region associated with
- /// all global variables.
- MemSpaceRegion* getGlobalsRegion();
-
- /// getHeapRegion - Retrieve the memory region associated with the
- /// generic "heap".
- MemSpaceRegion* getHeapRegion();
-
- /// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl. 'superRegion' corresponds to the containing
- /// memory region, and 'off' is the offset within the containing region.
- VarRegion* getVarRegion(const VarDecl* vd, MemRegion* superRegion);
-
- VarRegion* getVarRegion(const VarDecl* vd) {
- return getVarRegion(vd, vd->hasLocalStorage() ? getStackRegion()
- : getGlobalsRegion());
- }
-
- /// getFieldRegion - Retrieve or create the memory region associated with
- /// a specified FieldDecl. 'superRegion' corresponds to the containing
- /// memory region (which typically represents the memory representing
- /// a structure or class).
- FieldRegion* getFieldRegion(const FieldDecl* fd, MemRegion* superRegion);
-
- /// getObjCIvarRegion - Retrieve or create the memory region associated with
- /// a specified Objective-c instance variable. 'superRegion' corresponds
- /// to the containing region (which typically represents the Objective-C
- /// object).
- ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
- MemRegion* superRegion);
-
- bool hasStackStorage(const MemRegion* R);
-
-private:
- MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
-};
-
-
-
-} // end clang namespace
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/RValues.h b/clang/include/clang/Analysis/PathSensitive/RValues.h
deleted file mode 100644
index 82e511937399..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/RValues.h
+++ /dev/null
@@ -1,513 +0,0 @@
-//== RValues.h - Abstract RValues for Path-Sens. Value Tracking -*- 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 RVal, LVal, and NonLVal, classes that represent
-// abstract r-values for use with path-sensitive value tracking.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
-#define LLVM_CLANG_ANALYSIS_RVALUE_H
-
-#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
-#include "llvm/Support/Casting.h"
-
-//==------------------------------------------------------------------------==//
-// Base RVal types.
-//==------------------------------------------------------------------------==//
-
-namespace clang {
-
-class MemRegion;
-class GRStateManager;
-
-class RVal {
-public:
- enum BaseKind { UndefinedKind, UnknownKind, LValKind, NonLValKind };
- enum { BaseBits = 2, BaseMask = 0x3 };
-
-protected:
- void* Data;
- unsigned Kind;
-
-protected:
- RVal(const void* d, bool isLVal, unsigned ValKind)
- : Data(const_cast<void*>(d)),
- Kind((isLVal ? LValKind : NonLValKind) | (ValKind << BaseBits)) {}
-
- explicit RVal(BaseKind k, void* D = NULL)
- : Data(D), Kind(k) {}
-
-public:
- ~RVal() {};
-
- /// BufferTy - A temporary buffer to hold a set of RVals.
- typedef llvm::SmallVector<RVal,5> BufferTy;
-
- inline unsigned getRawKind() const { return Kind; }
- inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
- inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
-
- inline void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned) getRawKind());
- ID.AddPointer(reinterpret_cast<void*>(Data));
- }
-
- inline bool operator==(const RVal& R) const {
- return getRawKind() == R.getRawKind() && Data == R.Data;
- }
-
-
- inline bool operator!=(const RVal& R) const {
- return !(*this == R);
- }
-
- static RVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
-
- inline bool isUnknown() const {
- return getRawKind() == UnknownKind;
- }
-
- inline bool isUndef() const {
- return getRawKind() == UndefinedKind;
- }
-
- inline bool isUnknownOrUndef() const {
- return getRawKind() <= UnknownKind;
- }
-
- inline bool isValid() const {
- return getRawKind() > UnknownKind;
- }
-
- bool isZeroConstant() const;
-
- void print(std::ostream& OS) const;
- void printStdErr() const;
-
- typedef const SymbolID* symbol_iterator;
- symbol_iterator symbol_begin() const;
- symbol_iterator symbol_end() const;
-
- static RVal MakeVal(GRStateManager& SMgr, DeclRefExpr* E);
-
- // Implement isa<T> support.
- static inline bool classof(const RVal*) { return true; }
-};
-
-class UnknownVal : public RVal {
-public:
- UnknownVal() : RVal(UnknownKind) {}
-
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == UnknownKind;
- }
-};
-
-class UndefinedVal : public RVal {
-public:
- UndefinedVal() : RVal(UndefinedKind) {}
- UndefinedVal(void* D) : RVal(UndefinedKind, D) {}
-
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == UndefinedKind;
- }
-
- void* getData() const { return Data; }
-};
-
-class NonLVal : public RVal {
-protected:
- NonLVal(unsigned SubKind, const void* d) : RVal(d, false, SubKind) {}
-
-public:
- void print(std::ostream& Out) const;
-
- // Utility methods to create NonLVals.
- static NonLVal MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T);
-
- static NonLVal MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I);
-
- static NonLVal MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == NonLValKind;
- }
-};
-
-class LVal : public RVal {
-protected:
- LVal(unsigned SubKind, const void* D)
- : RVal(const_cast<void*>(D), true, SubKind) {}
-
- // Equality operators.
- NonLVal EQ(BasicValueFactory& BasicVals, const LVal& R) const;
- NonLVal NE(BasicValueFactory& BasicVals, const LVal& R) const;
-
-public:
- void print(std::ostream& Out) const;
-
- static LVal MakeVal(AddrLabelExpr* E);
-
- static LVal MakeVal(StringLiteral* S);
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind;
- }
-
- static inline bool IsLValType(QualType T) {
- return T->isPointerType() || T->isObjCQualifiedIdType()
- || T->isBlockPointerType();
- }
-};
-
-//==------------------------------------------------------------------------==//
-// Subclasses of NonLVal.
-//==------------------------------------------------------------------------==//
-
-namespace nonlval {
-
-enum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind,
- LValAsIntegerKind };
-
-class SymbolVal : public NonLVal {
-public:
- SymbolVal(unsigned SymID)
- : NonLVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
-
- SymbolID getSymbol() const {
- return (SymbolID) reinterpret_cast<uintptr_t>(Data);
- }
-
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == NonLValKind &&
- V->getSubKind() == SymbolValKind;
- }
-
- static inline bool classof(const NonLVal* V) {
- return V->getSubKind() == SymbolValKind;
- }
-};
-
-class SymIntConstraintVal : public NonLVal {
-public:
- SymIntConstraintVal(const SymIntConstraint& C)
- : NonLVal(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
-
- const SymIntConstraint& getConstraint() const {
- return *reinterpret_cast<SymIntConstraint*>(Data);
- }
-
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == NonLValKind &&
- V->getSubKind() == SymIntConstraintValKind;
- }
-
- static inline bool classof(const NonLVal* V) {
- return V->getSubKind() == SymIntConstraintValKind;
- }
-};
-
-class ConcreteInt : public NonLVal {
-public:
- ConcreteInt(const llvm::APSInt& V) : NonLVal(ConcreteIntKind, &V) {}
-
- const llvm::APSInt& getValue() const {
- return *static_cast<llvm::APSInt*>(Data);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
- ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const;
-
- ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const;
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == NonLValKind &&
- V->getSubKind() == ConcreteIntKind;
- }
-
- static inline bool classof(const NonLVal* V) {
- return V->getSubKind() == ConcreteIntKind;
- }
-};
-
-class LValAsInteger : public NonLVal {
- LValAsInteger(const std::pair<RVal, uintptr_t>& data) :
- NonLVal(LValAsIntegerKind, &data) {
- assert (isa<LVal>(data.first));
- }
-
-public:
-
- LVal getLVal() const {
- return cast<LVal>(((std::pair<RVal, uintptr_t>*) Data)->first);
- }
-
- const LVal& getPersistentLVal() const {
- const RVal& V = ((std::pair<RVal, uintptr_t>*) Data)->first;
- return cast<LVal>(V);
- }
-
- unsigned getNumBits() const {
- return ((std::pair<RVal, unsigned>*) Data)->second;
- }
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == NonLValKind &&
- V->getSubKind() == LValAsIntegerKind;
- }
-
- static inline bool classof(const NonLVal* V) {
- return V->getSubKind() == LValAsIntegerKind;
- }
-
- static inline LValAsInteger Make(BasicValueFactory& Vals, LVal V,
- unsigned Bits) {
- return LValAsInteger(Vals.getPersistentRValWithData(V, Bits));
- }
-};
-
-} // end namespace clang::nonlval
-
-//==------------------------------------------------------------------------==//
-// Subclasses of LVal.
-//==------------------------------------------------------------------------==//
-
-namespace lval {
-
-enum Kind { SymbolValKind, GotoLabelKind, MemRegionKind, FuncValKind,
- ConcreteIntKind, StringLiteralValKind, FieldOffsetKind,
- ArrayOffsetKind };
-
-class SymbolVal : public LVal {
-public:
- SymbolVal(unsigned SymID)
- : LVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
-
- SymbolID getSymbol() const {
- return (SymbolID) reinterpret_cast<uintptr_t>(Data);
- }
-
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == SymbolValKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == SymbolValKind;
- }
-};
-
-class GotoLabel : public LVal {
-public:
- GotoLabel(LabelStmt* Label) : LVal(GotoLabelKind, Label) {}
-
- LabelStmt* getLabel() const {
- return static_cast<LabelStmt*>(Data);
- }
-
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == GotoLabelKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == GotoLabelKind;
- }
-};
-
-
-class MemRegionVal : public LVal {
-public:
- MemRegionVal(const MemRegion* r) : LVal(MemRegionKind, r) {}
-
- MemRegion* getRegion() const {
- return static_cast<MemRegion*>(Data);
- }
-
- inline bool operator==(const MemRegionVal& R) const {
- return getRegion() == R.getRegion();
- }
-
- inline bool operator!=(const MemRegionVal& R) const {
- return getRegion() != R.getRegion();
- }
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == MemRegionKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == MemRegionKind;
- }
-};
-
-class FuncVal : public LVal {
-public:
- FuncVal(const FunctionDecl* fd) : LVal(FuncValKind, fd) {}
-
- FunctionDecl* getDecl() const {
- return static_cast<FunctionDecl*>(Data);
- }
-
- inline bool operator==(const FuncVal& R) const {
- return getDecl() == R.getDecl();
- }
-
- inline bool operator!=(const FuncVal& R) const {
- return getDecl() != R.getDecl();
- }
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == FuncValKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == FuncValKind;
- }
-};
-
-class ConcreteInt : public LVal {
-public:
- ConcreteInt(const llvm::APSInt& V) : LVal(ConcreteIntKind, &V) {}
-
- const llvm::APSInt& getValue() const {
- return *static_cast<llvm::APSInt*>(Data);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == ConcreteIntKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == ConcreteIntKind;
- }
-};
-
-class StringLiteralVal : public LVal {
-public:
- StringLiteralVal(StringLiteral* L) : LVal(StringLiteralValKind, L) {}
-
- StringLiteral* getLiteral() const { return (StringLiteral*) Data; }
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == StringLiteralValKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == StringLiteralValKind;
- }
-};
-
-class FieldOffset : public LVal {
- FieldOffset(const std::pair<RVal, uintptr_t>& data)
- : LVal(FieldOffsetKind, &data) {}
-
-public:
-
- LVal getBase() const {
- return reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->first;
- }
-
- const LVal& getPersistentBase() const {
- return reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->first;
- }
-
-
- FieldDecl* getFieldDecl() const {
- return (FieldDecl*)
- reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->second;
- }
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == FieldOffsetKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == FieldOffsetKind;
- }
-
- static inline RVal Make(BasicValueFactory& Vals, RVal Base, FieldDecl* D) {
-
- if (Base.isUnknownOrUndef())
- return Base;
-
- return FieldOffset(Vals.getPersistentRValWithData(cast<LVal>(Base),
- (uintptr_t) D));
- }
-};
-
-class ArrayOffset : public LVal {
- ArrayOffset(const std::pair<RVal,RVal>& data) : LVal(ArrayOffsetKind,&data) {}
-public:
-
- LVal getBase() const {
- return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->first;
- }
-
- const LVal& getPersistentBase() const {
- return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->first;
- }
-
- RVal getOffset() const {
- return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->second;
- }
-
- const RVal& getPersistentOffset() const {
- return reinterpret_cast<const std::pair<LVal,RVal>*> (Data)->second;
- }
-
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == ArrayOffsetKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == ArrayOffsetKind;
- }
-
- static inline RVal Make(BasicValueFactory& Vals, RVal Base, RVal Offset) {
-
- if (Base.isUnknownOrUndef())
- return Base;
-
- if (Offset.isUndef())
- return Offset;
-
- return ArrayOffset(Vals.getPersistentRValPair(cast<LVal>(Base), Offset));
- }
-};
-
-} // end clang::lval namespace
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/Store.h b/clang/include/clang/Analysis/PathSensitive/Store.h
deleted file mode 100644
index 060bce5992b9..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/Store.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//== Store.h - Interface for maps from Locations to Values ------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the types Store and StoreManager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_STORE_H
-#define LLVM_CLANG_ANALYSIS_STORE_H
-
-#include "clang/Analysis/PathSensitive/RValues.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include <iosfwd>
-
-namespace clang {
-
-typedef const void* Store;
-
-class GRStateManager;
-class LiveVariables;
-class Stmt;
-class MemRegion;
-class MemRegionManager;
-
-class StoreManager {
-public:
- typedef llvm::SmallSet<SymbolID, 20> LiveSymbolsTy;
- typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
-
- virtual ~StoreManager() {}
- virtual RVal GetRVal(Store St, LVal LV, QualType T = QualType()) = 0;
- virtual Store SetRVal(Store St, LVal LV, RVal V) = 0;
- virtual Store Remove(Store St, LVal LV) = 0;
- virtual Store getInitialStore() = 0;
- virtual MemRegionManager& getRegionManager() = 0;
- virtual LVal getLVal(const VarDecl* VD) = 0;
- virtual Store
- RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
- LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) = 0;
-
- virtual Store AddDecl(Store store,
- const VarDecl* VD, Expr* Ex,
- RVal InitVal = UndefinedVal(), unsigned Count = 0) = 0;
-
- virtual void print(Store store, std::ostream& Out,
- const char* nl, const char *sep) = 0;
-
- class BindingsHandler {
- public:
- virtual ~BindingsHandler();
- virtual bool HandleBinding(StoreManager& SMgr, Store store,
- MemRegion* R, RVal val) = 0;
- };
-
- /// iterBindings - Iterate over the bindings in the Store.
- virtual void iterBindings(Store store, BindingsHandler& f) = 0;
-};
-
-StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h b/clang/include/clang/Analysis/PathSensitive/SymbolManager.h
deleted file mode 100644
index 0f6476100c49..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//== SymbolManager.h - Management of Symbolic Values ------------*- 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 SymbolManager, a class that manages symbolic values
-// created for use by GRExprEngine and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H
-#define LLVM_CLANG_ANALYSIS_SYMMGR_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-
-
-class SymbolManager;
-
-class SymbolID {
- unsigned Data;
-public:
- SymbolID() : Data(~0U - 2) {}
- SymbolID(unsigned x) : Data(x) {}
-
- bool isInitialized() const { return Data != (unsigned) (~0U - 2); }
- operator unsigned() const { return getNumber(); }
- unsigned getNumber() const { assert (isInitialized()); return Data; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- assert (isInitialized());
- ID.AddInteger(Data);
- }
-};
-
-} // end clang namespace
-
-namespace llvm {
- template <> struct DenseMapInfo<clang::SymbolID> {
- static inline clang::SymbolID getEmptyKey() {
- return clang::SymbolID(~0U);
- }
- static inline clang::SymbolID getTombstoneKey() {
- return clang::SymbolID(~0U - 1);
- }
- static unsigned getHashValue(clang::SymbolID X) {
- return X.getNumber();
- }
- static bool isEqual(clang::SymbolID X, clang::SymbolID Y) {
- return X.getNumber() == Y.getNumber();
- }
- static bool isPod() { return true; }
- };
-}
-
-// SymbolData: Used to record meta data about symbols.
-
-namespace clang {
-
-class SymbolData : public llvm::FoldingSetNode {
-public:
- enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, ConjuredKind };
-
-private:
- Kind K;
- SymbolID Sym;
-
-protected:
- SymbolData(Kind k, SymbolID sym) : K(k), Sym(sym) {}
-
-public:
- virtual ~SymbolData() {}
-
- Kind getKind() const { return K; }
-
- SymbolID getSymbol() const { return Sym; }
-
- QualType getType(const SymbolManager& SymMgr) const;
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
-
- // Implement isa<T> support.
- static inline bool classof(const SymbolData*) { return true; }
-};
-
-class SymbolDataParmVar : public SymbolData {
- ParmVarDecl *VD;
-
-public:
- SymbolDataParmVar(SymbolID MySym, ParmVarDecl* vd)
- : SymbolData(ParmKind, MySym), VD(vd) {}
-
- ParmVarDecl* getDecl() const { return VD; }
-
- static void Profile(llvm::FoldingSetNodeID& profile, ParmVarDecl* VD) {
- profile.AddInteger((unsigned) ParmKind);
- profile.AddPointer(VD);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, VD);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymbolData* D) {
- return D->getKind() == ParmKind;
- }
-};
-
-class SymbolDataGlobalVar : public SymbolData {
- VarDecl *VD;
-
-public:
- SymbolDataGlobalVar(SymbolID MySym, VarDecl* vd) :
- SymbolData(GlobalKind, MySym), VD(vd) {}
-
- VarDecl* getDecl() const { return VD; }
-
- static void Profile(llvm::FoldingSetNodeID& profile, VarDecl* VD) {
- profile.AddInteger((unsigned) GlobalKind);
- profile.AddPointer(VD);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, VD);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymbolData* D) {
- return D->getKind() == GlobalKind;
- }
-};
-
-class SymbolDataContentsOf : public SymbolData {
- SymbolID Sym;
-
-public:
- SymbolDataContentsOf(SymbolID MySym, SymbolID sym) :
- SymbolData(ContentsOfKind, MySym), Sym(sym) {}
-
- SymbolID getContainerSymbol() const { return Sym; }
-
- static void Profile(llvm::FoldingSetNodeID& profile, SymbolID Sym) {
- profile.AddInteger((unsigned) ContentsOfKind);
- profile.AddInteger(Sym);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, Sym);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymbolData* D) {
- return D->getKind() == ContentsOfKind;
- }
-};
-
-class SymbolConjured : public SymbolData {
- Expr* E;
- QualType T;
- unsigned Count;
-
-public:
- SymbolConjured(SymbolID Sym, Expr* exp, QualType t, unsigned count)
- : SymbolData(ConjuredKind, Sym), E(exp), T(t), Count(count) {}
-
- Expr* getExpr() const { return E; }
- unsigned getCount() const { return Count; }
-
- QualType getType() const { return T; }
-
- static void Profile(llvm::FoldingSetNodeID& profile,
- Expr* E, QualType T, unsigned Count) {
-
- profile.AddInteger((unsigned) ConjuredKind);
- profile.AddPointer(E);
- profile.Add(T);
- profile.AddInteger(Count);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, E, T, Count);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymbolData* D) {
- return D->getKind() == ConjuredKind;
- }
-};
-
-// Constraints on symbols. Usually wrapped by RValues.
-
-class SymIntConstraint : public llvm::FoldingSetNode {
- SymbolID Symbol;
- BinaryOperator::Opcode Op;
- const llvm::APSInt& Val;
-public:
- SymIntConstraint(SymbolID sym, BinaryOperator::Opcode op,
- const llvm::APSInt& V)
- : Symbol(sym),
- Op(op), Val(V) {}
-
- BinaryOperator::Opcode getOpcode() const { return Op; }
- const SymbolID& getSymbol() const { return Symbol; }
- const llvm::APSInt& getInt() const { return Val; }
-
- static inline void Profile(llvm::FoldingSetNodeID& ID,
- SymbolID Symbol,
- BinaryOperator::Opcode Op,
- const llvm::APSInt& Val) {
- Symbol.Profile(ID);
- ID.AddInteger(Op);
- ID.AddPointer(&Val);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) {
- Profile(ID, Symbol, Op, Val);
- }
-};
-
-
-class SymbolManager {
- typedef llvm::FoldingSet<SymbolData> DataSetTy;
- typedef llvm::DenseMap<SymbolID, SymbolData*> DataMapTy;
-
- DataSetTy DataSet;
- DataMapTy DataMap;
-
- unsigned SymbolCounter;
- llvm::BumpPtrAllocator& BPAlloc;
-
-public:
- SymbolManager(llvm::BumpPtrAllocator& bpalloc)
- : SymbolCounter(0), BPAlloc(bpalloc) {}
-
- ~SymbolManager();
-
- SymbolID getSymbol(VarDecl* D);
- SymbolID getContentsOfSymbol(SymbolID sym);
- SymbolID getConjuredSymbol(Expr* E, QualType T, unsigned VisitCount);
- SymbolID getConjuredSymbol(Expr* E, unsigned VisitCount) {
- return getConjuredSymbol(E, E->getType(), VisitCount);
- }
-
- const SymbolData& getSymbolData(SymbolID ID) const;
-
- QualType getType(SymbolID ID) const {
- return getSymbolData(ID).getType(*this);
- }
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h
deleted file mode 100644
index db3acf41a4db..000000000000
--- a/clang/include/clang/Analysis/ProgramPoint.h
+++ /dev/null
@@ -1,228 +0,0 @@
-//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- 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 interface ProgramPoint, which identifies a
-// distinct location in a function.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
-#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
-
-#include "clang/AST/CFG.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include <cassert>
-
-namespace clang {
-
-class ProgramPoint {
-public:
- enum Kind { BlockEdgeKind=0, BlockEntranceKind, BlockExitKind,
- // Keep the following four together and in this order.
- PostStmtKind, PostLoadKind, PostStoreKind,
- PostPurgeDeadSymbolsKind };
-
-private:
- std::pair<uintptr_t,uintptr_t> Data;
-
-protected:
- ProgramPoint(const void* P, Kind k)
- : Data(reinterpret_cast<uintptr_t>(P), (uintptr_t) k) {}
-
- ProgramPoint(const void* P1, const void* P2)
- : Data(reinterpret_cast<uintptr_t>(P1) | 0x1,
- reinterpret_cast<uintptr_t>(P2)) {}
-
-protected:
- void* getData1NoMask() const {
- assert (getKind() != BlockEdgeKind);
- return reinterpret_cast<void*>(Data.first);
- }
-
- void* getData1() const {
- assert (getKind() == BlockEdgeKind);
- return reinterpret_cast<void*>(Data.first & ~0x1);
- }
-
- void* getData2() const {
- assert (getKind() == BlockEdgeKind);
- return reinterpret_cast<void*>(Data.second);
- }
-
-public:
-
- uintptr_t getKind() const {
- return Data.first & 0x1 ? (uintptr_t) BlockEdgeKind : Data.second;
- }
-
- // For use with DenseMap.
- unsigned getHashValue() const {
- std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first),
- reinterpret_cast<void*>(Data.second));
- return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P);
- }
-
- static bool classof(const ProgramPoint*) { return true; }
-
- bool operator==(const ProgramPoint & RHS) const {
- return Data == RHS.Data;
- }
-
- bool operator!=(const ProgramPoint& RHS) const {
- return Data != RHS.Data;
- }
-
- bool operator<(const ProgramPoint& RHS) const {
- return Data < RHS.Data;
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddPointer(reinterpret_cast<void*>(Data.first));
- ID.AddPointer(reinterpret_cast<void*>(Data.second));
- }
-};
-
-class BlockEntrance : public ProgramPoint {
-public:
- BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {}
-
- CFGBlock* getBlock() const {
- return reinterpret_cast<CFGBlock*>(getData1NoMask());
- }
-
- Stmt* getFirstStmt() const {
- CFGBlock* B = getBlock();
- return B->empty() ? NULL : B->front();
- }
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockEntranceKind;
- }
-};
-
-class BlockExit : public ProgramPoint {
-public:
- BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {}
-
- CFGBlock* getBlock() const {
- return reinterpret_cast<CFGBlock*>(getData1NoMask());
- }
-
- Stmt* getLastStmt() const {
- CFGBlock* B = getBlock();
- return B->empty() ? NULL : B->back();
- }
-
- Stmt* getTerminator() const {
- return getBlock()->getTerminator();
- }
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockExitKind;
- }
-};
-
-
-class PostStmt : public ProgramPoint {
-protected:
- PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {}
-public:
- PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {}
-
- Stmt* getStmt() const { return (Stmt*) getData1NoMask(); }
-
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
- return k >= PostStmtKind && k <= PostPurgeDeadSymbolsKind;
- }
-};
-
-class PostLoad : public PostStmt {
-public:
- PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLoadKind;
- }
-};
-
-class PostStore : public PostStmt {
-public:
- PostStore(const Stmt* S) : PostStmt(S, PostLoadKind) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostStoreKind;
- }
-};
-
-class PostPurgeDeadSymbols : public PostStmt {
-public:
- PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostPurgeDeadSymbolsKind;
- }
-};
-
-class BlockEdge : public ProgramPoint {
-public:
- BlockEdge(const CFGBlock* B1, const CFGBlock* B2)
- : ProgramPoint(B1, B2) {}
-
- CFGBlock* getSrc() const {
- return static_cast<CFGBlock*>(getData1());
- }
-
- CFGBlock* getDst() const {
- return static_cast<CFGBlock*>(getData2());
- }
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == BlockEdgeKind;
- }
-};
-
-
-} // end namespace clang
-
-
-namespace llvm { // Traits specialization for DenseMap
-
-template <> struct DenseMapInfo<clang::ProgramPoint> {
-
-static inline clang::ProgramPoint getEmptyKey() {
- uintptr_t x =
- reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
-}
-
-static inline clang::ProgramPoint getTombstoneKey() {
- uintptr_t x =
- reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x));
-}
-
-static unsigned getHashValue(const clang::ProgramPoint& Loc) {
- return Loc.getHashValue();
-}
-
-static bool isEqual(const clang::ProgramPoint& L,
- const clang::ProgramPoint& R) {
- return L == R;
-}
-
-static bool isPod() {
- return true;
-}
-};
-} // end namespace llvm
-
-#endif
diff --git a/clang/include/clang/Analysis/Support/ExprDeclBitVector.h b/clang/include/clang/Analysis/Support/ExprDeclBitVector.h
deleted file mode 100644
index 7b44fd7c6ba1..000000000000
--- a/clang/include/clang/Analysis/Support/ExprDeclBitVector.h
+++ /dev/null
@@ -1,276 +0,0 @@
-//=- ExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides definition of dataflow types used by analyses such
-// as LiveVariables and UninitializedValues. The underlying dataflow values
-// are implemented as bitvectors, but the definitions in this file include
-// the necessary boilerplate to use with our dataflow framework.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_EXPRDECLBVDVAL_H
-#define LLVM_CLANG_EXPRDECLBVDVAL_H
-
-#include "clang/AST/CFG.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
- class Expr;
- class ScopedDecl;
-
-struct DeclBitVector_Types {
-
- class Idx {
- unsigned I;
- public:
- explicit Idx(unsigned i) : I(i) {}
- Idx() : I(~0U) {}
-
- bool isValid() const {
- return I != ~0U;
- }
- operator unsigned() const {
- assert (isValid());
- return I;
- }
- };
-
- //===--------------------------------------------------------------------===//
- // AnalysisDataTy - Whole-function meta data.
- //===--------------------------------------------------------------------===//
-
- class AnalysisDataTy {
- public:
- typedef llvm::DenseMap<const ScopedDecl*, unsigned > DMapTy;
- typedef DMapTy::const_iterator decl_iterator;
-
- protected:
- DMapTy DMap;
- unsigned NDecls;
-
- public:
-
- AnalysisDataTy() : NDecls(0) {}
- virtual ~AnalysisDataTy() {}
-
- bool isTracked(const ScopedDecl* SD) { return DMap.find(SD) != DMap.end(); }
-
- Idx getIdx(const ScopedDecl* SD) const {
- DMapTy::const_iterator I = DMap.find(SD);
- return I == DMap.end() ? Idx() : Idx(I->second);
- }
-
- unsigned getNumDecls() const { return NDecls; }
-
- void Register(const ScopedDecl* SD) {
- if (!isTracked(SD)) DMap[SD] = NDecls++;
- }
-
- decl_iterator begin_decl() const { return DMap.begin(); }
- decl_iterator end_decl() const { return DMap.end(); }
- };
-
- //===--------------------------------------------------------------------===//
- // ValTy - Dataflow value.
- //===--------------------------------------------------------------------===//
-
- class ValTy {
- llvm::BitVector DeclBV;
- public:
-
- void resetValues(AnalysisDataTy& AD) {
- DeclBV.resize(AD.getNumDecls());
- DeclBV.reset();
- }
-
- bool operator==(const ValTy& RHS) const {
- assert (sizesEqual(RHS));
- return DeclBV == RHS.DeclBV;
- }
-
- void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; }
-
- llvm::BitVector::reference getBit(unsigned i) {
- return DeclBV[i];
- }
-
- bool getBit(unsigned i) const {
- return DeclBV[i];
- }
-
- llvm::BitVector::reference
- operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) {
- return getBit(AD.getIdx(SD));
- }
-
- bool operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) const {
- return getBit(AD.getIdx(SD));
- }
-
- llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; }
- const llvm::BitVector::reference getDeclBit(unsigned i) const {
- return const_cast<llvm::BitVector&>(DeclBV)[i];
- }
-
- ValTy& operator|=(const ValTy& RHS) {
- assert (sizesEqual(RHS));
- DeclBV |= RHS.DeclBV;
- return *this;
- }
-
- ValTy& operator&=(const ValTy& RHS) {
- assert (sizesEqual(RHS));
- DeclBV &= RHS.DeclBV;
- return *this;
- }
-
- ValTy& OrDeclBits(const ValTy& RHS) {
- return operator|=(RHS);
- }
-
- ValTy& AndDeclBits(const ValTy& RHS) {
- return operator&=(RHS);
- }
-
- bool sizesEqual(const ValTy& RHS) const {
- return DeclBV.size() == RHS.DeclBV.size();
- }
- };
-
- //===--------------------------------------------------------------------===//
- // Some useful merge operations.
- //===--------------------------------------------------------------------===//
-
- struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
- struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
-};
-
-
-struct ExprDeclBitVector_Types {
-
- //===--------------------------------------------------------------------===//
- // AnalysisDataTy - Whole-function meta data.
- //===--------------------------------------------------------------------===//
-
- class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy {
- CFG* cfg;
- public:
- AnalysisDataTy() {}
- virtual ~AnalysisDataTy() {}
-
- void setCFG(CFG* c) { cfg = c; }
- CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
-
- bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); }
- using DeclBitVector_Types::AnalysisDataTy::isTracked;
-
- unsigned getIdx(const Stmt* S) const {
- CFG::BlkExprNumTy I = cfg->getBlkExprNum(S);
- assert(I && "expression not tracked for bitvector.");
- return I;
- }
- using DeclBitVector_Types::AnalysisDataTy::getIdx;
-
- unsigned getNumExprs() const { return cfg->getNumBlkExprs(); }
- };
-
- //===--------------------------------------------------------------------===//
- // ValTy - Dataflow value.
- //===--------------------------------------------------------------------===//
-
- class ValTy : public DeclBitVector_Types::ValTy {
- llvm::BitVector ExprBV;
- typedef DeclBitVector_Types::ValTy ParentTy;
-
- static inline ParentTy& ParentRef(ValTy& X) {
- return static_cast<ParentTy&>(X);
- }
-
- static inline const ParentTy& ParentRef(const ValTy& X) {
- return static_cast<const ParentTy&>(X);
- }
-
- public:
-
- void resetValues(AnalysisDataTy& AD) {
- ParentRef(*this).resetValues(AD);
- ExprBV.resize(AD.getNumExprs());
- ExprBV.reset();
- }
-
- bool operator==(const ValTy& RHS) const {
- return ParentRef(*this) == ParentRef(RHS)
- && ExprBV == RHS.ExprBV;
- }
-
- void copyValues(const ValTy& RHS) {
- ParentRef(*this).copyValues(ParentRef(RHS));
- ExprBV = RHS.ExprBV;
- }
-
- llvm::BitVector::reference
- operator()(const Stmt* S, const AnalysisDataTy& AD) {
- return ExprBV[AD.getIdx(S)];
- }
- const llvm::BitVector::reference
- operator()(const Stmt* S, const AnalysisDataTy& AD) const {
- return const_cast<ValTy&>(*this)(S,AD);
- }
-
- using DeclBitVector_Types::ValTy::operator();
-
-
- llvm::BitVector::reference getExprBit(unsigned i) { return ExprBV[i]; }
- const llvm::BitVector::reference getExprBit(unsigned i) const {
- return const_cast<llvm::BitVector&>(ExprBV)[i];
- }
-
- ValTy& OrExprBits(const ValTy& RHS) {
- ExprBV |= RHS.ExprBV;
- return *this;
- }
-
- ValTy& AndExprBits(const ValTy& RHS) {
- ExprBV &= RHS.ExprBV;
- return *this;
- }
-
- ValTy& operator|=(const ValTy& RHS) {
- assert (sizesEqual(RHS));
- ParentRef(*this) |= ParentRef(RHS);
- ExprBV |= RHS.ExprBV;
- return *this;
- }
-
- ValTy& operator&=(const ValTy& RHS) {
- assert (sizesEqual(RHS));
- ParentRef(*this) &= ParentRef(RHS);
- ExprBV &= RHS.ExprBV;
- return *this;
- }
-
- bool sizesEqual(const ValTy& RHS) const {
- return ParentRef(*this).sizesEqual(ParentRef(RHS))
- && ExprBV.size() == RHS.ExprBV.size();
- }
- };
-
- //===--------------------------------------------------------------------===//
- // Some useful merge operations.
- //===--------------------------------------------------------------------===//
-
- struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
- struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
-
-};
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
deleted file mode 100644
index 49850a7d6fb0..000000000000
--- a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/decls -*- C++ --*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the template class CFGRecStmtDeclVisitor, which extends
-// CFGRecStmtVisitor by implementing (typed) visitation of decls.
-//
-// FIXME: This may not be fully complete. We currently explore only subtypes
-// of ScopedDecl.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
-#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H
-
-#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-
-#define DISPATCH_CASE(CASE,CLASS) \
-case Decl::CASE: \
-static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<CLASS*>(D));\
-break;
-
-#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS(CLASS* D) {}
-#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS(CLASS* D)\
- { static_cast<ImplClass*>(this)->VisitVarDecl(D); }
-
-
-namespace clang {
-template <typename ImplClass>
-class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> {
-public:
-
- void VisitDeclRefExpr(DeclRefExpr* DR) {
- for (ScopedDecl* D = DR->getDecl(); D != NULL; D = D->getNextDeclarator())
- static_cast<ImplClass*>(this)->VisitScopedDecl(D);
- }
-
- void VisitDeclStmt(DeclStmt* DS) {
- for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
- DI != DE; ++DI) {
- ScopedDecl* D = *DI;
- static_cast<ImplClass*>(this)->VisitScopedDecl(D);
- // Visit the initializer.
- if (VarDecl* VD = dyn_cast<VarDecl>(D))
- if (Expr* I = VD->getInit())
- static_cast<ImplClass*>(this)->Visit(I);
- }
- }
-
- void VisitScopedDecl(ScopedDecl* D) {
- switch (D->getKind()) {
- DISPATCH_CASE(Function,FunctionDecl)
- DISPATCH_CASE(Var,VarDecl)
- DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
- DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
- DISPATCH_CASE(EnumConstant,EnumConstantDecl)
- DISPATCH_CASE(Typedef,TypedefDecl)
- DISPATCH_CASE(Struct,RecordDecl) // FIXME: Refine. VisitStructDecl?
- DISPATCH_CASE(Union,RecordDecl) // FIXME: Refine.
- DISPATCH_CASE(Class,RecordDecl) // FIXME: Refine.
- DISPATCH_CASE(Enum,EnumDecl)
- default:
- assert(false && "Subtype of ScopedDecl not handled.");
- }
- }
-
- DEFAULT_DISPATCH(VarDecl)
- DEFAULT_DISPATCH(FunctionDecl)
- DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
- DEFAULT_DISPATCH(ImplicitParamDecl)
- DEFAULT_DISPATCH(EnumConstantDecl)
- DEFAULT_DISPATCH(TypedefDecl)
- DEFAULT_DISPATCH(RecordDecl)
- DEFAULT_DISPATCH(EnumDecl)
- DEFAULT_DISPATCH(ObjCInterfaceDecl)
- DEFAULT_DISPATCH(ObjCClassDecl)
- DEFAULT_DISPATCH(ObjCMethodDecl)
- DEFAULT_DISPATCH(ObjCProtocolDecl)
- DEFAULT_DISPATCH(ObjCCategoryDecl)
-};
-
-} // end namespace clang
-
-#undef DISPATCH_CASE
-#undef DEFAULT_DISPATCH
-#endif
diff --git a/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h b/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
deleted file mode 100644
index 4d3201962250..000000000000
--- a/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//==- CFGRecStmtVisitor - Recursive visitor of CFG statements ---*- C++ --*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the template class CFGRecStmtVisitor, which extends
-// CFGStmtVisitor by implementing a default recursive visit of all statements.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H
-#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H
-
-#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
-
-namespace clang {
-template <typename ImplClass>
-class CFGRecStmtVisitor : public CFGStmtVisitor<ImplClass,void> {
-public:
-
- void VisitStmt(Stmt* S) {
- static_cast< ImplClass* >(this)->VisitChildren(S);
- }
-
- // Defining operator() allows the visitor to be used as a C++ style functor.
- void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h
deleted file mode 100644
index 5c3b2839449a..000000000000
--- a/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h
+++ /dev/null
@@ -1,151 +0,0 @@
-//===--- CFGStmtVisitor.h - Visitor for Stmts in a CFG ----------*- 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 CFGStmtVisitor interface, which extends
-// StmtVisitor. This interface is useful for visiting statements in a CFG
-// where some statements have implicit control-flow and thus should
-// be treated specially.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
-#define LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H
-
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/CFG.h"
-
-namespace clang {
-
-#define DISPATCH_CASE(CLASS) \
-case Stmt::CLASS ## Class: return \
-static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S));
-
-#define DEFAULT_BLOCKSTMT_VISIT(CLASS) RetTy BlockStmt_Visit ## CLASS(CLASS *S)\
-{ return\
- static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(\
- cast<Expr>(S)); }
-
-template <typename ImplClass, typename RetTy=void>
-class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
- Stmt* CurrentBlkStmt;
-
- struct NullifyStmt {
- Stmt*& S;
-
- NullifyStmt(Stmt*& s) : S(s) {}
- ~NullifyStmt() { S = NULL; }
- };
-
-public:
- CFGStmtVisitor() : CurrentBlkStmt(NULL) {}
-
- Stmt* getCurrentBlkStmt() const { return CurrentBlkStmt; }
-
- RetTy Visit(Stmt* S) {
- if (S == CurrentBlkStmt ||
- !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S))
- return StmtVisitor<ImplClass,RetTy>::Visit(S);
- else
- return RetTy();
- }
-
- /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
- /// CFGBlocks. Root statements are the statements that appear explicitly in
- /// the list of statements in a CFGBlock. For substatements, or when there
- /// is no implementation provided for a BlockStmt_XXX method, we default
- /// to using StmtVisitor's Visit method.
- RetTy BlockStmt_Visit(Stmt* S) {
- CurrentBlkStmt = S;
- NullifyStmt cleanup(CurrentBlkStmt);
-
- switch (S->getStmtClass()) {
-
- DISPATCH_CASE(StmtExpr)
- DISPATCH_CASE(ConditionalOperator)
-
- case Stmt::BinaryOperatorClass: {
- BinaryOperator* B = cast<BinaryOperator>(S);
- if (B->isLogicalOp())
- return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B);
- else if (B->getOpcode() == BinaryOperator::Comma)
- return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B);
- // Fall through.
- }
-
- default:
- if (isa<Expr>(S))
- return
- static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(cast<Expr>(S));
- else
- return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
- }
- }
-
- DEFAULT_BLOCKSTMT_VISIT(StmtExpr)
- DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator)
-
- RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr* E) {
- return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E);
- }
-
- RetTy BlockStmt_VisitExpr(Expr* E) {
- return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E);
- }
-
- RetTy BlockStmt_VisitStmt(Stmt* S) {
- return static_cast<ImplClass*>(this)->Visit(S);
- }
-
- RetTy BlockStmt_VisitLogicalOp(BinaryOperator* B) {
- return
- static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
- }
-
- RetTy BlockStmt_VisitComma(BinaryOperator* B) {
- return
- static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B);
- }
-
- //===--------------------------------------------------------------------===//
- // Utility methods. Not called by default (but subclasses may use them).
- //===--------------------------------------------------------------------===//
-
- /// VisitChildren: Call "Visit" on each child of S.
- void VisitChildren(Stmt* S) {
-
- switch (S->getStmtClass()) {
- default:
- break;
-
- case Stmt::StmtExprClass: {
- CompoundStmt* CS = cast<StmtExpr>(S)->getSubStmt();
- if (CS->body_empty()) return;
- static_cast<ImplClass*>(this)->Visit(CS->body_back());
- return;
- }
-
- case Stmt::BinaryOperatorClass: {
- BinaryOperator* B = cast<BinaryOperator>(S);
- if (B->getOpcode() != BinaryOperator::Comma) break;
- static_cast<ImplClass*>(this)->Visit(B->getRHS());
- return;
- }
- }
-
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I != E;++I)
- if (*I) static_cast<ImplClass*>(this)->Visit(*I);
- }
-};
-
-#undef DEFAULT_BLOCKSTMT_VISIT
-#undef DISPATCH_CASE
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h b/clang/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h
deleted file mode 100644
index 25101235ddd2..000000000000
--- a/clang/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//==- CFGVarDeclVisitor - Generic visitor of VarDecls in a CFG --*- C++ --*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the template class CFGVarDeclVisitor, which provides
-// a generic way to visit all the VarDecl's in a CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFG_VARDECL_VISITOR_H
-#define LLVM_CLANG_ANALYSIS_CFG_VARDECL_VISITOR_H
-
-#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/CFG.h"
-
-namespace clang {
-
-template <typename ImplClass>
-class CFGVarDeclVisitor : public CFGStmtVisitor<ImplClass> {
- const CFG& cfg;
-public:
- CFGVarDeclVisitor(const CFG& c) : cfg(c) {}
-
- void VisitStmt(Stmt* S) {
- static_cast<ImplClass*>(this)->VisitChildren(S);
- }
-
- void VisitDeclRefExpr(DeclRefExpr* DR) {
- static_cast<ImplClass*>(this)->VisitDeclChain(DR->getDecl());
- }
-
- void VisitDeclStmt(DeclStmt* DS) {
- static_cast<ImplClass*>(this)->VisitDeclChain(DS->getDecl());
- }
-
- void VisitDeclChain(ScopedDecl* D) {
- for (; D != NULL ; D = D->getNextDeclarator())
- static_cast<ImplClass*>(this)->VisitScopedDecl(D);
- }
-
- void VisitScopedDecl(ScopedDecl* D) {
- if (VarDecl* V = dyn_cast<VarDecl>(D))
- static_cast<ImplClass*>(this)->VisitVarDecl(V);
- }
-
- void VisitVarDecl(VarDecl* D) {}
-
- void VisitAllDecls() {
- for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI)
- for (CFGBlock::const_iterator SI=BI->begin(),SE = BI->end();SI != SE;++SI)
- static_cast<ImplClass*>(this)->BlockStmt_Visit(const_cast<Stmt*>(*SI));
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
deleted file mode 100644
index 8b0637f59ee2..000000000000
--- a/clang/include/clang/Basic/Diagnostic.h
+++ /dev/null
@@ -1,213 +0,0 @@
-//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- 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 Diagnostic-related interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_DIAGNOSTIC_H
-#define LLVM_CLANG_DIAGNOSTIC_H
-
-#include "clang/Basic/SourceLocation.h"
-#include <string>
-#include <cassert>
-
-namespace clang {
- class DiagnosticClient;
- class SourceRange;
- class SourceManager;
-
- // Import the diagnostic enums themselves.
- namespace diag {
- class CustomDiagInfo;
-
- /// diag::kind - All of the diagnostics that can be emitted by the frontend.
- enum kind {
-#define DIAG(ENUM,FLAGS,DESC) ENUM,
-#include "DiagnosticKinds.def"
- NUM_BUILTIN_DIAGNOSTICS
- };
-
- /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
- /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
- /// (emit as an error), or MAP_DEFAULT (handle the default way).
- enum Mapping {
- MAP_DEFAULT = 0, //< Do not map this diagnostic.
- MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it.
- MAP_WARNING = 2, //< Map this diagnostic to a warning.
- MAP_ERROR = 3 //< Map this diagnostic to an error.
- };
- }
-
-/// Diagnostic - This concrete class is used by the front-end to report
-/// problems and issues. It massages the diagnostics (e.g. handling things like
-/// "report warnings as errors" and passes them off to the DiagnosticClient for
-/// reporting to the user.
-class Diagnostic {
-public:
- /// Level - The level of the diagnostic, after it has been through mapping.
- enum Level {
- Ignored, Note, Warning, Error, Fatal
- };
-
-private:
- bool IgnoreAllWarnings; // Ignore all warnings: -w
- bool WarningsAsErrors; // Treat warnings like errors:
- bool WarnOnExtensions; // Enables warnings for gcc extensions: -pedantic.
- bool ErrorOnExtensions; // Error on extensions: -pedantic-errors.
- bool SuppressSystemWarnings;// Suppress warnings in system headers.
- DiagnosticClient *Client;
-
- /// DiagMappings - Mapping information for diagnostics. Mapping info is
- /// packed into two bits per diagnostic.
- unsigned char DiagMappings[(diag::NUM_BUILTIN_DIAGNOSTICS+3)/4];
-
- /// ErrorOccurred - This is set to true when an error is emitted, and is
- /// sticky.
- bool ErrorOccurred;
-
- unsigned NumDiagnostics; // Number of diagnostics reported
- unsigned NumErrors; // Number of diagnostics that are errors
-
- /// CustomDiagInfo - Information for uniquing and looking up custom diags.
- diag::CustomDiagInfo *CustomDiagInfo;
-
-public:
- explicit Diagnostic(DiagnosticClient *client = 0);
- ~Diagnostic();
-
- //===--------------------------------------------------------------------===//
- // Diagnostic characterization methods, used by a client to customize how
- //
-
- DiagnosticClient *getClient() { return Client; };
- const DiagnosticClient *getClient() const { return Client; };
-
- void setClient(DiagnosticClient* client) { Client = client; }
-
- /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
- /// ignored. If this and WarningsAsErrors are both set, then this one wins.
- void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
- bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
-
- /// setWarningsAsErrors - When set to true, any warnings reported are issued
- /// as errors.
- void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
- bool getWarningsAsErrors() const { return WarningsAsErrors; }
-
- /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions,
- /// the equivalent of GCC's -pedantic.
- void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; }
- bool getWarnOnExtensions() const { return WarnOnExtensions; }
-
- /// setErrorOnExtensions - When set to true issue errors for GCC extensions
- /// instead of warnings. This is the equivalent to GCC's -pedantic-errors.
- void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; }
- bool getErrorOnExtensions() const { return ErrorOnExtensions; }
-
- /// setSuppressSystemWarnings - When set to true mask warnings that
- /// come from system headers.
- void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
- bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
-
- /// setDiagnosticMapping - This allows the client to specify that certain
- /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
- void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
- assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS &&
- "Can only map builtin diagnostics");
- assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!");
- unsigned char &Slot = DiagMappings[Diag/4];
- unsigned Bits = (Diag & 3)*2;
- Slot &= ~(3 << Bits);
- Slot |= Map << Bits;
- }
-
- /// getDiagnosticMapping - Return the mapping currently set for the specified
- /// diagnostic.
- diag::Mapping getDiagnosticMapping(diag::kind Diag) const {
- return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3);
- }
-
- bool hasErrorOccurred() const { return ErrorOccurred; }
-
- unsigned getNumErrors() const { return NumErrors; }
- unsigned getNumDiagnostics() const { return NumDiagnostics; }
-
- /// getCustomDiagID - Return an ID for a diagnostic with the specified message
- /// and level. If this is the first request for this diagnosic, it is
- /// registered and created, otherwise the existing ID is returned.
- unsigned getCustomDiagID(Level L, const char *Message);
-
- //===--------------------------------------------------------------------===//
- // Diagnostic classification and reporting interfaces.
- //
-
- /// getDescription - Given a diagnostic ID, return a description of the
- /// issue.
- const char *getDescription(unsigned DiagID);
-
- /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
- /// level of the specified diagnostic ID is a Note, Warning, or Extension.
- /// Note that this only works on builtin diagnostics, not custom ones.
- static bool isBuiltinNoteWarningOrExtension(unsigned DiagID);
-
- /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
- /// object, classify the specified diagnostic ID into a Level, consumable by
- /// the DiagnosticClient.
- Level getDiagnosticLevel(unsigned DiagID) const;
-
- /// Report - Issue the message to the client. DiagID is a member of the
- /// diag::kind enum.
- void Report(FullSourceLoc Pos, unsigned DiagID,
- const std::string *Strs = 0, unsigned NumStrs = 0,
- const SourceRange *Ranges = 0, unsigned NumRanges = 0) {
- Report(NULL, Pos, DiagID, Strs, NumStrs, Ranges, NumRanges);
- }
-
- /// Report - Issue the message to the client. DiagID is a member of the
- /// diag::kind enum.
- void Report(unsigned DiagID,
- const std::string *Strs = 0, unsigned NumStrs = 0,
- const SourceRange *Ranges = 0, unsigned NumRanges = 0) {
- Report(FullSourceLoc(), DiagID, Strs, NumStrs, Ranges, NumRanges);
- }
-
- /// Report - Issue the message to the specified client.
- /// DiagID is a member of the diag::kind enum.
- void Report(DiagnosticClient* C, FullSourceLoc Pos, unsigned DiagID,
- const std::string *Strs = 0, unsigned NumStrs = 0,
- const SourceRange *Ranges = 0, unsigned NumRanges = 0);
-};
-
-/// DiagnosticClient - This is an abstract interface implemented by clients of
-/// the front-end, which formats and prints fully processed diagnostics.
-class DiagnosticClient {
-protected:
- std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs);
-public:
- virtual ~DiagnosticClient();
-
- /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
- /// capturing it to a log as needed.
- virtual void HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level DiagLevel,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges) = 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
deleted file mode 100644
index 4e4a42f7ae87..000000000000
--- a/clang/include/clang/Basic/DiagnosticKinds.def
+++ /dev/null
@@ -1,1276 +0,0 @@
-//===-- DiagnosticKinds.def - C Family Diagnostic Kind Database -*- 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 DiagnosticKind database.
-//
-//===----------------------------------------------------------------------===//
-
-// Flags for diagnostic:
-//
-// DIAG_TYPE - Allows one of:
-// NOTE - Informational message.
-// WARNING - Warning.
-// EXTENSION - Notification that an extension to the language is being used.
-// EXTWARN - Warning for behaviour that is supported as an extension. This
-// differs from EXTENSION in that the warning is always emitted
-// by default.
-// ERROR - Error, compilation will stop after parsing completes.
-
-//===----------------------------------------------------------------------===//
-// Lexer Diagnostics
-//===----------------------------------------------------------------------===//
-
-DIAG(null_in_string, WARNING,
- "null character(s) preserved in string literal")
-DIAG(null_in_char , WARNING,
- "null character(s) preserved in character literal")
-DIAG(null_in_file , WARNING,
- "null character ignored")
-DIAG(nested_block_comment, WARNING,
- "\"/*\" within block comment")
-DIAG(escaped_newline_block_comment_end, WARNING,
- "escaped newline between */ characters at block comment end")
-DIAG(backslash_newline_space, WARNING,
- "backslash and newline separated by space")
-
-// Trigraphs.
-DIAG(trigraph_ignored, WARNING, "trigraph ignored")
-DIAG(trigraph_ignored_block_comment, WARNING,
- "ignored trigraph would end block comment")
-DIAG(trigraph_ends_block_comment, WARNING,
- "trigraph ends block comment")
-DIAG(trigraph_converted, WARNING,
- "trigraph converted to '%0' character")
-
-DIAG(ext_multi_line_bcpl_comment, EXTENSION,
- "multi-line // comment")
-DIAG(ext_bcpl_comment, EXTENSION,
- "// comments are not allowed in this language")
-DIAG(ext_no_newline_eof, EXTENSION,
- "no newline at end of file")
-DIAG(ext_backslash_newline_eof, EXTENSION,
- "backslash-newline at end of file")
-DIAG(ext_dollar_in_identifier, EXTENSION,
- "'$' in identifier")
-DIAG(charize_microsoft_ext, EXTENSION,
- "@# is a microsoft extension")
-
-DIAG(ext_token_used, EXTENSION,
- "extension used")
-
-DIAG(err_unterminated_string, ERROR,
- "missing terminating \" character")
-DIAG(err_unterminated_char, ERROR,
- "missing terminating ' character")
-DIAG(err_empty_character, ERROR,
- "empty character constant")
-DIAG(err_unterminated_block_comment, ERROR,
- "unterminated /* comment")
-DIAG(err_invalid_character_to_charify, ERROR,
- "invalid argument to convert to character")
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Diagnostics
-//===----------------------------------------------------------------------===//
-
-DIAG(pp_hash_warning, WARNING,
- "#warning%0")
-DIAG(pp_include_next_in_primary, WARNING,
- "#include_next in primary source file")
-DIAG(pp_include_next_absolute_path, WARNING,
- "#include_next with absolute path")
-DIAG(ext_c99_whitespace_required_after_macro_name, WARNING,
- "ISO C99 requires whitespace after the macro name")
-DIAG(pp_pragma_once_in_main_file, WARNING,
- "#pragma once in main file")
-DIAG(pp_pragma_sysheader_in_main_file, WARNING,
- "#pragma system_header ignored in main file")
-DIAG(pp_poisoning_existing_macro, WARNING,
- "poisoning existing macro")
-DIAG(pp_out_of_date_dependency, WARNING,
- "current file is older than dependency %0")
-DIAG(pp_undef_builtin_macro, WARNING,
- "undefining builtin macro")
-DIAG(pp_redef_builtin_macro, WARNING,
- "redefining builtin macro")
-DIAG(pp_macro_not_used, WARNING, // -Wunused-macros
- "macro is not used")
-DIAG(pp_invalid_string_literal, WARNING,
- "invalid string literal, ignoring final '\\'")
-DIAG(warn_pp_expr_overflow, WARNING,
- "integer overflow in preprocessor expression")
-DIAG(warn_pp_convert_lhs_to_positive, WARNING,
- "left side of operator converted from negative value to unsigned: %0")
-DIAG(warn_pp_convert_rhs_to_positive, WARNING,
- "right side of operator converted from negative value to unsigned: %0")
-
-DIAG(ext_pp_import_directive, EXTENSION,
- "#import is a language extension")
-DIAG(ext_pp_ident_directive, EXTENSION,
- "#ident is a language extension")
-DIAG(ext_pp_include_next_directive, EXTENSION,
- "#include_next is a language extension")
-DIAG(ext_pp_warning_directive, EXTENSION,
- "#warning is a language extension")
-DIAG(ext_pp_extra_tokens_at_eol, EXTENSION,
- "extra tokens at end of %0 directive")
-DIAG(ext_pp_comma_expr, EXTENSION,
- "comma operator in operand of #if")
-DIAG(ext_pp_bad_vaargs_use, EXTENSION,
- "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro")
-DIAG(ext_pp_macro_redef, EXTENSION,
- "\"%0\" macro redefined")
-DIAG(ext_pp_macro_redef2, EXTENSION,
- "this is previous definition")
-DIAG(ext_variadic_macro, EXTENSION,
- "variadic macros were introduced in C99")
-DIAG(ext_named_variadic_macro, EXTENSION,
- "named variadic macros are a GNU extension")
-DIAG(ext_embedded_directive, EXTENSION,
- "embedding a directive within macro arguments is not portable")
-DIAG(ext_missing_varargs_arg, EXTENSION,
- "varargs argument missing, but tolerated as an extension")
-DIAG(ext_empty_fnmacro_arg, EXTENSION,
- "empty macro arguments were standardized in C99")
-
-DIAG(ext_pp_base_file, EXTENSION,
- "__BASE_FILE__ is a language extension")
-DIAG(ext_pp_include_level, EXTENSION,
- "__INCLUDE_LEVEL__ is a language extension")
-DIAG(ext_pp_timestamp, EXTENSION,
- "__TIMESTAMP__ is a language extension")
-
-DIAG(err_pp_invalid_directive, ERROR,
- "invalid preprocessing directive")
-DIAG(err_pp_hash_error, ERROR,
- "#error%0")
-DIAG(err_pp_file_not_found, ERROR,
- "'%0' file not found")
-DIAG(err_pp_empty_filename, ERROR,
- "empty filename")
-DIAG(err_pp_include_too_deep, ERROR,
- "#include nested too deeply")
-DIAG(err_pp_expects_filename, ERROR,
- "expected \"FILENAME\" or <FILENAME>")
-DIAG(err_pp_macro_not_identifier, ERROR,
- "macro names must be identifiers")
-DIAG(err_pp_missing_macro_name, ERROR,
- "macro name missing")
-DIAG(err_pp_missing_rparen_in_macro_def, ERROR,
- "missing ')' in macro parameter list")
-DIAG(err_pp_invalid_tok_in_arg_list, ERROR,
- "invalid token in macro parameter list")
-DIAG(err_pp_expected_ident_in_arg_list, ERROR,
- "expected identifier in macro parameter list")
-DIAG(err_pp_expected_comma_in_arg_list, ERROR,
- "expected comma in macro parameter list")
-DIAG(err_pp_duplicate_name_in_arg_list, ERROR,
- "duplicate macro parameter name \"%0\"")
-DIAG(err_pp_stringize_not_parameter, ERROR,
- "'#' is not followed by a macro parameter")
-DIAG(err_pp_malformed_ident, ERROR,
- "invalid #ident directive")
-DIAG(err_pp_unterminated_conditional, ERROR,
- "unterminated conditional directive")
-DIAG(pp_err_else_after_else, ERROR,
- "#else after #else")
-DIAG(pp_err_elif_after_else, ERROR,
- "#elif after #else")
-DIAG(pp_err_else_without_if, ERROR,
- "#else without #if")
-DIAG(pp_err_elif_without_if, ERROR,
- "#elif without #if")
-DIAG(err_pp_endif_without_if, ERROR,
- "#endif without #if")
-DIAG(err_pp_expected_value_in_expr, ERROR,
- "expected value in expression")
-DIAG(err_pp_missing_val_before_operator, ERROR,
- "missing value before operator")
-DIAG(err_pp_expected_rparen, ERROR,
- "expected ')' in preprocessor expression")
-DIAG(err_pp_expected_eol, ERROR,
- "expected end of line in preprocessor expression")
-DIAG(warn_pp_undef_identifier, WARNING,
- "\"%0\" is not defined, evaluates to 0")
-DIAG(err_pp_defined_requires_identifier, ERROR,
- "operator \"defined\" requires an identifier")
-DIAG(err_pp_missing_rparen, ERROR,
- "missing ')' after \"defined\"")
-DIAG(err_pp_colon_without_question, ERROR,
- "':' without preceding '?'")
-DIAG(err_pp_division_by_zero, ERROR,
- "division by zero in preprocessor expression")
-DIAG(err_pp_remainder_by_zero, ERROR,
- "remainder by zero in preprocessor expression")
-DIAG(err_pp_expr_bad_token_binop, ERROR,
- "token is not a valid binary operator in a preprocessor subexpression")
-DIAG(err_pp_expr_bad_token_start_expr, ERROR,
- "invalid token at start of a preprocessor expression")
-DIAG(err_pp_invalid_poison, ERROR,
- "can only poison identifier tokens")
-DIAG(err_pp_used_poisoned_id, ERROR,
- "attempt to use a poisoned identifier")
-DIAG(err__Pragma_malformed, ERROR,
- "_Pragma takes a parenthesized string literal")
-DIAG(err_defined_macro_name, ERROR,
- "\"defined\" cannot be used as a macro name")
-DIAG(err_paste_at_start, ERROR,
- "\"##\" cannot appear at start of macro expansion")
-DIAG(err_paste_at_end, ERROR,
- "\"##\" cannot appear at end of macro expansion")
-DIAG(ext_paste_comma, EXTENSION,
- "Use of comma pasting extension is non-portable")
-DIAG(err_unterm_macro_invoc, ERROR,
- "unterminated function-like macro invocation")
-DIAG(err_too_many_args_in_macro_invoc, ERROR,
- "too many arguments provided to function-like macro invocation")
-DIAG(err_too_few_args_in_macro_invoc, ERROR,
- "too few arguments provided to function-like macro invocation")
-DIAG(err_pp_bad_paste, ERROR,
- "pasting formed \"%0\", an invalid preprocessing token")
-DIAG(err_pp_operator_used_as_macro_name, ERROR,
- "C++ operator \"%0\" cannot be used as a macro name")
-DIAG(err_pp_illegal_floating_literal, ERROR,
- "floating point literal in preprocessor expression")
-
-// Should be a sorry?
-DIAG(err_pp_I_dash_not_supported, ERROR,
- "-I- not supported, please use -iquote instead")
-
-//===----------------------------------------------------------------------===//
-// Parser Diagnostics
-//===----------------------------------------------------------------------===//
-DIAG(w_type_defaults_to_int, WARNING,
- "type defaults to 'int'")
-DIAG(w_no_declarators, WARNING,
- "declaration does not declare anything")
-DIAG(w_asm_qualifier_ignored, WARNING,
- "ignored %0 qualifier on asm")
-
-DIAG(ext_empty_source_file, EXTENSION,
- "ISO C forbids an empty source file")
-DIAG(ext_top_level_semi, EXTENSION,
- "ISO C does not allow an extra ';' outside of a function")
-DIAG(ext_extra_struct_semi, EXTENSION,
- "ISO C does not allow an extra ';' inside a struct or union")
-DIAG(ext_missing_declspec, EXTENSION,
- "declaration specifier missing, defaulting to 'int'")
-DIAG(ext_missing_type_specifier, EXTENSION,
- "type specifier missing, defaults to 'int'")
-
-DIAG(ext_duplicate_declspec, EXTENSION,
- "duplicate '%0' declaration specifier")
-DIAG(ext_plain_complex, EXTENSION,
- "ISO C does not support plain '_Complex' meaning '_Complex double'")
-DIAG(ext_integer_complex, EXTENSION,
- "ISO C does not support complex integer types")
-DIAG(ext_thread_before, EXTENSION,
- "'__thread' before 'static'")
-DIAG(ext_integer_increment_complex, EXTENSION,
- "ISO C does not support '++'/'--' on complex integer types")
-DIAG(ext_integer_complement_complex, EXTENSION,
- "ISO C does not support '~' for complex conjugation")
-
-DIAG(ext_mixed_decls_code, EXTENSION,
- "ISO C90 forbids mixing declarations and code")
-
-DIAG(ext_empty_struct_union_enum, EXTENSION,
- "use of empty %0 extension")
-DIAG(warn_enum_value_overflow, WARNING,
- "overflow in enumeration value")
-
-DIAG(ext_ident_list_in_param, EXTENSION,
- "type-less parameter names in function declaration")
-DIAG(ext_c99_array_usage, EXTENSION,
- "use of C99-specific array features")
-DIAG(ext_c99_variable_decl_in_for_loop, EXTENSION,
- "variable declaration in for loop is a C99-specific feature")
-DIAG(ext_c99_compound_literal, EXTENSION,
- "compound literals are a C99-specific feature")
-DIAG(ext_c99_enumerator_list_comma, EXTENSION,
- "commas at the end of enumerator lists are a C99-specific feature")
-
-DIAG(ext_gnu_void_ptr, EXTENSION,
- "use of GNU void* extension")
-DIAG(ext_gnu_indirect_goto, EXTENSION,
- "use of GNU indirect-goto extension")
-DIAG(ext_gnu_address_of_label, EXTENSION,
- "use of GNU address-of-label extension")
-DIAG(ext_gnu_statement_expr, EXTENSION,
- "use of GNU statement expression extension")
-DIAG(ext_gnu_conditional_expr, EXTENSION,
- "use of GNU ?: expression extension, eliding middle term")
-DIAG(ext_gnu_empty_initializer, EXTENSION,
- "use of GNU empty initializer extension")
-DIAG(ext_gnu_array_range, EXTENSION,
- "use of GNU array range extension")
-DIAG(ext_gnu_missing_equal_designator, EXTENSION,
- "use of GNU 'missing =' extension in designator")
-DIAG(ext_gnu_old_style_field_designator, EXTENSION,
- "use of GNU old-style field designator extension")
-DIAG(ext_gnu_case_range, EXTENSION,
- "use of GNU case range extension")
-
-// Generic errors.
-DIAG(err_parse_error, ERROR,
- "parse error")
-DIAG(err_expected_expression, ERROR,
- "expected expression")
-DIAG(err_expected_type, ERROR,
- "expected a type")
-DIAG(err_expected_external_declaration, ERROR,
- "expected external declaration")
-DIAG(err_expected_ident, ERROR,
- "expected identifier")
-DIAG(err_expected_ident_lparen, ERROR,
- "expected identifier or '('")
-DIAG(err_expected_ident_lbrace, ERROR,
- "expected identifier or '{'")
-DIAG(err_expected_lbrace, ERROR,
- "expected '{'")
-DIAG(err_expected_lparen, ERROR,
- "expected '('")
-DIAG(err_expected_rparen, ERROR,
- "expected ')'")
-DIAG(err_expected_rsquare, ERROR,
- "expected ']'")
-DIAG(err_expected_rbrace, ERROR,
- "expected '}'")
-DIAG(err_expected_greater, ERROR,
- "expected '>'")
-DIAG(err_expected_semi_decl_list, ERROR,
- "expected ';' at end of declaration list")
-DIAG(ext_expected_semi_decl_list, EXTENSION,
- "expected ';' at end of declaration list")
-DIAG(err_function_declared_typedef, ERROR,
- "function definition declared 'typedef'")
-DIAG(err_expected_fn_body, ERROR,
- "expected function body after function declarator")
-DIAG(err_expected_method_body, ERROR,
- "expected method body")
-DIAG(err_expected_after_declarator, ERROR,
- "expected '=', ',', ';', 'asm', or '__attribute__' after declarator")
-DIAG(err_expected_statement, ERROR,
- "expected statement")
-DIAG(err_expected_lparen_after, ERROR,
- "expected '(' after '%0'")
-DIAG(err_expected_less_after, ERROR,
- "expected '<' after '%0'")
-DIAG(err_expected_comma, ERROR,
- "expected ','")
-DIAG(err_expected_lbrace_in_compound_literal, ERROR,
- "expected '{' in compound literal")
-DIAG(err_expected_while, ERROR,
- "expected 'while' in do/while loop")
-DIAG(err_expected_semi_after, ERROR,
- "expected ';' after %0")
-DIAG(err_expected_semi_after_expr, ERROR,
- "expected ';' after expression")
-DIAG(err_expected_semi_for, ERROR,
- "expected ';' in 'for' statement specifier")
-DIAG(err_non_variable_decl_in_for, ERROR,
- "declaration of non-local variable in 'for' loop")
-DIAG(err_expected_colon_after, ERROR,
- "expected ':' after %0")
-DIAG(err_label_end_of_compound_statement, ERROR,
- "label at end of compound statement: expected statement")
-DIAG(err_expected_colon, ERROR,
- "expected ':'")
-DIAG(err_expected_string_literal, ERROR,
- "expected string literal")
-DIAG(err_expected_asm_operand, ERROR,
- "expected string literal or '[' for asm operand")
-DIAG(err_expected_selector_for_method, ERROR,
- "expected selector for Objective-C method")
-
-DIAG(err_unexpected_at, ERROR,
- "unexpected '@' in program")
-
-/// err_matching - this is used as a continuation of a previous error, e.g. to
-/// specify the '(' when we expected a ')'. This should probably be some
-/// special sort of diagnostic kind to indicate that it is the second half of
-/// the previous diagnostic.
-DIAG(err_matching, ERROR,
- "to match this '%0'")
-
-/// Objective-C parser diagnostics
-DIAG(err_unexpected_interface, ERROR,
- "unexpected interface name '%0': expected expression")
-DIAG(err_objc_no_attributes_on_category, ERROR,
- "attributes may not be specified on a category")
-DIAG(err_objc_missing_end, ERROR,
- "missing @end")
-DIAG(warn_objc_protocol_qualifier_missing_id, WARNING,
- "protocol qualifiers without 'id' is archaic")
-DIAG(warn_objc_array_of_interfaces, WARNING,
- "array of interface '%0' should probably be an array of pointers")
-
-DIAG(err_invalid_receiver_to_message, ERROR,
- "invalid receiver to message expression")
-DIAG(err_objc_illegal_visibility_spec, ERROR,
- "illegal visibility specification")
-DIAG(err_objc_illegal_interface_qual, ERROR,
- "illegal interface qualifier")
-DIAG(err_objc_expected_equal, ERROR,
- "setter/getter expects '=' followed by name")
-DIAG(err_objc_expected_property_attr, ERROR,
- "unknown property attribute detected")
-DIAG(err_objc_unexpected_attr, ERROR,
- "prefix attribute must be followed by an interface or protocol")
-DIAG(err_objc_property_attr_mutually_exclusive, ERROR,
- "property attributes '%0' and '%1' are mutually exclusive")
-DIAG(warn_objc_property_no_assignment_attribute, WARNING,
- "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed")
-DIAG(warn_objc_property_default_assign_on_object, WARNING,
- "default property attribute 'assign' not appropriate for non-gc object")
-DIAG(err_objc_property_requires_object, ERROR,
- "property with '%0' attribute must be of object type")
-DIAG(err_objc_protocol_required, ERROR,
- "@required may be specified in protocols only")
-DIAG(err_objc_protocol_optional, ERROR,
- "@optional may be specified in protocols only")
-DIAG(err_missing_catch_finally, ERROR,
- "@try statement without a @catch and @finally clause")
-DIAG(err_objc_concat_string, ERROR,
- "unexpected token after Objective-C string")
-DIAG(err_undef_superclass, ERROR,
- "cannot find interface declaration for '%0', superclass of '%1'")
-DIAG(err_duplicate_class_def, ERROR,
- "duplicate interface declaration for class '%0'")
-DIAG(warn_undef_protocolref, WARNING,
- "cannot find protocol definition for '%0'")
-DIAG(err_duplicate_protocol_def, ERROR,
- "duplicate protocol declaration of '%0'")
-DIAG(err_undef_interface, ERROR,
- "cannot find interface declaration for '%0'")
-DIAG(warn_dup_category_def, WARNING,
- "duplicate interface declaration for category '%0(%1)'")
-DIAG(warn_undef_interface, WARNING,
- "cannot find interface declaration for '%0'")
-DIAG(err_dup_implementation_class, ERROR,
- "reimplementation of class '%0'")
-DIAG(err_conflicting_super_class, ERROR,
- "conflicting super class name '%0'")
-DIAG(err_conflicting_ivar_name, ERROR,
- "conflicting instance variable name '%0'")
-DIAG(err_inconsistant_ivar_count, ERROR,
- "inconsistent number of instance variables specified")
-DIAG(err_conflicting_ivar_type, ERROR,
- "conflicting instance variable type")
-DIAG(warn_undef_method_impl, WARNING,
- "method definition for '%0' not found")
-DIAG(warn_incomplete_impl, WARNING,
- "incomplete implementation")
-DIAG(warn_multiple_method_decl, WARNING,
- "multiple methods named '%0' found")
-DIAG(warn_using_decl, WARNING,
- "using")
-DIAG(warn_also_found_decl, WARNING,
- "also found")
-DIAG(error_duplicate_method_decl, ERROR,
- "duplicate declaration of method '%0'")
-DIAG(err_previous_declaration, ERROR,
- "previous declaration is here")
-DIAG(err_previous_implicit_declaration, ERROR,
- "previous implicit declaration is here")
-DIAG(err_undeclared_protocol, ERROR,
- "cannot find protocol declaration for '%0'")
-DIAG(err_missing_sel_definition, ERROR,
- "cannot find definition of 'SEL'")
-DIAG(err_missing_id_definition, ERROR,
- "cannot find definition of 'id'")
-DIAG(err_missing_proto_definition, ERROR,
- "cannot find definition of 'Protocol'")
-DIAG(err_missing_class_definition, ERROR,
- "cannot find definition of 'Class'")
-DIAG(warn_previous_alias_decl, WARNING,
- "previously declared alias is ignored")
-DIAG(warn_previous_declaration, WARNING,
- "previous declaration is here")
-DIAG(err_conflicting_aliasing_type, ERROR,
- "conflicting types for alias '%0'")
-DIAG(err_statically_allocated_object, ERROR,
- "statically allocated Objective-C object '%0'")
-DIAG(warn_method_not_found, WARNING,
- "method '%0%1' not found (return type defaults to 'id')")
-DIAG(warn_method_not_found_in_protocol, WARNING,
- "method '%0%1' not found in protocol (return type defaults to 'id')")
-DIAG(err_collection_expr_type, ERROR,
- "collection expression type ('%0') is not a valid object")
-DIAG(err_selector_element_type, ERROR,
- "selector element type ('%0') is not a valid object")
-DIAG(err_selector_element_not_lvalue, ERROR,
- "selector element is not a valid lvalue")
-DIAG(err_toomany_element_decls, ERROR,
- "Only one element declaration is allowed")
-DIAG(warn_expected_implementation, WARNING,
- "@end must appear in an @implementation context")
-DIAG(error_missing_method_context, ERROR,
- "missing context for method declaration")
-DIAG(error_bad_receiver_type, ERROR,
- "bad receiver type '%0'")
-DIAG(error_no_super_class, ERROR,
- "no super class declared in @interface for '%0'")
-DIAG(error_missing_property_context, ERROR,
- "missing context for property implementation declaration")
-DIAG(error_bad_property_context, ERROR,
- "property implementation must be in a class or category implementation")
-DIAG(error_bad_property_decl, ERROR,
- "property implementation must have its declaration in interface '%0'")
-DIAG(error_bad_category_property_decl, ERROR,
- "property implementation must have its declaration in the category '%0'")
-DIAG(error_property_ivar_decl, ERROR,
- "property synthesize requires specification of an ivar")
-DIAG(error_dynamic_property_ivar_decl, ERROR,
- "dynamic property can not have ivar specification")
-DIAG(error_missing_property_interface, ERROR,
- "property implementation in a category with no category declaration")
-DIAG(error_missing_property_ivar_decl, ERROR,
- "synthesized property '%0' must either be named the same as a compatible"
- " ivar or must explicitly name an ivar")
-DIAG(error_synthesize_category_decl, ERROR,
- "@synthesize not allowed in a category's implementation")
-DIAG(error_property_ivar_type, ERROR,
- "type of property '%0' does not match type of ivar '%1'")
-DIAG(warn_readonly_property, WARNING,
- "attribute 'readonly' of property '%0' restricts attribute "
- "'readwrite' of property inherited from '%1'")
-DIAG(warn_property_attribute, WARNING,
- "property '%0' '%1' attribute does not match the property inherited from'%2' ")
-DIAG(warn_property_type, WARNING,
- "property type '%0' does not match property type inherited from '%1'")
-
-/// C++ parser diagnostics
-DIAG(err_no_declarators, ERROR,
- "declaration does not declare anything")
-DIAG(err_func_def_no_params, ERROR,
- "function definition does not declare parameters")
-DIAG(err_expected_lparen_after_type, ERROR,
- "expected '(' for function-style cast or type construction")
-DIAG(err_expected_equal_after_declarator, ERROR,
- "expected '=' after declarator")
-DIAG(warn_statement_disambiguation, WARNING,
- "statement was disambiguated as %0")
-
-// Language specific pragmas
-
-// #pragma pack
-DIAG(warn_pragma_pack_expected_lparen, WARNING,
- "missing '(' after '#pragma pack' - ignoring")
-DIAG(warn_pragma_pack_expected_rparen, WARNING,
- "missing ')' after '#pragma pack' - ignoring")
-DIAG(warn_pragma_pack_invalid_action, WARNING,
- "unknown action for '#pragma pack' - ignored")
-DIAG(warn_pragma_pack_invalid_constant, WARNING,
- "invalid constant for '#pragma pack', expected %0 - ignored")
-DIAG(warn_pragma_pack_malformed, WARNING,
- "malformed '#pragma pack', expected '#pragma pack(%0 [, id] [, n])' - ignored")
-
-//===----------------------------------------------------------------------===//
-// Semantic Analysis
-//===----------------------------------------------------------------------===//
-
-// Constant expressions
-DIAG(err_expr_not_constant, ERROR,
- "expression is invalid in a constant expression")
-DIAG(err_expr_divide_by_zero, ERROR,
- "division by zero")
-DIAG(ext_comma_in_constant_expr, EXTENSION,
- "C does not permit evaluated commas in constant expression")
-
-// Semantic analysis of string and character constant literals.
-DIAG(ext_nonstandard_escape, EXTENSION,
- "use of non-standard escape character '\\%0'")
-DIAG(ext_unknown_escape, EXTENSION,
- "unknown escape sequence '\\%0'")
-DIAG(warn_extraneous_wide_char_constant, WARNING,
- "extraneous characters in wide character constant ignored")
-DIAG(warn_char_constant_too_large, WARNING,
- "character constant too long for its type")
-DIAG(warn_hex_escape_too_large, WARNING,
- "hex escape sequence out of range")
-DIAG(warn_octal_escape_too_large, WARNING,
- "octal escape sequence out of range")
-
-DIAG(err_hex_escape_no_digits, ERROR,
- "\\x used with no following hex digits")
-
-DIAG(err_predef_outside_function, ERROR,
- "predefined identifier is only valid inside function")
-
-// Declarations.
-DIAG(err_typename_requires_specqual, ERROR,
- "type name requires a specifier or qualifier")
-DIAG(err_typename_invalid_storageclass, ERROR,
- "type name does not allow storage class to be specified")
-DIAG(err_typename_invalid_functionspec, ERROR,
- "type name does not allow function specifier to be specified")
-DIAG(err_invalid_decl_spec_combination, ERROR,
- "cannot combine with previous '%0' declaration specifier")
-DIAG(err_invalid_sign_spec, ERROR,
- "'%0' cannot be signed or unsigned")
-DIAG(ext_invalid_sign_spec, EXTENSION,
- "'%0' cannot be signed or unsigned")
-DIAG(err_invalid_short_spec, ERROR,
- "'short %0' is invalid")
-DIAG(err_invalid_long_spec, ERROR,
- "'long %0' is invalid")
-DIAG(err_invalid_longlong_spec, ERROR,
- "'long long %0' is invalid")
-DIAG(ext_longlong, EXTENSION,
- "'long long' is an extension when C99 mode is not enabled")
-DIAG(err_invalid_complex_spec, ERROR,
- "'_Complex %0' is invalid")
-DIAG(err_invalid_thread_spec, ERROR,
- "'__thread %0' is invalid")
-DIAG(err_ellipsis_first_arg, ERROR,
- "ISO C requires a named argument before '...'")
-DIAG(err_unspecified_vla_size_with_static, ERROR,
- "'static' may not be used with an unspecified variable length array size")
-DIAG(ext_vla, EXTENSION,
- "variable length arrays are a C99 feature, accepted as an extension")
-DIAG(err_invalid_storage_class_in_func_decl, ERROR,
- "invalid storage class specifier in function declarator")
-DIAG(ext_anon_param_requires_type_specifier, EXTENSION,
- "type specifier required for unnamed parameter, defaults to int")
-DIAG(err_missing_param, ERROR,
- "expected parameter declarator")
-
-DIAG(err_invalid_reference_qualifier_application, ERROR,
- "'%0' qualifier may not be applied to a reference")
-DIAG(err_declarator_need_ident, ERROR,
- "declarator requires an identifier")
-DIAG(err_bad_language, ERROR,
- "unknown linkage language")
-
-// C++ class members
-DIAG(err_storageclass_invalid_for_member, ERROR,
- "storage class specified for a member declaration")
-DIAG(err_not_bitfield_type, ERROR,
- "cannot declare '%0' to be a bit-field type")
-DIAG(err_static_not_bitfield, ERROR,
- "static member '%0' cannot be a bit-field")
-DIAG(err_not_integral_type_bitfield, ERROR,
- "bit-field '%0' with non-integral type")
-DIAG(err_member_initialization, ERROR,
- "'%0' can only be initialized if it is a static const integral data member")
-
-// Attributes
-DIAG(err_attribute_wrong_number_arguments, ERROR,
- "attribute requires %0 argument(s)")
-DIAG(err_attribute_missing_parameter_name, ERROR,
- "attribute requires unquoted parameter")
-DIAG(err_attribute_invalid_vector_type, ERROR,
- "invalid vector type '%0'")
-DIAG(err_attribute_argument_not_int, ERROR,
- "'%0' attribute requires integer constant")
-DIAG(err_attribute_argument_n_not_int, ERROR,
- "'%0' attribute requires parameter %1 to be an integer constant")
-DIAG(err_attribute_argument_n_not_string, ERROR,
- "'%0' attribute requires parameter %1 to be a string")
-DIAG(err_attribute_argument_out_of_bounds, ERROR,
- "'%0' attribute parameter %1 is out of bounds")
-DIAG(err_nonnull_pointers_only, ERROR,
- "nonnull attribute only applies to pointer arguments")
-DIAG(err_format_strftime_third_parameter, ERROR,
- "strftime format attribute requires 3rd parameter to be 0")
-DIAG(err_format_attribute_requires_variadic, ERROR,
- "format attribute requires variadic function")
-DIAG(err_format_attribute_not, ERROR,
- "format argument not %0")
-DIAG(err_attribute_invalid_size, ERROR,
- "vector size not an integral multiple of component size")
-DIAG(err_attribute_zero_size, ERROR,
- "zero vector size")
-DIAG(err_typecheck_vector_not_convertable, ERROR,
- "can't convert between vector values of different size ('%0' and '%1')")
-DIAG(err_typecheck_ext_vector_not_typedef, ERROR,
- "ext_vector_type only applies to types, not variables")
-DIAG(err_ext_vector_component_exceeds_length, ERROR,
- "vector component access exceeds type '%0'")
-DIAG(err_ext_vector_component_requires_even, ERROR,
- "vector component access invalid for odd-sized type '%0'")
-DIAG(err_ext_vector_component_name_illegal, ERROR,
- "illegal vector component name '%0'")
-DIAG(err_ext_vector_component_access, ERROR,
- "vector component access limited to variables")
-DIAG(err_attribute_address_space_not_int, ERROR,
- "address space attribute requires an integer constant")
-DIAG(err_attribute_address_multiple_qualifiers, ERROR,
- "multiple address spaces specified for type")
-DIAG(err_implicit_pointer_address_space_cast, ERROR,
- "illegal implicit cast between two pointers with different address spaces")
-DIAG(err_as_qualified_auto_decl, ERROR,
- "automatic variable qualified with an address space")
-DIAG(err_attribute_annotate_no_string, ERROR,
- "argument to annotate attribute was not a string literal")
-DIAG(warn_attribute_ignored, WARNING,
- "'%0' attribute ignored")
-DIAG(warn_attribute_wrong_decl_type, WARNING,
- "'%0' attribute only applies to %1 types")
-DIAG(warn_attribute_ignored_for_field_of_type, WARNING,
- "'%0' attribute ignored for field of type '%1'")
-DIAG(warn_attribute_type_not_supported, WARNING,
- "'%0' attribute argument not supported: '%1'")
-DIAG(err_unknown_machine_mode, ERROR,
- "unknown machine mode '%0'")
-DIAG(err_unsupported_machine_mode, ERROR,
- "unsupported machine mode '%0'")
-DIAG(err_mode_not_primitive, ERROR,
- "mode attribute only supported for integer and floating-point types")
-DIAG(err_mode_wrong_type, ERROR,
- "type of machine mode does not match type of base type")
-DIAG(err_attr_wrong_decl, ERROR,
- "'%0' attribute invalid on this declaration, requires typedef or value")
-DIAG(warn_attribute_nonnull_no_pointers, WARNING,
- "'nonnull' attribute applied to function with no pointer arguments")
-DIAG(warn_transparent_union_nonpointer, WARNING,
- "'transparent_union' attribute support incomplete; only supported for"
- "pointer unions")
-DIAG(warn_attribute_sentinel_not_variadic, WARNING,
- "'sentinel' attribute only supported for variadic functions")
-DIAG(err_attribute_sentinel_less_than_zero, ERROR,
- "'sentinel' parameter 1 less than zero")
-DIAG(err_attribute_sentinel_not_zero_or_one, ERROR,
- "'sentinel' parameter 2 not 0 or 1")
-
-// Clang-Specific Attributes
-DIAG(err_attribute_iboutlet_non_ivar, ERROR,
- "'iboutlet' attribute can only be applied to instance variables")
-
-// Function Parameter Semantic Analysis.
-DIAG(err_param_with_void_type, ERROR,
- "argument may not have 'void' type")
-DIAG(err_void_only_param, ERROR,
- "'void' must be the first and only parameter if specified")
-DIAG(err_void_param_qualified, ERROR,
- "'void' as parameter must not have type qualifiers")
-DIAG(err_param_redefinition, ERROR,
- "redefinition of parameter '%0'")
-DIAG(err_ident_list_in_fn_declaration, ERROR,
- "a parameter list without types is only allowed in a function definition")
-DIAG(err_declaration_does_not_declare_param, ERROR,
- "declaration does not declare a parameter")
-DIAG(err_no_matching_param, ERROR,
- "parameter named '%0' is missing")
-DIAG(ext_param_not_declared, EXTENSION,
- "parameter '%0' was not declared, defaulting to type 'int'")
-DIAG(ext_param_typedef_of_void, EXTENSION,
- "empty parameter list defined with a typedef of 'void' not allowed in C++")
-DIAG(err_param_default_argument, ERROR,
- "C does not support default arguments")
-DIAG(err_param_default_argument_redefinition, ERROR,
- "redefinition of default argument")
-DIAG(err_param_default_argument_missing, ERROR,
- "missing default argument on parameter")
-DIAG(err_param_default_argument_missing_name, ERROR,
- "missing default argument on parameter '%0'")
-DIAG(err_param_default_argument_references_param, ERROR,
- "default argument references parameter '%0'")
-DIAG(err_param_default_argument_references_local, ERROR,
- "default argument references local variable '%0' of enclosing function")
-DIAG(err_param_default_argument_nonfunc, ERROR,
- "default arguments can only be specified for parameters in a function"
- " declaration")
-DIAG(err_previous_definition, ERROR,
- "previous definition is here")
-DIAG(err_previous_use, ERROR,
- "previous use is here")
-DIAG(err_first_label, ERROR,
- "first label is here")
-
-DIAG(err_unexpected_typedef, ERROR,
- "unexpected type name '%0': expected expression")
-DIAG(err_unexpected_namespace, ERROR,
- "unexpected namespace name '%0': expected expression")
-DIAG(err_unexpected_typedef_ident, ERROR,
- "unexpected type name '%0': expected identifier")
-DIAG(err_undeclared_var_use, ERROR,
- "use of undeclared identifier '%0'")
-DIAG(warn_deprecated, WARNING,
- "'%0' is deprecated")
-DIAG(err_redefinition, ERROR,
- "redefinition of '%0'")
-DIAG(err_static_non_static, ERROR,
- "static declaration of '%0' follows non-static declaration")
-DIAG(err_non_static_static, ERROR,
- "non-static declaration of '%0' follows static declaration")
-DIAG(err_redefinition_different_kind, ERROR,
- "redefinition of '%0' as different kind of symbol")
-DIAG(err_redefinition_different_typedef, ERROR,
- "typedef redefinition with different types ('%0' vs '%1')")
-DIAG(err_conflicting_types, ERROR,
- "conflicting types for '%0'")
-DIAG(err_nested_redefinition, ERROR,
- "nested redefinition of '%0'")
-DIAG(err_use_with_wrong_tag, ERROR,
- "use of '%0' with tag type that does not match previous declaration")
-DIAG(ext_forward_ref_enum, EXTENSION,
- "ISO C forbids forward references to 'enum' types")
-DIAG(err_redefinition_of_enumerator, ERROR,
- "redefinition of enumerator '%0'")
-DIAG(err_duplicate_member, ERROR,
- "duplicate member '%0'")
-DIAG(err_enum_value_not_integer_constant_expr, ERROR,
- "enumerator value for '%0' is not an integer constant")
-DIAG(ext_enum_value_not_int, EXTENSION,
- "ISO C restricts enumerator values to range of 'int' (%0 is too large)")
-DIAG(warn_enum_too_large, WARNING,
- "enumeration values exceed range of largest integer")
-DIAG(err_case_label_not_integer_constant_expr, ERROR,
- "case label does not reduce to an integer constant")
-DIAG(warn_illegal_constant_array_size, EXTENSION,
- "size of static array must be an integer constant expression")
-DIAG(err_typecheck_illegal_vla, ERROR,
- "arrays with static storage duration must have constant integer length")
-DIAG(err_typecheck_negative_array_size, ERROR,
- "array size is negative")
-DIAG(warn_typecheck_function_qualifiers, WARNING,
- "qualifier on function type '%0' has unspecified behavior")
-DIAG(err_typecheck_invalid_restrict_not_pointer, ERROR,
- "restrict requires a pointer or reference ('%0' is invalid)")
-DIAG(err_typecheck_invalid_restrict_invalid_pointee, ERROR,
- "pointer to function type ('%0') may not be 'restrict' qualified")
-DIAG(ext_typecheck_zero_array_size, EXTENSION,
- "zero size arrays are an extension")
-DIAG(err_at_least_one_initializer_needed_to_size_array, ERROR,
- "at least one initializer value required to size array")
-DIAG(err_array_size_non_int, ERROR,
- "size of array has non-integer type '%0'")
-DIAG(err_init_element_not_constant, ERROR,
- "initializer element is not a compile-time constant")
-DIAG(err_block_extern_cant_init, ERROR,
- "'extern' variable cannot have an initializer")
-DIAG(warn_extern_init, WARNING,
- "'extern' variable has an initializer")
-DIAG(err_variable_object_no_init, ERROR,
- "variable-sized object may not be initialized")
-DIAG(err_array_init_list_required, ERROR,
- "initialization with \"{...}\" expected for array")
-DIAG(warn_excess_initializers, WARNING,
- "excess elements in array initializer")
-DIAG(err_excess_initializers_in_char_array_initializer, ERROR,
- "excess elements in char array initializer")
-DIAG(warn_initializer_string_for_char_array_too_long, WARNING,
- "initializer-string for char array is too long")
-DIAG(warn_braces_around_scalar_init, WARNING,
- "braces around scalar initializer")
-DIAG(err_many_braces_around_scalar_init, ERROR,
- "too many braces around scalar initializer")
-DIAG(err_empty_scalar_initializer, ERROR,
- "scalar initializer cannot be empty")
-DIAG(err_illegal_initializer, ERROR,
- "illegal initializer (only variables can be initialized)")
-DIAG(err_illegal_initializer_type, ERROR,
- "illegal initializer type ('%0')")
-DIAG(err_implicit_empty_initializer, ERROR,
- "initializer for aggregate with no elements requires explicit braces")
-
-DIAG(err_redefinition_of_label, ERROR,
- "redefinition of label '%0'")
-DIAG(err_undeclared_label_use, ERROR,
- "use of undeclared label '%0'")
-
-DIAG(warn_implicit_function_decl, WARNING,
- "implicit declaration of function '%0'")
-DIAG(ext_implicit_function_decl, EXTENSION,
- "implicit declaration of function '%0' is invalid in C99")
-
-DIAG(err_func_returning_array_function, ERROR,
- "function cannot return array or function type '%0'")
-DIAG(err_field_declared_as_function, ERROR,
- "field '%0' declared as a function")
-DIAG(err_field_incomplete, ERROR,
- "field '%0' has incomplete type")
-DIAG(err_variable_sized_type_in_struct, EXTENSION,
- "variable sized type '%0' must be at end of struct or class")
-DIAG(err_flexible_array_empty_struct, ERROR,
- "flexible array '%0' not allowed in otherwise empty struct")
-DIAG(ext_flexible_array_in_struct, EXTENSION,
- "'%0' may not be nested in a struct due to flexible array member")
-DIAG(err_flexible_array_in_array, ERROR,
- "'%0' may not be used as an array element due to flexible array member")
-DIAG(err_illegal_decl_array_of_functions, ERROR,
- "'%0' declared as array of functions")
-DIAG(err_illegal_decl_array_incomplete_type, ERROR,
- "array has incomplete element type '%0'")
-DIAG(err_illegal_decl_array_of_references, ERROR,
- "'%0' declared as array of references")
-DIAG(err_illegal_decl_pointer_to_reference, ERROR,
- "'%0' declared as a pointer to a reference")
-DIAG(err_illegal_decl_reference_to_reference, ERROR,
- "'%0' declared as a reference to a reference")
-DIAG(err_qualified_block_pointer_type, ERROR,
- "qualifier specification on block pointer type not allowed")
-DIAG(err_nonfunction_block_type, ERROR,
- "block pointer to non-function type is invalid")
-DIAG(err_return_block_has_expr, ERROR,
- "void block should not return a value")
-DIAG(err_block_return_missing_expr, ERROR,
- "non-void block should return a value")
-DIAG(err_block_with_return_type_requires_args, ERROR,
- "block with explicit return type requires argument list")
-
-// Expressions.
-DIAG(ext_sizeof_function_type, EXTENSION,
- "invalid application of 'sizeof' to a function type")
-DIAG(ext_sizeof_void_type, EXTENSION,
- "invalid application of '%0' to a void type")
-DIAG(err_sizeof_incomplete_type, ERROR,
- "invalid application of 'sizeof' to an incomplete type '%0'")
-DIAG(err_alignof_incomplete_type, ERROR,
- "invalid application of '__alignof' to an incomplete type '%0'")
-DIAG(err_offsetof_record_type, ERROR,
- "offsetof requires struct, union, or class type, '%0' invalid")
-DIAG(err_offsetof_array_type, ERROR,
- "offsetof requires array type, '%0' invalid")
-DIAG(ext_offsetof_extended_field_designator, EXTENSION,
- "using extended field designator is an extension")
-
-DIAG(err_invalid_suffix_integer_constant, ERROR,
- "invalid suffix '%0' on integer constant")
-DIAG(err_invalid_suffix_float_constant, ERROR,
- "invalid suffix '%0' on floating constant")
-DIAG(ext_imaginary_constant, EXTENSION,
- "imaginary constants are an extension")
-DIAG(warn_integer_too_large, WARNING,
- "integer constant is too large for its type")
-DIAG(warn_integer_too_large_for_signed, WARNING,
- "integer constant is so large that it is unsigned")
-DIAG(err_exponent_has_no_digits, ERROR,
- "exponent has no digits")
-DIAG(ext_binary_literal, EXTENSION,
- "binary integer literals are an extension")
-DIAG(err_invalid_binary_digit, ERROR,
- "invalid digit '%0' in binary constant")
-DIAG(err_invalid_octal_digit, ERROR,
- "invalid digit '%0' in octal constant")
-DIAG(err_invalid_decimal_digit, ERROR,
- "invalid digit '%0' in decimal constant")
-DIAG(err_hexconstant_requires_exponent, ERROR,
- "hexadecimal floating constants require an exponent")
-DIAG(ext_hexconstant_invalid, EXTENSION,
- "hexadecimal floating constants are a C99 feature")
-DIAG(err_typecheck_subscript_value, ERROR,
- "subscripted value is neither array nor pointer")
-DIAG(err_typecheck_subscript, ERROR,
- "array subscript is not an integer")
-DIAG(err_typecheck_subscript_not_object, ERROR,
- "illegal subscript of non-object type '%0'")
-DIAG(err_typecheck_member_reference_struct_union, ERROR,
- "member reference base type ('%0') is not a structure or union")
-DIAG(err_typecheck_member_reference_ivar, ERROR,
- "'%0' does not have a member named '%1'")
-DIAG(err_typecheck_member_reference_arrow, ERROR,
- "member reference type '%0' is not a pointer")
-DIAG(err_typecheck_incomplete_tag, ERROR,
- "incomplete definition of type '%0'")
-DIAG(err_typecheck_no_member, ERROR,
- "no member named '%0'")
-DIAG(err_typecheck_illegal_increment_decrement, ERROR,
- "cannot modify value of type '%0'")
-DIAG(err_typecheck_invalid_lvalue_incr_decr, ERROR,
- "invalid lvalue in increment/decrement expression")
-DIAG(err_typecheck_arithmetic_incomplete_type, ERROR,
- "arithmetic on pointer to incomplete type '%0'")
-DIAG(err_typecheck_decl_incomplete_type, ERROR,
- "variable has incomplete type '%0'")
-DIAG(err_realimag_invalid_type, ERROR,
- "invalid type '%0' to __real or __imag operator")
-DIAG(err_typecheck_sclass_fscope, ERROR,
- "illegal storage class on file-scoped variable")
-DIAG(err_typecheck_sclass_func, ERROR,
- "illegal storage class on function")
-DIAG(err_typecheck_address_of, ERROR,
- "address of %0 requested")
-DIAG(err_typecheck_invalid_lvalue_addrof, ERROR,
- "address expression must be an lvalue or a function designator")
-DIAG(err_typecheck_unary_expr, ERROR,
- "invalid argument type to unary expression '%0'")
-DIAG(err_typecheck_indirection_requires_pointer, ERROR,
- "indirection requires pointer operand ('%0' invalid)")
-DIAG(err_typecheck_invalid_operands, ERROR,
- "invalid operands to binary expression ('%0' and '%1')")
-DIAG(err_typecheck_sub_ptr_object, ERROR,
- "'%0' is not a complete object type")
-DIAG(err_typecheck_sub_ptr_compatible, ERROR,
- "'%0' and '%1' are not pointers to compatible types")
-DIAG(ext_typecheck_comparison_of_pointer_integer, WARNING,
- "comparison between pointer and integer ('%0' and '%1')")
-DIAG(ext_typecheck_comparison_of_distinct_pointers, WARNING,
- "comparison of distinct pointer types ('%0' and '%1')")
-DIAG(err_typecheck_assign_const, ERROR,
- "read-only variable is not assignable")
-
-DIAG(err_invalid_this_use, ERROR,
- "invalid use of 'this' outside of a nonstatic member function")
-DIAG(err_invalid_member_use_in_static_method, ERROR,
- "invalid use of member '%0' in static member function")
-DIAG(err_invalid_non_static_member_use, ERROR,
- "invalid use of nonstatic data member '%0'")
-DIAG(err_invalid_incomplete_type_use, ERROR,
- "invalid use of incomplete type '%0'")
-DIAG(err_builtin_func_cast_more_than_one_arg, ERROR,
- "function-style cast to a builtin type can only take one argument")
-DIAG(err_builtin_direct_init_more_than_one_arg, ERROR,
- "initializer of a builtin type can only take one argument")
-DIAG(err_value_init_for_array_type, ERROR,
- "array types cannot be value-initialized")
-DIAG(err_invalid_use_of_function_type, ERROR,
- "a function type is not allowed here")
-DIAG(err_invalid_use_of_array_type, ERROR,
- "an array type is not allowed here")
-DIAG(err_type_defined_in_condition, ERROR,
- "types may not be defined in conditions")
-DIAG(err_typecheck_bool_condition, ERROR,
- "expression must have bool type (or be convertible to bool) ('%0' invalid)")
-
-
-// assignment related diagnostics (also for argument passing, returning, etc).
-DIAG(err_typecheck_convert_incompatible, ERROR,
- "incompatible type %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_pointer_int, EXTWARN,
- "incompatible pointer to integer conversion %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_int_pointer, EXTWARN,
- "incompatible integer to pointer conversion %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_pointer_void_func, EXTENSION,
- "%2 '%1' converts between void* and function pointer, expected '%0'")
-DIAG(ext_typecheck_convert_incompatible_pointer, EXTWARN,
- "incompatible pointer types %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_discards_qualifiers, EXTWARN,
- "%2 '%1' discards qualifiers, expected '%0'")
-DIAG(err_int_to_block_pointer, ERROR,
- "invalid conversion %2 integer '%1', expected block pointer '%0'")
-DIAG(err_typecheck_comparison_of_distinct_blocks, ERROR,
- "comparison of distinct block types ('%0' and '%1')")
-DIAG(ext_typecheck_convert_incompatible_block_pointer, EXTWARN,
- "incompatible block pointer types %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_pointer_void_block, EXTENSION,
- "%2 '%1' converts between void* and block pointer, expected '%0'")
-
-DIAG(err_typecheck_array_not_modifiable_lvalue, ERROR,
- "array type '%0' is not assignable")
-DIAG(err_typecheck_non_object_not_modifiable_lvalue, ERROR,
- "non-object type '%0' is not assignable")
-DIAG(err_typecheck_expression_not_modifiable_lvalue, ERROR,
- "expression is not assignable")
-DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, ERROR,
- "incomplete type '%0' is not assignable")
-
-DIAG(err_typecheck_duplicate_vector_components_not_mlvalue, ERROR,
- "vector is not assignable (contains duplicate components)")
-DIAG(err_block_decl_ref_not_modifiable_lvalue, ERROR,
- "variable is not assignable (missing __block type specifier)")
-DIAG(err_typecheck_call_not_function, ERROR,
- "called object is not a function or function pointer")
-DIAG(err_typecheck_call_too_few_args, ERROR,
- "too few arguments to function")
-DIAG(err_typecheck_block_too_few_args, ERROR,
- "too few arguments to block")
-DIAG(err_typecheck_call_too_many_args, ERROR,
- "too many arguments to function")
-DIAG(err_typecheck_block_too_many_args, ERROR,
- "too many arguments to block call")
-DIAG(err_typecheck_closure_too_many_args, ERROR,
- "too many arguments to closure call")
-DIAG(err_typecheck_call_invalid_ordered_compare, ERROR,
- "ordered compare requires two args of floating point type ('%0' and '%1')")
-DIAG(err_typecheck_cond_expect_scalar, ERROR,
- "used type '%0' where arithmetic or pointer type is required")
-DIAG(ext_typecheck_cond_one_void, EXTENSION,
- "C99 forbids conditional expressions with only one void side")
-DIAG(ext_typecheck_cast_nonscalar, EXTENSION,
- "C99 forbids casting nonscalar to the same type")
-DIAG(err_typecheck_expect_scalar_operand, ERROR,
- "operand of type '%0' where arithmetic or pointer type is required")
-DIAG(err_typecheck_cond_incompatible_operands, ERROR,
- "incompatible operand types ('%0' and '%1')")
-DIAG(warn_typecheck_cond_incompatible_pointers, WARNING,
- "pointer type mismatch ('%0' and '%1')")
-DIAG(err_typecheck_choose_expr_requires_constant, ERROR,
- "'__builtin_choose_expr' requires a constant expression")
-DIAG(ext_typecheck_expression_not_constant_but_accepted, EXTENSION,
- "expression is not a constant, but is accepted as one by GNU extensions")
-DIAG(warn_unused_expr, WARNING,
- "expression result unused")
-DIAG(err_pascal_string_too_long, ERROR,
- "Pascal string is too long")
-DIAG(err_asm_wide_character, ERROR,
- "wide string is invalid in 'asm'")
-DIAG(err_asm_invalid_lvalue_in_output, ERROR,
- "invalid lvalue in asm output")
-DIAG(err_asm_invalid_output_constraint, ERROR,
- "invalid output constraint '%0' in asm")
-DIAG(err_asm_invalid_input_constraint, ERROR,
- "invalid input constraint '%0' in asm")
-DIAG(err_asm_invalid_type_in_input, ERROR,
- "invalid type '%0' in asm input for constraint '%1'")
-DIAG(err_asm_unknown_register_name, ERROR,
- "unknown register name '%0' in asm")
-DIAG(err_invalid_conversion_between_vectors, ERROR,
- "invalid conversion between vector type '%0' and '%1' of different size")
-DIAG(err_invalid_conversion_between_vector_and_integer, ERROR,
- "invalid conversion between vector type '%0' and integer type '%1' "
- "of different size")
-DIAG(err_invalid_conversion_between_vector_and_scalar, ERROR,
- "invalid conversion between vector type '%0' and scalar type '%1'")
-DIAG(err_overload_expr_requires_non_zero_constant, ERROR,
- "overload requires a non-zero constant expression as first argument")
-DIAG(err_overload_incorrect_fntype, ERROR,
- "argument is not a function, or has wrong number of parameters")
-DIAG(err_overload_no_match, ERROR,
- "no matching overload found for arguments of type '%0'")
-DIAG(err_overload_multiple_match, ERROR,
- "more than one matching function found in __builtin_overload")
-
-// Classes.
-DIAG(err_dup_virtual, ERROR,
- "duplicate 'virtual' in base specifier")
-DIAG(err_expected_class_name, ERROR,
- "expected class name")
-DIAG(err_anon_type_definition, ERROR,
- "declaration of anonymous %0 must be a definition")
-DIAG(err_base_clause_on_union, ERROR,
- "unions cannot have base classes")
-DIAG(err_base_must_be_class, ERROR,
- "base specifier must name a class")
-DIAG(err_union_as_base_class, ERROR,
- "unions cannot be base classes")
-DIAG(err_incomplete_base_class, ERROR,
- "base class has incomplete type")
-
-DIAG(warn_not_compound_assign, WARNING,
- "use of unary operator that may be intended as compound assignment (%0=)")
-
-// CHECK: printf format string errors
-DIAG(warn_printf_not_string_constant, WARNING,
- "format string is not a string literal (potentially insecure)")
-DIAG(warn_printf_write_back, WARNING,
- "use of '%n' in format string discouraged (potentially insecure)")
-DIAG(warn_printf_insufficient_data_args, WARNING,
- "more '%' conversions than data arguments")
-DIAG(warn_printf_too_many_data_args, WARNING,
- "more data arguments than '%' conversions")
-DIAG(warn_printf_invalid_conversion, WARNING,
- "invalid conversion '%0'")
-DIAG(warn_printf_missing_format_string, WARNING,
- "format string missing")
-DIAG(warn_printf_empty_format_string, WARNING,
- "format string is empty")
-DIAG(warn_printf_format_string_is_wide_literal, WARNING,
- "format string should not be a wide string")
-DIAG(warn_printf_format_string_contains_null_char, WARNING,
- "format string contains '\\0' within the string body")
-DIAG(warn_printf_asterisk_width_missing_arg, WARNING,
- "'*' specified field width is missing a matching 'int' argument")
-DIAG(warn_printf_asterisk_precision_missing_arg, WARNING,
- "'.*' specified field precision is missing a matching 'int' argument")
-DIAG(warn_printf_asterisk_width_wrong_type, WARNING,
- "field width should have type 'int', but argument has type '%0'")
-DIAG(warn_printf_asterisk_precision_wrong_type, WARNING,
- "field precision should have type 'int', but argument has type '%0'")
-
-// CHECK: returning address/reference of stack memory
-DIAG(warn_ret_stack_addr, WARNING,
- "address of stack memory associated with local variable '%0' returned")
-DIAG(warn_ret_stack_ref, WARNING,
- "reference to stack memory associated with local variable '%0' returned")
-
-// CHECK: floating point values should not use "==" or "!="
-DIAG(warn_floatingpoint_eq, WARNING,
- "comparing floating point with == or != is unsafe")
-
-// CHECK: for non-floating point, expressions of the form x == x or x != x
-// should result in a warning, since these always evaluate to a constant.
-DIAG(warn_selfcomparison,WARNING,
- "self-comparison always results in a constant value.")
-
-// CHECK: use of uninitialized values
-DIAG(warn_uninit_val, WARNING, "use of uninitialized variable")
-
-// Blocks
-DIAG(err_expected_block_lbrace, ERROR,
- "expected '{' in block literal")
-DIAG(err_goto_in_block, ERROR,
- "goto not allowed in block literal")
-DIAG(err_return_in_block_expression, ERROR,
- "return not allowed in block expression literal")
-
-DIAG(err_ret_local_block, ERROR,
- "returning block that lives on the local stack")
-
-// CFString checking
-DIAG(err_cfstring_literal_not_string_constant, ERROR,
- "CFString literal is not a string constant")
-DIAG(warn_cfstring_literal_contains_non_ascii_character, WARNING,
- "CFString literal contains non-ASCII character")
-DIAG(warn_cfstring_literal_contains_nul_character, WARNING,
- "CFString literal contains NUL character")
-
-// Statements.
-DIAG(err_continue_not_in_loop, ERROR,
- "'continue' statement not in loop statement")
-DIAG(err_break_not_in_loop_or_switch, ERROR,
- "'break' statement not in loop or switch statement")
-DIAG(err_default_not_in_switch, ERROR,
- "'default' statement not in switch statement")
-DIAG(err_case_not_in_switch, ERROR,
- "'case' statement not in switch statement")
-DIAG(warn_case_value_overflow, WARNING,
- "overflow converting case value to switch condition type (%0 to %1)")
-DIAG(err_duplicate_case, ERROR,
- "duplicate case value '%0'")
-DIAG(err_duplicate_case_prev, ERROR,
- "previous case value occurrence defined here")
-DIAG(warn_case_empty_range, WARNING,
- "empty case range specified")
-DIAG(err_typecheck_statement_requires_scalar, ERROR,
- "statement requires expression of scalar type ('%0' invalid)")
-DIAG(err_typecheck_statement_requires_integer, ERROR,
- "statement requires expression of integer type ('%0' invalid)")
-DIAG(err_multiple_default_labels_defined, ERROR,
- "multiple default labels in one switch")
-DIAG(warn_empty_if_body, WARNING,
- "if statement has empty body")
-DIAG(err_va_start_used_in_non_variadic_function, ERROR,
- "'va_start' used in function with fixed args")
-DIAG(warn_second_parameter_of_va_start_not_last_named_argument, WARNING,
- "second parameter of 'va_start' not last named argument")
-DIAG(err_first_argument_to_va_arg_not_of_type_va_list, ERROR,
- "first argument to 'va_arg' is of type '%0' and not 'va_list'")
-
-DIAG(warn_return_missing_expr, WARNING,
- "non-void function '%0' should return a value")
-DIAG(ext_return_missing_expr, EXTENSION,
- "non-void function '%0' should return a value")
-DIAG(ext_return_has_expr, EXTENSION,
- "void function '%0' should not return a value")
-
-DIAG(err_shufflevector_non_vector, ERROR,
- "first two arguments to __builtin_shufflevector must be vectors")
-DIAG(err_shufflevector_incompatible_vector, ERROR,
- "first two arguments to __builtin_shufflevector must have the same type")
-DIAG(err_shufflevector_nonconstant_argument, ERROR,
- "index for __builtin_shufflevector must be a constant integer")
-DIAG(err_shufflevector_argument_too_large, ERROR,
- "index for __builtin_shufflevector must be less than the total number"
- " of vector elements")
-
-DIAG(err_stack_const_level, ERROR,
- "level argument for a stack address builtin must be constant")
-
-DIAG(err_prefetch_invalid_argument, ERROR,
- "argument to __builtin_prefetch must be a constant integer")
-DIAG(err_argument_invalid_range, ERROR,
- "argument should be a value from %0 to %1")
-
-DIAG(err_object_size_invalid_argument, ERROR,
- "argument to __builtin_object_size must be a constant integer")
-
-#undef DIAG
diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h
deleted file mode 100644
index 1b4ca81c3974..000000000000
--- a/clang/include/clang/Basic/FileManager.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- FileManager.h - File System Probing and Caching --------*- 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 FileManager interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FILEMANAGER_H
-#define LLVM_CLANG_FILEMANAGER_H
-
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include <map>
-#include <set>
-#include <string>
-// FIXME: Enhance libsystem to support inode and other fields in stat.
-#include <sys/types.h>
-
-namespace clang {
-class FileManager;
-
-/// DirectoryEntry - Cached information about one directory on the disk.
-///
-class DirectoryEntry {
- const char *Name; // Name of the directory.
- friend class FileManager;
-public:
- DirectoryEntry() : Name(0) {}
- const char *getName() const { return Name; }
-};
-
-/// FileEntry - Cached information about one file on the disk.
-///
-class FileEntry {
- const char *Name; // Name of the file.
- off_t Size; // File size in bytes.
- time_t ModTime; // Modification time of file.
- const DirectoryEntry *Dir; // Directory file lives in.
- unsigned UID; // A unique (small) ID for the file.
- dev_t Device; // ID for the device containing the file.
- ino_t Inode; // Inode number for the file.
- friend class FileManager;
-public:
- FileEntry(dev_t device, ino_t inode) : Name(0), Device(device), Inode(inode){}
- // Add a default constructor for use with llvm::StringMap
- FileEntry() : Name(0), Device(0), Inode(0) {}
-
- const char *getName() const { return Name; }
- off_t getSize() const { return Size; }
- unsigned getUID() const { return UID; }
- ino_t getInode() const { return Inode; }
- dev_t getDevice() const { return Device; }
- time_t getModificationTime() const { return ModTime; }
-
- /// getDir - Return the directory the file lives in.
- ///
- const DirectoryEntry *getDir() const { return Dir; }
-
- bool operator<(const FileEntry& RHS) const {
- return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
- }
-};
-
-
-/// FileManager - Implements support for file system lookup, file system
-/// caching, and directory search management. This also handles more advanced
-/// properties, such as uniquing files based on "inode", so that a file with two
-/// names (e.g. symlinked) will be treated as a single file.
-///
-class FileManager {
-
- class UniqueDirContainer;
- class UniqueFileContainer;
-
- /// UniqueDirs/UniqueFiles - Cache for existing directories/files.
- ///
- UniqueDirContainer &UniqueDirs;
- UniqueFileContainer &UniqueFiles;
-
- /// DirEntries/FileEntries - This is a cache of directory/file entries we have
- /// looked up. The actual Entry is owned by UniqueFiles/UniqueDirs above.
- ///
- llvm::StringMap<DirectoryEntry*> DirEntries;
- llvm::StringMap<FileEntry*> FileEntries;
-
- /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
- ///
- unsigned NextFileUID;
-
- // Statistics.
- unsigned NumDirLookups, NumFileLookups;
- unsigned NumDirCacheMisses, NumFileCacheMisses;
-public:
- FileManager();
- ~FileManager();
-
- /// getDirectory - Lookup, cache, and verify the specified directory. This
- /// returns null if the directory doesn't exist.
- ///
- const DirectoryEntry *getDirectory(const std::string &Filename) {
- return getDirectory(&Filename[0], &Filename[0] + Filename.size());
- }
- const DirectoryEntry *getDirectory(const char *FileStart,const char *FileEnd);
-
- /// getFile - Lookup, cache, and verify the specified file. This returns null
- /// if the file doesn't exist.
- ///
- const FileEntry *getFile(const std::string &Filename) {
- return getFile(&Filename[0], &Filename[0] + Filename.size());
- }
- const FileEntry *getFile(const char *FilenameStart,
- const char *FilenameEnd);
-
- void PrintStats() const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
deleted file mode 100644
index fc32b4d7d36d..000000000000
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ /dev/null
@@ -1,335 +0,0 @@
-//===--- IdentifierTable.h - Hash table for identifier lookup ---*- 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 IdentifierInfo, IdentifierTable, and Selector
-// interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
-#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
-
-#include "clang/Basic/TokenKinds.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include <string>
-#include <cassert>
-
-namespace llvm {
- template <typename T> struct DenseMapInfo;
-}
-
-namespace clang {
- struct LangOptions;
- class MultiKeywordSelector; // a private class used by Selector.
- class IdentifierInfo;
- class SourceLocation;
-
- /// IdentifierLocPair - A simple pair of identifier info and location.
- typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
-
-
-/// IdentifierInfo - One of these records is kept for each identifier that
-/// is lexed. This contains information about whether the token was #define'd,
-/// is a language keyword, or if it is a front-end token of some sort (e.g. a
-/// variable or function name). The preprocessor keeps this information in a
-/// set, and all tok::identifier tokens have a pointer to one of these.
-class IdentifierInfo {
- // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
- // signed char and TokenKinds > 127 won't be handled correctly.
- unsigned TokenID : 8; // Front-end token ID or tok::identifier.
- unsigned BuiltinID :10; // ID if this is a builtin (__builtin_inf).
- // NOTE: VC++ treats enums as signed, avoid using tok::ObjCKeywordKind enum
- unsigned ObjCID : 5; // ID for objc @ keyword like @'protocol'.
- bool HasMacro : 1; // True if there is a #define for this.
- bool IsExtension : 1; // True if identifier is a lang extension.
- bool IsPoisoned : 1; // True if identifier is poisoned.
- bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
- // 5 bits left in 32-bit word.
- void *FETokenInfo; // Managed by the language front-end.
- IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
- void operator=(const IdentifierInfo&); // NONASSIGNABLE.
-public:
- IdentifierInfo();
-
- /// getName - Return the actual string for this identifier. The returned
- /// string is properly null terminated.
- ///
- const char *getName() const {
- // We know that this is embedded into a StringMapEntry, and it knows how to
- // efficiently find the string.
- return llvm::StringMapEntry<IdentifierInfo>::
- GetStringMapEntryFromValue(*this).getKeyData();
- }
-
- /// getLength - Efficiently return the length of this identifier info.
- ///
- unsigned getLength() const {
- return llvm::StringMapEntry<IdentifierInfo>::
- GetStringMapEntryFromValue(*this).getKeyLength();
- }
-
- /// hasMacroDefinition - Return true if this identifier is #defined to some
- /// other value.
- bool hasMacroDefinition() const {
- return HasMacro;
- }
- void setHasMacroDefinition(bool Val) { HasMacro = Val; }
-
- /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
- /// can be used to cause the lexer to map identifiers to source-language
- /// tokens.
- tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
- void setTokenID(tok::TokenKind ID) { TokenID = ID; }
-
- /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
- /// For example, "define" will return tok::pp_define.
- tok::PPKeywordKind getPPKeywordID() const;
-
- /// getObjCKeywordID - Return the Objective-C keyword ID for the this
- /// identifier. For example, 'class' will return tok::objc_class if ObjC is
- /// enabled.
- tok::ObjCKeywordKind getObjCKeywordID() const {
- return tok::ObjCKeywordKind(ObjCID);
- }
- void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCID = ID; }
-
- /// getBuiltinID - Return a value indicating whether this is a builtin
- /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target.
- /// 2+ are specific builtin functions.
- unsigned getBuiltinID() const { return BuiltinID; }
- void setBuiltinID(unsigned ID) {
- BuiltinID = ID;
- assert(BuiltinID == ID && "ID too large for field!");
- }
-
- /// get/setExtension - Initialize information about whether or not this
- /// language token is an extension. This controls extension warnings, and is
- /// only valid if a custom token ID is set.
- bool isExtensionToken() const { return IsExtension; }
- void setIsExtensionToken(bool Val) { IsExtension = Val; }
-
- /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
- /// Preprocessor will emit an error every time this token is used.
- void setIsPoisoned(bool Value = true) { IsPoisoned = Value; }
-
- /// isPoisoned - Return true if this token has been poisoned.
- bool isPoisoned() const { return IsPoisoned; }
-
- /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
- /// this identifier is a C++ alternate representation of an operator.
- void setIsCPlusPlusOperatorKeyword(bool Val = true)
- { IsCPPOperatorKeyword = Val; }
- bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
-
- /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
- /// associate arbitrary metadata with this token.
- template<typename T>
- T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
- void setFETokenInfo(void *T) { FETokenInfo = T; }
-
- /// Emit - Serialize this IdentifierInfo to a bitstream.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Deserialize an IdentifierInfo object from a bitstream.
- void Read(llvm::Deserializer& D);
-};
-
-/// IdentifierTable - This table implements an efficient mapping from strings to
-/// IdentifierInfo nodes. It has no other purpose, but this is an
-/// extremely performance-critical piece of the code, as each occurrance of
-/// every identifier goes through here when lexed.
-class IdentifierTable {
- // Shark shows that using MallocAllocator is *much* slower than using this
- // BumpPtrAllocator!
- typedef llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator> HashTableTy;
- HashTableTy HashTable;
-public:
- /// IdentifierTable ctor - Create the identifier table, populating it with
- /// info about the language keywords for the language specified by LangOpts.
- IdentifierTable(const LangOptions &LangOpts);
-
- /// get - Return the identifier token info for the specified named identifier.
- ///
- IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
- return HashTable.GetOrCreateValue(NameStart, NameEnd).getValue();
- }
-
- IdentifierInfo &get(const char *Name) {
- return get(Name, Name+strlen(Name));
- }
- IdentifierInfo &get(const std::string &Name) {
- // Don't use c_str() here: no need to be null terminated.
- const char *NameBytes = &Name[0];
- return get(NameBytes, NameBytes+Name.size());
- }
-
- typedef HashTableTy::const_iterator iterator;
- typedef HashTableTy::const_iterator const_iterator;
-
- iterator begin() const { return HashTable.begin(); }
- iterator end() const { return HashTable.end(); }
-
- unsigned size() const { return HashTable.size(); }
-
- /// PrintStats - Print some statistics to stderr that indicate how well the
- /// hashing is doing.
- void PrintStats() const;
-
- void AddKeywords(const LangOptions &LangOpts);
-
- /// Emit - Serialize this IdentifierTable to a bitstream. This should
- /// be called AFTER objects that externally reference the identifiers in the
- /// table have been serialized. This is because only the identifiers that
- /// are actually referenced are serialized.
- void Emit(llvm::Serializer& S) const;
-
- /// Create - Deserialize an IdentifierTable from a bitstream.
- static IdentifierTable* CreateAndRegister(llvm::Deserializer& D);
-
-private:
- /// This ctor is not intended to be used by anyone except for object
- /// serialization.
- IdentifierTable();
-};
-
-/// Selector - This smart pointer class efficiently represents Objective-C
-/// method names. This class will either point to an IdentifierInfo or a
-/// MultiKeywordSelector (which is private). This enables us to optimize
-/// selectors that take no arguments and selectors that take 1 argument, which
-/// accounts for 78% of all selectors in Cocoa.h.
-class Selector {
- enum IdentifierInfoFlag {
- // MultiKeywordSelector = 0.
- ZeroArg = 0x1,
- OneArg = 0x2,
- ArgFlags = ZeroArg|OneArg
- };
- uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
-
- Selector(IdentifierInfo *II, unsigned nArgs) {
- InfoPtr = reinterpret_cast<uintptr_t>(II);
- assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
- assert(nArgs < 2 && "nArgs not equal to 0/1");
- InfoPtr |= nArgs+1;
- }
- Selector(MultiKeywordSelector *SI) {
- InfoPtr = reinterpret_cast<uintptr_t>(SI);
- assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
- }
- Selector(uintptr_t V) : InfoPtr(V) {}
-public:
- friend class SelectorTable; // only the SelectorTable can create these.
-
- /// The default ctor should only be used when creating data structures that
- /// will contain selectors.
- Selector() : InfoPtr(0) {}
-
- IdentifierInfo *getAsIdentifierInfo() const {
- if (getIdentifierInfoFlag())
- return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
- return 0;
- }
- unsigned getIdentifierInfoFlag() const {
- return InfoPtr & ArgFlags;
- }
- /// operator==/!= - Indicate whether the specified selectors are identical.
- bool operator==(Selector RHS) const {
- return InfoPtr == RHS.InfoPtr;
- }
- bool operator!=(Selector RHS) const {
- return InfoPtr != RHS.InfoPtr;
- }
- void *getAsOpaquePtr() const {
- return reinterpret_cast<void*>(InfoPtr);
- }
- // Predicates to identify the selector type.
- bool isKeywordSelector() const {
- return getIdentifierInfoFlag() != ZeroArg;
- }
- bool isUnarySelector() const {
- return getIdentifierInfoFlag() == ZeroArg;
- }
- unsigned getNumArgs() const;
- IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
-
- /// getName - Derive the full selector name (e.g. "foo:bar:") and return it.
- ///
- std::string getName() const;
-
- static Selector getEmptyMarker() {
- return Selector(uintptr_t(-1));
- }
- static Selector getTombstoneMarker() {
- return Selector(uintptr_t(-2));
- }
-
- // Emit - Emit a selector to bitcode.
- void Emit(llvm::Serializer& S) const;
-
- // ReadVal - Read a selector from bitcode.
- static Selector ReadVal(llvm::Deserializer& D);
-};
-
-/// SelectorTable - This table allows us to fully hide how we implement
-/// multi-keyword caching.
-class SelectorTable {
- void *Impl; // Actually a FoldingSet<MultiKeywordSelector>*
- SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
- void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT
-public:
- SelectorTable();
- ~SelectorTable();
-
- /// getSelector - This can create any sort of selector. NumArgs indicates
- /// whether this is a no argument selector "foo", a single argument selector
- /// "foo:" or multi-argument "foo:bar:".
- Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
-
- Selector getUnarySelector(IdentifierInfo *ID) {
- return Selector(ID, 1);
- }
- Selector getNullarySelector(IdentifierInfo *ID) {
- return Selector(ID, 0);
- }
-
- // Emit - Emit a SelectorTable to bitcode.
- void Emit(llvm::Serializer& S) const;
-
- // Create - Reconstitute a SelectorTable from bitcode.
- static SelectorTable* CreateAndRegister(llvm::Deserializer& D);
-};
-
-} // end namespace clang
-
-
-/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
-/// DenseSets.
-namespace llvm {
-template <>
-struct DenseMapInfo<clang::Selector> {
- static inline clang::Selector getEmptyKey() {
- return clang::Selector::getEmptyMarker();
- }
- static inline clang::Selector getTombstoneKey() {
- return clang::Selector::getTombstoneMarker();
- }
-
- static unsigned getHashValue(clang::Selector S);
-
- static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
- return LHS == RHS;
- }
-
- static bool isPod() { return true; }
-};
-} // end namespace llvm
-
-#endif
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
deleted file mode 100644
index b1bdebabc473..000000000000
--- a/clang/include/clang/Basic/LangOptions.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//===--- LangOptions.h - C Language Family Language Options -----*- 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 LangOptions interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LANGOPTIONS_H
-#define LLVM_CLANG_LANGOPTIONS_H
-
-#include "llvm/Bitcode/SerializationFwd.h"
-
-namespace clang {
-
-/// LangOptions - This class keeps track of the various options that can be
-/// enabled, which controls the dialect of C that is accepted.
-struct LangOptions {
-
- unsigned Trigraphs : 1; // Trigraphs in source files.
- unsigned BCPLComment : 1; // BCPL-style '//' comments.
- unsigned DollarIdents : 1; // '$' allowed in identifiers.
- unsigned ImplicitInt : 1; // C89 implicit 'int'.
- unsigned Digraphs : 1; // C94, C99 and C++
- unsigned HexFloats : 1; // C99 Hexadecimal float constants.
- unsigned C99 : 1; // C99 Support
- unsigned Microsoft : 1; // Microsoft extensions.
- unsigned CPlusPlus : 1; // C++ Support
- unsigned CPlusPlus0x : 1; // C++0x Support
- unsigned NoExtensions : 1; // All extensions are disabled, strict mode.
- unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords.
-
- unsigned ObjC1 : 1; // Objective-C 1 support enabled.
- unsigned ObjC2 : 1; // Objective-C 2 support enabled.
-
- unsigned PascalStrings : 1; // Allow Pascal strings
- unsigned Boolean : 1; // Allow bool/true/false
- unsigned WritableStrings : 1; // Allow writable strings
- unsigned LaxVectorConversions : 1;
- unsigned Exceptions : 1; // Support exception handling.
-
- unsigned NeXTRuntime : 1; // Use NeXT runtime.
-
- unsigned ThreadsafeStatics : 1; // Whether static initializers are protected
- // by lockis.
- unsigned Blocks : 1; // block extension to C
-private:
- unsigned GC : 2; // Objective-C Garbage Collection modes. We declare
- // this enum as unsigned because MSVC insists on making enums
- // signed. Set/Query this value using accessors.
-public:
-
- enum GCMode { NonGC, GCOnly, HybridGC };
-
- LangOptions() {
- Trigraphs = BCPLComment = DollarIdents = ImplicitInt = Digraphs = 0;
- HexFloats = 0;
- GC = ObjC1 = ObjC2 = 0;
- C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0;
- CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0;
- LaxVectorConversions = Exceptions = NeXTRuntime = 0;
-
- // FIXME: The default should be 1.
- ThreadsafeStatics = 0;
- Blocks = 1;
- }
-
- GCMode getGCMode() const { return (GCMode) GC; }
- void setGCMode(GCMode m) { GC = (unsigned) m; }
-
- /// Emit - Emit this LangOptions object to bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Read new values for this LangOption object from bitcode.
- void Read(llvm::Deserializer& S);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h
deleted file mode 100644
index ee6cc145fe7e..000000000000
--- a/clang/include/clang/Basic/SourceLocation.h
+++ /dev/null
@@ -1,275 +0,0 @@
-//===--- SourceLocation.h - Compact identifier for Source Files -*- 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 SourceLocation class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SOURCELOCATION_H
-#define LLVM_CLANG_SOURCELOCATION_H
-
-#include <cassert>
-#include "llvm/Bitcode/SerializationFwd.h"
-
-namespace llvm {
-class MemoryBuffer;
-}
-
-namespace clang {
-
-class SourceManager;
-class FileEntry;
-
-/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
-/// a full include stack, line and column number information for a position in
-/// an input translation unit.
-class SourceLocation {
- unsigned ID;
-public:
- enum {
- // FileID Layout:
- // bit 31: 0 -> FileID, 1 -> MacroID (invalid for FileID)
- // 30...17 -> FileID of source location, index into SourceManager table.
- FileIDBits = 14,
- // 0...16 -> Index into the chunk of the specified FileID.
- FilePosBits = 32-1-FileIDBits,
-
- // MacroID Layout:
- // bit 31: 1 -> MacroID, 0 -> FileID (invalid for MacroID)
-
- // bit 29,30: unused.
-
- // bits 28...9 -> MacroID number.
- MacroIDBits = 20,
- // bits 8...0 -> Macro Physical offset
- MacroPhysOffsBits = 9,
-
-
- // Useful constants.
- ChunkSize = (1 << FilePosBits)
- };
-
- SourceLocation() : ID(0) {} // 0 is an invalid FileID.
-
- bool isFileID() const { return (ID >> 31) == 0; }
- bool isMacroID() const { return (ID >> 31) != 0; }
-
- /// isValid - Return true if this is a valid SourceLocation object. Invalid
- /// SourceLocations are often used when events have no corresponding location
- /// in the source (e.g. a diagnostic is required for a command line option).
- ///
- bool isValid() const { return ID != 0; }
- bool isInvalid() const { return ID == 0; }
-
- static SourceLocation getFileLoc(unsigned FileID, unsigned FilePos) {
- SourceLocation L;
- // If a FilePos is larger than (1<<FilePosBits), the SourceManager makes
- // enough consequtive FileIDs that we have one for each chunk.
- if (FilePos >= ChunkSize) {
- FileID += FilePos >> FilePosBits;
- FilePos &= ChunkSize-1;
- }
-
- // FIXME: Find a way to handle out of FileID bits! Maybe MaxFileID is an
- // escape of some sort?
- assert(FileID < (1 << FileIDBits) && "Out of fileid's");
-
- L.ID = (FileID << FilePosBits) | FilePos;
- return L;
- }
-
- static bool isValidMacroPhysOffs(int Val) {
- if (Val >= 0)
- return Val < (1 << (MacroPhysOffsBits-1));
- return -Val <= (1 << (MacroPhysOffsBits-1));
- }
-
- static SourceLocation getMacroLoc(unsigned MacroID, int PhysOffs){
- assert(MacroID < (1 << MacroIDBits) && "Too many macros!");
- assert(isValidMacroPhysOffs(PhysOffs) && "Physoffs too large!");
-
- // Mask off sign bits.
- PhysOffs &= (1 << MacroPhysOffsBits)-1;
-
- SourceLocation L;
- L.ID = (1 << 31) |
- (MacroID << MacroPhysOffsBits) |
- PhysOffs;
- return L;
- }
-
-
- /// getFileID - Return the file identifier for this SourceLocation. This
- /// FileID can be used with the SourceManager object to obtain an entire
- /// include stack for a file position reference.
- unsigned getFileID() const {
- assert(isFileID() && "can't get the file id of a non-file sloc!");
- return ID >> FilePosBits;
- }
-
- /// getRawFilePos - Return the byte offset from the start of the file-chunk
- /// referred to by FileID. This method should not be used to get the offset
- /// from the start of the file, instead you should use
- /// SourceManager::getDecomposedFileLoc. This method will be
- // incorrect for large files.
- unsigned getRawFilePos() const {
- assert(isFileID() && "can't get the file id of a non-file sloc!");
- return ID & (ChunkSize-1);
- }
-
- unsigned getMacroID() const {
- assert(isMacroID() && "Is not a macro id!");
- return (ID >> MacroPhysOffsBits) & ((1 << MacroIDBits)-1);
- }
-
- int getMacroPhysOffs() const {
- assert(isMacroID() && "Is not a macro id!");
- int Val = ID & ((1 << MacroPhysOffsBits)-1);
- // Sign extend it properly.
- unsigned ShAmt = sizeof(int)*8 - MacroPhysOffsBits;
- return (Val << ShAmt) >> ShAmt;
- }
-
- /// getFileLocWithOffset - Return a source location with the specified offset
- /// from this file SourceLocation.
- SourceLocation getFileLocWithOffset(int Offset) const {
- unsigned FileID = getFileID();
- Offset += getRawFilePos();
- // Handle negative offsets correctly.
- while (Offset < 0) {
- --FileID;
- Offset += ChunkSize;
- }
- return getFileLoc(FileID, Offset);
- }
-
- /// getRawEncoding - When a SourceLocation itself cannot be used, this returns
- /// an (opaque) 32-bit integer encoding for it. This should only be passed
- /// to SourceLocation::getFromRawEncoding, it should not be inspected
- /// directly.
- unsigned getRawEncoding() const { return ID; }
-
- /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
- /// a real SourceLocation.
- static SourceLocation getFromRawEncoding(unsigned Encoding) {
- SourceLocation X;
- X.ID = Encoding;
- return X;
- }
-
- /// Emit - Emit this SourceLocation object to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// ReadVal - Read a SourceLocation object from Bitcode.
- static SourceLocation ReadVal(llvm::Deserializer& D);
-};
-
-inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
- return LHS.getRawEncoding() == RHS.getRawEncoding();
-}
-
-inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
- return !(LHS == RHS);
-}
-
-/// SourceRange - a trival tuple used to represent a source range.
-class SourceRange {
- SourceLocation B;
- SourceLocation E;
-public:
- SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
- SourceRange(SourceLocation loc) : B(loc), E(loc) {}
- SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
-
- SourceLocation getBegin() const { return B; }
- SourceLocation getEnd() const { return E; }
-
- void setBegin(SourceLocation b) { B = b; }
- void setEnd(SourceLocation e) { E = e; }
-
- bool isValid() const { return B.isValid() && E.isValid(); }
-
- /// Emit - Emit this SourceRange object to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// ReadVal - Read a SourceRange object from Bitcode.
- static SourceRange ReadVal(llvm::Deserializer& D);
-};
-
-/// FullSourceLoc - A tuple containing both a SourceLocation
-/// and its associated SourceManager. Useful for argument passing to functions
-/// that expect both objects.
-class FullSourceLoc {
- SourceLocation Loc;
- SourceManager* SrcMgr;
-public:
- // Creates a FullSourceLoc where isValid() returns false.
- explicit FullSourceLoc()
- : Loc(SourceLocation()), SrcMgr((SourceManager*) 0) {}
-
- explicit FullSourceLoc(SourceLocation loc, SourceManager& smgr)
- : Loc(loc), SrcMgr(&smgr) {}
-
- bool isValid() const { return Loc.isValid(); }
- bool isInvalid() const { return Loc.isInvalid(); }
-
- SourceLocation getLocation() const { return Loc; }
-
- SourceManager& getManager() {
- assert (SrcMgr && "SourceManager is NULL.");
- return *SrcMgr;
- }
-
- const SourceManager& getManager() const {
- assert (SrcMgr && "SourceManager is NULL.");
- return *SrcMgr;
- }
-
- FullSourceLoc getLogicalLoc() const;
- FullSourceLoc getPhysicalLoc() const;
- FullSourceLoc getIncludeLoc() const;
-
- unsigned getLineNumber() const;
- unsigned getColumnNumber() const;
-
- unsigned getLogicalLineNumber() const;
- unsigned getLogicalColumnNumber() const;
-
- unsigned getPhysicalLineNumber() const;
- unsigned getPhysicalColumnNumber() const;
-
- const char *getCharacterData() const;
-
- const llvm::MemoryBuffer* getBuffer() const;
-
- const char* getSourceName() const;
- const FileEntry* getFileEntryForLoc() const;
-
- bool isInSystemHeader() const;
-
- bool isFileID() const { return Loc.isFileID(); }
-
- unsigned getCanonicalFileID() const;
-
- bool operator==(const FullSourceLoc& RHS) const {
- return SrcMgr == RHS.SrcMgr && Loc == RHS.Loc;
- }
-
- bool operator!=(const FullSourceLoc& RHS) const {
- return SrcMgr != RHS.SrcMgr || Loc != RHS.Loc;
- }
-
- /// Prints information about this FullSourceLoc to stderr. Useful for
- /// debugging.
- void dump() const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
deleted file mode 100644
index 7d28db20e58f..000000000000
--- a/clang/include/clang/Basic/SourceManager.h
+++ /dev/null
@@ -1,508 +0,0 @@
-//===--- SourceManager.h - Track and cache source files ---------*- 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 SourceManager interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SOURCEMANAGER_H
-#define LLVM_CLANG_SOURCEMANAGER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include <vector>
-#include <set>
-#include <list>
-#include <cassert>
-
-namespace llvm {
-class MemoryBuffer;
-}
-
-namespace clang {
-
-class SourceManager;
-class FileManager;
-class FileEntry;
-class IdentifierTokenInfo;
-
-/// SrcMgr - Public enums and private classes that are part of the
-/// SourceManager implementation.
-///
-namespace SrcMgr {
- /// Characteristic_t - This is used to represent whether a file or directory
- /// holds normal user code, system code, or system code which is implicitly
- /// 'extern "C"' in C++ mode. Entire directories can be tagged with this
- /// (this is maintained by DirectoryLookup and friends) as can specific
- /// FileIDInfos when a #pragma system_header is seen or various other cases.
- ///
- enum Characteristic_t {
- C_User, C_System, C_ExternCSystem
- };
-
- /// ContentCache - Once instance of this struct is kept for every file
- /// loaded or used. This object owns the MemoryBuffer object.
- struct ContentCache {
- /// Reference to the file entry. This reference does not own
- /// the FileEntry object. It is possible for this to be NULL if
- /// the ContentCache encapsulates an imaginary text buffer.
- const FileEntry* Entry;
-
- /// Buffer - The actual buffer containing the characters from the input
- /// file. This is owned by the ContentCache object.
- const llvm::MemoryBuffer* Buffer;
-
- /// SourceLineCache - A new[]'d array of offsets for each source line. This
- /// is lazily computed. This is owned by the ContentCache object.
- unsigned* SourceLineCache;
-
- /// NumLines - The number of lines in this ContentCache. This is only valid
- /// if SourceLineCache is non-null.
- unsigned NumLines;
-
- ContentCache(const FileEntry* e = NULL)
- : Entry(e), Buffer(NULL), SourceLineCache(NULL), NumLines(0) {}
-
- ~ContentCache();
-
- /// The copy ctor does not allow copies where source object has either
- /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
- /// is not transfered, so this is a logical error.
- ContentCache(const ContentCache& RHS) : Buffer(NULL),SourceLineCache(NULL) {
- Entry = RHS.Entry;
-
- assert (RHS.Buffer == NULL && RHS.SourceLineCache == NULL
- && "Passed ContentCache object cannot own a buffer.");
-
- NumLines = RHS.NumLines;
- }
-
- /// Emit - Emit this ContentCache to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// ReadToSourceManager - Reconstitute a ContentCache from Bitcode
- // and store it in the specified SourceManager.
- static void ReadToSourceManager(llvm::Deserializer& D, SourceManager& SMgr,
- FileManager* FMgr, std::vector<char>& Buf);
-
- private:
- // Disable assignments.
- ContentCache& operator=(const ContentCache& RHS);
- };
-
- /// FileIDInfo - Information about a FileID, basically just the logical file
- /// that it represents and include stack information. A File SourceLocation
- /// is a byte offset from the start of this.
- ///
- /// FileID's are used to compute the location of a character in memory as well
- /// as the logical source location, which can be differ from the physical
- /// location. It is different when #line's are active or when macros have
- /// been expanded.
- ///
- /// Each FileID has include stack information, indicating where it came from.
- /// For the primary translation unit, it comes from SourceLocation() aka 0.
- /// This information encodes the #include chain that a token was instantiated
- /// from.
- ///
- /// FileIDInfos contain a "ContentCache *", describing the source file,
- /// and a Chunk number, which allows a SourceLocation to index into very
- /// large files (those which there are not enough FilePosBits to address).
- ///
- struct FileIDInfo {
- private:
- /// IncludeLoc - The location of the #include that brought in this file.
- /// This SourceLocation object has an invalid SLOC for the main file.
- SourceLocation IncludeLoc;
-
- /// ChunkNo - Really large buffers are broken up into chunks that are
- /// each (1 << SourceLocation::FilePosBits) in size. This specifies the
- /// chunk number of this FileID.
- unsigned ChunkNo : 30;
-
- /// FileCharacteristic - This is an instance of Characteristic_t,
- /// indicating whether this is a system header dir or not.
- unsigned FileCharacteristic : 2;
-
- /// Content - Information about the source buffer itself.
- const ContentCache* Content;
-
- public:
- /// get - Return a FileIDInfo object.
- static FileIDInfo get(SourceLocation IL, unsigned CN,
- const ContentCache *Con,
- Characteristic_t FileCharacter) {
- FileIDInfo X;
- X.IncludeLoc = IL;
- X.ChunkNo = CN;
- X.Content = Con;
- X.FileCharacteristic = FileCharacter;
- return X;
- }
-
- SourceLocation getIncludeLoc() const { return IncludeLoc; }
- unsigned getChunkNo() const { return ChunkNo; }
- const ContentCache* getContentCache() const { return Content; }
-
- /// getCharacteristic - Return whether this is a system header or not.
- Characteristic_t getFileCharacteristic() const {
- return (Characteristic_t)FileCharacteristic;
- }
-
- /// Emit - Emit this FileIDInfo to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// ReadVal - Reconstitute a FileIDInfo from Bitcode.
- static FileIDInfo ReadVal(llvm::Deserializer& S);
- };
-
- /// MacroIDInfo - Macro SourceLocations refer to these records by their ID.
- /// Each MacroIDInfo encodes the Instantiation location - where the macro was
- /// instantiated, and the PhysicalLoc - where the actual character data for
- /// the token came from. An actual macro SourceLocation stores deltas from
- /// these positions.
- class MacroIDInfo {
- SourceLocation VirtualLoc, PhysicalLoc;
- public:
- SourceLocation getVirtualLoc() const { return VirtualLoc; }
- SourceLocation getPhysicalLoc() const { return PhysicalLoc; }
-
- /// get - Return a MacroID for a macro expansion. VL specifies
- /// the instantiation location (where the macro is expanded), and PL
- /// specifies the physical location (where the characters from the token
- /// come from). Both VL and PL refer to normal File SLocs.
- static MacroIDInfo get(SourceLocation VL, SourceLocation PL) {
- MacroIDInfo X;
- X.VirtualLoc = VL;
- X.PhysicalLoc = PL;
- return X;
- }
-
- /// Emit - Emit this MacroIDInfo to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// ReadVal - Reconstitute a MacroIDInfo from Bitcode.
- static MacroIDInfo ReadVal(llvm::Deserializer& S);
- };
-} // end SrcMgr namespace.
-} // end clang namespace
-
-namespace std {
-template <> struct less<clang::SrcMgr::ContentCache> {
- inline bool operator()(const clang::SrcMgr::ContentCache& L,
- const clang::SrcMgr::ContentCache& R) const {
- return L.Entry < R.Entry;
- }
-};
-} // end std namespace
-
-namespace clang {
-
-/// SourceManager - This file handles loading and caching of source files into
-/// memory. This object owns the MemoryBuffer objects for all of the loaded
-/// files and assigns unique FileID's for each unique #include chain.
-///
-/// The SourceManager can be queried for information about SourceLocation
-/// objects, turning them into either physical or logical locations. Physical
-/// locations represent where the bytes corresponding to a token came from and
-/// logical locations represent where the location is in the user's view. In
-/// the case of a macro expansion, for example, the physical location indicates
-/// where the expanded token came from and the logical location specifies where
-/// it was expanded. Logical locations are also influenced by #line directives,
-/// etc.
-class SourceManager {
- /// FileInfos - Memoized information about all of the files tracked by this
- /// SourceManager. This set allows us to merge ContentCache entries based
- /// on their FileEntry*. All ContentCache objects will thus have unique,
- /// non-null, FileEntry pointers.
- std::set<SrcMgr::ContentCache> FileInfos;
-
- /// MemBufferInfos - Information about various memory buffers that we have
- /// read in. This is a list, instead of a vector, because we need pointers to
- /// the ContentCache objects to be stable. All FileEntry* within the
- /// stored ContentCache objects are NULL, as they do not refer to a file.
- std::list<SrcMgr::ContentCache> MemBufferInfos;
-
- /// FileIDs - Information about each FileID. FileID #0 is not valid, so all
- /// entries are off by one.
- std::vector<SrcMgr::FileIDInfo> FileIDs;
-
- /// MacroIDs - Information about each MacroID.
- std::vector<SrcMgr::MacroIDInfo> MacroIDs;
-
- /// LastLineNo - These ivars serve as a cache used in the getLineNumber
- /// method which is used to speedup getLineNumber calls to nearby locations.
- unsigned LastLineNoFileIDQuery;
- SrcMgr::ContentCache *LastLineNoContentCache;
- unsigned LastLineNoFilePos;
- unsigned LastLineNoResult;
-
- /// MainFileID - The file ID for the main source file of the translation unit.
- unsigned MainFileID;
-
- // SourceManager doesn't support copy construction.
- explicit SourceManager(const SourceManager&);
- void operator=(const SourceManager&);
-public:
- SourceManager() : LastLineNoFileIDQuery(~0U), MainFileID(0) {}
- ~SourceManager() {}
-
- void clearIDTables() {
- MainFileID = 0;
- FileIDs.clear();
- MacroIDs.clear();
- LastLineNoFileIDQuery = ~0U;
- LastLineNoContentCache = 0;
- }
-
- /// getMainFileID - Returns the FileID of the main source file.
- unsigned getMainFileID() const { return MainFileID; }
-
- /// createFileID - Create a new FileID that represents the specified file
- /// being #included from the specified IncludePosition. This returns 0 on
- /// error and translates NULL into standard input.
- unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
- SrcMgr::Characteristic_t FileCharacter) {
- const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
- if (IR == 0) return 0; // Error opening file?
- return createFileID(IR, IncludePos, FileCharacter);
- }
-
- /// createMainFileID - Create the FileID for the main source file.
- unsigned createMainFileID(const FileEntry *SourceFile,
- SourceLocation IncludePos) {
-
- assert (MainFileID == 0 && "MainFileID already set!");
- MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
- return MainFileID;
- }
-
- /// createFileIDForMemBuffer - Create a new FileID that represents the
- /// specified memory buffer. This does no caching of the buffer and takes
- /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
- unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
- return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
- SrcMgr::C_User);
- }
-
- /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
- /// that will represent the FileID for the main source. One example
- /// of when this would be used is when the main source is read from STDIN.
- unsigned createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
- assert (MainFileID == 0 && "MainFileID already set!");
- MainFileID = createFileIDForMemBuffer(Buffer);
- return MainFileID;
- }
-
- /// getInstantiationLoc - Return a new SourceLocation that encodes the fact
- /// that a token at Loc should actually be referenced from InstantiationLoc.
- SourceLocation getInstantiationLoc(SourceLocation Loc,
- SourceLocation InstantiationLoc);
-
- /// getBuffer - Return the buffer for the specified FileID.
- ///
- const llvm::MemoryBuffer *getBuffer(unsigned FileID) const {
- return getContentCache(FileID)->Buffer;
- }
-
- /// getBufferData - Return a pointer to the start and end of the character
- /// data for the specified FileID.
- std::pair<const char*, const char*> getBufferData(unsigned FileID) const;
-
- /// getIncludeLoc - Return the location of the #include for the specified
- /// SourceLocation. If this is a macro expansion, this transparently figures
- /// out which file includes the file being expanded into.
- SourceLocation getIncludeLoc(SourceLocation ID) const {
- return getFIDInfo(getLogicalLoc(ID).getFileID())->getIncludeLoc();
- }
-
- /// getCharacterData - Return a pointer to the start of the specified location
- /// in the appropriate MemoryBuffer.
- const char *getCharacterData(SourceLocation SL) const;
-
- /// getColumnNumber - Return the column # for the specified file position.
- /// This is significantly cheaper to compute than the line number. This
- /// returns zero if the column number isn't known. This may only be called on
- /// a file sloc, so you must choose a physical or logical location before
- /// calling this method.
- unsigned getColumnNumber(SourceLocation Loc) const;
-
- unsigned getPhysicalColumnNumber(SourceLocation Loc) const {
- return getColumnNumber(getPhysicalLoc(Loc));
- }
- unsigned getLogicalColumnNumber(SourceLocation Loc) const {
- return getColumnNumber(getLogicalLoc(Loc));
- }
-
-
- /// getLineNumber - Given a SourceLocation, return the physical line number
- /// for the position indicated. This requires building and caching a table of
- /// line offsets for the MemoryBuffer, so this is not cheap: use only when
- /// about to emit a diagnostic.
- unsigned getLineNumber(SourceLocation Loc);
-
- unsigned getLogicalLineNumber(SourceLocation Loc) {
- return getLineNumber(getLogicalLoc(Loc));
- }
- unsigned getPhysicalLineNumber(SourceLocation Loc) {
- return getLineNumber(getPhysicalLoc(Loc));
- }
-
- /// getSourceName - This method returns the name of the file or buffer that
- /// the SourceLocation specifies. This can be modified with #line directives,
- /// etc.
- const char *getSourceName(SourceLocation Loc) const;
-
- /// Given a SourceLocation object, return the logical location referenced by
- /// the ID. This logical location is subject to #line directives, etc.
- SourceLocation getLogicalLoc(SourceLocation Loc) const {
- // File locations are both physical and logical.
- if (Loc.isFileID()) return Loc;
-
- return MacroIDs[Loc.getMacroID()].getVirtualLoc();
- }
-
- /// getPhysicalLoc - Given a SourceLocation object, return the physical
- /// location referenced by the ID.
- SourceLocation getPhysicalLoc(SourceLocation Loc) const {
- // File locations are both physical and logical.
- if (Loc.isFileID()) return Loc;
-
- SourceLocation PLoc = MacroIDs[Loc.getMacroID()].getPhysicalLoc();
- return PLoc.getFileLocWithOffset(Loc.getMacroPhysOffs());
- }
-
- /// getContentCacheForLoc - Return the ContentCache for the physloc of the
- /// specified SourceLocation, if one exists.
- const SrcMgr::ContentCache* getContentCacheForLoc(SourceLocation Loc) const {
- Loc = getPhysicalLoc(Loc);
- unsigned FileID = Loc.getFileID();
- assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
- return FileIDs[FileID-1].getContentCache();
- }
-
- /// getFileEntryForLoc - Return the FileEntry record for the physloc of the
- /// specified SourceLocation, if one exists.
- const FileEntry* getFileEntryForLoc(SourceLocation Loc) const {
- return getContentCacheForLoc(Loc)->Entry;
- }
-
- /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
- const FileEntry* getFileEntryForID(unsigned id) const {
- return getContentCache(id)->Entry;
- }
-
- /// getCanonicalFileID - Return the canonical FileID for a SourceLocation.
- /// A file can have multiple FileIDs if it is large enough to be broken
- /// into multiple chunks. This method returns the unique FileID without
- /// chunk information for a given SourceLocation. Use this method when
- /// you want to compare FileIDs across SourceLocations.
- unsigned getCanonicalFileID(SourceLocation PhysLoc) const {
- return getDecomposedFileLoc(PhysLoc).first;
- }
-
- /// getDecomposedFileLoc - Decompose the specified file location into a raw
- /// FileID + Offset pair. The first element is the FileID, the second is the
- /// offset from the start of the buffer of the location.
- std::pair<unsigned, unsigned> getDecomposedFileLoc(SourceLocation Loc) const {
- assert(Loc.isFileID() && "Isn't a File SourceLocation");
-
- // TODO: Add a flag "is first chunk" to SLOC.
- const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
-
- // If this file has been split up into chunks, factor in the chunk number
- // that the FileID references.
- unsigned ChunkNo = FIDInfo->getChunkNo();
- unsigned Offset = Loc.getRawFilePos();
- Offset += (ChunkNo << SourceLocation::FilePosBits);
-
- assert(Loc.getFileID() >= ChunkNo && "Unexpected offset");
-
- return std::make_pair(Loc.getFileID()-ChunkNo, Offset);
- }
-
- /// getFullFilePos - This (efficient) method returns the offset from the start
- /// of the file that the specified physical SourceLocation represents. This
- /// returns the location of the physical character data, not the logical file
- /// position.
- unsigned getFullFilePos(SourceLocation PhysLoc) const {
- return getDecomposedFileLoc(PhysLoc).second;
- }
-
- /// isFromSameFile - Returns true if both SourceLocations correspond to
- /// the same file.
- bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
- return getCanonicalFileID(Loc1) == getCanonicalFileID(Loc2);
- }
-
- /// isFromMainFile - Returns true if the file of provided SourceLocation is
- /// the main file.
- bool isFromMainFile(SourceLocation Loc) const {
- return getCanonicalFileID(Loc) == getMainFileID();
- }
-
- /// isInSystemHeader - Returns if a SourceLocation is in a system header.
- bool isInSystemHeader(SourceLocation Loc) const {
- return getFileCharacteristic(Loc) != SrcMgr::C_User;
- }
- SrcMgr::Characteristic_t getFileCharacteristic(SourceLocation Loc) const {
- return getFIDInfo(getPhysicalLoc(Loc).getFileID())->getFileCharacteristic();
- }
-
-
- /// PrintStats - Print statistics to stderr.
- ///
- void PrintStats() const;
-
- /// Emit - Emit this SourceManager to Bitcode.
- void Emit(llvm::Serializer& S) const;
-
- /// Read - Reconstitute a SourceManager from Bitcode.
- static SourceManager* CreateAndRegister(llvm::Deserializer& S,
- FileManager &FMgr);
-
-private:
- friend struct SrcMgr::ContentCache; // Used for deserialization.
-
- /// createFileID - Create a new fileID for the specified ContentCache and
- /// include position. This works regardless of whether the ContentCache
- /// corresponds to a file or some other input source.
- unsigned createFileID(const SrcMgr::ContentCache* File,
- SourceLocation IncludePos,
- SrcMgr::Characteristic_t DirCharacter);
-
- /// getContentCache - Create or return a cached ContentCache for the specified
- /// file. This returns null on failure.
- const SrcMgr::ContentCache* getContentCache(const FileEntry* SourceFile);
-
- /// createMemBufferContentCache - Create a new ContentCache for the specified
- /// memory buffer.
- const SrcMgr::ContentCache*
- createMemBufferContentCache(const llvm::MemoryBuffer* Buf);
-
- const SrcMgr::FileIDInfo* getFIDInfo(unsigned FileID) const {
- assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
- return &FileIDs[FileID-1];
- }
-
- const SrcMgr::ContentCache *getContentCache(unsigned FileID) const {
- return getContentCache(getFIDInfo(FileID));
- }
-
- /// Return the ContentCache structure for the specified FileID.
- /// This is always the physical reference for the ID.
- const SrcMgr::ContentCache*
- getContentCache(const SrcMgr::FileIDInfo* FIDInfo) const {
- return FIDInfo->getContentCache();
- }
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
deleted file mode 100644
index 0d990179ffa8..000000000000
--- a/clang/include/clang/Basic/TargetInfo.h
+++ /dev/null
@@ -1,233 +0,0 @@
-//===--- TargetInfo.h - Expose information about the target -----*- 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 TargetInfo interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
-#define LLVM_CLANG_BASIC_TARGETINFO_H
-
-#include "llvm/Support/DataTypes.h"
-#include <vector>
-#include <string>
-
-namespace llvm { struct fltSemantics; }
-
-namespace clang {
-
-class Diagnostic;
-class SourceManager;
-
-namespace Builtin { struct Info; }
-
-/// TargetInfo - This class exposes information about the current target.
-///
-class TargetInfo {
- std::string Triple;
-protected:
- // Target values set by the ctor of the actual target implementation. Default
- // values are specified by the TargetInfo constructor.
- bool CharIsSigned;
- unsigned char PointerWidth, PointerAlign;
- unsigned char WCharWidth, WCharAlign;
- unsigned char IntWidth, IntAlign;
- unsigned char FloatWidth, FloatAlign;
- unsigned char DoubleWidth, DoubleAlign;
- unsigned char LongDoubleWidth, LongDoubleAlign;
- unsigned char LongWidth, LongAlign;
- unsigned char LongLongWidth, LongLongAlign;
- const char *DescriptionString;
- const char *UserLabelPrefix;
- const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
-
- // TargetInfo Constructor. Default initializes all fields.
- TargetInfo(const std::string &T);
-
-public:
- /// CreateTargetInfo - Return the target info object for the specified target
- /// triple.
- static TargetInfo* CreateTargetInfo(const std::string &Triple);
-
- virtual ~TargetInfo();
-
- ///===---- Target Data Type Query Methods -------------------------------===//
-
- /// isCharSigned - Return true if 'char' is 'signed char' or false if it is
- /// treated as 'unsigned char'. This is implementation defined according to
- /// C99 6.2.5p15. In our implementation, this is target-specific.
- bool isCharSigned() const { return CharIsSigned; }
-
- /// getPointerWidth - Return the width of pointers on this target, for the
- /// specified address space.
- uint64_t getPointerWidth(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
- }
- uint64_t getPointerAlign(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
- }
-
- /// getBoolWidth/Align - Return the size of '_Bool' and C++ 'bool' for this
- /// target, in bits.
- unsigned getBoolWidth(bool isWide = false) const { return 8; } // FIXME
- unsigned getBoolAlign(bool isWide = false) const { return 8; } // FIXME
-
- unsigned getCharWidth(bool isWide = false) const {
- return isWide ? getWCharWidth() : 8; // FIXME
- }
- unsigned getCharAlign(bool isWide = false) const {
- return isWide ? getWCharAlign() : 8; // FIXME
- }
-
- /// getShortWidth/Align - Return the size of 'signed short' and
- /// 'unsigned short' for this target, in bits.
- unsigned getShortWidth() const { return 16; } // FIXME
- unsigned getShortAlign() const { return 16; } // FIXME
-
- /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
- /// this target, in bits.
- unsigned getIntWidth() const { return IntWidth; }
- unsigned getIntAlign() const { return IntAlign; }
-
- /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
- /// for this target, in bits.
- unsigned getLongWidth() const { return LongWidth; }
- unsigned getLongAlign() const { return LongAlign; }
-
- /// getLongLongWidth/Align - Return the size of 'signed long long' and
- /// 'unsigned long long' for this target, in bits.
- unsigned getLongLongWidth() const { return LongLongWidth; }
- unsigned getLongLongAlign() const { return LongLongAlign; }
-
- /// getWcharWidth/Align - Return the size of 'wchar_t' for this target, in
- /// bits.
- unsigned getWCharWidth() const { return WCharWidth; }
- unsigned getWCharAlign() const { return WCharAlign; }
-
- /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
- unsigned getFloatWidth() const { return FloatWidth; }
- unsigned getFloatAlign() const { return FloatAlign; }
- const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
-
- /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
- unsigned getDoubleWidth() const { return DoubleWidth; }
- unsigned getDoubleAlign() const { return DoubleAlign; }
- const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
-
- /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
- /// double'.
- unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
- unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
- const llvm::fltSemantics &getLongDoubleFormat() const {
- return *LongDoubleFormat;
- }
-
- /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
- /// target, in bits.
- unsigned getIntMaxTWidth() const {
- // FIXME: implement correctly.
- return 64;
- }
-
- /// getUserLabelPrefix - This returns the default value of the
- /// __USER_LABEL_PREFIX__ macro, which is the prefix given to user symbols by
- /// default. On most platforms this is "_", but it is "" on some, and "." on
- /// others.
- const char *getUserLabelPrefix() const {
- return UserLabelPrefix;
- }
-
- ///===---- Other target property query methods --------------------------===//
-
- /// getTargetDefines - Appends the target-specific #define values for this
- /// target set to the specified buffer.
- virtual void getTargetDefines(std::vector<char> &DefineBuffer) const = 0;
-
- /// getTargetBuiltins - Return information about target-specific builtins for
- /// the current primary target, and info about which builtins are non-portable
- /// across the current set of primary and secondary targets.
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const = 0;
-
- /// getVAListDeclaration - Return the declaration to use for
- /// __builtin_va_list, which is target-specific.
- virtual const char *getVAListDeclaration() const = 0;
-
- /// isValidGCCRegisterName - Returns whether the passed in string
- /// is a valid register name according to GCC. This is used by Sema for
- /// inline asm statements.
- bool isValidGCCRegisterName(const char *Name) const;
-
- // getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
- // For example, on x86 it will return "ax" when "eax" is passed in.
- const char *getNormalizedGCCRegisterName(const char *Name) const;
-
- enum ConstraintInfo {
- CI_None = 0x00,
- CI_AllowsMemory = 0x01,
- CI_AllowsRegister = 0x02,
- CI_ReadWrite = 0x04
- };
-
- // validateOutputConstraint, validateInputConstraint - Checks that
- // a constraint is valid and provides information about it.
- // FIXME: These should return a real error instead of just true/false.
- bool validateOutputConstraint(const char *Name, ConstraintInfo &Info) const;
- bool validateInputConstraint (const char *Name, unsigned NumOutputs,
- ConstraintInfo &info) const;
-
- virtual std::string convertConstraint(const char Constraint) const {
- return std::string(1, Constraint);
- }
-
- // Returns a string of target-specific clobbers, in LLVM format.
- virtual const char *getClobbers() const = 0;
-
-
- /// getTargetPrefix - Return the target prefix used for identifying
- /// llvm intrinsics.
- virtual const char *getTargetPrefix() const = 0;
-
- /// getTargetTriple - Return the target triple of the primary target.
- const char *getTargetTriple() const {
- return Triple.c_str();
- }
-
- const char *getTargetDescription() const {
- return DescriptionString;
- }
-
- struct GCCRegAlias {
- const char * const Aliases[5];
- const char * const Register;
- };
-
- virtual bool useGlobalsForAutomaticVariables() const { return false; }
-
- virtual bool useNeXTRuntimeAsDefault() const { return false; }
-
-protected:
- virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
- return PointerWidth;
- }
- virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
- return PointerAlign;
- }
-
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const = 0;
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const = 0;
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const= 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
deleted file mode 100644
index 9b636183dd08..000000000000
--- a/clang/include/clang/Basic/TokenKinds.def
+++ /dev/null
@@ -1,364 +0,0 @@
-//===--- TokenKinds.def - C Family Token Kind Database ----------*- 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 TokenKind database. This includes normal tokens like
-// tok::ampamp (corresponding to the && token) as well as keywords for various
-// languages. Users of this file must optionally #define the TOK, KEYWORD,
-// ALIAS, or PPKEYWORD macros to make use of this file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TOK
-#define TOK(X)
-#endif
-#ifndef KEYWORD
-#define KEYWORD(X,Y) TOK(kw_ ## X)
-#endif
-#ifndef ALIAS
-#define ALIAS(X,Y)
-#endif
-#ifndef PPKEYWORD
-#define PPKEYWORD(X)
-#endif
-#ifndef CXX_KEYWORD_OPERATOR
-#define CXX_KEYWORD_OPERATOR(X,Y)
-#endif
-#ifndef OBJC1_AT_KEYWORD
-#define OBJC1_AT_KEYWORD(X)
-#endif
-#ifndef OBJC2_AT_KEYWORD
-#define OBJC2_AT_KEYWORD(X)
-#endif
-
-//===----------------------------------------------------------------------===//
-// Preprocessor keywords.
-//===----------------------------------------------------------------------===//
-
-// These have meaning after a '#' at the start of a line. These define enums in
-// the tok::pp_* namespace. Note that IdentifierInfo::getPPKeywordID must be
-// manually updated if something is added here.
-PPKEYWORD(not_keyword)
-
-// C99 6.10.1 - Conditional Inclusion.
-PPKEYWORD(if)
-PPKEYWORD(ifdef)
-PPKEYWORD(ifndef)
-PPKEYWORD(elif)
-PPKEYWORD(else)
-PPKEYWORD(endif)
-PPKEYWORD(defined)
-
-// C99 6.10.2 - Source File Inclusion.
-PPKEYWORD(include)
-
-// C99 6.10.3 - Macro Replacement.
-PPKEYWORD(define)
-PPKEYWORD(undef)
-
-// C99 6.10.4 - Line Control.
-PPKEYWORD(line)
-
-// C99 6.10.5 - Error Directive.
-PPKEYWORD(error)
-
-// C99 6.10.6 - Pragma Directive.
-PPKEYWORD(pragma)
-
-// GNU Extensions.
-PPKEYWORD(import)
-PPKEYWORD(include_next)
-PPKEYWORD(warning)
-PPKEYWORD(ident)
-PPKEYWORD(sccs)
-PPKEYWORD(assert)
-PPKEYWORD(unassert)
-
-//===----------------------------------------------------------------------===//
-// Language keywords.
-//===----------------------------------------------------------------------===//
-
-// These define members of the tok::* namespace.
-
-TOK(unknown) // Not a token.
-TOK(eof) // End of file.
-TOK(eom) // End of macro (end of line inside a macro).
-
-// C99 6.4.9: Comments.
-TOK(comment) // Comment (only in -E -C[C] mode)
-
-// C99 6.4.2: Identifiers.
-TOK(identifier) // abcde123
-
-// C99 6.4.4.1: Integer Constants
-// C99 6.4.4.2: Floating Constants
-TOK(numeric_constant) // 0x123
-
-// C99 6.4.4: Character Constants
-TOK(char_constant) // 'a' L'b'
-
-// C99 6.4.5: String Literals.
-TOK(string_literal) // "foo"
-TOK(wide_string_literal) // L"foo"
-TOK(angle_string_literal)// <foo>
-
-// C99 6.4.6: Punctuators.
-TOK(l_square) // [
-TOK(r_square) // ]
-TOK(l_paren) // (
-TOK(r_paren) // )
-TOK(l_brace) // {
-TOK(r_brace) // }
-TOK(period) // .
-TOK(ellipsis) // ...
-TOK(amp) // &
-TOK(ampamp) // &&
-TOK(ampequal) // &=
-TOK(star) // *
-TOK(starequal) // *=
-TOK(plus) // +
-TOK(plusplus) // ++
-TOK(plusequal) // +=
-TOK(minus) // -
-TOK(arrow) // ->
-TOK(minusminus) // --
-TOK(minusequal) // -=
-TOK(tilde) // ~
-TOK(exclaim) // !
-TOK(exclaimequal) // !=
-TOK(slash) // /
-TOK(slashequal) // /=
-TOK(percent) // %
-TOK(percentequal) // %=
-TOK(less) // <
-TOK(lessless) // <<
-TOK(lessequal) // <=
-TOK(lesslessequal) // <<=
-TOK(greater) // >
-TOK(greatergreater) // >>
-TOK(greaterequal) // >=
-TOK(greatergreaterequal) // >>=
-TOK(caret) // ^
-TOK(caretequal) // ^=
-TOK(pipe) // |
-TOK(pipepipe) // ||
-TOK(pipeequal) // |=
-TOK(question) // ?
-TOK(colon) // :
-TOK(semi) // ;
-TOK(equal) // =
-TOK(equalequal) // ==
-TOK(comma) // ,
-TOK(hash) // #
-TOK(hashhash) // ##
-TOK(hashat) // #@
-
-// C++ Support
-TOK(periodstar) // .*
-TOK(arrowstar) // ->*
-TOK(coloncolon) // ::
-
-// Objective C support.
-TOK(at) // @
-
-
-// C99 6.4.1: Keywords. These turn into kw_* tokens.
-// Flags allowed:
-// NOTC90 - In C90, this token is never available.
-// EXTC90 - In C90, this token is an extension that is enabled unless strict.
-// NOTC99 - In C99, this token is never available.
-// EXTC99 - In C99, this token is an extension that is enabled unless strict.
-// NOTCPP - In C++98, this token is never available.
-// EXTCPP - In C++98, this token is an extension that is enabled unless strict.
-// NOTCPP0x - In C++0x, this token is never available.
-// EXTCPP0x - In C++0x, this token is an extension that is enabled unless
-// strict.
-//
-KEYWORD(auto , 0)
-KEYWORD(break , 0)
-KEYWORD(case , 0)
-KEYWORD(char , 0)
-KEYWORD(const , 0)
-KEYWORD(continue , 0)
-KEYWORD(default , 0)
-KEYWORD(do , 0)
-KEYWORD(double , 0)
-KEYWORD(else , 0)
-KEYWORD(enum , 0)
-KEYWORD(extern , 0)
-KEYWORD(float , 0)
-KEYWORD(for , 0)
-KEYWORD(goto , 0)
-KEYWORD(if , 0)
-KEYWORD(inline , EXTC90) // Ext in C90, ok in C99/C++
-KEYWORD(int , 0)
-KEYWORD(long , 0)
-KEYWORD(register , 0)
-KEYWORD(restrict , NOTC90) // Not in C90
-KEYWORD(return , 0)
-KEYWORD(short , 0)
-KEYWORD(signed , 0)
-KEYWORD(sizeof , 0)
-KEYWORD(static , 0)
-KEYWORD(struct , 0)
-KEYWORD(switch , 0)
-KEYWORD(typedef , 0)
-KEYWORD(union , 0)
-KEYWORD(unsigned , 0)
-KEYWORD(void , 0)
-KEYWORD(volatile , 0)
-KEYWORD(while , 0)
-KEYWORD(_Bool , EXTC90|EXTCPP|EXTCPP0x) // C99 only
-KEYWORD(_Complex , EXTC90|EXTCPP|EXTCPP0x) // C99 only
-KEYWORD(_Imaginary , EXTC90|NOTCPP|NOTCPP0x) // C90 only
-
-// Special tokens to the compiler.
-KEYWORD(__func__ , EXTC90|EXTCPP|EXTCPP0x) // Only in C99.
-KEYWORD(__FUNCTION__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x) // GCC Extension.
-KEYWORD(__PRETTY_FUNCTION__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x) // GCC Extension.
-
-// C++ 2.11p1: Keywords.
-KEYWORD(asm , EXTC90|EXTC99) // Exts in C90/C99
-KEYWORD(bool , BOOLSUPPORT)
-KEYWORD(catch , NOTC90|NOTC99)
-KEYWORD(class , NOTC90|NOTC99)
-KEYWORD(const_cast , NOTC90|NOTC99)
-KEYWORD(delete , NOTC90|NOTC99)
-KEYWORD(dynamic_cast , NOTC90|NOTC99)
-KEYWORD(explicit , NOTC90|NOTC99)
-KEYWORD(export , NOTC90|NOTC99)
-KEYWORD(false , BOOLSUPPORT)
-KEYWORD(friend , NOTC90|NOTC99)
-KEYWORD(mutable , NOTC90|NOTC99)
-KEYWORD(namespace , NOTC90|NOTC99)
-KEYWORD(new , NOTC90|NOTC99)
-KEYWORD(operator , NOTC90|NOTC99)
-KEYWORD(private , NOTC90|NOTC99)
-KEYWORD(protected , NOTC90|NOTC99)
-KEYWORD(public , NOTC90|NOTC99)
-KEYWORD(reinterpret_cast , NOTC90|NOTC99)
-KEYWORD(static_cast , NOTC90|NOTC99)
-KEYWORD(template , NOTC90|NOTC99)
-KEYWORD(this , NOTC90|NOTC99)
-KEYWORD(throw , NOTC90|NOTC99)
-KEYWORD(true , BOOLSUPPORT)
-KEYWORD(try , NOTC90|NOTC99)
-KEYWORD(typename , NOTC90|NOTC99)
-KEYWORD(typeid , NOTC90|NOTC99)
-KEYWORD(using , NOTC90|NOTC99)
-KEYWORD(virtual , NOTC90|NOTC99)
-KEYWORD(wchar_t , NOTC90|NOTC99)
-
-// C++ 2.5p2: Alternative Representations.
-CXX_KEYWORD_OPERATOR(and , ampamp)
-CXX_KEYWORD_OPERATOR(and_eq , ampequal)
-CXX_KEYWORD_OPERATOR(bitand , amp)
-CXX_KEYWORD_OPERATOR(bitor , pipe)
-CXX_KEYWORD_OPERATOR(compl , tilde)
-CXX_KEYWORD_OPERATOR(not , exclaim)
-CXX_KEYWORD_OPERATOR(not_eq , exclaimequal)
-CXX_KEYWORD_OPERATOR(or , pipepipe)
-CXX_KEYWORD_OPERATOR(or_eq , pipeequal)
-CXX_KEYWORD_OPERATOR(xor , caret)
-CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
-
-// C++0x keywords
-KEYWORD(char16_t , NOTC90|NOTC99|NOTCPP)
-KEYWORD(char32_t , NOTC90|NOTC99|NOTCPP)
-KEYWORD(static_assert , NOTC90|NOTC99|NOTCPP)
-
-// GNU Extensions.
-KEYWORD(_Decimal32 , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(_Decimal64 , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(_Decimal128 , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(typeof , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__null , NOTC90|NOTC99|EXTCPP|EXTCPP0x) // C++-only Extensn
-KEYWORD(__alignof , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__attribute , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__builtin_choose_expr , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__builtin_overload , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__builtin_offsetof , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__builtin_types_compatible_p, EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__builtin_va_arg , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__extension__ , 0) // Not treated as an extension!
-KEYWORD(__imag , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__label__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__real , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__thread , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-
-// Apple Extension.
-KEYWORD(__private_extern__ , EXTC90|EXTC99|NOTCPP)
-
-// Alternate spelling for various tokens. There are GCC extensions in all
-// languages, but should not be disabled in strict conformance mode.
-ALIAS("__attribute__", __attribute)
-ALIAS("__const" , const )
-ALIAS("__const__" , const )
-ALIAS("__alignof__" , __alignof )
-ALIAS("_asm" , asm )
-ALIAS("__asm" , asm )
-ALIAS("__asm__" , asm )
-ALIAS("__complex" , _Complex )
-ALIAS("__complex__" , _Complex )
-ALIAS("__imag__" , __imag )
-ALIAS("__inline" , inline )
-ALIAS("__inline__" , inline )
-ALIAS("__real__" , __real )
-ALIAS("__restrict" , restrict )
-ALIAS("__restrict__" , restrict )
-ALIAS("__signed" , signed )
-ALIAS("__signed__" , signed )
-ALIAS("__typeof" , typeof )
-ALIAS("__typeof__" , typeof )
-ALIAS("__volatile" , volatile )
-ALIAS("__volatile__" , volatile )
-
-
-//===----------------------------------------------------------------------===//
-// Objective-C @-preceeded keywords.
-//===----------------------------------------------------------------------===//
-
-// These have meaning after an '@' in Objective-C mode. These define enums in
-// the tok::objc_* namespace.
-
-OBJC1_AT_KEYWORD(not_keyword)
-OBJC1_AT_KEYWORD(class)
-OBJC1_AT_KEYWORD(compatibility_alias)
-OBJC1_AT_KEYWORD(defs)
-OBJC1_AT_KEYWORD(encode)
-OBJC1_AT_KEYWORD(end)
-OBJC1_AT_KEYWORD(implementation)
-OBJC1_AT_KEYWORD(interface)
-OBJC1_AT_KEYWORD(private)
-OBJC1_AT_KEYWORD(protected)
-OBJC1_AT_KEYWORD(protocol)
-OBJC1_AT_KEYWORD(public)
-OBJC1_AT_KEYWORD(selector)
-OBJC1_AT_KEYWORD(throw)
-OBJC1_AT_KEYWORD(try)
-OBJC1_AT_KEYWORD(catch)
-OBJC1_AT_KEYWORD(finally)
-OBJC1_AT_KEYWORD(synchronized)
-
-OBJC2_AT_KEYWORD(property)
-OBJC2_AT_KEYWORD(package)
-OBJC2_AT_KEYWORD(required)
-OBJC2_AT_KEYWORD(optional)
-OBJC2_AT_KEYWORD(synthesize)
-OBJC2_AT_KEYWORD(dynamic)
-
-// TODO: What to do about context-sensitive keywords like:
-// bycopy/byref/in/inout/oneway/out?
-
-#undef OBJC2_AT_KEYWORD
-#undef OBJC1_AT_KEYWORD
-#undef CXX_KEYWORD_OPERATOR
-#undef PPKEYWORD
-#undef ALIAS
-#undef KEYWORD
-#undef TOK
diff --git a/clang/include/clang/Basic/TokenKinds.h b/clang/include/clang/Basic/TokenKinds.h
deleted file mode 100644
index cfef30b4f5eb..000000000000
--- a/clang/include/clang/Basic/TokenKinds.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===--- TokenKinds.h - Enum values for C Token Kinds -----------*- 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 TokenKind enum and support functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOKENKINDS_H
-#define LLVM_CLANG_TOKENKINDS_H
-
-namespace clang {
-
-namespace tok {
-
-/// TokenKind - This provides a simple uniform namespace for tokens from all C
-/// languages.
-enum TokenKind {
-#define TOK(X) X,
-#include "clang/Basic/TokenKinds.def"
- NUM_TOKENS
-};
-
-/// PPKeywordKind - This provides a namespace for preprocessor keywords which
-/// start with a '#' at the beginning of the line.
-enum PPKeywordKind {
-#define PPKEYWORD(X) pp_##X,
-#include "clang/Basic/TokenKinds.def"
- NUM_PP_KEYWORDS
-};
-
-/// ObjCKeywordKind - This provides a namespace for Objective-C keywords which
-/// start with an '@'.
-enum ObjCKeywordKind {
-#define OBJC1_AT_KEYWORD(X) objc_##X,
-#define OBJC2_AT_KEYWORD(X) objc_##X,
-#include "clang/Basic/TokenKinds.def"
- NUM_OBJC_KEYWORDS
-};
-
-const char *getTokenName(enum TokenKind Kind);
-
-} // end namespace tok
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h
deleted file mode 100644
index 0f9b39341bd8..000000000000
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- 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 ModuleBuilder interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H
-#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
-
-#include "clang/AST/ASTConsumer.h"
-#include <string>
-
-namespace llvm {
- class Module;
-}
-
-namespace clang {
- class Diagnostic;
- struct LangOptions;
-
- class CodeGenerator : public ASTConsumer {
- public:
- virtual llvm::Module* ReleaseModule() = 0;
- };
-
- CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags,
- const LangOptions &Features,
- const std::string& ModuleName,
- bool GenerateDebugInfo);
-}
-
-#endif
diff --git a/clang/include/clang/Driver/HTMLDiagnostics.h b/clang/include/clang/Driver/HTMLDiagnostics.h
deleted file mode 100644
index be72c49fd2eb..000000000000
--- a/clang/include/clang/Driver/HTMLDiagnostics.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===--- HTMLPathDiagnostic.h - HTML Diagnostics for Paths ------*- 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 interface to create a HTMLPathDiagnostic object.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PATH_HTML_DIAGNOSTIC_H
-#define LLVM_CLANG_PATH_HTML_DIAGNOSTIC_H
-
-#include <string>
-
-namespace clang {
-
-class PathDiagnosticClient;
-class Preprocessor;
-class PreprocessorFactory;
-
-
-PathDiagnosticClient* CreateHTMLDiagnosticClient(const std::string& prefix,
- Preprocessor* PP,
- PreprocessorFactory* PPF);
-}
-
-#endif
diff --git a/clang/include/clang/Driver/InitHeaderSearch.h b/clang/include/clang/Driver/InitHeaderSearch.h
deleted file mode 100644
index a113456e8a5b..000000000000
--- a/clang/include/clang/Driver/InitHeaderSearch.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===--- InitHeaderSearch.h - Initialize header search paths ----*- 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 InitHeaderSearch class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DRIVER_INIT_HEADER_SEARCH_H_
-#define DRIVER_INIT_HEADER_SEARCH_H_
-
-#include <string>
-#include <vector>
-
-#include "clang/Lex/DirectoryLookup.h"
-
-namespace clang {
-
-class HeaderSearch;
-class LangOptions;
-
-/// InitHeaderSearch - This class makes it easier to set the search paths of
-/// a HeaderSearch object. InitHeaderSearch stores several search path lists
-/// internally, which can be sent to a HeaderSearch object in one swoop.
-class InitHeaderSearch {
- std::vector<DirectoryLookup> IncludeGroup[4];
- HeaderSearch& Headers;
- bool Verbose;
- std::string isysroot;
-
-public:
- /// InitHeaderSearch::IncludeDirGroup - Identifies the several search path
- /// lists stored internally.
- 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.
- };
-
- InitHeaderSearch(HeaderSearch &HS,
- bool verbose = false, const std::string &iSysroot = "")
- : Headers(HS), Verbose(verbose), isysroot(iSysroot) {}
-
- /// AddPath - Add the specified path to the specified group list.
- void AddPath(const std::string &Path, IncludeDirGroup Group,
- bool isCXXAware, bool isUserSupplied,
- bool isFramework);
-
- /// AddEnvVarPaths - Add a list of paths from an environment variable to a
- /// header search list.
- void AddEnvVarPaths(const char *Name);
-
- /// AddDefaultEnvVarPaths - Adds list of paths from default environment
- /// variables such as CPATH.
- void AddDefaultEnvVarPaths(const LangOptions &Lang);
-
- /// AddDefaultSystemIncludePaths - Adds the default system include paths so
- /// that e.g. stdio.h is found.
- void AddDefaultSystemIncludePaths(const LangOptions &Lang);
-
- /// Realise - Merges all search path lists into one list and send it to
- /// HeaderSearch.
- void Realize();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Driver/TextDiagnosticBuffer.h b/clang/include/clang/Driver/TextDiagnosticBuffer.h
deleted file mode 100644
index 28f2287c675a..000000000000
--- a/clang/include/clang/Driver/TextDiagnosticBuffer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a concrete diagnostic client, which buffers the diagnostic messages.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DRIVER_TEXT_DIAGNOSTIC_BUFFER_H_
-#define DRIVER_TEXT_DIAGNOSTIC_BUFFER_H_
-
-#include "clang/Basic/Diagnostic.h"
-#include <vector>
-
-namespace clang {
-
-class Preprocessor;
-class SourceManager;
-
-class TextDiagnosticBuffer : public DiagnosticClient {
-public:
- typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
- typedef DiagList::iterator iterator;
- typedef DiagList::const_iterator const_iterator;
-private:
- DiagList Errors, Warnings, Notes;
-public:
- const_iterator err_begin() const { return Errors.begin(); }
- const_iterator err_end() const { return Errors.end(); }
-
- const_iterator warn_begin() const { return Warnings.begin(); }
- const_iterator warn_end() const { return Warnings.end(); }
-
- const_iterator note_begin() const { return Notes.begin(); }
- const_iterator note_end() const { return Notes.end(); }
-
- virtual void HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level DiagLevel,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges);
-};
-
-} // end namspace clang
-
-#endif
diff --git a/clang/include/clang/Driver/TextDiagnosticPrinter.h b/clang/include/clang/Driver/TextDiagnosticPrinter.h
deleted file mode 100644
index 1d609ced4d10..000000000000
--- a/clang/include/clang/Driver/TextDiagnosticPrinter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a concrete diagnostic client, which prints the diagnostics to
-// standard error.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TEXT_DIAGNOSTIC_PRINTER_H_
-#define TEXT_DIAGNOSTIC_PRINTER_H_
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/Streams.h"
-
-namespace clang {
-class SourceManager;
-
-class TextDiagnosticPrinter : public DiagnosticClient {
- FullSourceLoc LastWarningLoc;
- FullSourceLoc LastLoc;
- llvm::OStream OS;
- bool ShowColumn;
- bool CaretDiagnostics;
-public:
- TextDiagnosticPrinter(bool showColumn = true, bool caretDiagnistics = true,
- llvm::OStream &os = llvm::cerr)
- : OS(os), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics) {}
-
- void PrintIncludeStack(FullSourceLoc Pos);
-
- void HighlightRange(const SourceRange &R,
- SourceManager& SrcMgr,
- unsigned LineNo, unsigned FileID,
- std::string &CaretLine,
- const std::string &SourceLine);
-
- virtual void HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level DiagLevel,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges);
-};
-
-} // end namspace clang
-
-#endif
diff --git a/clang/include/clang/Lex/DirectoryLookup.h b/clang/include/clang/Lex/DirectoryLookup.h
deleted file mode 100644
index e5171cd7fe87..000000000000
--- a/clang/include/clang/Lex/DirectoryLookup.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===--- DirectoryLookup.h - Info for searching for headers -----*- 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 DirectoryLookup interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
-#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
-
-#include "clang/Basic/SourceManager.h"
-
-namespace clang {
-class HeaderMap;
-class DirectoryEntry;
-class FileEntry;
-class HeaderSearch;
-
-/// DirectoryLookup - This class represents one entry in the search list that
-/// specifies the search order for directories in #include directives. It
-/// represents either a directory, a framework, or a headermap.
-///
-class DirectoryLookup {
-public:
- enum LookupType_t {
- LT_NormalDir,
- LT_Framework,
- LT_HeaderMap
- };
-private:
- union { // This union is discriminated by isHeaderMap.
- /// Dir - This is the actual directory that we're referring to for a normal
- /// directory or a framework.
- const DirectoryEntry *Dir;
-
- /// Map - This is the HeaderMap if this is a headermap lookup.
- ///
- const HeaderMap *Map;
- } u;
-
- /// DirCharacteristic - The type of directory this is: this is an instance of
- /// SrcMgr::Characteristic_t.
- unsigned DirCharacteristic : 2;
-
- /// UserSupplied - True if this is a user-supplied directory.
- ///
- bool UserSupplied : 1;
-
- /// LookupType - This indicates whether this DirectoryLookup object is a
- /// normal directory, a framework, or a headermap.
- unsigned LookupType : 2;
-public:
- /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
- /// 'dir'.
- DirectoryLookup(const DirectoryEntry *dir, SrcMgr::Characteristic_t DT,
- bool isUser, bool isFramework)
- : DirCharacteristic(DT), UserSupplied(isUser),
- LookupType(isFramework ? LT_Framework : LT_NormalDir) {
- u.Dir = dir;
- }
-
- /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
- /// 'map'.
- DirectoryLookup(const HeaderMap *map, SrcMgr::Characteristic_t DT,
- bool isUser)
- : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) {
- u.Map = map;
- }
-
- /// getLookupType - Return the kind of directory lookup that this is: either a
- /// normal directory, a framework path, or a HeaderMap.
- LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
-
- /// getName - Return the directory or filename corresponding to this lookup
- /// object.
- const char *getName() const;
-
- /// getDir - Return the directory that this entry refers to.
- ///
- const DirectoryEntry *getDir() const { return isNormalDir() ? u.Dir : 0; }
-
- /// getFrameworkDir - Return the directory that this framework refers to.
- ///
- const DirectoryEntry *getFrameworkDir() const {
- return isFramework() ? u.Dir : 0;
- }
-
- /// getHeaderMap - Return the directory that this entry refers to.
- ///
- const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
-
- /// isNormalDir - Return true if this is a normal directory, not a header map.
- bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
-
- /// isFramework - True if this is a framework directory.
- ///
- bool isFramework() const { return getLookupType() == LT_Framework; }
-
- /// isHeaderMap - Return true if this is a header map, not a normal directory.
- bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
-
- /// DirCharacteristic - The type of directory this is, one of the DirType enum
- /// values.
- SrcMgr::Characteristic_t getDirCharacteristic() const {
- return (SrcMgr::Characteristic_t)DirCharacteristic;
- }
-
- /// isUserSupplied - True if this is a user-supplied directory.
- ///
- bool isUserSupplied() const { return UserSupplied; }
-
-
- /// LookupFile - Lookup the specified file in this search path, returning it
- /// if it exists or returning null if not.
- const FileEntry *LookupFile(const char *FilenameStart,
- const char *FilenameEnd, HeaderSearch &HS) const;
-
-private:
- const FileEntry *DoFrameworkLookup(const char *FilenameStart,
- const char *FilenameEnd,
- HeaderSearch &HS) const;
-
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/HeaderMap.h b/clang/include/clang/Lex/HeaderMap.h
deleted file mode 100644
index d8033093bd8e..000000000000
--- a/clang/include/clang/Lex/HeaderMap.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- 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 HeaderMap interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_HEADERMAP_H
-#define LLVM_CLANG_LEX_HEADERMAP_H
-
-namespace llvm {
- class MemoryBuffer;
-}
-namespace clang {
- class FileEntry;
- class FileManager;
- struct HMapBucket;
- struct HMapHeader;
-
-/// This class represents an Apple concept known as a 'header map'. To the
-/// #include file resolution process, it basically acts like a directory of
-/// symlinks to files. Its advantages are that it is dense and more efficient
-/// to create and process than a directory of symlinks.
-class HeaderMap {
- HeaderMap(const HeaderMap&); // DO NOT IMPLEMENT
- void operator=(const HeaderMap&); // DO NOT IMPLEMENT
-
- const llvm::MemoryBuffer *FileBuffer;
- bool NeedsBSwap;
-
- HeaderMap(const llvm::MemoryBuffer *File, bool BSwap)
- : FileBuffer(File), NeedsBSwap(BSwap) {
- }
-public:
- ~HeaderMap();
-
- /// HeaderMap::Create - This attempts to load the specified file as a header
- /// map. If it doesn't look like a HeaderMap, it gives up and returns null.
- static const HeaderMap *Create(const FileEntry *FE);
-
- /// LookupFile - Check to see if the specified relative filename is located in
- /// this HeaderMap. If so, open it and return its FileEntry.
- const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
- FileManager &FM) const;
-
- /// getFileName - Return the filename of the headermap.
- const char *getFileName() const;
-
- /// dump - Print the contents of this headermap to stderr.
- void dump() const;
-
-private:
- unsigned getEndianAdjustedWord(unsigned X) const;
- const HMapHeader &getHeader() const;
- HMapBucket getBucket(unsigned BucketNo) const;
- const char *getString(unsigned StrTabIdx) const;
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
deleted file mode 100644
index fc0321b3aa07..000000000000
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ /dev/null
@@ -1,204 +0,0 @@
-//===--- HeaderSearch.h - Resolve Header File Locations ---------*- 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 HeaderSearch interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
-#define LLVM_CLANG_LEX_HEADERSEARCH_H
-
-#include "clang/Lex/DirectoryLookup.h"
-#include "llvm/ADT/StringMap.h"
-#include <vector>
-
-namespace clang {
-class FileEntry;
-class FileManager;
-class IdentifierInfo;
-
-
-/// HeaderSearch - This class encapsulates the information needed to find the
-/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
-class HeaderSearch {
- FileManager &FileMgr;
-
- /// #include search path information. Requests for #include "x" search the
- /// directory of the #including file first, then each directory in SearchDirs
- /// consequtively. Requests for <x> search the current dir first, then each
- /// directory in SearchDirs, starting at SystemDirIdx, consequtively. If
- /// NoCurDirSearch is true, then the check for the file in the current
- /// directory is supressed.
- std::vector<DirectoryLookup> SearchDirs;
- unsigned SystemDirIdx;
- bool NoCurDirSearch;
-
- /// PreFileInfo - The preprocessor keeps track of this information for each
- /// file that is #included.
- struct PerFileInfo {
- /// isImport - True if this is a #import'd or #pragma once file.
- bool isImport : 1;
-
- /// DirInfo - Keep track of whether this is a system header, and if so,
- /// whether it is C++ clean or not. This can be set by the include paths or
- /// by #pragma gcc system_header. This is an instance of
- /// SrcMgr::Characteristic_t.
- unsigned DirInfo : 2;
-
- /// NumIncludes - This is the number of times the file has been included
- /// already.
- unsigned short NumIncludes;
-
- /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
- /// that protects the entire contents of the file, this is the identifier
- /// for the macro that controls whether or not it has any effect.
- const IdentifierInfo *ControllingMacro;
-
- PerFileInfo() : isImport(false), DirInfo(SrcMgr::C_User),
- NumIncludes(0), ControllingMacro(0) {}
- };
-
- /// FileInfo - This contains all of the preprocessor-specific data about files
- /// that are included. The vector is indexed by the FileEntry's UID.
- ///
- std::vector<PerFileInfo> FileInfo;
-
- /// LookupFileCache - This is keeps track of each lookup performed by
- /// LookupFile. The first part of the value is the starting index in
- /// SearchDirs that the cached search was performed from. If there is a hit
- /// and this value doesn't match the current query, the cache has to be
- /// ignored. The second value is the entry in SearchDirs that satisfied the
- /// query.
- llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache;
-
-
- /// FrameworkMap - This is a collection mapping a framework or subframework
- /// name like "Carbon" to the Carbon.framework directory.
- llvm::StringMap<const DirectoryEntry *> FrameworkMap;
-
- /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
- /// headermaps. This vector owns the headermap.
- std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
-
- // Various statistics we track for performance analysis.
- unsigned NumIncluded;
- unsigned NumMultiIncludeFileOptzn;
- unsigned NumFrameworkLookups, NumSubFrameworkLookups;
-
- // HeaderSearch doesn't support default or copy construction.
- explicit HeaderSearch();
- explicit HeaderSearch(const HeaderSearch&);
- void operator=(const HeaderSearch&);
-public:
- HeaderSearch(FileManager &FM);
- ~HeaderSearch();
-
- FileManager &getFileMgr() const { return FileMgr; }
-
- /// SetSearchPaths - Interface for setting the file search paths.
- ///
- void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
- unsigned systemDirIdx, bool noCurDirSearch) {
- SearchDirs = dirs;
- SystemDirIdx = systemDirIdx;
- NoCurDirSearch = noCurDirSearch;
- //LookupFileCache.clear();
- }
-
- /// ClearFileInfo - Forget everything we know about headers so far.
- void ClearFileInfo() {
- FileInfo.clear();
- }
-
- /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
- /// return null on failure. isAngled indicates whether the file reference is
- /// a <> reference. If successful, this returns 'UsedDir', the
- /// DirectoryLookup member the file was found in, or null if not applicable.
- /// If CurDir is non-null, the file was found in the specified directory
- /// search location. This is used to implement #include_next. CurFileEnt, if
- /// non-null, indicates where the #including file is, in case a relative
- /// search is needed.
- const FileEntry *LookupFile(const char *FilenameStart,
- const char *FilenameEnd, bool isAngled,
- const DirectoryLookup *FromDir,
- const DirectoryLookup *&CurDir,
- const FileEntry *CurFileEnt);
-
- /// LookupSubframeworkHeader - Look up a subframework for the specified
- /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
- /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
- /// is a subframework within Carbon.framework. If so, return the FileEntry
- /// for the designated file, otherwise return null.
- const FileEntry *LookupSubframeworkHeader(const char *FilenameStart,
- const char *FilenameEnd,
- const FileEntry *RelativeFileEnt);
-
- /// LookupFrameworkCache - Look up the specified framework name in our
- /// framework cache, returning the DirectoryEntry it is in if we know,
- /// otherwise, return null.
- const DirectoryEntry *&LookupFrameworkCache(const char *FWNameStart,
- const char *FWNameEnd) {
- return FrameworkMap.GetOrCreateValue(FWNameStart, FWNameEnd).getValue();
- }
-
- /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
- /// #include, #include_next, or #import directive. Return false if #including
- /// the file will have no effect or true if we should include it.
- bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
-
-
- /// getFileDirFlavor - Return whether the specified file is a normal header,
- /// a system header, or a C++ friendly system header.
- SrcMgr::Characteristic_t getFileDirFlavor(const FileEntry *File) {
- return (SrcMgr::Characteristic_t)getFileInfo(File).DirInfo;
- }
-
- /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
- /// due to #pragma once.
- void MarkFileIncludeOnce(const FileEntry *File) {
- getFileInfo(File).isImport = true;
- }
-
- /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
- /// due to #pragma GCC system_header.
- void MarkFileSystemHeader(const FileEntry *File) {
- getFileInfo(File).DirInfo = SrcMgr::C_System;
- }
-
- /// IncrementIncludeCount - Increment the count for the number of times the
- /// specified FileEntry has been entered.
- void IncrementIncludeCount(const FileEntry *File) {
- ++getFileInfo(File).NumIncludes;
- }
-
- /// SetFileControllingMacro - Mark the specified file as having a controlling
- /// macro. This is used by the multiple-include optimization to eliminate
- /// no-op #includes.
- void SetFileControllingMacro(const FileEntry *File,
- const IdentifierInfo *ControllingMacro) {
- getFileInfo(File).ControllingMacro = ControllingMacro;
- }
-
- /// CreateHeaderMap - This method returns a HeaderMap for the specified
- /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
- const HeaderMap *CreateHeaderMap(const FileEntry *FE);
-
- void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
-
- void PrintStats();
-private:
-
- /// getFileInfo - Return the PerFileInfo structure for the specified
- /// FileEntry.
- PerFileInfo &getFileInfo(const FileEntry *FE);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h
deleted file mode 100644
index 0ba51a603784..000000000000
--- a/clang/include/clang/Lex/Lexer.h
+++ /dev/null
@@ -1,383 +0,0 @@
-//===--- Lexer.h - C Language Family Lexer ----------------------*- 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 Lexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEXER_H
-#define LLVM_CLANG_LEXER_H
-
-#include "clang/Lex/Token.h"
-#include "clang/Lex/MultipleIncludeOpt.h"
-#include "clang/Basic/LangOptions.h"
-#include "llvm/ADT/SmallVector.h"
-#include <string>
-#include <vector>
-#include <cassert>
-
-namespace clang {
-class Diagnostic;
-class SourceManager;
-class Preprocessor;
-
-/// Lexer - This provides a simple interface that turns a text buffer into a
-/// stream of tokens. This provides no support for file reading or buffering,
-/// or buffering/seeking of tokens, only forward lexing is supported. It relies
-/// on the specified Preprocessor object to handle preprocessor directives, etc.
-class Lexer {
- //===--------------------------------------------------------------------===//
- // Constant configuration values for this lexer.
- const char *BufferStart; // Start of the buffer.
- const char *BufferEnd; // End of the buffer.
- SourceLocation FileLoc; // Location for start of file.
- Preprocessor *PP; // Preprocessor object controlling lexing.
- LangOptions Features; // Features enabled by this language (cache).
- bool Is_PragmaLexer; // True if lexer for _Pragma handling.
-
- //===--------------------------------------------------------------------===//
- // Context-specific lexing flags set by the preprocessor.
- //
-
- /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns
- /// '\n' into a tok::eom token.
- bool ParsingPreprocessorDirective;
-
- /// ParsingFilename - True after #include: this turns <xx> into a
- /// tok::angle_string_literal token.
- bool ParsingFilename;
-
- /// LexingRawMode - True if in raw mode: This flag disables interpretation of
- /// tokens and is a far faster mode to lex in than non-raw-mode. This flag:
- /// 1. If EOF of the current lexer is found, the include stack isn't popped.
- /// 2. Identifier information is not looked up for identifier tokens. As an
- /// effect of this, implicit macro expansion is naturally disabled.
- /// 3. "#" tokens at the start of a line are treated as normal tokens, not
- /// implicitly transformed by the lexer.
- /// 4. All diagnostic messages are disabled, except for unterminated /*.
- /// 5. The only callback made into the preprocessor is to report a hard error
- /// on an unterminated '/*' comment.
- ///
- /// Note that in raw mode that the PP pointer may be null.
- bool LexingRawMode;
-
- /// KeepCommentMode - The lexer can optionally keep C & BCPL-style comments,
- /// and return them as tokens. This is used for -C and -CC modes.
- bool KeepCommentMode;
-
- //===--------------------------------------------------------------------===//
- // Context that changes as the file is lexed.
- // NOTE: any state that mutates when in raw mode must have save/restore code
- // in Lexer::isNextPPTokenLParen.
-
- // BufferPtr - Current pointer into the buffer. This is the next character
- // to be lexed.
- const char *BufferPtr;
-
- // IsAtStartOfLine - True if the next lexed token should get the "start of
- // line" flag set on it.
- bool IsAtStartOfLine;
-
- /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
- /// idiom for the multiple-include optimization.
- MultipleIncludeOpt MIOpt;
-
- /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
- /// we are currently in.
- std::vector<PPConditionalInfo> ConditionalStack;
-
- Lexer(const Lexer&); // DO NOT IMPLEMENT
- void operator=(const Lexer&); // DO NOT IMPLEMENT
- friend class Preprocessor;
-public:
-
- /// Lexer constructor - Create a new lexer object for the specified buffer
- /// with the specified preprocessor managing the lexing process. This lexer
- /// assumes that the associated file buffer and Preprocessor objects will
- /// outlive it, so it doesn't take ownership of either of them.
- Lexer(SourceLocation FileLoc, Preprocessor &PP,
- const char *BufStart = 0, const char *BufEnd = 0);
-
- /// Lexer constructor - Create a new raw lexer object. This object is only
- /// suitable for calls to 'LexRawToken'. This lexer assumes that the
- /// associated file buffer will outlive it, so it doesn't take ownership of
- /// either of them.
- Lexer(SourceLocation FileLoc, const LangOptions &Features,
- const char *BufStart, const char *BufEnd);
-
- /// getFeatures - Return the language features currently enabled. NOTE: this
- /// lexer modifies features as a file is parsed!
- const LangOptions &getFeatures() const { return Features; }
-
- /// getFileLoc - Return the File Location for the file we are lexing out of.
- /// The physical location encodes the location where the characters come from,
- /// the virtual location encodes where we should *claim* the characters came
- /// from. Currently this is only used by _Pragma handling.
- SourceLocation getFileLoc() const { return FileLoc; }
-
- /// Lex - Return the next token in the file. If this is the end of file, it
- /// return the tok::eof token. Return true if an error occurred and
- /// compilation should terminate, false if normal. This implicitly involves
- /// the preprocessor.
- void Lex(Token &Result) {
- // Start a new token.
- Result.startToken();
-
- // NOTE, any changes here should also change code after calls to
- // Preprocessor::HandleDirective
- if (IsAtStartOfLine) {
- Result.setFlag(Token::StartOfLine);
- IsAtStartOfLine = false;
- }
-
- // Get a token. Note that this may delete the current lexer if the end of
- // file is reached.
- LexTokenInternal(Result);
- }
-
- /// LexRawToken - Switch the lexer to raw mode, lex a token into Result and
- /// switch it back. Return true if the 'next character to read' pointer
- /// points and the end of the lexer buffer, false otherwise.
- bool LexRawToken(Token &Result) {
- assert(!(PP && LexingRawMode) && "Already in raw mode!");
- LexingRawMode = true;
- Lex(Result);
- LexingRawMode = PP == 0;
- // Note that lexing to the end of the buffer doesn't implicitly delete the
- // lexer when in raw mode.
- return BufferPtr == BufferEnd;
- }
-
- /// SetCommentRetentionMode - Change the comment retention mode of the lexer
- /// to the specified mode. This is really only useful when lexing in raw
- /// mode, because otherwise the lexer needs to manage this.
- void SetCommentRetentionState(bool Mode) {
- KeepCommentMode = Mode;
- }
-
- /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
- /// uninterpreted string. This switches the lexer out of directive mode.
- std::string ReadToEndOfLine();
-
-
- /// Diag - Forwarding function for diagnostics. This translate a source
- /// position in the current buffer into a SourceLocation object for rendering.
- void Diag(const char *Loc, unsigned DiagID,
- const std::string &Msg = std::string()) const;
- void Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg = std::string()) const;
-
- /// getSourceLocation - Return a source location identifier for the specified
- /// offset in the current file.
- SourceLocation getSourceLocation(const char *Loc) const;
-
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
- /// If Charify is true, this escapes the ' character instead of ".
- static std::string Stringify(const std::string &Str, bool Charify = false);
-
- /// Stringify - Convert the specified string into a C string by escaping '\'
- /// and " characters. This does not add surrounding ""'s to the string.
- static void Stringify(llvm::SmallVectorImpl<char> &Str);
-
- /// MeasureTokenLength - Relex the token at the specified location and return
- /// its length in bytes in the input file. If the token needs cleaning (e.g.
- /// includes a trigraph or an escaped newline) then this count includes bytes
- /// that are part of that.
- static unsigned MeasureTokenLength(SourceLocation Loc,
- const SourceManager &SM);
-
- //===--------------------------------------------------------------------===//
- // Internal implementation interfaces.
-private:
-
- /// LexTokenInternal - Internal interface to lex a preprocessing token. Called
- /// by Lex.
- ///
- void LexTokenInternal(Token &Result);
-
- /// FormTokenWithChars - When we lex a token, we have identified a span
- /// starting at BufferPtr, going to TokEnd that forms the token. This method
- /// takes that range and assigns it to the token as its location and size. In
- /// addition, since tokens cannot overlap, this also updates BufferPtr to be
- /// TokEnd.
- void FormTokenWithChars(Token &Result, const char *TokEnd) {
- Result.setLocation(getSourceLocation(BufferPtr));
- Result.setLength(TokEnd-BufferPtr);
- BufferPtr = TokEnd;
- }
-
- /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
- /// tok::l_paren token, 0 if it is something else and 2 if there are no more
- /// tokens in the buffer controlled by this lexer.
- unsigned isNextPPTokenLParen();
-
- //===--------------------------------------------------------------------===//
- // Lexer character reading interfaces.
-public:
-
- // This lexer is built on two interfaces for reading characters, both of which
- // automatically provide phase 1/2 translation. getAndAdvanceChar is used
- // when we know that we will be reading a character from the input buffer and
- // that this character will be part of the result token. This occurs in (f.e.)
- // string processing, because we know we need to read until we find the
- // closing '"' character.
- //
- // The second interface is the combination of PeekCharAndSize with
- // ConsumeChar. PeekCharAndSize reads a phase 1/2 translated character,
- // returning it and its size. If the lexer decides that this character is
- // part of the current token, it calls ConsumeChar on it. This two stage
- // approach allows us to emit diagnostics for characters (e.g. warnings about
- // trigraphs), knowing that they only are emitted if the character is
- // consumed.
-
- /// isObviouslySimpleCharacter - Return true if the specified character is
- /// obviously the same in translation phase 1 and translation phase 3. This
- /// can return false for characters that end up being the same, but it will
- /// never return true for something that needs to be mapped.
- static bool isObviouslySimpleCharacter(char C) {
- return C != '?' && C != '\\';
- }
-
- /// getAndAdvanceChar - Read a single 'character' from the specified buffer,
- /// advance over it, and return it. This is tricky in several cases. Here we
- /// just handle the trivial case and fall-back to the non-inlined
- /// getCharAndSizeSlow method to handle the hard case.
- inline char getAndAdvanceChar(const char *&Ptr, Token &Tok) {
- // If this is not a trigraph and not a UCN or escaped newline, return
- // quickly.
- if (isObviouslySimpleCharacter(Ptr[0])) return *Ptr++;
-
- unsigned Size = 0;
- char C = getCharAndSizeSlow(Ptr, Size, &Tok);
- Ptr += Size;
- return C;
- }
-
-private:
- /// ConsumeChar - When a character (identified by PeekCharAndSize) is consumed
- /// and added to a given token, check to see if there are diagnostics that
- /// need to be emitted or flags that need to be set on the token. If so, do
- /// it.
- const char *ConsumeChar(const char *Ptr, unsigned Size, Token &Tok) {
- // Normal case, we consumed exactly one token. Just return it.
- if (Size == 1)
- return Ptr+Size;
-
- // Otherwise, re-lex the character with a current token, allowing
- // diagnostics to be emitted and flags to be set.
- Size = 0;
- getCharAndSizeSlow(Ptr, Size, &Tok);
- return Ptr+Size;
- }
-
- /// getCharAndSize - Peek a single 'character' from the specified buffer,
- /// get its size, and return it. This is tricky in several cases. Here we
- /// just handle the trivial case and fall-back to the non-inlined
- /// getCharAndSizeSlow method to handle the hard case.
- inline char getCharAndSize(const char *Ptr, unsigned &Size) {
- // If this is not a trigraph and not a UCN or escaped newline, return
- // quickly.
- if (isObviouslySimpleCharacter(Ptr[0])) {
- Size = 1;
- return *Ptr;
- }
-
- Size = 0;
- return getCharAndSizeSlow(Ptr, Size);
- }
-
- /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
- /// method.
- char getCharAndSizeSlow(const char *Ptr, unsigned &Size, Token *Tok = 0);
-
- /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
- /// emit a warning.
- static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features) {
- // If this is not a trigraph and not a UCN or escaped newline, return
- // quickly.
- if (isObviouslySimpleCharacter(Ptr[0])) {
- Size = 1;
- return *Ptr;
- }
-
- Size = 0;
- return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
- }
-
- /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
- /// diagnostic.
- static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features);
-
- //===--------------------------------------------------------------------===//
- // #if directive handling.
-
- /// pushConditionalLevel - When we enter a #if directive, this keeps track of
- /// what we are currently in for diagnostic emission (e.g. #if with missing
- /// #endif).
- void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
- bool FoundNonSkip, bool FoundElse) {
- PPConditionalInfo CI;
- CI.IfLoc = DirectiveStart;
- CI.WasSkipping = WasSkipping;
- CI.FoundNonSkip = FoundNonSkip;
- CI.FoundElse = FoundElse;
- ConditionalStack.push_back(CI);
- }
- void pushConditionalLevel(const PPConditionalInfo &CI) {
- ConditionalStack.push_back(CI);
- }
-
- /// popConditionalLevel - Remove an entry off the top of the conditional
- /// stack, returning information about it. If the conditional stack is empty,
- /// this returns true and does not fill in the arguments.
- bool popConditionalLevel(PPConditionalInfo &CI) {
- if (ConditionalStack.empty()) return true;
- CI = ConditionalStack.back();
- ConditionalStack.pop_back();
- return false;
- }
-
- /// peekConditionalLevel - Return the top of the conditional stack. This
- /// requires that there be a conditional active.
- PPConditionalInfo &peekConditionalLevel() {
- assert(!ConditionalStack.empty() && "No conditionals active!");
- return ConditionalStack.back();
- }
-
- unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
-
- //===--------------------------------------------------------------------===//
- // Other lexer functions.
-
- // Helper functions to lex the remainder of a token of the specific type.
- void LexIdentifier (Token &Result, const char *CurPtr);
- void LexNumericConstant (Token &Result, const char *CurPtr);
- void LexStringLiteral (Token &Result, const char *CurPtr,bool Wide);
- void LexAngledStringLiteral(Token &Result, const char *CurPtr);
- void LexCharConstant (Token &Result, const char *CurPtr);
- bool LexEndOfFile (Token &Result, const char *CurPtr);
-
- void SkipWhitespace (Token &Result, const char *CurPtr);
- bool SkipBCPLComment (Token &Result, const char *CurPtr);
- bool SkipBlockComment (Token &Result, const char *CurPtr);
- bool SaveBCPLComment (Token &Result, const char *CurPtr);
-
- /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
- /// (potentially) macro expand the filename. If the sequence parsed is not
- /// lexically legal, emit a diagnostic and return a result EOM token.
- void LexIncludeFilename(Token &Result);
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h
deleted file mode 100644
index 834bb074e878..000000000000
--- a/clang/include/clang/Lex/LiteralSupport.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//===--- LiteralSupport.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 NumericLiteralParser, CharLiteralParser, and
-// StringLiteralParser interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_LITERALSUPPORT_H
-#define CLANG_LITERALSUPPORT_H
-
-#include <string>
-#include "llvm/ADT/SmallString.h"
-
-namespace llvm {
- class APInt;
- class APFloat;
- struct fltSemantics;
-}
-
-namespace clang {
-
-class Diagnostic;
-class Preprocessor;
-class Token;
-class SourceLocation;
-class TargetInfo;
-
-/// NumericLiteralParser - This performs strict semantic analysis of the content
-/// of a ppnumber, classifying it as either integer, floating, or erroneous,
-/// determines the radix of the value and can convert it to a useful value.
-class NumericLiteralParser {
- Preprocessor &PP; // needed for diagnostics
-
- const char *const ThisTokBegin;
- const char *const ThisTokEnd;
- const char *DigitsBegin, *SuffixBegin; // markers
- const char *s; // cursor
-
- unsigned radix;
-
- bool saw_exponent, saw_period;
-
-public:
- NumericLiteralParser(const char *begin, const char *end,
- SourceLocation Loc, Preprocessor &PP);
- bool hadError;
- bool isUnsigned;
- bool isLong; // This is *not* set for long long.
- bool isLongLong;
- bool isFloat; // 1.0f
- bool isImaginary; // 1.0i
-
- bool isIntegerLiteral() const {
- return !saw_period && !saw_exponent;
- }
- bool isFloatingLiteral() const {
- return saw_period || saw_exponent;
- }
- bool hasSuffix() const {
- return SuffixBegin != ThisTokEnd;
- }
-
- unsigned getRadix() const { return radix; }
-
- /// GetIntegerValue - Convert this numeric literal value to an APInt that
- /// matches Val's input width. If there is an overflow (i.e., if the unsigned
- /// value read is larger than the APInt's bits will hold), set Val to the low
- /// bits of the result and return true. Otherwise, return false.
- bool GetIntegerValue(llvm::APInt &Val);
-
- /// GetFloatValue - Convert this numeric literal to a floating value, using
- /// the specified APFloat fltSemantics (specifying float, double, etc).
- /// The optional bool isExact (passed-by-reference) has its value
- /// set to true if the returned APFloat can represent the number in the
- /// literal exactly, and false otherwise.
- llvm::APFloat GetFloatValue(const llvm::fltSemantics &Format,
- bool* isExact = NULL);
-
-private:
- void Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &M = std::string());
-
- void ParseNumberStartingWithZero(SourceLocation TokLoc);
-
- /// SkipHexDigits - Read and skip over any hex digits, up to End.
- /// Return a pointer to the first non-hex digit or End.
- const char *SkipHexDigits(const char *ptr) {
- while (ptr != ThisTokEnd && isxdigit(*ptr))
- ptr++;
- return ptr;
- }
-
- /// SkipOctalDigits - Read and skip over any octal digits, up to End.
- /// Return a pointer to the first non-hex digit or End.
- const char *SkipOctalDigits(const char *ptr) {
- while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7')))
- ptr++;
- return ptr;
- }
-
- /// SkipDigits - Read and skip over any digits, up to End.
- /// Return a pointer to the first non-hex digit or End.
- const char *SkipDigits(const char *ptr) {
- while (ptr != ThisTokEnd && isdigit(*ptr))
- ptr++;
- return ptr;
- }
-
- /// SkipBinaryDigits - Read and skip over any binary digits, up to End.
- /// Return a pointer to the first non-binary digit or End.
- const char *SkipBinaryDigits(const char *ptr) {
- while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1'))
- ptr++;
- return ptr;
- }
-
-};
-
-/// CharLiteralParser - Perform interpretation and semantic analysis of a
-/// character literal.
-class CharLiteralParser {
- unsigned Value;
- bool IsWide;
- bool HadError;
-public:
- CharLiteralParser(const char *begin, const char *end,
- SourceLocation Loc, Preprocessor &PP);
-
- bool hadError() const { return HadError; }
- bool isWide() const { return IsWide; }
- unsigned getValue() const { return Value; }
-};
-
-/// StringLiteralParser - This decodes string escape characters and performs
-/// wide string analysis and Translation Phase #6 (concatenation of string
-/// literals) (C99 5.1.1.2p1).
-class StringLiteralParser {
- Preprocessor &PP;
- TargetInfo &Target;
-
- unsigned MaxTokenLength;
- unsigned SizeBound;
- unsigned wchar_tByteWidth;
- llvm::SmallString<512> ResultBuf;
- char *ResultPtr; // cursor
-public:
- StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
- Preprocessor &PP, TargetInfo &T);
- bool hadError;
- bool AnyWide;
- bool Pascal;
-
- const char *GetString() { return &ResultBuf[0]; }
- unsigned GetStringLength() { return ResultPtr-&ResultBuf[0]; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/MacroInfo.h b/clang/include/clang/Lex/MacroInfo.h
deleted file mode 100644
index c63b701a85cd..000000000000
--- a/clang/include/clang/Lex/MacroInfo.h
+++ /dev/null
@@ -1,190 +0,0 @@
-//===--- MacroInfo.h - Information about #defined identifiers ---*- 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 MacroInfo interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_MACROINFO_H
-#define LLVM_CLANG_MACROINFO_H
-
-#include "clang/Lex/Token.h"
-#include "llvm/ADT/SmallVector.h"
-#include <vector>
-#include <cassert>
-
-namespace clang {
- class Preprocessor;
-
-/// MacroInfo - Each identifier that is #define'd has an instance of this class
-/// associated with it, used to implement macro expansion.
-class MacroInfo {
- //===--------------------------------------------------------------------===//
- // State set when the macro is defined.
-
- /// Location - This is the place the macro is defined.
- SourceLocation Location;
-
- /// Arguments - The list of arguments for a function-like macro. This can be
- /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this
- /// includes the __VA_ARGS__ identifier on the list.
- IdentifierInfo **ArgumentList;
- unsigned NumArguments;
-
- /// ReplacementTokens - This is the list of tokens that the macro is defined
- /// to.
- llvm::SmallVector<Token, 8> ReplacementTokens;
-
- /// IsFunctionLike - True if this macro is a function-like macro, false if it
- /// is an object-like macro.
- bool IsFunctionLike : 1;
-
- /// IsC99Varargs - True if this macro is of the form "#define X(...)" or
- /// "#define X(Y,Z,...)". The __VA_ARGS__ token should be replaced with the
- /// contents of "..." in an invocation.
- bool IsC99Varargs : 1;
-
- /// IsGNUVarargs - True if this macro is of the form "#define X(a...)". The
- /// "a" identifier in the replacement list will be replaced with all arguments
- /// of the macro starting with the specified one.
- bool IsGNUVarargs : 1;
-
- /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
- /// it has not yet been redefined or undefined.
- bool IsBuiltinMacro : 1;
-
-private:
- //===--------------------------------------------------------------------===//
- // State that changes as the macro is used.
-
- /// IsDisabled - True if we have started an expansion of this macro already.
- /// This disbles recursive expansion, which would be quite bad for things like
- /// #define A A.
- bool IsDisabled : 1;
-
- /// IsUsed - True if this macro is either defined in the main file and has
- /// been used, or if it is not defined in the main file. This is used to
- /// emit -Wunused-macros diagnostics.
- bool IsUsed : 1;
-public:
- MacroInfo(SourceLocation DefLoc);
-
- ~MacroInfo() {
- delete[] ArgumentList;
- }
-
- /// getDefinitionLoc - Return the location that the macro was defined at.
- ///
- SourceLocation getDefinitionLoc() const { return Location; }
-
- /// isIdenticalTo - Return true if the specified macro definition is equal to
- /// this macro in spelling, arguments, and whitespace. This is used to emit
- /// duplicate definition warnings. This implements the rules in C99 6.10.3.
- bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
-
- /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
- ///
- void setIsBuiltinMacro(bool Val = true) {
- IsBuiltinMacro = Val;
- }
-
- /// setIsUsed - Set the value of the IsUsed flag.
- ///
- void setIsUsed(bool Val) {
- IsUsed = Val;
- }
-
- /// setArgumentList - Set the specified list of identifiers as the argument
- /// list for this macro.
- template<typename ItTy>
- void setArgumentList(ItTy ArgBegin, ItTy ArgEnd) {
- assert(ArgumentList == 0 && "Argument list already set!");
- unsigned NumArgs = ArgEnd-ArgBegin;
- if (NumArgs == 0) return;
- NumArguments = NumArgs;
- ArgumentList = new IdentifierInfo*[NumArgs];
- for (unsigned i = 0; ArgBegin != ArgEnd; ++i, ++ArgBegin)
- ArgumentList[i] = *ArgBegin;
- }
-
- /// Arguments - The list of arguments for a function-like macro. This can be
- /// empty, for, e.g. "#define X()".
- typedef IdentifierInfo* const *arg_iterator;
- arg_iterator arg_begin() const { return ArgumentList; }
- arg_iterator arg_end() const { return ArgumentList+NumArguments; }
- unsigned getNumArgs() const { return NumArguments; }
-
- /// getArgumentNum - Return the argument number of the specified identifier,
- /// or -1 if the identifier is not a formal argument identifier.
- int getArgumentNum(IdentifierInfo *Arg) const {
- for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
- if (*I == Arg) return I-arg_begin();
- return -1;
- }
-
- /// Function/Object-likeness. Keep track of whether this macro has formal
- /// parameters.
- void setIsFunctionLike() { IsFunctionLike = true; }
- bool isFunctionLike() const { return IsFunctionLike; }
- bool isObjectLike() const { return !IsFunctionLike; }
-
- /// Varargs querying methods. This can only be set for function-like macros.
- void setIsC99Varargs() { IsC99Varargs = true; }
- void setIsGNUVarargs() { IsGNUVarargs = true; }
- bool isC99Varargs() const { return IsC99Varargs; }
- bool isGNUVarargs() const { return IsGNUVarargs; }
- bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
-
- /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
- /// __LINE__, which requires processing before expansion.
- bool isBuiltinMacro() const { return IsBuiltinMacro; }
-
- /// isUsed - Return false if this macro is defined in the main file and has
- /// not yet been used.
- bool isUsed() const { return IsUsed; }
-
- /// getNumTokens - Return the number of tokens that this macro expands to.
- ///
- unsigned getNumTokens() const {
- return ReplacementTokens.size();
- }
-
- const Token &getReplacementToken(unsigned Tok) const {
- assert(Tok < ReplacementTokens.size() && "Invalid token #");
- return ReplacementTokens[Tok];
- }
-
- typedef llvm::SmallVector<Token, 8>::const_iterator tokens_iterator;
- tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
- tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
-
- /// AddTokenToBody - Add the specified token to the replacement text for the
- /// macro.
- void AddTokenToBody(const Token &Tok) {
- ReplacementTokens.push_back(Tok);
- }
-
- /// isEnabled - Return true if this macro is enabled: in other words, that we
- /// are not currently in an expansion of this macro.
- bool isEnabled() const { return !IsDisabled; }
-
- void EnableMacro() {
- assert(IsDisabled && "Cannot enable an already-enabled macro!");
- IsDisabled = false;
- }
-
- void DisableMacro() {
- assert(!IsDisabled && "Cannot disable an already-disabled macro!");
- IsDisabled = true;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/MultipleIncludeOpt.h b/clang/include/clang/Lex/MultipleIncludeOpt.h
deleted file mode 100644
index 94d4677f9d29..000000000000
--- a/clang/include/clang/Lex/MultipleIncludeOpt.h
+++ /dev/null
@@ -1,130 +0,0 @@
-//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- 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 MultipleIncludeOpt interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H
-#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H
-
-namespace clang {
-class IdentifierInfo;
-
-/// MultipleIncludeOpt - This class implements the simple state machine that the
-/// Lexer class uses to detect files subject to the 'multiple-include'
-/// optimization. The public methods in this class are triggered by various
-/// events that occur when a file is lexed, and after the entire file is lexed,
-/// information about which macro (if any) controls the header is returned.
-class MultipleIncludeOpt {
- /// ReadAnyTokens - This is set to false when a file is first opened and true
- /// any time a token is returned to the client or a (non-multiple-include)
- /// directive is parsed. When the final #endif is parsed this is reset back
- /// to false, that way any tokens before the first #ifdef or after the last
- /// #endif can be easily detected.
- bool ReadAnyTokens;
-
- /// ReadAnyTokens - This is set to false when a file is first opened and true
- /// any time a token is returned to the client or a (non-multiple-include)
- /// directive is parsed. When the final #endif is parsed this is reset back
- /// to false, that way any tokens before the first #ifdef or after the last
- /// #endif can be easily detected.
- bool DidMacroExpansion;
-
- /// TheMacro - The controlling macro for a file, if valid.
- ///
- const IdentifierInfo *TheMacro;
-public:
- MultipleIncludeOpt() {
- ReadAnyTokens = false;
- DidMacroExpansion = false;
- TheMacro = 0;
- }
-
- /// Invalidate - Permenantly mark this file as not being suitable for the
- /// include-file optimization.
- void Invalidate() {
- // If we have read tokens but have no controlling macro, the state-machine
- // below can never "accept".
- ReadAnyTokens = true;
- TheMacro = 0;
- }
-
- /// getHasReadAnyTokensVal - This is used for the #ifndef hande-shake at the
- /// top of the file when reading preprocessor directives. Otherwise, reading
- /// the "ifndef x" would count as reading tokens.
- bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
-
- // If a token is read, remember that we have seen a side-effect in this file.
- void ReadToken() { ReadAnyTokens = true; }
-
- /// ExpandedMacro - When a macro is expanded with this lexer as the current
- /// buffer, this method is called to disable the MIOpt if needed.
- void ExpandedMacro() { DidMacroExpansion = true; }
-
- /// EnterTopLevelIFNDEF - When entering a top-level #ifndef directive (or the
- /// "#if !defined" equivalent) without any preceding tokens, this method is
- /// called.
- ///
- /// Note, we don't care about the input value of 'ReadAnyTokens'. The caller
- /// ensures that this is only called if there are no tokens read before the
- /// #ifndef. The caller is required to do this, because reading the #if line
- /// obviously reads in in tokens.
- void EnterTopLevelIFNDEF(const IdentifierInfo *M) {
- // If the macro is already set, this is after the top-level #endif.
- if (TheMacro)
- return Invalidate();
-
- // If we have already expanded a macro by the end of the #ifndef line, then
- // there is a macro expansion *in* the #ifndef line. This means that the
- // condition could evaluate differently when subsequently #included. Reject
- // this.
- if (DidMacroExpansion)
- return Invalidate();
-
- // Remember that we're in the #if and that we have the macro.
- ReadAnyTokens = true;
- TheMacro = M;
- }
-
- /// EnterTopLevelConditional - This is invoked when a top level conditional
- /// (except #ifndef) is found.
- void EnterTopLevelConditional() {
- /// If a conditional directive (except #ifndef) is found at the top level,
- /// there is a chunk of the file not guarded by the controlling macro.
- Invalidate();
- }
-
- /// ExitTopLevelConditional - This method is called when the lexer exits the
- /// top-level conditional.
- void ExitTopLevelConditional() {
- // If we have a macro, that means the top of the file was ok. Set our state
- // back to "not having read any tokens" so we can detect anything after the
- // #endif.
- if (!TheMacro) return Invalidate();
-
- // At this point, we haven't "read any tokens" but we do have a controlling
- // macro.
- ReadAnyTokens = false;
- }
-
- /// GetControllingMacroAtEndOfFile - Once the entire file has been lexed, if
- /// there is a controlling macro, return it.
- const IdentifierInfo *GetControllingMacroAtEndOfFile() const {
- // If we haven't read any tokens after the #endif, return the controlling
- // macro if it's valid (if it isn't, it will be null).
- if (!ReadAnyTokens)
- return TheMacro;
- return 0;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h
deleted file mode 100644
index d8bcdeb09822..000000000000
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- 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 PPCallbacks interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
-#define LLVM_CLANG_LEX_PPCALLBACKS_H
-
-#include "clang/Lex/DirectoryLookup.h"
-#include "clang/Basic/SourceLocation.h"
-#include <string>
-
-namespace clang {
- class SourceLocation;
-
-/// PPCallbacks - This interface provides a way to observe the actions of the
-/// preprocessor as it does its thing. Clients can define their hooks here to
-/// implement preprocessor level tools.
-class PPCallbacks {
-public:
- virtual ~PPCallbacks();
-
- enum FileChangeReason {
- EnterFile, ExitFile, SystemHeaderPragma, RenameFile
- };
-
- /// FileChanged - This callback is invoked whenever a source file is
- /// entered or exited. The SourceLocation indicates the new location, and
- /// EnteringFile indicates whether this is because we are entering a new
- /// #include'd file (when true) or whether we're exiting one because we ran
- /// off the end (when false).
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::Characteristic_t FileType) {
- }
-
- /// Ident - This callback is invoked when a #ident or #sccs directive is read.
- ///
- virtual void Ident(SourceLocation Loc, const std::string &str) {
- }
-
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/Pragma.h b/clang/include/clang/Lex/Pragma.h
deleted file mode 100644
index 136dc6fabfb6..000000000000
--- a/clang/include/clang/Lex/Pragma.h
+++ /dev/null
@@ -1,90 +0,0 @@
-//===--- Pragma.h - Pragma registration and handling ------------*- 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 PragmaHandler and PragmaTable interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PRAGMA_H
-#define LLVM_CLANG_PRAGMA_H
-
-#include <cassert>
-#include <vector>
-
-namespace clang {
- class Preprocessor;
- class Token;
- class IdentifierInfo;
- class PragmaNamespace;
-
-/// PragmaHandler - Instances of this interface defined to handle the various
-/// pragmas that the language front-end uses. Each handler optionally has a
-/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
-/// that identifier is found. If a handler does not match any of the declared
-/// pragmas the handler with a null identifier is invoked, if it exists.
-///
-/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
-/// we treat "#pragma STDC" and "#pragma GCC" as namespaces that contain other
-/// pragmas.
-class PragmaHandler {
- const IdentifierInfo *Name;
-public:
- PragmaHandler(const IdentifierInfo *name) : Name(name) {}
- virtual ~PragmaHandler();
-
- const IdentifierInfo *getName() const { return Name; }
- virtual void HandlePragma(Preprocessor &PP, Token &FirstToken) = 0;
-
- /// getIfNamespace - If this is a namespace, return it. This is equivalent to
- /// using a dynamic_cast, but doesn't require RTTI.
- virtual PragmaNamespace *getIfNamespace() { return 0; }
-};
-
-/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
-/// allowing hierarchical pragmas to be defined. Common examples of namespaces
-/// are "#pragma GCC", "#pragma STDC", and "#pragma omp", but any namespaces may
-/// be (potentially recursively) defined.
-class PragmaNamespace : public PragmaHandler {
- /// Handlers - This is the list of handlers in this namespace.
- ///
- std::vector<PragmaHandler*> Handlers;
-public:
- PragmaNamespace(const IdentifierInfo *Name) : PragmaHandler(Name) {}
- virtual ~PragmaNamespace();
-
- /// FindHandler - Check to see if there is already a handler for the
- /// specified name. If not, return the handler for the null identifier if it
- /// exists, otherwise return null. If IgnoreNull is true (the default) then
- /// the null handler isn't returned on failure to match.
- PragmaHandler *FindHandler(const IdentifierInfo *Name,
- bool IgnoreNull = true) const;
-
- /// AddPragma - Add a pragma to this namespace.
- ///
- void AddPragma(PragmaHandler *Handler) {
- Handlers.push_back(Handler);
- }
-
- /// RemovePragmaHandler - Remove the given handler from the
- /// namespace.
- void RemovePragmaHandler(PragmaHandler *Handler);
-
- bool IsEmpty() {
- return Handlers.empty();
- }
-
- virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
-
- virtual PragmaNamespace *getIfNamespace() { return this; }
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
deleted file mode 100644
index 4c8fa67e9433..000000000000
--- a/clang/include/clang/Lex/Preprocessor.h
+++ /dev/null
@@ -1,612 +0,0 @@
-//===--- Preprocessor.h - C Language Family Preprocessor --------*- 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 Preprocessor interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
-#define LLVM_CLANG_LEX_PREPROCESSOR_H
-
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/TokenLexer.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class SourceManager;
-class FileManager;
-class FileEntry;
-class HeaderSearch;
-class PragmaNamespace;
-class PragmaHandler;
-class ScratchBuffer;
-class TargetInfo;
-class PPCallbacks;
-class DirectoryLookup;
-
-/// Preprocessor - This object engages in a tight little dance with the lexer to
-/// efficiently preprocess tokens. Lexers know only about tokens within a
-/// single source file, and don't know anything about preprocessor-level issues
-/// like the #include stack, token expansion, etc.
-///
-class Preprocessor {
- Diagnostic &Diags;
- const LangOptions &Features;
- TargetInfo &Target;
- FileManager &FileMgr;
- SourceManager &SourceMgr;
- ScratchBuffer *ScratchBuf;
- HeaderSearch &HeaderInfo;
-
- /// Identifiers for builtin macros and other builtins.
- IdentifierInfo *Ident__LINE__, *Ident__FILE__; // __LINE__, __FILE__
- IdentifierInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__
- IdentifierInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__
- IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__
- IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__
- IdentifierInfo *Ident_Pragma, *Ident__VA_ARGS__; // _Pragma, __VA_ARGS__
-
- SourceLocation DATELoc, TIMELoc;
-
- enum {
- /// MaxIncludeStackDepth - Maximum depth of #includes.
- MaxAllowedIncludeStackDepth = 200
- };
-
- // State that is set before the preprocessor begins.
- bool KeepComments : 1;
- bool KeepMacroComments : 1;
-
- // State that changes while the preprocessor runs:
- bool DisableMacroExpansion : 1; // True if macro expansion is disabled.
- bool InMacroArgs : 1; // True if parsing fn macro invocation args.
-
- /// CacheTokens - True when the lexed tokens are cached for backtracking.
- bool CacheTokens : 1;
-
- /// Identifiers - This is mapping/lookup information for all identifiers in
- /// the program, including program keywords.
- IdentifierTable Identifiers;
-
- /// Selectors - This table contains all the selectors in the program. Unlike
- /// IdentifierTable above, this table *isn't* populated by the preprocessor.
- /// It is declared/instantiated here because it's role/lifetime is
- /// conceptually similar the IdentifierTable. In addition, the current control
- /// flow (in clang::ParseAST()), make it convenient to put here.
- /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
- /// the lifetime fo the preprocessor.
- SelectorTable Selectors;
-
- /// PragmaHandlers - This tracks all of the pragmas that the client registered
- /// with this preprocessor.
- PragmaNamespace *PragmaHandlers;
-
- /// CurLexer - This is the current top of the stack that we're lexing from if
- /// not expanding a macro. One of CurLexer and CurTokenLexer must be null.
- Lexer *CurLexer;
-
- /// CurLookup - The DirectoryLookup structure used to find the current
- /// FileEntry, if CurLexer is non-null and if applicable. This allows us to
- /// implement #include_next and find directory-specific properties.
- const DirectoryLookup *CurDirLookup;
-
- /// CurTokenLexer - This is the current macro we are expanding, if we are
- /// expanding a macro. One of CurLexer and CurTokenLexer must be null.
- TokenLexer *CurTokenLexer;
-
- /// IncludeMacroStack - This keeps track of the stack of files currently
- /// #included, and macros currently being expanded from, not counting
- /// CurLexer/CurTokenLexer.
- struct IncludeStackInfo {
- Lexer *TheLexer;
- const DirectoryLookup *TheDirLookup;
- TokenLexer *TheTokenLexer;
- IncludeStackInfo(Lexer *L, const DirectoryLookup *D, TokenLexer *TL)
- : TheLexer(L), TheDirLookup(D), TheTokenLexer(TL) {
- }
- };
- std::vector<IncludeStackInfo> IncludeMacroStack;
-
- /// Callbacks - These are actions invoked when some preprocessor activity is
- /// encountered (e.g. a file is #included, etc).
- PPCallbacks *Callbacks;
-
- /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping
- /// to the actual definition of the macro.
- llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
-
- // Various statistics we track for performance analysis.
- unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
- unsigned NumIf, NumElse, NumEndif;
- unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
- unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
- unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
- unsigned NumSkipped;
-
- /// Predefines - This string is the predefined macros that preprocessor
- /// should use from the command line etc.
- std::string Predefines;
-
- /// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
- enum { TokenLexerCacheSize = 8 };
- unsigned NumCachedTokenLexers;
- TokenLexer *TokenLexerCache[TokenLexerCacheSize];
-
-private: // Cached tokens state.
- typedef std::vector<Token> CachedTokensTy;
-
- /// CachedTokens - Cached tokens are stored here when we do backtracking or
- /// lookahead. They are "lexed" by the CachingLex() method.
- CachedTokensTy CachedTokens;
-
- /// CachedLexPos - The position of the cached token that CachingLex() should
- /// "lex" next. If it points beyond the CachedTokens vector, it means that
- /// a normal Lex() should be invoked.
- CachedTokensTy::size_type CachedLexPos;
-
- /// BacktrackPositions - Stack of backtrack positions, allowing nested
- /// backtracks. The EnableBacktrackAtThisPos() method pushes a position to
- /// indicate where CachedLexPos should be set when the BackTrack() method is
- /// invoked (at which point the last position is popped).
- std::vector<CachedTokensTy::size_type> BacktrackPositions;
-
-public:
- Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
- SourceManager &SM, HeaderSearch &Headers);
- ~Preprocessor();
-
- Diagnostic &getDiagnostics() const { return Diags; }
- const LangOptions &getLangOptions() const { return Features; }
- TargetInfo &getTargetInfo() const { return Target; }
- FileManager &getFileManager() const { return FileMgr; }
- SourceManager &getSourceManager() const { return SourceMgr; }
- HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
-
- IdentifierTable &getIdentifierTable() { return Identifiers; }
- SelectorTable &getSelectorTable() { return Selectors; }
-
- inline FullSourceLoc getFullLoc(SourceLocation Loc) const {
- return FullSourceLoc(Loc, getSourceManager());
- }
-
- /// SetCommentRetentionState - Control whether or not the preprocessor retains
- /// comments in output.
- void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
- this->KeepComments = KeepComments | KeepMacroComments;
- this->KeepMacroComments = KeepMacroComments;
- }
-
- bool getCommentRetentionState() const { return KeepComments; }
-
- /// isCurrentLexer - Return true if we are lexing directly from the specified
- /// lexer.
- bool isCurrentLexer(const Lexer *L) const {
- return CurLexer == L;
- }
-
- /// getCurrentLexer - Return the current file lexer being lexed from. Note
- /// that this ignores any potentially active macro expansions and _Pragma
- /// expansions going on at the time.
- Lexer *getCurrentFileLexer() const;
-
- /// getPPCallbacks/setPPCallbacks - Accessors for preprocessor callbacks.
- /// Note that this class takes ownership of any PPCallbacks object given to
- /// it.
- PPCallbacks *getPPCallbacks() const { return Callbacks; }
- void setPPCallbacks(PPCallbacks *C) {
- delete Callbacks;
- Callbacks = C;
- }
-
- /// getMacroInfo - Given an identifier, return the MacroInfo it is #defined to
- /// or null if it isn't #define'd.
- MacroInfo *getMacroInfo(IdentifierInfo *II) const {
- return II->hasMacroDefinition() ? Macros.find(II)->second : 0;
- }
-
- /// setMacroInfo - Specify a macro for this identifier.
- ///
- void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
-
- const std::string &getPredefines() const { return Predefines; }
- /// setPredefines - Set the predefines for this Preprocessor. These
- /// predefines are automatically injected when parsing the main file.
- void setPredefines(const char *P) { Predefines = P; }
- void setPredefines(const std::string &P) { Predefines = P; }
-
- /// getIdentifierInfo - Return information about the specified preprocessor
- /// identifier token. The version of this method that takes two character
- /// pointers is preferred unless the identifier is already available as a
- /// string (this avoids allocation and copying of memory to construct an
- /// std::string).
- IdentifierInfo *getIdentifierInfo(const char *NameStart,
- const char *NameEnd) {
- return &Identifiers.get(NameStart, NameEnd);
- }
- IdentifierInfo *getIdentifierInfo(const char *NameStr) {
- return getIdentifierInfo(NameStr, NameStr+strlen(NameStr));
- }
-
- /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
- /// If 'Namespace' is non-null, then it is a token required to exist on the
- /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
- void AddPragmaHandler(const char *Namespace, PragmaHandler *Handler);
-
- /// RemovePragmaHandler - Remove the specific pragma handler from
- /// the preprocessor. If \arg Namespace is non-null, then it should
- /// be the namespace that \arg Handler was added to. It is an error
- /// to remove a handler that has not been registered.
- void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
-
- /// EnterMainSourceFile - Enter the specified FileID as the main source file,
- /// which implicitly adds the builtin defines etc.
- void EnterMainSourceFile();
-
- /// EnterSourceFile - Add a source file to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer. If isMainFile
- /// is true, this is the main file for the translation unit.
- void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir);
-
- /// EnterMacro - Add a Macro to the top of the include stack and start lexing
- /// tokens from it instead of the current buffer. Args specifies the
- /// tokens input to a function-like macro.
- void EnterMacro(Token &Identifier, MacroArgs *Args);
-
- /// EnterTokenStream - Add a "macro" context to the top of the include stack,
- /// which will cause the lexer to start returning the specified tokens.
- ///
- /// If DisableMacroExpansion is true, tokens lexed from the token stream will
- /// not be subject to further macro expansion. Otherwise, these tokens will
- /// be re-macro-expanded when/if expansion is enabled.
- ///
- /// If OwnsTokens is false, this method assumes that the specified stream of
- /// tokens has a permanent owner somewhere, so they do not need to be copied.
- /// If it is true, it assumes the array of tokens is allocated with new[] and
- /// must be freed.
- ///
- void EnterTokenStream(const Token *Toks, unsigned NumToks,
- bool DisableMacroExpansion, bool OwnsTokens);
-
- /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
- /// lexer stack. This should only be used in situations where the current
- /// state of the top-of-stack lexer is known.
- void RemoveTopOfLexerStack();
-
- /// EnableBacktrackAtThisPos - From the point that this method is called, and
- /// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
- /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
- /// make the Preprocessor re-lex the same tokens.
- ///
- /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
- /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
- /// be combined with the EnableBacktrackAtThisPos calls in reverse order.
- ///
- /// NOTE: *DO NOT* forget to call either CommitBacktrackedTokens or Backtrack
- /// at some point after EnableBacktrackAtThisPos. If you don't, caching of
- /// tokens will continue indefinitely.
- ///
- void EnableBacktrackAtThisPos();
-
- /// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
- void CommitBacktrackedTokens();
-
- /// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
- /// EnableBacktrackAtThisPos() was previously called.
- void Backtrack();
-
- /// isBacktrackEnabled - True if EnableBacktrackAtThisPos() was called and
- /// caching of tokens is on.
- bool isBacktrackEnabled() const { return CacheTokens; }
-
- /// Lex - To lex a token from the preprocessor, just pull a token from the
- /// current lexer or macro object.
- void Lex(Token &Result) {
- if (CurLexer)
- CurLexer->Lex(Result);
- else if (CurTokenLexer)
- CurTokenLexer->Lex(Result);
- else
- CachingLex(Result);
- }
-
- /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get
- /// something not a comment. This is useful in -E -C mode where comments
- /// would foul up preprocessor directive handling.
- void LexNonComment(Token &Result) {
- do
- Lex(Result);
- while (Result.getKind() == tok::comment);
- }
-
- /// LexUnexpandedToken - This is just like Lex, but this disables macro
- /// expansion of identifier tokens.
- void LexUnexpandedToken(Token &Result) {
- // Disable macro expansion.
- bool OldVal = DisableMacroExpansion;
- DisableMacroExpansion = true;
- // Lex the token.
- Lex(Result);
-
- // Reenable it.
- DisableMacroExpansion = OldVal;
- }
-
- /// LookAhead - This peeks ahead N tokens and returns that token without
- /// consuming any tokens. LookAhead(0) returns the next token that would be
- /// returned by Lex(), LookAhead(1) returns the token after it, etc. This
- /// returns normal tokens after phase 5. As such, it is equivalent to using
- /// 'Lex', not 'LexUnexpandedToken'.
- const Token &LookAhead(unsigned N) {
- if (CachedLexPos + N < CachedTokens.size())
- return CachedTokens[CachedLexPos+N];
- else
- return PeekAhead(N+1);
- }
-
- /// Diag - Forwarding function for diagnostics. This emits a diagnostic at
- /// the specified Token's location, translating the token's start
- /// position in the current buffer into a SourcePosition object for rendering.
- void Diag(SourceLocation Loc, unsigned DiagID);
- void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg);
- void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange &R1, const SourceRange &R2);
- void Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R);
- void Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R1,
- const SourceRange &R2);
- void Diag(const Token &Tok, unsigned DiagID) {
- Diag(Tok.getLocation(), DiagID);
- }
- void Diag(const Token &Tok, unsigned DiagID, const std::string &Msg) {
- Diag(Tok.getLocation(), DiagID, Msg);
- }
-
- /// 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.
- std::string getSpelling(const Token &Tok) const;
-
- /// 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
- /// Tok.getLength() bytes long. The length of the actual result is returned.
- ///
- /// Note that this method may do two possible things: it may either fill in
- /// the buffer specified with characters, or it may *change the input pointer*
- /// to point to a constant buffer with the data already in it (avoiding a
- /// copy). The caller is not allowed to modify the returned buffer pointer
- /// if an internal buffer is returned.
- unsigned getSpelling(const Token &Tok, const char *&Buffer) const;
-
-
- /// CreateString - Plop the specified string into a scratch buffer and return
- /// a location for it. If specified, the source location provides a source
- /// location for the token.
- SourceLocation CreateString(const char *Buf, unsigned Len,
- SourceLocation SourceLoc = SourceLocation());
-
- /// DumpToken - Print the token to stderr, used for debugging.
- ///
- void DumpToken(const Token &Tok, bool DumpFlags = false) const;
- void DumpLocation(SourceLocation Loc) const;
- void DumpMacro(const MacroInfo &MI) const;
-
- /// AdvanceToTokenCharacter - Given a location that specifies the start of a
- /// token, return a new location that specifies a character within the token.
- SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,unsigned Char);
-
- /// IncrementPasteCounter - Increment the counters for the number of token
- /// paste operations performed. If fast was specified, this is a 'fast paste'
- /// case we handled.
- ///
- void IncrementPasteCounter(bool isFast) {
- if (isFast)
- ++NumFastTokenPaste;
- else
- ++NumTokenPaste;
- }
-
- void PrintStats();
-
- /// HandleMicrosoftCommentPaste - When the macro expander pastes together a
- /// comment (/##/) in microsoft mode, this method handles updating the current
- /// state, returning the token on the next source line.
- void HandleMicrosoftCommentPaste(Token &Tok);
-
- //===--------------------------------------------------------------------===//
- // Preprocessor callback methods. These are invoked by a lexer as various
- // directives and events are found.
-
- /// LookUpIdentifierInfo - Given a tok::identifier token, look up the
- /// identifier information for the token and install it into the token.
- IdentifierInfo *LookUpIdentifierInfo(Token &Identifier,
- const char *BufPtr = 0);
-
- /// HandleIdentifier - This callback is invoked when the lexer reads an
- /// identifier and has filled in the tokens IdentifierInfo member. This
- /// callback potentially macro expands it or turns it into a named token (like
- /// 'for').
- void HandleIdentifier(Token &Identifier);
-
-
- /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
- /// the current file. This either returns the EOF token and returns true, or
- /// pops a level off the include stack and returns false, at which point the
- /// client should call lex again.
- bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
-
- /// HandleEndOfTokenLexer - This callback is invoked when the current
- /// TokenLexer hits the end of its token stream.
- bool HandleEndOfTokenLexer(Token &Result);
-
- /// HandleDirective - This callback is invoked when the lexer sees a # token
- /// at the start of a line. This consumes the directive, modifies the
- /// lexer/preprocessor state, and advances the lexer(s) so that the next token
- /// read is the correct one.
- void HandleDirective(Token &Result);
-
- /// CheckEndOfDirective - Ensure that the next token is a tok::eom token. If
- /// not, emit a diagnostic and consume up until the eom.
- void CheckEndOfDirective(const char *Directive);
-private:
- /// isInPrimaryFile - Return true if we're in the top-level file, not in a
- /// #include.
- bool isInPrimaryFile() const;
-
- /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
- /// current line until the tok::eom token is found.
- void DiscardUntilEndOfDirective();
-
- /// ReadMacroName - Lex and validate a macro name, which occurs after a
- /// #define or #undef. This emits a diagnostic, sets the token kind to eom,
- /// and discards the rest of the macro line if the macro name is invalid.
- void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
-
- /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
- /// definition has just been read. Lex the rest of the arguments and the
- /// closing ), updating MI with what we learn. Return true if an error occurs
- /// parsing the arg list.
- bool ReadMacroDefinitionArgList(MacroInfo *MI);
-
- /// SkipExcludedConditionalBlock - We just read a #if or related directive and
- /// decided that the subsequent tokens are in the #if'd out portion of the
- /// file. Lex the rest of the file, until we see an #endif. If
- /// FoundNonSkipPortion is true, then we have already emitted code for part of
- /// this #if directive, so #else/#elif blocks should never be entered. If
- /// FoundElse is false, then #else directives are ok, if not, then we have
- /// already seen one so a #else directive is a duplicate. When this returns,
- /// the caller can lex the first valid token.
- void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
- bool FoundNonSkipPortion, bool FoundElse);
-
- /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
- /// may occur after a #if or #elif directive and return it as a bool. If the
- /// expression is equivalent to "!defined(X)" return X in IfNDefMacro.
- bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
-
- /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
- /// #pragma GCC poison/system_header/dependency and #pragma once.
- void RegisterBuiltinPragmas();
-
- /// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
- /// identifier table.
- void RegisterBuiltinMacros();
- IdentifierInfo *RegisterBuiltinMacro(const char *Name);
-
- /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
- /// be expanded as a macro, handle it and return the next token as 'Tok'. If
- /// the macro should not be expanded return true, otherwise return false.
- bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI);
-
- /// isNextPPTokenLParen - Determine whether the next preprocessor token to be
- /// lexed is a '('. If so, consume the token and return true, if not, this
- /// method should have no observable side-effect on the lexed tokens.
- bool isNextPPTokenLParen();
-
- /// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
- /// invoked to read all of the formal arguments specified for the macro
- /// invocation. This returns null on error.
- MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI);
-
- /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
- /// as a builtin macro, handle it and return the next token as 'Tok'.
- void ExpandBuiltinMacro(Token &Tok);
-
- /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
- /// return the first token after the directive. The _Pragma token has just
- /// been read into 'Tok'.
- void Handle_Pragma(Token &Tok);
-
-
- /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer.
- void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
-
- /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
- /// checked and spelled filename, e.g. as an operand of #include. This returns
- /// true if the input filename was in <>'s or false if it were in ""'s. The
- /// caller is expected to provide a buffer that is large enough to hold the
- /// spelling of the filename, but is also expected to handle the case when
- /// this method decides to use a different buffer.
- bool GetIncludeFilenameSpelling(SourceLocation Loc,
- const char *&BufStart, const char *&BufEnd);
-
- /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
- /// return null on failure. isAngled indicates whether the file reference is
- /// for system #include's or not (i.e. using <> instead of "").
- const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
- bool isAngled, const DirectoryLookup *FromDir,
- const DirectoryLookup *&CurDir);
-
- //===--------------------------------------------------------------------===//
- // Caching stuff.
- void CachingLex(Token &Result);
- bool InCachingLexMode() const { return CurLexer == 0 && CurTokenLexer == 0; }
- void EnterCachingLexMode();
- void ExitCachingLexMode() {
- if (InCachingLexMode())
- RemoveTopOfLexerStack();
- }
- const Token &PeekAhead(unsigned N);
-
- //===--------------------------------------------------------------------===//
- /// Handle*Directive - implement the various preprocessor directives. These
- /// should side-effect the current preprocessor object so that the next call
- /// to Lex() will return the appropriate token next.
-
- void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
- void HandleIdentSCCSDirective(Token &Tok);
-
- // File inclusion.
- void HandleIncludeDirective(Token &Tok,
- const DirectoryLookup *LookupFrom = 0,
- bool isImport = false);
- void HandleIncludeNextDirective(Token &Tok);
- void HandleImportDirective(Token &Tok);
-
- // Macro handling.
- void HandleDefineDirective(Token &Tok);
- void HandleUndefDirective(Token &Tok);
- // HandleAssertDirective(Token &Tok);
- // HandleUnassertDirective(Token &Tok);
-
- // Conditional Inclusion.
- void HandleIfdefDirective(Token &Tok, bool isIfndef,
- bool ReadAnyTokensBeforeDirective);
- void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
- void HandleEndifDirective(Token &Tok);
- void HandleElseDirective(Token &Tok);
- void HandleElifDirective(Token &Tok);
-
- // Pragmas.
- void HandlePragmaDirective();
-public:
- void HandlePragmaOnce(Token &OnceTok);
- void HandlePragmaMark();
- void HandlePragmaPoison(Token &PoisonTok);
- void HandlePragmaSystemHeader(Token &SysHeaderTok);
- void HandlePragmaDependency(Token &DependencyTok);
-};
-
-/// PreprocessorFactory - A generic factory interface for lazily creating
-/// Preprocessor objects on-demand when they are needed.
-class PreprocessorFactory {
-public:
- virtual ~PreprocessorFactory();
- virtual Preprocessor* CreatePreprocessor() = 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/ScratchBuffer.h b/clang/include/clang/Lex/ScratchBuffer.h
deleted file mode 100644
index c1d134de11a9..000000000000
--- a/clang/include/clang/Lex/ScratchBuffer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- 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 ScratchBuffer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SCRATCHBUFFER_H
-#define LLVM_CLANG_SCRATCHBUFFER_H
-
-namespace clang {
- class SourceManager;
- class SourceLocation;
-
-/// ScratchBuffer - This class exposes a simple interface for the dynamic
-/// construction of tokens. This is used for builtin macros (e.g. __LINE__) as
-/// well as token pasting, etc.
-class ScratchBuffer {
- SourceManager &SourceMgr;
- char *CurBuffer;
- unsigned FileID;
- unsigned BytesUsed;
-public:
- ScratchBuffer(SourceManager &SM);
-
- /// getToken - Splat the specified text into a temporary MemoryBuffer and
- /// return a SourceLocation that refers to the token. The SourceLoc value
- /// gives a virtual location that the token will appear to be from.
- SourceLocation getToken(const char *Buf, unsigned Len,
- SourceLocation SourceLoc);
-
- /// getToken - Splat the specified text into a temporary MemoryBuffer and
- /// return a SourceLocation that refers to the token. This is just like the
- /// previous method, but returns a location that indicates the physloc of the
- /// token.
- SourceLocation getToken(const char *Buf, unsigned Len);
-
-private:
- void AllocScratchBuffer(unsigned RequestLen);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h
deleted file mode 100644
index 474d4048d154..000000000000
--- a/clang/include/clang/Lex/Token.h
+++ /dev/null
@@ -1,154 +0,0 @@
-//===--- Token.h - Token interface ------------------------------*- 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 Token interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOKEN_H
-#define LLVM_CLANG_TOKEN_H
-
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-class IdentifierInfo;
-
-/// Token - This structure provides full information about a lexed token.
-/// It is not intended to be space efficient, it is intended to return as much
-/// information as possible about each returned token. This is expected to be
-/// compressed into a smaller form if memory footprint is important.
-class Token {
- /// The location and length of the token text itself.
- SourceLocation Loc;
- unsigned Length;
-
- /// IdentifierInfo - If this was an identifier, this points to the uniqued
- /// information about this identifier.
- IdentifierInfo *IdentInfo;
-
- /// Kind - The actual flavor of token this is.
- ///
- unsigned Kind : 8; // DON'T make Kind a 'tok::TokenKind';
- // MSVC will treat it as a signed char and
- // TokenKinds > 127 won't be handled correctly.
-
- /// Flags - Bits we track about this token, members of the TokenFlags enum.
- unsigned Flags : 8;
-public:
-
- // Various flags set per token:
- enum TokenFlags {
- StartOfLine = 0x01, // At start of line or only after whitespace.
- LeadingSpace = 0x02, // Whitespace exists before this token.
- DisableExpand = 0x04, // This identifier may never be macro expanded.
- NeedsCleaning = 0x08 // Contained an escaped newline or trigraph.
- };
-
- tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
- void setKind(tok::TokenKind K) { Kind = K; }
-
- /// is/isNot - Predicates to check if this token is a specific kind, as in
- /// "if (Tok.is(tok::l_brace)) {...}".
- bool is(tok::TokenKind K) const { return Kind == (unsigned) K; }
- bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; }
-
- /// getLocation - Return a source location identifier for the specified
- /// offset in the current file.
- SourceLocation getLocation() const { return Loc; }
- unsigned getLength() const { return Length; }
-
- void setLocation(SourceLocation L) { Loc = L; }
- void setLength(unsigned Len) { Length = Len; }
-
- const char *getName() const {
- return tok::getTokenName( (tok::TokenKind) Kind);
- }
-
- /// startToken - Reset all flags to cleared.
- ///
- void startToken() {
- Flags = 0;
- IdentInfo = 0;
- Loc = SourceLocation();
- }
-
- IdentifierInfo *getIdentifierInfo() const { return IdentInfo; }
- void setIdentifierInfo(IdentifierInfo *II) {
- IdentInfo = II;
- }
-
- /// setFlag - Set the specified flag.
- void setFlag(TokenFlags Flag) {
- Flags |= Flag;
- }
-
- /// clearFlag - Unset the specified flag.
- void clearFlag(TokenFlags Flag) {
- Flags &= ~Flag;
- }
-
- /// setFlagValue - Set a flag to either true or false.
- void setFlagValue(TokenFlags Flag, bool Val) {
- if (Val)
- setFlag(Flag);
- else
- clearFlag(Flag);
- }
-
- /// isAtStartOfLine - Return true if this token is at the start of a line.
- ///
- bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; }
-
- /// hasLeadingSpace - Return true if this token has whitespace before it.
- ///
- bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; }
-
- /// isExpandDisabled - Return true if this identifier token should never
- /// be expanded in the future, due to C99 6.10.3.4p2.
- bool isExpandDisabled() const {
- return (Flags & DisableExpand) ? true : false;
- }
-
- /// isObjCAtKeyword - Return true if we have an ObjC keyword identifier.
- bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
-
- /// getObjCKeywordID - Return the ObjC keyword kind.
- tok::ObjCKeywordKind getObjCKeywordID() const;
-
- /// needsCleaning - Return true if this token has trigraphs or escaped
- /// newlines in it.
- ///
- bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
-};
-
-/// PPConditionalInfo - Information about the conditional stack (#if directives)
-/// currently active.
-struct PPConditionalInfo {
- /// IfLoc - Location where the conditional started.
- ///
- SourceLocation IfLoc;
-
- /// WasSkipping - True if this was contained in a skipping directive, e.g.
- /// in a "#if 0" block.
- bool WasSkipping;
-
- /// FoundNonSkip - True if we have emitted tokens already, and now we're in
- /// an #else block or something. Only useful in Skipping blocks.
- bool FoundNonSkip;
-
- /// FoundElse - True if we've seen a #else in this block. If so,
- /// #elif/#else directives are not allowed.
- bool FoundElse;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Lex/TokenLexer.h b/clang/include/clang/Lex/TokenLexer.h
deleted file mode 100644
index 9e384347d1b5..000000000000
--- a/clang/include/clang/Lex/TokenLexer.h
+++ /dev/null
@@ -1,146 +0,0 @@
-//===--- TokenLexer.h - Lex from a token buffer -----------------*- 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 TokenLexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOKENLEXER_H
-#define LLVM_CLANG_TOKENLEXER_H
-
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
- class MacroArgs;
-
-/// TokenLexer - This implements a lexer that returns token from a macro body
-/// or token stream instead of lexing from a character buffer. This is used for
-/// macro expansion and _Pragma handling, for example.
-///
-class TokenLexer {
- /// Macro - The macro we are expanding from. This is null if expanding a
- /// token stream.
- ///
- MacroInfo *Macro;
-
- /// ActualArgs - The actual arguments specified for a function-like macro, or
- /// null. The TokenLexer owns the pointed-to object.
- MacroArgs *ActualArgs;
-
- /// PP - The current preprocessor object we are expanding for.
- ///
- Preprocessor &PP;
-
- /// Tokens - This is the pointer to an array of tokens that the macro is
- /// defined to, with arguments expanded for function-like macros. If this is
- /// a token stream, these are the tokens we are returning.
- const Token *Tokens;
-
- /// NumTokens - This is the length of the Tokens array.
- ///
- unsigned NumTokens;
-
- /// CurToken - This is the next token that Lex will return.
- ///
- unsigned CurToken;
-
- /// InstantiateLoc - The source location where this macro was instantiated.
- ///
- SourceLocation InstantiateLoc;
-
- /// Lexical information about the expansion point of the macro: the identifier
- /// that the macro expanded from had these properties.
- bool AtStartOfLine : 1;
- bool HasLeadingSpace : 1;
-
- /// OwnsTokens - This is true if this TokenLexer allocated the Tokens
- /// array, and thus needs to free it when destroyed. For simple object-like
- /// macros (for example) we just point into the token buffer of the macro
- /// definition, we don't make a copy of it.
- bool OwnsTokens : 1;
-
- /// DisableMacroExpansion - This is true when tokens lexed from the TokenLexer
- /// should not be subject to further macro expansion.
- bool DisableMacroExpansion : 1;
-
- TokenLexer(const TokenLexer&); // DO NOT IMPLEMENT
- void operator=(const TokenLexer&); // DO NOT IMPLEMENT
-public:
- /// Create a TokenLexer for the specified macro with the specified actual
- /// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
- TokenLexer(Token &Tok, MacroArgs *ActualArgs, Preprocessor &pp)
- : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
- Init(Tok, ActualArgs);
- }
-
- /// Init - Initialize this TokenLexer to expand from the specified macro
- /// with the specified argument information. Note that this ctor takes
- /// ownership of the ActualArgs pointer.
- void Init(Token &Tok, MacroArgs *ActualArgs);
-
- /// Create a TokenLexer for the specified token stream. This does not
- /// take ownership of the specified token vector.
- TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
- bool OwnsTokens, Preprocessor &pp)
- : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
- Init(TokArray, NumToks, DisableExpansion, OwnsTokens);
- }
-
- /// Init - Initialize this TokenLexer with the specified token stream.
- /// This does not take ownership of the specified token vector.
- ///
- /// DisableExpansion is true when macro expansion of tokens lexed from this
- /// stream should be disabled.
- void Init(const Token *TokArray, unsigned NumToks,
- bool DisableMacroExpansion, bool OwnsTokens);
-
- ~TokenLexer() { destroy(); }
-
- /// isNextTokenLParen - If the next token lexed will pop this macro off the
- /// expansion stack, return 2. If the next unexpanded token is a '(', return
- /// 1, otherwise return 0.
- unsigned isNextTokenLParen() const;
-
- /// Lex - Lex and return a token from this macro stream.
- void Lex(Token &Tok);
-
-private:
- void destroy();
-
- /// isAtEnd - Return true if the next lex call will pop this macro off the
- /// include stack.
- bool isAtEnd() const {
- return CurToken == NumTokens;
- }
-
- /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
- /// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
- /// are is another ## after it, chomp it iteratively. Return the result as
- /// Tok. If this returns true, the caller should immediately return the
- /// token.
- bool PasteTokens(Token &Tok);
-
- /// Expand the arguments of a function-like macro so that we can quickly
- /// return preexpanded tokens from Tokens.
- void ExpandFunctionArguments();
-
- /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
- /// together to form a comment that comments out everything in the current
- /// macro, other active macros, and anything left on the current physical
- /// source line of the instantiated buffer. Handle this by returning the
- /// first token on the next line.
- void HandleMicrosoftCommentPaste(Token &Tok);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Parse/AccessSpecifier.h b/clang/include/clang/Parse/AccessSpecifier.h
deleted file mode 100644
index a35725ab3fde..000000000000
--- a/clang/include/clang/Parse/AccessSpecifier.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===--- AccessSpecifier.h - C++ Access Specifiers -*- 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 interfaces used for Declaration Specifiers and Declarators.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_ACCESS_SPECIFIER_H
-#define LLVM_CLANG_PARSE_ACCESS_SPECIFIER_H
-
-namespace clang {
-
-/// AccessSpecifier - A C++ access specifier (none, public, private,
-/// protected).
-enum AccessSpecifier {
- AS_none,
- AS_public,
- AS_protected,
- AS_private
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h
deleted file mode 100644
index ee7b7a938975..000000000000
--- a/clang/include/clang/Parse/Action.h
+++ /dev/null
@@ -1,938 +0,0 @@
-//===--- Action.h - Parser Action Interface ---------------------*- 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 Action and EmptyAction interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_ACTION_H
-#define LLVM_CLANG_PARSE_ACTION_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Parse/AccessSpecifier.h"
-
-namespace clang {
- // Semantic.
- class DeclSpec;
- class ObjCDeclSpec;
- class Declarator;
- class AttributeList;
- struct FieldDeclarator;
- // Parse.
- class Scope;
- class Action;
- class Selector;
- // Lex.
- class Token;
-
-/// Action - As the parser reads the input file and recognizes the productions
-/// of the grammar, it invokes methods on this class to turn the parsed input
-/// into something useful: e.g. a parse tree.
-///
-/// The callback methods that this class provides are phrased as actions that
-/// the parser has just done or is about to do when the method is called. They
-/// are not requests that the actions module do the specified action.
-///
-/// All of the methods here are optional except isTypeName(), which must be
-/// specified in order for the parse to complete accurately. The MinimalAction
-/// class does this bare-minimum of tracking to implement this functionality.
-class Action {
-public:
- /// Out-of-line virtual destructor to provide home for this class.
- virtual ~Action();
-
- // Types - Though these don't actually enforce strong typing, they document
- // what types are required to be identical for the actions.
- typedef void ExprTy;
- typedef void StmtTy;
- typedef void DeclTy;
- typedef void TypeTy;
- typedef void AttrTy;
-
- /// ActionResult - This structure is used while parsing/acting on expressions,
- /// stmts, etc. It encapsulates both the object returned by the action, plus
- /// a sense of whether or not it is valid.
- template<unsigned UID>
- struct ActionResult {
- void *Val;
- bool isInvalid;
-
- ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
- template<typename ActualExprTy>
- ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
-
- const ActionResult &operator=(void *RHS) {
- Val = RHS;
- isInvalid = false;
- return *this;
- }
- };
-
- /// Expr/Stmt/TypeResult - Provide a unique type to wrap ExprTy/StmtTy/TypeTy,
- /// providing strong typing and allowing for failure.
- typedef ActionResult<0> ExprResult;
- typedef ActionResult<1> StmtResult;
- typedef ActionResult<2> TypeResult;
-
- /// Deletion callbacks - Since the parser doesn't know the concrete types of
- /// the AST nodes being generated, it must do callbacks to delete objects when
- /// recovering from errors.
- virtual void DeleteExpr(ExprTy *E) {}
- virtual void DeleteStmt(StmtTy *E) {}
-
- /// Statistics.
- virtual void PrintStats() const {}
- //===--------------------------------------------------------------------===//
- // Declaration Tracking Callbacks.
- //===--------------------------------------------------------------------===//
-
- /// isTypeName - Return non-null if the specified identifier is a typedef name
- /// in the current scope.
- virtual TypeTy *isTypeName(const IdentifierInfo &II, Scope *S) = 0;
-
- /// ActOnDeclarator - This callback is invoked when a declarator is parsed and
- /// 'Init' specifies the initializer if any. This is for things like:
- /// "int X = 4" or "typedef int foo".
- ///
- /// LastInGroup is non-null for cases where one declspec has multiple
- /// declarators on it. For example in 'int A, B', ActOnDeclarator will be
- /// called with LastInGroup=A when invoked for B.
- virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D,DeclTy *LastInGroup) {
- return 0;
- }
-
- /// ActOnParamDeclarator - This callback is invoked when a parameter
- /// declarator is parsed. This callback only occurs for functions
- /// with prototypes. S is the function prototype scope for the
- /// parameters (C++ [basic.scope.proto]).
- virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D) {
- return 0;
- }
-
- /// AddInitializerToDecl - This action is called immediately after
- /// ActOnDeclarator (when an initializer is present). The code is factored
- /// this way to make sure we are able to handle the following:
- /// void func() { int xx = xx; }
- /// This allows ActOnDeclarator to register "xx" prior to parsing the
- /// initializer. The declaration above should still result in a warning,
- /// since the reference to "xx" is uninitialized.
- virtual void AddInitializerToDecl(DeclTy *Dcl, ExprTy *Init) {
- return;
- }
- /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
- /// gives the actions implementation a chance to process the group as a whole.
- virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
- return Group;
- }
-
- /// ActOnStartOfFunctionDef - This is called at the start of a function
- /// definition, instead of calling ActOnDeclarator. The Declarator includes
- /// information about formal arguments that are part of this function.
- virtual DeclTy *ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
- // Default to ActOnDeclarator.
- return ActOnStartOfFunctionDef(FnBodyScope,
- ActOnDeclarator(FnBodyScope, D, 0));
- }
-
- /// ActOnStartOfFunctionDef - This is called at the start of a function
- /// definition, after the FunctionDecl has already been created.
- virtual DeclTy *ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
- return D;
- }
-
- virtual void ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
- return;
- }
-
- /// ActOnFunctionDefBody - This is called when a function body has completed
- /// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
- virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body) {
- return Decl;
- }
-
- virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprTy *AsmString) {
- return 0;
- }
-
- /// ActOnPopScope - This callback is called immediately before the specified
- /// scope is popped and deleted.
- virtual void ActOnPopScope(SourceLocation Loc, Scope *S) {}
-
- /// ActOnTranslationUnitScope - This callback is called once, immediately
- /// after creating the translation unit scope (in Parser::Initialize).
- virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {}
-
- /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
- /// no declarator (e.g. "struct foo;") is parsed.
- virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
- return 0;
- }
-
- virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
- SourceLocation RBrace, const char *Lang,
- unsigned StrSize, DeclTy *D) {
- return 0;
- }
-
- /// ActOnEndOfTranslationUnit - This is called at the very end of the
- /// translation unit when EOF is reached and all but the top-level scope is
- /// popped.
- virtual void ActOnEndOfTranslationUnit() {}
-
- //===--------------------------------------------------------------------===//
- // Type Parsing Callbacks.
- //===--------------------------------------------------------------------===//
-
- virtual TypeResult ActOnTypeName(Scope *S, Declarator &D) {
- return 0;
- }
-
- enum TagKind {
- TK_Reference, // Reference to a tag: 'struct foo *X;'
- TK_Declaration, // Fwd decl of a tag: 'struct foo;'
- TK_Definition // Definition of a tag: 'struct foo { int X; } Y;'
- };
- virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK,
- SourceLocation KWLoc, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr) {
- // TagType is an instance of DeclSpec::TST, indicating what kind of tag this
- // is (struct/union/enum/class).
- return 0;
- }
-
- /// Act on @defs() element found when parsing a structure. ClassName is the
- /// name of the referenced class.
- virtual void ActOnDefs(Scope *S, SourceLocation DeclStart,
- IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclTy*> &Decls) {}
- virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth) {
- return 0;
- }
-
- virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth,
- tok::ObjCKeywordKind visibility) {
- return 0;
- }
-
- virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *TagDecl,
- DeclTy **Fields, unsigned NumFields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *AttrList) {}
-
- virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
- DeclTy *LastEnumConstant,
- SourceLocation IdLoc, IdentifierInfo *Id,
- SourceLocation EqualLoc, ExprTy *Val) {
- return 0;
- }
- virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
- DeclTy **Elements, unsigned NumElements) {}
-
- //===--------------------------------------------------------------------===//
- // Statement Parsing Callbacks.
- //===--------------------------------------------------------------------===//
-
- virtual StmtResult ActOnNullStmt(SourceLocation SemiLoc) {
- return 0;
- }
-
- virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
- StmtTy **Elts, unsigned NumElts,
- bool isStmtExpr) {
- return 0;
- }
- virtual StmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
- SourceLocation EndLoc) {
- return 0;
- }
-
- virtual StmtResult ActOnExprStmt(ExprTy *Expr) {
- return StmtResult(Expr);
- }
-
- /// ActOnCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
- /// which can specify an RHS value.
- virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
- SourceLocation DotDotDotLoc, ExprTy *RHSVal,
- SourceLocation ColonLoc, StmtTy *SubStmt) {
- return 0;
- }
- virtual StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc, StmtTy *SubStmt,
- Scope *CurScope){
- return 0;
- }
-
- virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, StmtTy *SubStmt) {
- return 0;
- }
-
- virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
- StmtTy *ThenVal, SourceLocation ElseLoc,
- StmtTy *ElseVal) {
- return 0;
- }
-
- virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond) {
- return 0;
- }
-
- virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
- StmtTy *Switch, ExprTy *Body) {
- return 0;
- }
-
- virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
- StmtTy *Body) {
- return 0;
- }
- virtual StmtResult ActOnDoStmt(SourceLocation DoLoc, StmtTy *Body,
- SourceLocation WhileLoc, ExprTy *Cond) {
- return 0;
- }
- virtual StmtResult ActOnForStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- StmtTy *First, ExprTy *Second, ExprTy *Third,
- SourceLocation RParenLoc, StmtTy *Body) {
- return 0;
- }
- virtual StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
- SourceLocation LParenLoc,
- StmtTy *First, ExprTy *Second,
- SourceLocation RParenLoc, StmtTy *Body) {
- return 0;
- }
- virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
- SourceLocation LabelLoc,
- IdentifierInfo *LabelII) {
- return 0;
- }
- virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
- SourceLocation StarLoc,
- ExprTy *DestExp) {
- return 0;
- }
- virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
- Scope *CurScope) {
- return 0;
- }
- virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope) {
- return 0;
- }
- virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
- ExprTy *RetValExp) {
- return 0;
- }
- virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
- bool IsSimple,
- bool IsVolatile,
- unsigned NumOutputs,
- unsigned NumInputs,
- std::string *Names,
- ExprTy **Constraints,
- ExprTy **Exprs,
- ExprTy *AsmString,
- unsigned NumClobbers,
- ExprTy **Clobbers,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- // Objective-c statements
- virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
- SourceLocation RParen, StmtTy *Parm,
- StmtTy *Body, StmtTy *CatchList) {
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
- StmtTy *Body) {
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtTy *Try,
- StmtTy *Catch, StmtTy *Finally) {
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
- StmtTy *Throw) {
- return 0;
- }
-
- virtual StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
- ExprTy *SynchExpr,
- StmtTy *SynchBody) {
- return 0;
- }
-
- //===--------------------------------------------------------------------===//
- // Expression Parsing Callbacks.
- //===--------------------------------------------------------------------===//
-
- // Primary Expressions.
-
- /// ActOnIdentifierExpr - Parse an identifier in expression context.
- /// 'HasTrailingLParen' indicates whether or not the identifier has a '('
- /// token immediately after it.
- virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
- IdentifierInfo &II,
- bool HasTrailingLParen) {
- return 0;
- }
-
- virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc,
- tok::TokenKind Kind) {
- return 0;
- }
- virtual ExprResult ActOnCharacterConstant(const Token &) { return 0; }
- virtual ExprResult ActOnNumericConstant(const Token &) { return 0; }
-
- /// ActOnStringLiteral - The specified tokens were lexed as pasted string
- /// fragments (e.g. "foo" "bar" L"baz").
- virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks) {
- return 0;
- }
-
- virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
- ExprTy *Val) {
- return Val; // Default impl returns operand.
- }
-
- // Postfix Expressions.
- virtual ExprResult ActOnPostfixUnaryOp(SourceLocation OpLoc,
- tok::TokenKind Kind, ExprTy *Input) {
- return 0;
- }
- virtual ExprResult ActOnArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
- ExprTy *Idx, SourceLocation RLoc) {
- return 0;
- }
- virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation MemberLoc,
- IdentifierInfo &Member) {
- return 0;
- }
-
- /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
- /// This provides the location of the left/right parens and a list of comma
- /// locations. There are guaranteed to be one fewer commas than arguments,
- /// unless there are zero arguments.
- virtual ExprResult ActOnCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
- ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- // Unary Operators. 'Tok' is the token for the operator.
- virtual ExprResult ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
- ExprTy *Input) {
- return 0;
- }
- virtual ExprResult
- ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
- SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- virtual ExprResult ActOnCompoundLiteral(SourceLocation LParen, TypeTy *Ty,
- SourceLocation RParen, ExprTy *Op) {
- return 0;
- }
- virtual ExprResult ActOnInitList(SourceLocation LParenLoc,
- ExprTy **InitList, unsigned NumInit,
- SourceLocation RParenLoc) {
- return 0;
- }
- virtual ExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprTy *Op) {
- return 0;
- }
-
- virtual ExprResult ActOnBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
- ExprTy *LHS, ExprTy *RHS) {
- return 0;
- }
-
- /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
- /// in the case of a the GNU conditional expr extension.
- virtual ExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
- SourceLocation ColonLoc,
- ExprTy *Cond, ExprTy *LHS, ExprTy *RHS){
- return 0;
- }
-
- //===---------------------- GNU Extension Expressions -------------------===//
-
- virtual ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
- IdentifierInfo *LabelII) { // "&&foo"
- return 0;
- }
-
- virtual ExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
- SourceLocation RPLoc) { // "({..})"
- return 0;
- }
-
- // __builtin_offsetof(type, identifier(.identifier|[expr])*)
- struct OffsetOfComponent {
- SourceLocation LocStart, LocEnd;
- bool isBrackets; // true if [expr], false if .ident
- union {
- IdentifierInfo *IdentInfo;
- ExprTy *E;
- } U;
- };
-
- virtual ExprResult ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
- SourceLocation TypeLoc, TypeTy *Arg1,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- // __builtin_types_compatible_p(type1, type2)
- virtual ExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1, TypeTy *arg2,
- SourceLocation RPLoc) {
- return 0;
- }
- // __builtin_choose_expr(constExpr, expr1, expr2)
- virtual ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
- ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
- SourceLocation RPLoc) {
- return 0;
- }
- // __builtin_overload(...)
- virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation BuiltinLoc,
- SourceLocation RPLoc) {
- return 0;
- }
-
-
- // __builtin_va_arg(expr, type)
- virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
- ExprTy *expr, TypeTy *type,
- SourceLocation RPLoc) {
- return 0;
- }
-
- //===------------------------- "Block" Extension ------------------------===//
-
- /// ActOnBlockStart - This callback is invoked when a block literal is
- /// started. The result pointer is passed into the block finalizers.
- virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope,
- Declarator &ParamInfo) {}
-
- /// ActOnBlockError - If there is an error parsing a block, this callback
- /// is invoked to pop the information about the block from the action impl.
- virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {}
-
- /// ActOnBlockStmtExpr - This is called when the body of a block statement
- /// literal was successfully completed. ^(int x){...}
- virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
- Scope *CurScope) { return 0; }
-
- //===------------------------- C++ Declarations -------------------------===//
-
- /// ActOnStartNamespaceDef - This is called at the start of a namespace
- /// definition.
- virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
- IdentifierInfo *Ident,
- SourceLocation LBrace) {
- return 0;
- }
-
- /// ActOnFinishNamespaceDef - This callback is called after a namespace is
- /// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef.
- virtual void ActOnFinishNamespaceDef(DeclTy *Dcl,SourceLocation RBrace) {
- return;
- }
-
- /// ActOnParamDefaultArgument - Parse default argument for function parameter
- virtual void ActOnParamDefaultArgument(DeclTy *param,
- SourceLocation EqualLoc,
- ExprTy *defarg) {
- }
-
- /// AddCXXDirectInitializerToDecl - This action is called immediately after
- /// ActOnDeclarator, when a C++ direct initializer is present.
- /// e.g: "int x(1);"
- virtual void AddCXXDirectInitializerToDecl(DeclTy *Dcl,
- SourceLocation LParenLoc,
- ExprTy **Exprs, unsigned NumExprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc) {
- return;
- }
-
- //===------------------------- C++ Expressions --------------------------===//
-
- /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
- virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
- SourceLocation LAngleBracketLoc, TypeTy *Ty,
- SourceLocation RAngleBracketLoc,
- SourceLocation LParenLoc, ExprTy *Op,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- /// ActOnCXXThis - Parse the C++ 'this' pointer.
- virtual ExprResult ActOnCXXThis(SourceLocation ThisLoc) {
- return 0;
- }
-
- /// ActOnCXXBoolLiteral - Parse {true,false} literals.
- virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
- tok::TokenKind Kind) {
- return 0;
- }
-
- /// ActOnCXXThrow - Parse throw expressions.
- virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
- ExprTy *Op = 0) {
- return 0;
- }
-
- /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
- /// Can be interpreted either as function-style casting ("int(x)")
- /// or class type construction ("ClassType(x,y,z)")
- /// or creation of a value-initialized type ("int()").
- virtual ExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
- TypeTy *TypeRep,
- SourceLocation LParenLoc,
- ExprTy **Exprs,
- unsigned NumExprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
- /// C++ if/switch/while/for statement.
- /// e.g: "if (int x = f()) {...}"
- virtual ExprResult ActOnCXXConditionDeclarationExpr(Scope *S,
- SourceLocation StartLoc,
- Declarator &D,
- SourceLocation EqualLoc,
- ExprTy *AssignExprVal) {
- return 0;
- }
-
- //===---------------------------- C++ Classes ---------------------------===//
- /// ActOnBaseSpecifier - Parsed a base specifier
- virtual void ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- TypeTy *basetype, SourceLocation BaseLoc) {
- }
-
- /// ActOnStartCXXClassDef - This is called at the start of a class/struct/union
- /// definition, when on C++.
- virtual void ActOnStartCXXClassDef(Scope *S, DeclTy *TagDecl,
- SourceLocation LBrace) {
- }
-
- /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
- /// declarator is parsed. 'AS' is the access specifier, 'BitfieldWidth'
- /// specifies the bitfield width if there is one and 'Init' specifies the
- /// initializer if any. 'LastInGroup' is non-null for cases where one declspec
- /// has multiple declarators on it.
- virtual DeclTy *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
- Declarator &D, ExprTy *BitfieldWidth,
- ExprTy *Init, DeclTy *LastInGroup) {
- return 0;
- }
-
- /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators
- /// are parsed but *before* parsing of inline method definitions.
- virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- DeclTy *TagDecl,
- SourceLocation LBrac,
- SourceLocation RBrac) {
- }
-
- /// ActOnFinishCXXClassDef - This is called when a class/struct/union has
- /// completed parsing, when on C++.
- virtual void ActOnFinishCXXClassDef(DeclTy *TagDecl) {
- }
-
- //===----------------------- Obj-C Declarations -------------------------===//
-
- // ActOnStartClassInterface - this action is called immediately after parsing
- // the prologue for a class interface (before parsing the instance
- // variables). Instance variables are processed by ActOnFields().
- virtual DeclTy *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
- return 0;
- }
-
- /// ActOnCompatiblityAlias - this action is called after complete parsing of
- /// @compaatibility_alias declaration. It sets up the alias relationships.
- virtual DeclTy *ActOnCompatiblityAlias(
- SourceLocation AtCompatibilityAliasLoc,
- IdentifierInfo *AliasName, SourceLocation AliasLocation,
- IdentifierInfo *ClassName, SourceLocation ClassLocation) {
- return 0;
- }
-
- // ActOnStartProtocolInterface - this action is called immdiately after
- // parsing the prologue for a protocol interface.
- virtual DeclTy *ActOnStartProtocolInterface(SourceLocation AtProtoLoc,
- IdentifierInfo *ProtocolName,
- SourceLocation ProtocolLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
- return 0;
- }
- // ActOnStartCategoryInterface - this action is called immdiately after
- // parsing the prologue for a category interface.
- virtual DeclTy *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc) {
- return 0;
- }
- // ActOnStartClassImplementation - this action is called immdiately after
- // parsing the prologue for a class implementation. Instance variables are
- // processed by ActOnFields().
- virtual DeclTy *ActOnStartClassImplementation(
- SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc) {
- return 0;
- }
- // ActOnStartCategoryImplementation - this action is called immdiately after
- // parsing the prologue for a category implementation.
- virtual DeclTy *ActOnStartCategoryImplementation(
- SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CatName,
- SourceLocation CatLoc) {
- return 0;
- }
- // ActOnPropertyImplDecl - called for every property implementation
- virtual DeclTy *ActOnPropertyImplDecl(
- SourceLocation AtLoc, // location of the @synthesize/@dynamic
- SourceLocation PropertyNameLoc, // location for the property name
- bool ImplKind, // true for @synthesize, false for
- // @dynamic
- DeclTy *ClassImplDecl, // class or category implementation
- IdentifierInfo *propertyId, // name of property
- IdentifierInfo *propertyIvar) { // name of the ivar
- return 0;
- }
-
- // ActOnMethodDeclaration - called for all method declarations.
- virtual DeclTy *ActOnMethodDeclaration(
- SourceLocation BeginLoc, // location of the + or -.
- SourceLocation EndLoc, // location of the ; or {.
- tok::TokenKind MethodType, // tok::minus for instance, tok::plus for class.
- DeclTy *ClassDecl, // class this methods belongs to.
- ObjCDeclSpec &ReturnQT, // for return type's in inout etc.
- TypeTy *ReturnType, // the method return type.
- Selector Sel, // a unique name for the method.
- ObjCDeclSpec *ArgQT, // for arguments' in inout etc.
- TypeTy **ArgTypes, // non-zero when Sel.getNumArgs() > 0
- IdentifierInfo **ArgNames, // non-zero when Sel.getNumArgs() > 0
- AttributeList *AttrList, // optional
- // tok::objc_not_keyword, tok::objc_optional, tok::objc_required
- tok::ObjCKeywordKind impKind,
- bool isVariadic = false) {
- return 0;
- }
- // ActOnAtEnd - called to mark the @end. For declarations (interfaces,
- // protocols, categories), the parser passes all methods/properties.
- // For class implementations, these values default to 0. For implementations,
- // methods are processed incrementally (by ActOnMethodDeclaration above).
- virtual void ActOnAtEnd(
- SourceLocation AtEndLoc,
- DeclTy *classDecl,
- DeclTy **allMethods = 0,
- unsigned allNum = 0,
- DeclTy **allProperties = 0,
- unsigned pNum = 0) {
- return;
- }
- // ActOnProperty - called to build one property AST
- virtual DeclTy *ActOnProperty (Scope *S, SourceLocation AtLoc,
- FieldDeclarator &FD, ObjCDeclSpec &ODS,
- Selector GetterSel, Selector SetterSel,
- tok::ObjCKeywordKind MethodImplKind) {
- return 0;
- }
-
- // ActOnClassMessage - used for both unary and keyword messages.
- // ArgExprs is optional - if it is present, the number of expressions
- // is obtained from NumArgs.
- virtual ExprResult ActOnClassMessage(
- Scope *S,
- IdentifierInfo *receivingClassName,
- Selector Sel,
- SourceLocation lbrac,
- SourceLocation rbrac,
- ExprTy **ArgExprs, unsigned NumArgs) {
- return 0;
- }
- // ActOnInstanceMessage - used for both unary and keyword messages.
- // ArgExprs is optional - if it is present, the number of expressions
- // is obtained from NumArgs.
- virtual ExprResult ActOnInstanceMessage(
- ExprTy *receiver, Selector Sel,
- SourceLocation lbrac, SourceLocation rbrac,
- ExprTy **ArgExprs, unsigned NumArgs) {
- return 0;
- }
- virtual DeclTy *ActOnForwardClassDeclaration(
- SourceLocation AtClassLoc,
- IdentifierInfo **IdentList,
- unsigned NumElts) {
- return 0;
- }
- virtual DeclTy *ActOnForwardProtocolDeclaration(
- SourceLocation AtProtocolLoc,
- const IdentifierLocPair*IdentList,
- unsigned NumElts) {
- return 0;
- }
-
- /// FindProtocolDeclaration - This routine looks up protocols and
- /// issues error if they are not declared. It returns list of valid
- /// protocols found.
- virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
- const IdentifierLocPair *ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVectorImpl<DeclTy*> &ResProtos) {
- }
-
- //===----------------------- Obj-C Expressions --------------------------===//
-
- virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
- ExprTy **Strings,
- unsigned NumStrings) {
- return 0;
- }
-
- virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
- SourceLocation EncLoc,
- SourceLocation LParenLoc,
- TypeTy *Ty,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
- SourceLocation AtLoc,
- SourceLocation SelLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
- SourceLocation AtLoc,
- SourceLocation ProtoLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return 0;
- }
-
- //===---------------------------- Pragmas -------------------------------===//
-
- enum PragmaPackKind {
- PPK_Default, // #pragma pack([n])
- PPK_Show, // #pragma pack(show), only supported by MSVC.
- PPK_Push, // #pragma pack(push, [identifier], [n])
- PPK_Pop // #pragma pack(pop, [identifier], [n])
- };
-
- /// ActOnPragmaPack - Called on well formed #pragma pack(...).
- virtual void ActOnPragmaPack(PragmaPackKind Kind,
- IdentifierInfo *Name,
- ExprTy *Alignment,
- SourceLocation PragmaLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return;
- }
-};
-
-/// MinimalAction - Minimal actions are used by light-weight clients of the
-/// parser that do not need name resolution or significant semantic analysis to
-/// be performed. The actions implemented here are in the form of unresolved
-/// identifiers. By using a simpler interface than the SemanticAction class,
-/// the parser doesn't have to build complex data structures and thus runs more
-/// quickly.
-class MinimalAction : public Action {
- /// Translation Unit Scope - useful to Objective-C actions that need
- /// to lookup file scope declarations in the "ordinary" C decl namespace.
- /// For example, user-defined classes, built-in "id" type, etc.
- Scope *TUScope;
- IdentifierTable &Idents;
-public:
- MinimalAction(IdentifierTable &IT) : Idents(IT) {}
-
- /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to
- /// determine whether the name is a typedef or not in this scope.
- virtual TypeTy *isTypeName(const IdentifierInfo &II, Scope *S);
-
- /// ActOnDeclarator - If this is a typedef declarator, we modify the
- /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
- /// popped.
- virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup);
-
- /// ActOnPopScope - When a scope is popped, if any typedefs are now
- /// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
- virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
- virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
-
- virtual DeclTy *ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
- IdentifierInfo **IdentList,
- unsigned NumElts);
-
- virtual DeclTy *ActOnStartClassInterface(SourceLocation interLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Parse/AttributeList.h b/clang/include/clang/Parse/AttributeList.h
deleted file mode 100644
index d41faa31b07b..000000000000
--- a/clang/include/clang/Parse/AttributeList.h
+++ /dev/null
@@ -1,150 +0,0 @@
-//===--- AttributeList.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 AttributeList class interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ATTRLIST_H
-#define LLVM_CLANG_ATTRLIST_H
-
-#include "clang/Parse/Action.h"
-#include <cassert>
-
-namespace clang {
-
-/// AttributeList - Represents GCC's __attribute__ declaration. There are
-/// 4 forms of this construct...they are:
-///
-/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
-/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
-/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
-/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
-///
-class AttributeList {
- IdentifierInfo *AttrName;
- SourceLocation AttrLoc;
- IdentifierInfo *ParmName;
- SourceLocation ParmLoc;
- Action::ExprTy **Args;
- unsigned NumArgs;
- AttributeList *Next;
-public:
- AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
- IdentifierInfo *ParmName, SourceLocation ParmLoc,
- Action::ExprTy **args, unsigned numargs, AttributeList *Next);
- ~AttributeList();
-
- enum Kind { // Please keep this list alphabetized.
- AT_address_space,
- AT_alias,
- AT_aligned,
- AT_annotate,
- AT_constructor,
- AT_deprecated,
- AT_destructor,
- AT_dllimport,
- AT_dllexport,
- AT_ext_vector_type,
- AT_fastcall,
- AT_format,
- AT_IBOutlet, // Clang-specific.
- AT_malloc,
- AT_mode,
- AT_noinline,
- AT_nonnull,
- AT_noreturn,
- AT_nothrow,
- AT_packed,
- AT_pure,
- AT_stdcall,
- AT_transparent_union,
- AT_unused,
- AT_vector_size,
- AT_visibility,
- AT_warn_unused_result,
- AT_weak,
- AT_objc_gc,
- AT_blocks,
- AT_sentinel,
- AT_const,
- UnknownAttribute
- };
-
- IdentifierInfo *getName() const { return AttrName; }
- SourceLocation getLoc() const { return AttrLoc; }
- IdentifierInfo *getParameterName() const { return ParmName; }
-
- Kind getKind() const { return getKind(getName()); }
- static Kind getKind(const IdentifierInfo *Name);
-
- AttributeList *getNext() const { return Next; }
- void setNext(AttributeList *N) { Next = N; }
-
- void addAttributeList(AttributeList *alist) {
- assert((alist != 0) && "addAttributeList(): alist is null");
- AttributeList *next = this, *prev;
- do {
- prev = next;
- next = next->getNext();
- } while (next);
- prev->setNext(alist);
- }
-
- /// getNumArgs - Return the number of actual arguments to this attribute.
- unsigned getNumArgs() const { return NumArgs; }
-
- /// getArg - Return the specified argument.
- Action::ExprTy *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return Args[Arg];
- }
-
- class arg_iterator {
- Action::ExprTy** X;
- unsigned Idx;
- public:
- arg_iterator(Action::ExprTy** x, unsigned idx) : X(x), Idx(idx) {}
-
- arg_iterator& operator++() {
- ++Idx;
- return *this;
- }
-
- bool operator==(const arg_iterator& I) const {
- assert (X == I.X &&
- "compared arg_iterators are for different argument lists");
- return Idx == I.Idx;
- }
-
- bool operator!=(const arg_iterator& I) const {
- return !operator==(I);
- }
-
- Action::ExprTy* operator*() const {
- return X[Idx];
- }
-
- unsigned getArgNum() const {
- return Idx+1;
- }
- };
-
- arg_iterator arg_begin() const {
- return arg_iterator(Args, 0);
- }
-
- arg_iterator arg_end() const {
- return arg_iterator(Args, NumArgs);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h
deleted file mode 100644
index cc20e21a1eb9..000000000000
--- a/clang/include/clang/Parse/DeclSpec.h
+++ /dev/null
@@ -1,758 +0,0 @@
-//===--- SemaDeclSpec.h - Declaration Specifier Semantic Analys -*- 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 interfaces used for Declaration Specifiers and Declarators.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_SEMADECLSPEC_H
-#define LLVM_CLANG_PARSE_SEMADECLSPEC_H
-
-#include "clang/Parse/Action.h"
-#include "clang/Parse/AttributeList.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- struct LangOptions;
- class Diagnostic;
- class IdentifierInfo;
-
-/// DeclSpec - This class captures information about "declaration specifiers",
-/// which encompasses storage-class-specifiers, type-specifiers,
-/// type-qualifiers, and function-specifiers.
-class DeclSpec {
-public:
- // storage-class-specifier
- enum SCS {
- SCS_unspecified,
- SCS_typedef,
- SCS_extern,
- SCS_static,
- SCS_auto,
- SCS_register,
- SCS_private_extern
- };
-
- // type-specifier
- enum TSW {
- TSW_unspecified,
- TSW_short,
- TSW_long,
- TSW_longlong
- };
-
- enum TSC {
- TSC_unspecified,
- TSC_imaginary,
- TSC_complex
- };
-
- enum TSS {
- TSS_unspecified,
- TSS_signed,
- TSS_unsigned
- };
-
- enum TST {
- TST_unspecified,
- TST_void,
- TST_char,
- TST_wchar, // C++ wchar_t
- TST_int,
- TST_float,
- TST_double,
- TST_bool, // _Bool
- TST_decimal32, // _Decimal32
- TST_decimal64, // _Decimal64
- TST_decimal128, // _Decimal128
- TST_enum,
- TST_union,
- TST_struct,
- TST_class, // C++ class type
- TST_typedef,
- TST_typeofType,
- TST_typeofExpr
- };
-
- // type-qualifiers
- enum TQ { // NOTE: These flags must be kept in sync with QualType::TQ.
- TQ_unspecified = 0,
- TQ_const = 1,
- TQ_restrict = 2,
- TQ_volatile = 4
- };
-
- /// ParsedSpecifiers - Flags to query which specifiers were applied. This is
- /// returned by getParsedSpecifiers.
- enum ParsedSpecifiers {
- PQ_None = 0,
- PQ_StorageClassSpecifier = 1,
- PQ_TypeSpecifier = 2,
- PQ_TypeQualifier = 4,
- PQ_FunctionSpecifier = 8
- };
-
-private:
-
- // storage-class-specifier
- /*SCS*/unsigned StorageClassSpec : 3;
- bool SCS_thread_specified : 1;
-
- // type-specifier
- /*TSW*/unsigned TypeSpecWidth : 2;
- /*TSC*/unsigned TypeSpecComplex : 2;
- /*TSS*/unsigned TypeSpecSign : 2;
- /*TST*/unsigned TypeSpecType : 5;
-
- // type-qualifiers
- unsigned TypeQualifiers : 3; // Bitwise OR of TQ.
-
- // function-specifier
- bool FS_inline_specified : 1;
-
- /// TypeRep - This contains action-specific information about a specific TST.
- /// For example, for a typedef or struct, it might contain the declaration for
- /// these.
- Action::TypeTy *TypeRep;
-
- // attributes.
- AttributeList *AttrList;
-
- // List of protocol qualifiers for objective-c classes. Used for
- // protocol-qualified interfaces "NString<foo>" and protocol-qualified id
- // "id<foo>".
- Action::DeclTy * const *ProtocolQualifiers;
- unsigned NumProtocolQualifiers;
-
- // SourceLocation info. These are null if the item wasn't specified or if
- // the setting was synthesized.
- SourceRange Range;
-
- SourceLocation StorageClassSpecLoc, SCS_threadLoc;
- SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
- SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
- SourceLocation FS_inlineLoc;
-
- bool BadSpecifier(TST T, const char *&PrevSpec);
- bool BadSpecifier(TQ T, const char *&PrevSpec);
- bool BadSpecifier(TSS T, const char *&PrevSpec);
- bool BadSpecifier(TSC T, const char *&PrevSpec);
- bool BadSpecifier(TSW T, const char *&PrevSpec);
- bool BadSpecifier(SCS T, const char *&PrevSpec);
-
- DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT
- void operator=(const DeclSpec&); // DO NOT IMPLEMENT
-public:
-
- DeclSpec()
- : StorageClassSpec(SCS_unspecified),
- SCS_thread_specified(false),
- TypeSpecWidth(TSW_unspecified),
- TypeSpecComplex(TSC_unspecified),
- TypeSpecSign(TSS_unspecified),
- TypeSpecType(TST_unspecified),
- TypeQualifiers(TSS_unspecified),
- FS_inline_specified(false),
- TypeRep(0),
- AttrList(0),
- ProtocolQualifiers(0),
- NumProtocolQualifiers(0) {
- }
- ~DeclSpec() {
- delete AttrList;
- delete [] ProtocolQualifiers;
- }
- // storage-class-specifier
- SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
- bool isThreadSpecified() const { return SCS_thread_specified; }
-
- SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
- SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
-
- void ClearStorageClassSpecs() {
- StorageClassSpec = DeclSpec::SCS_unspecified;
- SCS_thread_specified = false;
- StorageClassSpecLoc = SourceLocation();
- SCS_threadLoc = SourceLocation();
- }
-
- // type-specifier
- TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; }
- TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
- TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; }
- TST getTypeSpecType() const { return (TST)TypeSpecType; }
- void *getTypeRep() const { return TypeRep; }
-
- const SourceRange &getSourceRange() const { return Range; }
- SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
- SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
- SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
- SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
-
- /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool"
- /// or "union".
- static const char *getSpecifierName(DeclSpec::TST T);
- static const char *getSpecifierName(DeclSpec::SCS S);
-
- // type-qualifiers
-
- /// getTypeQualifiers - Return a set of TQs.
- unsigned getTypeQualifiers() const { return TypeQualifiers; }
- SourceLocation getConstSpecLoc() const { return TQ_constLoc; }
- SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
- SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
-
-
- // function-specifier
- bool isInlineSpecified() const { return FS_inline_specified; }
- SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
- void ClearFunctionSpecs() {
- FS_inline_specified = false;
- FS_inlineLoc = SourceLocation();
- }
-
- /// hasTypeSpecifier - Return true if any type-specifier has been found.
- bool hasTypeSpecifier() const {
- return getTypeSpecType() != DeclSpec::TST_unspecified ||
- getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
- getTypeSpecComplex() != DeclSpec::TSC_unspecified ||
- getTypeSpecSign() != DeclSpec::TSS_unspecified;
- }
-
-
- /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
- /// DeclSpec includes.
- ///
- unsigned getParsedSpecifiers() const;
-
- void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); }
- void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); }
-
- /// These methods set the specified attribute of the DeclSpec, but return true
- /// and ignore the request if invalid (e.g. "extern" then "auto" is
- /// specified). The name of the previous specifier is returned in prevspec.
- bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec);
- bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec);
- bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec);
- bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec);
- bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec);
- bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- Action::TypeTy *TypeRep = 0);
-
- bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
- const LangOptions &Lang);
-
- bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec);
-
- /// AddAttributes - contatenates two attribute lists.
- /// The GCC attribute syntax allows for the following:
- ///
- /// short __attribute__(( unused, deprecated ))
- /// int __attribute__(( may_alias, aligned(16) )) var;
- ///
- /// This declares 4 attributes using 2 lists. The following syntax is
- /// also allowed and equivalent to the previous declaration.
- ///
- /// short __attribute__((unused)) __attribute__((deprecated))
- /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
- ///
- void AddAttributes(AttributeList *alist) {
- if (!alist)
- return; // we parsed __attribute__(()) or had a syntax error
-
- if (AttrList)
- alist->addAttributeList(AttrList);
- AttrList = alist;
- }
- void SetAttributes(AttributeList *AL) { AttrList = AL; }
- const AttributeList *getAttributes() const { return AttrList; }
- AttributeList *getAttributes() { return AttrList; }
-
- /// TakeAttributes - Return the current attribute list and remove them from
- /// the DeclSpec so that it doesn't own them.
- AttributeList *TakeAttributes() {
- AttributeList *AL = AttrList;
- AttrList = 0;
- return AL;
- }
-
- typedef Action::DeclTy *const * const ProtocolQualifierListTy;
- ProtocolQualifierListTy getProtocolQualifiers() const {
- return ProtocolQualifiers;
- }
- unsigned getNumProtocolQualifiers() const {
- return NumProtocolQualifiers;
- }
- void setProtocolQualifiers(Action::DeclTy* const *Protos, unsigned NumProtos){
- if (NumProtos == 0) return;
- ProtocolQualifiers = new Action::DeclTy*[NumProtos];
- memcpy((void*)ProtocolQualifiers, Protos,sizeof(Action::DeclTy*)*NumProtos);
- NumProtocolQualifiers = NumProtos;
- }
-
- /// Finish - This does final analysis of the declspec, issuing diagnostics for
- /// things like "_Imaginary" (lacking an FP type). After calling this method,
- /// DeclSpec is guaranteed self-consistent, even if an error occurred.
- void Finish(Diagnostic &D, SourceManager& SrcMgr, const LangOptions &Lang);
-
-private:
- void Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr,
- unsigned DiagID);
-
- void Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr,
- unsigned DiagID, const std::string &info);
-};
-
-/// ObjCDeclSpec - This class captures information about
-/// "declaration specifiers" specific to objective-c
-class ObjCDeclSpec {
-public:
- /// ObjCDeclQualifier - Qualifier used on types in method declarations
- enum ObjCDeclQualifier {
- DQ_None = 0x0,
- DQ_In = 0x1,
- DQ_Inout = 0x2,
- DQ_Out = 0x4,
- DQ_Bycopy = 0x8,
- DQ_Byref = 0x10,
- DQ_Oneway = 0x20
- };
-
- /// PropertyAttributeKind - list of property attributes.
- enum ObjCPropertyAttributeKind { DQ_PR_noattr = 0x0,
- DQ_PR_readonly = 0x01,
- DQ_PR_getter = 0x02,
- DQ_PR_assign = 0x04,
- DQ_PR_readwrite = 0x08,
- DQ_PR_retain = 0x10,
- DQ_PR_copy = 0x20,
- DQ_PR_nonatomic = 0x40,
- DQ_PR_setter = 0x80
- };
-
-
- ObjCDeclSpec() : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
- GetterName(0), SetterName(0)
- {}
- ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
- void setObjCDeclQualifier(ObjCDeclQualifier DQVal)
- { objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); }
-
- ObjCPropertyAttributeKind getPropertyAttributes() const
- { return ObjCPropertyAttributeKind(PropertyAttributes); }
- void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) {
- PropertyAttributes =
- (ObjCPropertyAttributeKind) (PropertyAttributes | PRVal);
- }
-
- const IdentifierInfo *getGetterName() const { return GetterName; }
- IdentifierInfo *getGetterName() { return GetterName; }
- void setGetterName(IdentifierInfo *name) { GetterName = name; }
-
- const IdentifierInfo *getSetterName() const { return SetterName; }
- IdentifierInfo *getSetterName() { return SetterName; }
- void setSetterName(IdentifierInfo *name) { SetterName = name; }
-private:
- // FIXME: These two are unrelated and mutially exclusive. So perhaps
- // we can put them in a union to reflect their mutual exclusiveness
- // (space saving is negligible).
- ObjCDeclQualifier objcDeclQualifier : 6;
-
- // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
- unsigned PropertyAttributes : 8;
- IdentifierInfo *GetterName; // getter name of NULL if no getter
- IdentifierInfo *SetterName; // setter name of NULL if no setter
-};
-
-/// DeclaratorChunk - One instance of this struct is used for each type in a
-/// declarator that is parsed.
-///
-/// This is intended to be a small value object.
-struct DeclaratorChunk {
- enum {
- Pointer, Reference, Array, Function, BlockPointer
- } Kind;
-
- /// Loc - The place where this type was defined.
- SourceLocation Loc;
-
- struct PointerTypeInfo {
- /// The type qualifiers: const/volatile/restrict.
- unsigned TypeQuals : 3;
- AttributeList *AttrList;
- void destroy() {
- delete AttrList;
- }
- };
-
- struct ReferenceTypeInfo {
- /// The type qualifier: restrict. [GNU] C++ extension
- bool HasRestrict;
- AttributeList *AttrList;
- void destroy() {
- delete AttrList;
- }
- };
-
- struct ArrayTypeInfo {
- /// The type qualifiers for the array: const/volatile/restrict.
- unsigned TypeQuals : 3;
-
- /// True if this dimension included the 'static' keyword.
- bool hasStatic : 1;
-
- /// True if this dimension was [*]. In this case, NumElts is null.
- bool isStar : 1;
-
- /// This is the size of the array, or null if [] or [*] was specified.
- /// Since the parser is multi-purpose, and we don't want to impose a root
- /// expression class on all clients, NumElts is untyped.
- Action::ExprTy *NumElts;
- void destroy() {}
- };
-
- /// ParamInfo - An array of paraminfo objects is allocated whenever a function
- /// declarator is parsed. There are two interesting styles of arguments here:
- /// K&R-style identifier lists and parameter type lists. K&R-style identifier
- /// lists will have information about the identifier, but no type information.
- /// Parameter type lists will have type info (if the actions module provides
- /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
- struct ParamInfo {
- IdentifierInfo *Ident;
- SourceLocation IdentLoc;
- Action::DeclTy *Param;
- ParamInfo() {}
- ParamInfo(IdentifierInfo *ident, SourceLocation iloc, Action::DeclTy *param)
- : Ident(ident), IdentLoc(iloc), Param(param) {}
- };
-
- struct FunctionTypeInfo {
- /// hasPrototype - This is true if the function had at least one typed
- /// argument. If the function is () or (a,b,c), then it has no prototype,
- /// and is treated as a K&R-style function.
- bool hasPrototype : 1;
-
- /// isVariadic - If this function has a prototype, and if that proto ends
- /// with ',...)', this is true.
- bool isVariadic : 1;
-
- /// NumArgs - This is the number of formal arguments provided for the
- /// declarator.
- unsigned NumArgs;
-
- /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
- /// describe the arguments for this function declarator. This is null if
- /// there are no arguments specified.
- ParamInfo *ArgInfo;
-
- void destroy() {
- delete[] ArgInfo;
- }
- };
-
- struct BlockPointerTypeInfo {
- /// For now, sema will catch these as invalid.
- /// The type qualifiers: const/volatile/restrict.
- unsigned TypeQuals : 3;
- void destroy() {}
- };
-
- union {
- PointerTypeInfo Ptr;
- ReferenceTypeInfo Ref;
- ArrayTypeInfo Arr;
- FunctionTypeInfo Fun;
- BlockPointerTypeInfo Cls;
- };
-
-
- /// getAttrs - If there are attributes applied to this declaratorchunk, return
- /// them.
- const AttributeList *getAttrs() const {
- switch (Kind) {
- default: assert(0 && "Unknown declarator kind!");
- case Pointer: return Ptr.AttrList;
- case Reference: return Ref.AttrList;
- case Array: return 0;
- case Function: return 0;
- case BlockPointer: return 0; // FIXME: Do blocks have attr list?
- }
- }
-
-
- /// getPointer - Return a DeclaratorChunk for a pointer.
- ///
- static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
- AttributeList *AL) {
- DeclaratorChunk I;
- I.Kind = Pointer;
- I.Loc = Loc;
- I.Ptr.TypeQuals = TypeQuals;
- I.Ptr.AttrList = AL;
- return I;
- }
-
- /// getReference - Return a DeclaratorChunk for a reference.
- ///
- static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
- AttributeList *AL) {
- DeclaratorChunk I;
- I.Kind = Reference;
- I.Loc = Loc;
- I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
- I.Ref.AttrList = AL;
- return I;
- }
-
- /// getArray - Return a DeclaratorChunk for an array.
- ///
- static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
- bool isStar, void *NumElts,
- SourceLocation Loc) {
- DeclaratorChunk I;
- I.Kind = Array;
- I.Loc = Loc;
- I.Arr.TypeQuals = TypeQuals;
- I.Arr.hasStatic = isStatic;
- I.Arr.isStar = isStar;
- I.Arr.NumElts = NumElts;
- return I;
- }
-
- /// getFunction - Return a DeclaratorChunk for a function.
- static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
- ParamInfo *ArgInfo, unsigned NumArgs,
- SourceLocation Loc) {
- DeclaratorChunk I;
- I.Kind = Function;
- I.Loc = Loc;
- I.Fun.hasPrototype = hasProto;
- I.Fun.isVariadic = isVariadic;
- I.Fun.NumArgs = NumArgs;
- I.Fun.ArgInfo = 0;
-
- // new[] an argument array if needed.
- if (NumArgs) {
- I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
- memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
- }
- return I;
- }
- /// getBlockPointer - Return a DeclaratorChunk for a block.
- ///
- static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
- SourceLocation Loc) {
- DeclaratorChunk I;
- I.Kind = BlockPointer;
- I.Loc = Loc;
- I.Cls.TypeQuals = TypeQuals;
- return I;
- }
-};
-
-
-/// Declarator - Information about one declarator, including the parsed type
-/// information and the identifier. When the declarator is fully formed, this
-/// is turned into the appropriate Decl object.
-///
-/// Declarators come in two types: normal declarators and abstract declarators.
-/// Abstract declarators are used when parsing types, and don't have an
-/// identifier. Normal declarators do have ID's.
-///
-/// Instances of this class should be a transient object that lives on the
-/// stack, not objects that are allocated in large quantities on the heap.
-class Declarator {
- const DeclSpec &DS;
- IdentifierInfo *Identifier;
- SourceLocation IdentifierLoc;
-
-public:
- enum TheContext {
- FileContext, // File scope declaration.
- PrototypeContext, // Within a function prototype.
- KNRTypeListContext, // K&R type definition list for formals.
- TypeNameContext, // Abstract declarator for types.
- MemberContext, // Struct/Union field.
- BlockContext, // Declaration within a block in a function.
- ForContext, // Declaration within first part of a for loop.
- ConditionContext // Condition declaration in a C++ if/switch/while/for.
- };
-private:
- /// Context - Where we are parsing this declarator.
- ///
- TheContext Context;
-
- /// DeclTypeInfo - This holds each type that the declarator includes as it is
- /// parsed. This is pushed from the identifier out, which means that element
- /// #0 will be the most closely bound to the identifier, and
- /// DeclTypeInfo.back() will be the least closely bound.
- llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
-
- // InvalidType - Set by Sema::GetTypeForDeclarator().
- bool InvalidType : 1;
-
- /// GroupingParens - Set by Parser::ParseParenDeclarator().
- bool GroupingParens : 1;
-
- /// AttrList - Attributes.
- AttributeList *AttrList;
-
- /// AsmLabel - The asm label, if specified.
- Action::ExprTy *AsmLabel;
-
-public:
- Declarator(const DeclSpec &ds, TheContext C)
- : DS(ds), Identifier(0), Context(C), InvalidType(false),
- GroupingParens(false), AttrList(0), AsmLabel(0) {
- }
-
- ~Declarator() {
- clear();
- }
-
- /// getDeclSpec - Return the declaration-specifier that this declarator was
- /// declared with.
- const DeclSpec &getDeclSpec() const { return DS; }
-
- /// getMutableDeclSpec - Return a non-const version of the DeclSpec. This
- /// should be used with extreme care: declspecs can often be shared between
- /// multiple declarators, so mutating the DeclSpec affects all of the
- /// Declarators. This should only be done when the declspec is known to not
- /// be shared or when in error recovery etc.
- DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); }
-
- TheContext getContext() const { return Context; }
-
- // getSourceRange - FIXME: This should be implemented.
- const SourceRange getSourceRange() const { return SourceRange(); }
-
- /// clear - Reset the contents of this Declarator.
- void clear() {
- Identifier = 0;
- IdentifierLoc = SourceLocation();
-
- for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) {
- if (DeclTypeInfo[i].Kind == DeclaratorChunk::Function)
- DeclTypeInfo[i].Fun.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Pointer)
- DeclTypeInfo[i].Ptr.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::BlockPointer)
- DeclTypeInfo[i].Cls.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Reference)
- DeclTypeInfo[i].Ref.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Array)
- DeclTypeInfo[i].Arr.destroy();
- else
- assert(0 && "Unknown decl type!");
- }
- DeclTypeInfo.clear();
- delete AttrList;
- AttrList = 0;
- AsmLabel = 0;
- }
-
- /// mayOmitIdentifier - Return true if the identifier is either optional or
- /// not allowed. This is true for typenames and prototypes.
- bool mayOmitIdentifier() const {
- return Context == TypeNameContext || Context == PrototypeContext;
- }
-
- /// mayHaveIdentifier - Return true if the identifier is either optional or
- /// required. This is true for normal declarators and prototypes, but not
- /// typenames.
- bool mayHaveIdentifier() const {
- return Context != TypeNameContext;
- }
-
- /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be
- /// followed by a C++ direct initializer, e.g. "int x(1);".
- bool mayBeFollowedByCXXDirectInit() const {
- return !hasGroupingParens() &&
- (Context == FileContext ||
- Context == BlockContext ||
- Context == ForContext );
- }
-
- /// isPastIdentifier - Return true if we have parsed beyond the point where
- /// the
- bool isPastIdentifier() const { return IdentifierLoc.isValid(); }
-
- IdentifierInfo *getIdentifier() const { return Identifier; }
- SourceLocation getIdentifierLoc() const { return IdentifierLoc; }
-
- void SetIdentifier(IdentifierInfo *ID, SourceLocation Loc) {
- Identifier = ID;
- IdentifierLoc = Loc;
- }
-
- void AddTypeInfo(const DeclaratorChunk &TI) {
- DeclTypeInfo.push_back(TI);
- }
-
- /// getNumTypeObjects() - Return the number of types applied to this
- /// declarator.
- unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); }
-
- /// Return the specified TypeInfo from this declarator. TypeInfo #0 is
- /// closest to the identifier.
- const DeclaratorChunk &getTypeObject(unsigned i) const {
- assert(i < DeclTypeInfo.size() && "Invalid type chunk");
- return DeclTypeInfo[i];
- }
- DeclaratorChunk &getTypeObject(unsigned i) {
- assert(i < DeclTypeInfo.size() && "Invalid type chunk");
- return DeclTypeInfo[i];
- }
-
- /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
- /// this method returns true if the identifier is a function declarator.
- bool isFunctionDeclarator() const {
- return !DeclTypeInfo.empty() &&
- DeclTypeInfo[0].Kind == DeclaratorChunk::Function;
- }
-
- /// AddAttributes - simply adds the attribute list to the Declarator.
- /// Unlike AddAttributes on DeclSpec, this routine should never have to
- /// concatenate two lists. The following syntax adds 3 attributes to "var":
- ///
- /// short int var __attribute__((aligned(16),common,deprecated));
- ///
- void AddAttributes(AttributeList *alist) {
- if (!alist)
- return; // we parsed __attribute__(()) or had a syntax error
- assert((AttrList == 0) && "Declarator already has an attribute list");
- AttrList = alist;
- }
- const AttributeList *getAttributes() const { return AttrList; }
- AttributeList *getAttributes() { return AttrList; }
-
- void setAsmLabel(Action::ExprTy *E) { AsmLabel = E; }
- Action::ExprTy *getAsmLabel() const { return AsmLabel; }
-
- void setInvalidType(bool flag) { InvalidType = flag; }
- bool getInvalidType() const { return InvalidType; }
-
- void setGroupingParens(bool flag) { GroupingParens = flag; }
- bool hasGroupingParens() const { return GroupingParens; }
-};
-
-/// FieldDeclarator - This little struct is used to capture information about
-/// structure field declarators, which is basically just a bitfield size.
-struct FieldDeclarator {
- Declarator D;
- Action::ExprTy *BitfieldSize;
- explicit FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) {
- BitfieldSize = 0;
- }
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
deleted file mode 100644
index c1259c69654f..000000000000
--- a/clang/include/clang/Parse/Parser.h
+++ /dev/null
@@ -1,721 +0,0 @@
-//===--- Parser.h - C Language Parser ---------------------------*- 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 Parser interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_PARSER_H
-#define LLVM_CLANG_PARSE_PARSER_H
-
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Action.h"
-#include <stack>
-
-namespace clang {
- class AttributeList;
- class DeclSpec;
- class Declarator;
- class FieldDeclarator;
- class ObjCDeclSpec;
- class PragmaHandler;
- class Scope;
-
-/// Parser - This implements a parser for the C family of languages. After
-/// parsing units of the grammar, productions are invoked to handle whatever has
-/// been read.
-///
-class Parser {
- Preprocessor &PP;
-
- /// Tok - The current token we are peeking ahead. All parsing methods assume
- /// that this is valid.
- Token Tok;
-
- unsigned short ParenCount, BracketCount, BraceCount;
-
- /// Actions - These are the callbacks we invoke as we parse various constructs
- /// in the file. This refers to the common base class between MinimalActions
- /// and SemaActions for those uses that don't matter.
- Action &Actions;
-
- Scope *CurScope;
- Diagnostic &Diags;
-
- /// ScopeCache - Cache scopes to reduce malloc traffic.
- enum { ScopeCacheSize = 16 };
- unsigned NumCachedScopes;
- Scope *ScopeCache[ScopeCacheSize];
-
- /// Ident_super - IdentifierInfo for "super", to support fast
- /// comparison.
- IdentifierInfo *Ident_super;
-
- PragmaHandler *PackHandler;
-
-public:
- Parser(Preprocessor &PP, Action &Actions);
- ~Parser();
-
- const LangOptions &getLang() const { return PP.getLangOptions(); }
- TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
- Action &getActions() const { return Actions; }
-
- // Type forwarding. All of these are statically 'void*', but they may all be
- // different actual classes based on the actions in place.
- typedef Action::ExprTy ExprTy;
- typedef Action::StmtTy StmtTy;
- typedef Action::DeclTy DeclTy;
- typedef Action::TypeTy TypeTy;
-
- // Parsing methods.
-
- /// ParseTranslationUnit - All in one method that initializes parses, and
- /// shuts down the parser.
- void ParseTranslationUnit();
-
- /// Initialize - Warm up the parser.
- ///
- void Initialize();
-
- /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
- /// the EOF was encountered.
- bool ParseTopLevelDecl(DeclTy*& Result);
-
-private:
- //===--------------------------------------------------------------------===//
- // Low-Level token peeking and consumption methods.
- //
-
- /// isTokenParen - Return true if the cur token is '(' or ')'.
- bool isTokenParen() const {
- return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
- }
- /// isTokenBracket - Return true if the cur token is '[' or ']'.
- bool isTokenBracket() const {
- return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
- }
- /// isTokenBrace - Return true if the cur token is '{' or '}'.
- bool isTokenBrace() const {
- return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
- }
-
- /// isTokenStringLiteral - True if this token is a string-literal.
- ///
- bool isTokenStringLiteral() const {
- return Tok.getKind() == tok::string_literal ||
- Tok.getKind() == tok::wide_string_literal;
- }
-
- /// ConsumeToken - Consume the current 'peek token' and lex the next one.
- /// This does not work with all kinds of tokens: strings and specific other
- /// tokens must be consumed with custom methods below. This returns the
- /// location of the consumed token.
- SourceLocation ConsumeToken() {
- assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
- !isTokenBrace() &&
- "Should consume special tokens with Consume*Token");
- SourceLocation L = Tok.getLocation();
- PP.Lex(Tok);
- return L;
- }
-
- /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
- /// current token type. This should only be used in cases where the type of
- /// the token really isn't known, e.g. in error recovery.
- SourceLocation ConsumeAnyToken() {
- if (isTokenParen())
- return ConsumeParen();
- else if (isTokenBracket())
- return ConsumeBracket();
- else if (isTokenBrace())
- return ConsumeBrace();
- else if (isTokenStringLiteral())
- return ConsumeStringToken();
- else
- return ConsumeToken();
- }
-
- /// ConsumeParen - This consume method keeps the paren count up-to-date.
- ///
- SourceLocation ConsumeParen() {
- assert(isTokenParen() && "wrong consume method");
- if (Tok.getKind() == tok::l_paren)
- ++ParenCount;
- else if (ParenCount)
- --ParenCount; // Don't let unbalanced )'s drive the count negative.
- SourceLocation L = Tok.getLocation();
- PP.Lex(Tok);
- return L;
- }
-
- /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
- ///
- SourceLocation ConsumeBracket() {
- assert(isTokenBracket() && "wrong consume method");
- if (Tok.getKind() == tok::l_square)
- ++BracketCount;
- else if (BracketCount)
- --BracketCount; // Don't let unbalanced ]'s drive the count negative.
-
- SourceLocation L = Tok.getLocation();
- PP.Lex(Tok);
- return L;
- }
-
- /// ConsumeBrace - This consume method keeps the brace count up-to-date.
- ///
- SourceLocation ConsumeBrace() {
- assert(isTokenBrace() && "wrong consume method");
- if (Tok.getKind() == tok::l_brace)
- ++BraceCount;
- else if (BraceCount)
- --BraceCount; // Don't let unbalanced }'s drive the count negative.
-
- SourceLocation L = Tok.getLocation();
- PP.Lex(Tok);
- return L;
- }
-
- /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
- /// and returning the token kind. This method is specific to strings, as it
- /// handles string literal concatenation, as per C99 5.1.1.2, translation
- /// phase #6.
- SourceLocation ConsumeStringToken() {
- assert(isTokenStringLiteral() &&
- "Should only consume string literals with this method");
- SourceLocation L = Tok.getLocation();
- PP.Lex(Tok);
- return L;
- }
-
- /// GetLookAheadToken - This peeks ahead N tokens and returns that token
- /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
- /// returns the token after Tok, etc.
- ///
- /// Note that this differs from the Preprocessor's LookAhead method, because
- /// the Parser always has one token lexed that the preprocessor doesn't.
- ///
- const Token &GetLookAheadToken(unsigned N) {
- if (N == 0 || Tok.is(tok::eof)) return Tok;
- return PP.LookAhead(N-1);
- }
-
- /// NextToken - This peeks ahead one token and returns it without
- /// consuming it.
- const Token &NextToken() {
- return PP.LookAhead(0);
- }
-
- /// TentativeParsingAction - An object that is used as a kind of "tentative
- /// parsing transaction". It gets instantiated to mark the token position and
- /// after the token consumption is done, Commit() or Revert() is called to
- /// either "commit the consumed tokens" or revert to the previously marked
- /// token position. Example:
- ///
- /// TentativeParsingAction TPA;
- /// ConsumeToken();
- /// ....
- /// TPA.Revert();
- ///
- class TentativeParsingAction {
- Parser &P;
- Token PrevTok;
- bool isActive;
-
- public:
- explicit TentativeParsingAction(Parser& p) : P(p) {
- PrevTok = P.Tok;
- P.PP.EnableBacktrackAtThisPos();
- isActive = true;
- }
- void Commit() {
- assert(isActive && "Parsing action was finished!");
- P.PP.CommitBacktrackedTokens();
- isActive = false;
- }
- void Revert() {
- assert(isActive && "Parsing action was finished!");
- P.PP.Backtrack();
- P.Tok = PrevTok;
- isActive = false;
- }
- ~TentativeParsingAction() {
- assert(!isActive && "Forgot to call Commit or Revert!");
- }
- };
-
-
- /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
- /// this helper function matches and consumes the specified RHS token if
- /// present. If not present, it emits the specified diagnostic indicating
- /// that the parser failed to match the RHS of the token at LHSLoc. LHSName
- /// should be the name of the unmatched LHS token. This returns the location
- /// of the consumed token.
- SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
- SourceLocation LHSLoc);
-
- /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
- /// input. If so, it is consumed and false is returned.
- ///
- /// If the input is malformed, this emits the specified diagnostic. Next, if
- /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
- /// returned.
- bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
- const char *DiagMsg = "",
- tok::TokenKind SkipToTok = tok::unknown);
-
- //===--------------------------------------------------------------------===//
- // Scope manipulation
-
- /// EnterScope - Start a new scope.
- void EnterScope(unsigned ScopeFlags);
-
- /// ExitScope - Pop a scope off the scope stack.
- void ExitScope();
-
- //===--------------------------------------------------------------------===//
- // Diagnostic Emission and Error recovery.
-
- bool Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg = std::string());
- bool Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange& R1);
- bool Diag(const Token &Tok, unsigned DiagID,
- const std::string &M = std::string()) {
- return Diag(Tok.getLocation(), DiagID, M);
- }
-
- /// SkipUntil - Read tokens until we get to the specified token, then consume
- /// it (unless DontConsume is true). Because we cannot guarantee that the
- /// token will ever occur, this skips to the next token, or to some likely
- /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
- /// character.
- ///
- /// If SkipUntil finds the specified token, it returns true, otherwise it
- /// returns false.
- bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
- bool DontConsume = false) {
- return SkipUntil(&T, 1, StopAtSemi, DontConsume);
- }
- bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
- bool DontConsume = false) {
- tok::TokenKind TokArray[] = {T1, T2};
- return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
- }
- bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
- bool StopAtSemi = true, bool DontConsume = false);
-
- typedef Action::ExprResult ExprResult;
- typedef Action::StmtResult StmtResult;
-
- //===--------------------------------------------------------------------===//
- // Lexing and parsing of C++ inline methods.
-
- typedef llvm::SmallVector<Token, 32> TokensTy;
- struct LexedMethod {
- Action::DeclTy *D;
- TokensTy Toks;
- explicit LexedMethod(Action::DeclTy *MD) : D(MD) {}
- };
-
- /// LexedMethodsForTopClass - During parsing of a top (non-nested) C++ class,
- /// its inline method definitions and the inline method definitions of its
- /// nested classes are lexed and stored here.
- typedef std::stack<LexedMethod> LexedMethodsForTopClass;
-
- /// TopClassStacks - This is initialized with one LexedMethodsForTopClass used
- /// for lexing all top classes, until a local class in an inline method is
- /// encountered, at which point a new LexedMethodsForTopClass is pushed here
- /// and used until the parsing of that local class is finished.
- std::stack<LexedMethodsForTopClass> TopClassStacks;
-
- LexedMethodsForTopClass &getCurTopClassStack() {
- assert(!TopClassStacks.empty() && "No lexed method stacks!");
- return TopClassStacks.top();
- }
-
- void PushTopClassStack() {
- TopClassStacks.push(LexedMethodsForTopClass());
- }
- void PopTopClassStack() { TopClassStacks.pop(); }
-
- DeclTy *ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D);
- void ParseLexedMethodDefs();
- bool ConsumeAndStoreUntil(tok::TokenKind T, TokensTy &Toks);
-
- //===--------------------------------------------------------------------===//
- // C99 6.9: External Definitions.
- DeclTy *ParseExternalDeclaration();
- DeclTy *ParseDeclarationOrFunctionDefinition();
- DeclTy *ParseFunctionDefinition(Declarator &D);
- void ParseKNRParamDeclarations(Declarator &D);
- ExprResult ParseSimpleAsm();
- ExprResult ParseAsmStringLiteral();
-
- // Objective-C External Declarations
- DeclTy *ParseObjCAtDirectives();
- DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc);
- DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
- AttributeList *prefixAttrs = 0);
- void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
- SourceLocation atLoc);
- bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &P,
- bool WarnOnDeclarations,
- SourceLocation &EndProtoLoc);
- void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
- tok::ObjCKeywordKind contextKey);
- DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
- AttributeList *prefixAttrs = 0);
-
- DeclTy *ObjCImpDecl;
-
- DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
- DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
- DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
- DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc);
- DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc);
-
- IdentifierInfo *ParseObjCSelector(SourceLocation &MethodLocation);
- // Definitions for Objective-c context sensitive keywords recognition.
- enum ObjCTypeQual {
- objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
- objc_NumQuals
- };
- IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
- // Definitions for ObjC2's @property attributes.
- enum ObjCPropertyAttr {
- objc_readonly=0, objc_getter, objc_setter, objc_assign,
- objc_readwrite, objc_retain, objc_copy, objc_nonatomic, objc_NumAttrs
- };
- IdentifierInfo *ObjCPropertyAttrs[objc_NumAttrs];
- bool isObjCPropertyAttribute();
-
- bool isTokIdentifier_in() const;
-
- TypeTy *ParseObjCTypeName(ObjCDeclSpec &DS);
- void ParseObjCMethodRequirement();
- DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat,
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
- DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
- DeclTy *classDecl,
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
- void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
-
- DeclTy *ParseObjCMethodDefinition();
-
- //===--------------------------------------------------------------------===//
- // C99 6.5: Expressions.
-
- ExprResult ParseExpression();
- ExprResult ParseConstantExpression();
- ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
-
- ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
-
- ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
- ExprResult ParseCastExpression(bool isUnaryExpression);
- ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
- ExprResult ParseSizeofAlignofExpression();
- ExprResult ParseBuiltinPrimaryExpression();
-
- typedef llvm::SmallVector<ExprTy*, 8> ExprListTy;
- typedef llvm::SmallVector<SourceLocation, 8> CommaLocsTy;
-
- /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
- bool ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs);
-
- /// ParenParseOption - Control what ParseParenExpression will parse.
- enum ParenParseOption {
- SimpleExpr, // Only parse '(' expression ')'
- CompoundStmt, // Also allow '(' compound-statement ')'
- CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
- CastExpr // Also allow '(' type-name ')' <anything>
- };
- ExprResult ParseParenExpression(ParenParseOption &ExprType, TypeTy *&CastTy,
- SourceLocation &RParenLoc);
-
- ExprResult ParseSimpleParenExpression() { // Parse SimpleExpr only.
- SourceLocation RParenLoc;
- return ParseSimpleParenExpression(RParenLoc);
- }
- ExprResult ParseSimpleParenExpression(SourceLocation &RParenLoc) {
- ParenParseOption Op = SimpleExpr;
- TypeTy *CastTy;
- return ParseParenExpression(Op, CastTy, RParenLoc);
- }
- ExprResult ParseStringLiteralExpression();
-
- //===--------------------------------------------------------------------===//
- // C++ 5.2p1: C++ Casts
- ExprResult ParseCXXCasts();
-
- //===--------------------------------------------------------------------===//
- // C++ 9.3.2: C++ 'this' pointer
- ExprResult ParseCXXThis();
-
- //===--------------------------------------------------------------------===//
- // C++ 15: C++ Throw Expression
- ExprResult ParseThrowExpression();
-
- //===--------------------------------------------------------------------===//
- // C++ 2.13.5: C++ Boolean Literals
- ExprResult ParseCXXBoolLiteral();
-
- //===--------------------------------------------------------------------===//
- // C++ 5.2.3: Explicit type conversion (functional notation)
- ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
-
- /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
- /// This should only be called when the current token is known to be part of
- /// simple-type-specifier.
- void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
-
- //===--------------------------------------------------------------------===//
- // C++ if/switch/while/for condition expression.
- ExprResult ParseCXXCondition();
-
- //===--------------------------------------------------------------------===//
- // C99 6.7.8: Initialization.
- ExprResult ParseInitializer();
- ExprResult ParseInitializerWithPotentialDesignator();
-
- //===--------------------------------------------------------------------===//
- // clang Expressions
-
- ExprResult ParseBlockLiteralExpression(); // ^{...}
-
- //===--------------------------------------------------------------------===//
- // Objective-C Expressions
-
- bool isTokObjCMessageIdentifierReceiver() const {
- if (!Tok.is(tok::identifier))
- return false;
-
- if (Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
- return true;
-
- return Tok.getIdentifierInfo() == Ident_super;
- }
-
- ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
- ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
- ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
- ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
- ExprResult ParseObjCMessageExpression();
- ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
- IdentifierInfo *ReceiverName,
- ExprTy *ReceiverExpr);
- ExprResult ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracloc,
- IdentifierInfo *ReceiverName,
- ExprTy *ReceiverExpr);
-
- //===--------------------------------------------------------------------===//
- // C99 6.8: Statements and Blocks.
-
- StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
- StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
- StmtResult ParseLabeledStatement();
- StmtResult ParseCaseStatement();
- StmtResult ParseDefaultStatement();
- StmtResult ParseCompoundStatement(bool isStmtExpr = false);
- StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
- StmtResult ParseIfStatement();
- StmtResult ParseSwitchStatement();
- StmtResult ParseWhileStatement();
- StmtResult ParseDoStatement();
- StmtResult ParseForStatement();
- StmtResult ParseGotoStatement();
- StmtResult ParseContinueStatement();
- StmtResult ParseBreakStatement();
- StmtResult ParseReturnStatement();
- StmtResult ParseAsmStatement(bool &msAsm);
- StmtResult FuzzyParseMicrosoftAsmStatement();
- StmtResult ParseObjCAtStatement(SourceLocation atLoc);
- StmtResult ParseObjCTryStmt(SourceLocation atLoc);
- StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
- StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
- bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
- llvm::SmallVectorImpl<ExprTy*> &Constraints,
- llvm::SmallVectorImpl<ExprTy*> &Exprs);
-
-
- //===--------------------------------------------------------------------===//
- // C99 6.7: Declarations.
-
- DeclTy *ParseDeclaration(unsigned Context);
- DeclTy *ParseSimpleDeclaration(unsigned Context);
- DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
- DeclTy *ParseFunctionStatementBody(DeclTy *Decl,
- SourceLocation L, SourceLocation R);
- void ParseDeclarationSpecifiers(DeclSpec &DS);
- void ParseSpecifierQualifierList(DeclSpec &DS);
-
- void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
-
- void ParseEnumSpecifier(DeclSpec &DS);
- void ParseEnumBody(SourceLocation StartLoc, DeclTy *TagDecl);
- void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
- DeclTy *TagDecl);
- void ParseStructDeclaration(DeclSpec &DS,
- llvm::SmallVectorImpl<FieldDeclarator> &Fields);
-
- bool isDeclarationSpecifier() const;
- bool isTypeSpecifierQualifier() const;
- bool isTypeQualifier() const;
-
- /// isDeclarationStatement - Disambiguates between a declaration or an
- /// expression statement, when parsing function bodies.
- /// Returns true for declaration, false for expression.
- bool isDeclarationStatement() {
- if (getLang().CPlusPlus)
- return isCXXDeclarationStatement();
- return isDeclarationSpecifier();
- }
-
- /// isSimpleDeclaration - Disambiguates between a declaration or an
- /// expression, mainly used for the C 'clause-1' or the C++
- // 'for-init-statement' part of a 'for' statement.
- /// Returns true for declaration, false for expression.
- bool isSimpleDeclaration() {
- if (getLang().CPlusPlus)
- return isCXXSimpleDeclaration();
- return isDeclarationSpecifier();
- }
-
- /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
- /// whether the parens contain an expression or a type-id.
- /// Returns true for a type-id and false for an expression.
- bool isTypeIdInParens() {
- if (getLang().CPlusPlus)
- return isCXXTypeIdInParens();
- return isTypeSpecifierQualifier();
- }
-
- /// isCXXDeclarationStatement - C++-specialized function that disambiguates
- /// between a declaration or an expression statement, when parsing function
- /// bodies. Returns true for declaration, false for expression.
- bool isCXXDeclarationStatement();
-
- /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
- /// between a simple-declaration or an expression-statement.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- /// Returns false if the statement is disambiguated as expression.
- bool isCXXSimpleDeclaration();
-
- /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
- /// a constructor-style initializer, when parsing declaration statements.
- /// Returns true for function declarator and false for constructor-style
- /// initializer.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- bool isCXXFunctionDeclarator();
-
- /// isCXXConditionDeclaration - Disambiguates between a declaration or an
- /// expression for a condition of a if/switch/while/for statement.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- bool isCXXConditionDeclaration();
-
- /// isCXXTypeIdInParens - Assumes that a '(' was parsed and now we want to
- /// know whether the parens contain an expression or a type-id.
- /// Returns true for a type-id and false for an expression.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- bool isCXXTypeIdInParens();
-
- /// TPResult - Used as the result value for functions whose purpose is to
- /// disambiguate C++ constructs by "tentatively parsing" them.
- /// This is a class instead of a simple enum because the implicit enum-to-bool
- /// conversions may cause subtle bugs.
- class TPResult {
- enum Result {
- TPR_true,
- TPR_false,
- TPR_ambiguous,
- TPR_error
- };
- Result Res;
- TPResult(Result result) : Res(result) {}
- public:
- static TPResult True() { return TPR_true; }
- static TPResult False() { return TPR_false; }
- static TPResult Ambiguous() { return TPR_ambiguous; }
- static TPResult Error() { return TPR_error; }
-
- bool operator==(const TPResult &RHS) const { return Res == RHS.Res; }
- bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; }
- };
-
- /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a
- /// declaration specifier, TPResult::False() if it is not,
- /// TPResult::Ambiguous() if it could be either a decl-specifier or a
- /// function-style cast, and TPResult::Error() if a parsing error was
- /// encountered.
- /// Doesn't consume tokens.
- TPResult isCXXDeclarationSpecifier();
-
- // "Tentative parsing" functions, used for disambiguation. If a parsing error
- // is encountered they will return TPResult::Error().
- // Returning TPResult::True()/False() indicates that the ambiguity was
- // resolved and tentative parsing may stop. TPResult::Ambiguous() indicates
- // that more tentative parsing is necessary for disambiguation.
- // They all consume tokens, so backtracking should be used after calling them.
-
- TPResult TryParseDeclarationSpecifier();
- TPResult TryParseSimpleDeclaration();
- TPResult TryParseTypeofSpecifier();
- TPResult TryParseInitDeclaratorList();
- TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
- TPResult TryParseParameterDeclarationClause();
- TPResult TryParseFunctionDeclarator();
- TPResult TryParseBracketDeclarator();
-
-
- TypeTy *ParseTypeName();
- AttributeList *ParseAttributes();
- void ParseTypeofSpecifier(DeclSpec &DS);
-
- /// ParseDeclarator - Parse and verify a newly-initialized declarator.
- void ParseDeclarator(Declarator &D);
- void ParseDeclaratorInternal(Declarator &D);
- void ParseTypeQualifierListOpt(DeclSpec &DS);
- void ParseDirectDeclarator(Declarator &D);
- void ParseParenDeclarator(Declarator &D);
- void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D);
- void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
- Declarator &D);
- void ParseBracketDeclarator(Declarator &D);
-
- //===--------------------------------------------------------------------===//
- // C++ 7: Declarations [dcl.dcl]
-
- DeclTy *ParseNamespace(unsigned Context);
- DeclTy *ParseLinkage(unsigned Context);
-
- //===--------------------------------------------------------------------===//
- // C++ 9: classes [class] and C structs/unions.
- void ParseClassSpecifier(DeclSpec &DS);
- void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
- DeclTy *TagDecl);
- DeclTy *ParseCXXClassMemberDeclaration(AccessSpecifier AS);
-
- //===--------------------------------------------------------------------===//
- // C++ 10: Derived classes [class.derived]
- void ParseBaseClause(DeclTy *ClassDecl);
- bool ParseBaseSpecifier(DeclTy *ClassDecl);
- AccessSpecifier getAccessSpecifierIfPresent() const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Parse/Scope.h b/clang/include/clang/Parse/Scope.h
deleted file mode 100644
index 17a61c78f1e6..000000000000
--- a/clang/include/clang/Parse/Scope.h
+++ /dev/null
@@ -1,203 +0,0 @@
-//===--- Scope.h - Scope interface ------------------------------*- 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 Scope interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_SCOPE_H
-#define LLVM_CLANG_PARSE_SCOPE_H
-
-#include "clang/Parse/Action.h"
-#include "llvm/ADT/SmallPtrSet.h"
-
-namespace clang {
-
-/// Scope - A scope is a transient data structure that is used while parsing the
-/// program. It assists with resolving identifiers to the appropriate
-/// declaration.
-///
-class Scope {
-public:
- /// ScopeFlags - These are bitfields that are or'd together when creating a
- /// scope, which defines the sorts of things the scope contains.
- enum ScopeFlags {
- /// FnScope - This indicates that the scope corresponds to a function, which
- /// means that labels are set here.
- FnScope = 0x01,
-
- /// BreakScope - This is a while,do,switch,for, etc that can have break
- /// stmts embedded into it.
- BreakScope = 0x02,
-
- /// ContinueScope - This is a while,do,for, which can have continue
- /// stmt embedded into it.
- ContinueScope = 0x04,
-
- /// DeclScope - This is a scope that can contain a declaration. Some scopes
- /// just contain loop constructs but don't contain decls.
- DeclScope = 0x08,
-
- /// ControlScope - The controlling scope in a if/switch/while/for statement.
- ControlScope = 0x10,
-
- /// CXXClassScope - The scope of a C++ struct/union/class definition.
- CXXClassScope = 0x20,
-
- /// BlockScope - This is a scope that corresponds to a block object.
- /// Blocks serve as top-level scopes for some objects like labels, they
- /// also prevent things like break and continue. BlockScopes have the
- /// other flags set as well.
- BlockScope = 0x40
- };
-private:
- /// The parent scope for this scope. This is null for the translation-unit
- /// scope.
- Scope *AnyParent;
-
- /// Depth - This is the depth of this scope. The translation-unit scope has
- /// depth 0.
- unsigned Depth : 16;
-
- /// Flags - This contains a set of ScopeFlags, which indicates how the scope
- /// interrelates with other control flow statements.
- unsigned Flags : 8;
-
- /// FnParent - If this scope has a parent scope that is a function body, this
- /// pointer is non-null and points to it. This is used for label processing.
- Scope *FnParent;
-
- /// BreakParent/ContinueParent - This is a direct link to the immediately
- /// preceeding BreakParent/ContinueParent if this scope is not one, or null if
- /// there is no containing break/continue scope.
- Scope *BreakParent, *ContinueParent;
-
- /// BlockParent - This is a direct link to the immediately containing
- /// BlockScope if this scope is not one, or null if there is none.
- Scope *BlockParent;
-
- /// DeclsInScope - This keeps track of all declarations in this scope. When
- /// the declaration is added to the scope, it is set as the current
- /// declaration for the identifier in the IdentifierTable. When the scope is
- /// popped, these declarations are removed from the IdentifierTable's notion
- /// of current declaration. It is up to the current Action implementation to
- /// implement these semantics.
- typedef llvm::SmallPtrSet<Action::DeclTy*, 32> DeclSetTy;
- DeclSetTy DeclsInScope;
-
-public:
- Scope(Scope *Parent, unsigned ScopeFlags) {
- Init(Parent, ScopeFlags);
- }
-
- /// getFlags - Return the flags for this scope.
- ///
- unsigned getFlags() const { return Flags; }
-
- /// isBlockScope - Return true if this scope does not correspond to a
- /// closure.
- bool isBlockScope() const { return Flags & BlockScope; }
-
- /// getParent - Return the scope that this is nested in.
- ///
- const Scope *getParent() const { return AnyParent; }
- Scope *getParent() { return AnyParent; }
-
- /// getFnParent - Return the closest scope that is a function body.
- ///
- const Scope *getFnParent() const { return FnParent; }
- Scope *getFnParent() { return FnParent; }
-
- /// getContinueParent - Return the closest scope that a continue statement
- /// would be affected by. If the closest scope is a closure scope, we know
- /// that there is no loop *inside* the closure.
- Scope *getContinueParent() {
- if (ContinueParent && !ContinueParent->isBlockScope())
- return ContinueParent;
- return 0;
- }
-
- const Scope *getContinueParent() const {
- return const_cast<Scope*>(this)->getContinueParent();
- }
-
- /// getBreakParent - Return the closest scope that a break statement
- /// would be affected by. If the closest scope is a block scope, we know
- /// that there is no loop *inside* the block.
- Scope *getBreakParent() {
- if (BreakParent && !BreakParent->isBlockScope())
- return BreakParent;
- return 0;
- }
- const Scope *getBreakParent() const {
- return const_cast<Scope*>(this)->getBreakParent();
- }
-
- Scope *getBlockParent() { return BlockParent; }
- const Scope *getBlockParent() const { return BlockParent; }
-
- typedef DeclSetTy::iterator decl_iterator;
- decl_iterator decl_begin() const { return DeclsInScope.begin(); }
- decl_iterator decl_end() const { return DeclsInScope.end(); }
- bool decl_empty() const { return DeclsInScope.empty(); }
-
- void AddDecl(Action::DeclTy *D) {
- DeclsInScope.insert(D);
- }
-
- /// isDeclScope - Return true if this is the scope that the specified decl is
- /// declared in.
- bool isDeclScope(Action::DeclTy *D) {
- return DeclsInScope.count(D) != 0;
- }
-
- /// isCXXClassScope - Return true if this scope is a C++ class scope.
- bool isCXXClassScope() const {
- return (getFlags() & Scope::CXXClassScope);
- }
-
- /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
- /// method scope or is inside one.
- bool isInCXXInlineMethodScope() const {
- if (const Scope *FnS = getFnParent()) {
- assert(FnS->getParent() && "TUScope not created?");
- return FnS->getParent()->isCXXClassScope();
- }
- return false;
- }
-
- /// Init - This is used by the parser to implement scope caching.
- ///
- void Init(Scope *Parent, unsigned ScopeFlags) {
- AnyParent = Parent;
- Depth = AnyParent ? AnyParent->Depth+1 : 0;
- Flags = ScopeFlags;
-
- if (AnyParent) {
- FnParent = AnyParent->FnParent;
- BreakParent = AnyParent->BreakParent;
- ContinueParent = AnyParent->ContinueParent;
- BlockParent = AnyParent->BlockParent;
- } else {
- FnParent = BreakParent = ContinueParent = BlockParent = 0;
- }
-
- // If this scope is a function or contains breaks/continues, remember it.
- if (Flags & FnScope) FnParent = this;
- if (Flags & BreakScope) BreakParent = this;
- if (Flags & ContinueScope) ContinueParent = this;
- if (Flags & BlockScope) BlockParent = this;
-
- DeclsInScope.clear();
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Rewrite/DeltaTree.h b/clang/include/clang/Rewrite/DeltaTree.h
deleted file mode 100644
index 7bf9305e2877..000000000000
--- a/clang/include/clang/Rewrite/DeltaTree.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- DeltaTree.h - B-Tree for Rewrite Delta tracking --------*- 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 DeltaTree class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_REWRITE_DELTATREE_H
-#define CLANG_REWRITE_DELTATREE_H
-
-namespace clang {
-
- /// DeltaTree - a multiway search tree (BTree) structure with some fancy
- /// features. B-Trees are are generally more memory and cache efficient than
- /// binary trees, because they store multiple keys/values in each node. This
- /// implements a key/value mapping from index to delta, and allows fast lookup
- /// on index. However, an added (important) bonus is that it can also
- /// efficiently tell us the full accumulated delta for a specific file offset
- /// as well, without traversing the whole tree.
- class DeltaTree {
- void *Root; // "DeltaTreeNode *"
- void operator=(const DeltaTree&); // DO NOT IMPLEMENT
- public:
- DeltaTree();
-
- // Note: Currently we only support copying when the RHS is empty.
- DeltaTree(const DeltaTree &RHS);
- ~DeltaTree();
-
- /// getDeltaAt - Return the accumulated delta at the specified file offset.
- /// This includes all insertions or delections that occurred *before* the
- /// specified file index.
- int getDeltaAt(unsigned FileIndex) const;
-
- /// AddDelta - When a change is made that shifts around the text buffer,
- /// this method is used to record that info. It inserts a delta of 'Delta'
- /// into the current DeltaTree at offset FileIndex.
- void AddDelta(unsigned FileIndex, int Delta);
- };
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Rewrite/HTMLRewrite.h b/clang/include/clang/Rewrite/HTMLRewrite.h
deleted file mode 100644
index bbb7f3490bd4..000000000000
--- a/clang/include/clang/Rewrite/HTMLRewrite.h
+++ /dev/null
@@ -1,90 +0,0 @@
-//==- HTMLRewrite.h - Translate source code into prettified HTML ---*- 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 a set of functions used for translating source code
-// into beautified HTML.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_HTMLREWRITER_H
-#define LLVM_CLANG_HTMLREWRITER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include <string>
-
-namespace clang {
-
-class Rewriter;
-class RewriteBuffer;
-class Preprocessor;
-class PreprocessorFactory;
-
-namespace html {
-
- /// HighlightRange - Highlight a range in the source code with the specified
- /// start/end tags. B/E must be in the same file. This ensures that
- /// start/end tags are placed at the start/end of each line if the range is
- /// multiline.
- void HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
- const char *StartTag, const char *EndTag);
-
- /// HighlightRange - Highlight a range in the source code with the specified
- /// start/end tags. The Start/end of the range must be in the same file.
- /// This ensures that start/end tags are placed at the start/end of each line
- /// if the range is multiline.
- inline void HighlightRange(Rewriter &R, SourceRange Range,
- const char *StartTag, const char *EndTag) {
- HighlightRange(R, Range.getBegin(), Range.getEnd(), StartTag, EndTag);
- }
-
- /// HighlightRange - This is the same as the above method, but takes
- /// decomposed file locations.
- void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
- const char *BufferStart,
- const char *StartTag, const char *EndTag);
-
- /// EscapeText - HTMLize a specified file so that special characters are
- /// are translated so that they are not interpreted as HTML tags.
- void EscapeText(Rewriter& R, unsigned FileID,
- bool EscapeSpaces = false, bool ReplacesTabs = true);
-
- /// EscapeText - HTMLized the provided string so that special characters
- /// in 's' are not interpreted as HTML tags. Unlike the version of
- /// EscapeText that rewrites a file, this version by default replaces tabs
- /// with spaces.
- std::string EscapeText(const std::string& s,
- bool EscapeSpaces = false, bool ReplaceTabs = true);
-
- void AddLineNumbers(Rewriter& R, unsigned FileID);
-
- void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID,
- const char *title = NULL);
-
- /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
- /// information about keywords, comments, etc.
- void SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP);
-
- /// HighlightMacros - This uses the macro table state from the end of the
- /// file, to reexpand macros and insert (into the HTML) information about the
- /// macro expansions. This won't be perfectly perfect, but it will be
- /// reasonably close.
- void HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor &PP);
-
-
- void HighlightMacros(Rewriter &R, unsigned FileID, PreprocessorFactory &PPF);
-
-
-
-
-
-
-} // end html namespace
-} // end clang namespace
-
-#endif
diff --git a/clang/include/clang/Rewrite/RewriteRope.h b/clang/include/clang/Rewrite/RewriteRope.h
deleted file mode 100644
index 7faa451290e4..000000000000
--- a/clang/include/clang/Rewrite/RewriteRope.h
+++ /dev/null
@@ -1,230 +0,0 @@
-//===--- RewriteRope.h - Rope specialized for rewriter ----------*- 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 RewriteRope class, which is a powerful string class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITEROPE_H
-#define LLVM_CLANG_REWRITEROPE_H
-
-#include "llvm/ADT/iterator.h"
-#include <cstring>
-#include <cassert>
-
-namespace clang {
- //===--------------------------------------------------------------------===//
- // RopeRefCountString Class
- //===--------------------------------------------------------------------===//
-
- /// RopeRefCountString - This struct is allocated with 'new char[]' from the
- /// heap, and represents a reference counted chunk of string data. When its
- /// ref count drops to zero, it is delete[]'d. This is primarily managed
- /// through the RopePiece class below.
- struct RopeRefCountString {
- unsigned RefCount;
- char Data[1]; // Variable sized.
-
- void addRef() {
- if (this) ++RefCount;
- }
-
- void dropRef() {
- if (this && --RefCount == 0)
- delete [] (char*)this;
- }
- };
-
- //===--------------------------------------------------------------------===//
- // RopePiece Class
- //===--------------------------------------------------------------------===//
-
- /// RopePiece - This class represents a view into a RopeRefCountString object.
- /// This allows references to string data to be efficiently chopped up and
- /// moved around without having to push around the string data itself.
- ///
- /// For example, we could have a 1M RopePiece and want to insert something
- /// into the middle of it. To do this, we split it into two RopePiece objects
- /// that both refer to the same underlying RopeRefCountString (just with
- /// different offsets) which is a nice constant time operation.
- struct RopePiece {
- RopeRefCountString *StrData;
- unsigned StartOffs;
- unsigned EndOffs;
-
- RopePiece() : StrData(0), StartOffs(0), EndOffs(0) {}
-
- RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
- : StrData(Str), StartOffs(Start), EndOffs(End) {
- StrData->addRef();
- }
- RopePiece(const RopePiece &RP)
- : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
- StrData->addRef();
- }
-
- ~RopePiece() {
- StrData->dropRef();
- }
-
- void operator=(const RopePiece &RHS) {
- if (StrData != RHS.StrData) {
- StrData->dropRef();
- StrData = RHS.StrData;
- StrData->addRef();
- }
- StartOffs = RHS.StartOffs;
- EndOffs = RHS.EndOffs;
- }
-
- const char &operator[](unsigned Offset) const {
- return StrData->Data[Offset+StartOffs];
- }
- char &operator[](unsigned Offset) {
- return StrData->Data[Offset+StartOffs];
- }
-
- unsigned size() const { return EndOffs-StartOffs; }
- };
-
- //===--------------------------------------------------------------------===//
- // RopePieceBTreeIterator Class
- //===--------------------------------------------------------------------===//
-
- /// RopePieceBTreeIterator - This class provides read-only forward iteration
- /// over bytes that are in a RopePieceBTree. This first iterates over bytes
- /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
- /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
- class RopePieceBTreeIterator :
- public forward_iterator<const char, ptrdiff_t> {
- /// CurNode - The current B+Tree node that we are inspecting.
- const void /*RopePieceBTreeLeaf*/ *CurNode;
- /// CurPiece - The current RopePiece in the B+Tree node that we're
- /// inspecting.
- const RopePiece *CurPiece;
- /// CurChar - The current byte in the RopePiece we are pointing to.
- unsigned CurChar;
- public:
- // begin iterator.
- RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
- // end iterator
- RopePieceBTreeIterator() : CurNode(0), CurPiece(0), CurChar(0) {}
-
- char operator*() const {
- return (*CurPiece)[CurChar];
- }
-
- bool operator==(const RopePieceBTreeIterator &RHS) const {
- return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
- }
- bool operator!=(const RopePieceBTreeIterator &RHS) const {
- return !operator==(RHS);
- }
-
- RopePieceBTreeIterator& operator++() { // Preincrement
- if (CurChar+1 < CurPiece->size())
- ++CurChar;
- else
- MoveToNextPiece();
- return *this;
- }
- inline RopePieceBTreeIterator operator++(int) { // Postincrement
- RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
- }
- private:
- void MoveToNextPiece();
- };
-
- //===--------------------------------------------------------------------===//
- // RopePieceBTree Class
- //===--------------------------------------------------------------------===//
-
- class RopePieceBTree {
- void /*RopePieceBTreeNode*/ *Root;
- void operator=(const RopePieceBTree &); // DO NOT IMPLEMENT
- public:
- RopePieceBTree();
- RopePieceBTree(const RopePieceBTree &RHS);
- ~RopePieceBTree();
-
- typedef RopePieceBTreeIterator iterator;
- iterator begin() const { return iterator(Root); }
- iterator end() const { return iterator(); }
- unsigned size() const;
- unsigned empty() const { return size() == 0; }
-
- void clear();
-
- void insert(unsigned Offset, const RopePiece &R);
-
- void erase(unsigned Offset, unsigned NumBytes);
- };
-
- //===--------------------------------------------------------------------===//
- // RewriteRope Class
- //===--------------------------------------------------------------------===//
-
-/// RewriteRope - A powerful string class. This class supports extremely
-/// efficient insertions and deletions into the middle of it, even for
-/// ridiculously long strings.
-class RewriteRope {
- RopePieceBTree Chunks;
-
- /// We allocate space for string data out of a buffer of size AllocChunkSize.
- /// This keeps track of how much space is left.
- RopeRefCountString *AllocBuffer;
- unsigned AllocOffs;
- enum { AllocChunkSize = 4080 };
-
-public:
- RewriteRope() : AllocBuffer(0), AllocOffs(AllocChunkSize) {}
- RewriteRope(const RewriteRope &RHS)
- : Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
- }
-
- ~RewriteRope() {
- // If we had an allocation buffer, drop our reference to it.
- AllocBuffer->dropRef();
- }
-
- typedef RopePieceBTree::iterator iterator;
- typedef RopePieceBTree::iterator const_iterator;
- iterator begin() const { return Chunks.begin(); }
- iterator end() const { return Chunks.end(); }
- unsigned size() const { return Chunks.size(); }
-
- void clear() {
- Chunks.clear();
- }
-
- void assign(const char *Start, const char *End) {
- clear();
- if (Start != End)
- Chunks.insert(0, MakeRopeString(Start, End));
- }
-
- void insert(unsigned Offset, const char *Start, const char *End) {
- assert(Offset <= size() && "Invalid position to insert!");
- if (Start == End) return;
- Chunks.insert(Offset, MakeRopeString(Start, End));
- }
-
- void erase(unsigned Offset, unsigned NumBytes) {
- assert(Offset+NumBytes <= size() && "Invalid region to erase!");
- if (NumBytes == 0) return;
- Chunks.erase(Offset, NumBytes);
- }
-
-private:
- RopePiece MakeRopeString(const char *Start, const char *End);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Rewrite/Rewriter.h b/clang/include/clang/Rewrite/Rewriter.h
deleted file mode 100644
index 59ed5d826b41..000000000000
--- a/clang/include/clang/Rewrite/Rewriter.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===--- Rewriter.h - Code rewriting interface ------------------*- 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 Rewriter class, which is used for code
-// transformations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_REWRITER_H
-#define LLVM_CLANG_REWRITER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Rewrite/RewriteRope.h"
-#include <map>
-#include <vector>
-#include <cstring>
-#include <string>
-#include "clang/Rewrite/DeltaTree.h"
-
-namespace clang {
- class SourceManager;
- class Rewriter;
- class Stmt;
-
-/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
-/// input with modifications get a new RewriteBuffer associated with them. The
-/// RewriteBuffer captures the modified text itself as well as information used
-/// to map between SourceLocation's in the original input and offsets in the
-/// RewriteBuffer. For example, if text is inserted into the buffer, any
-/// locations after the insertion point have to be mapped.
-class RewriteBuffer {
- friend class Rewriter;
- /// Deltas - Keep track of all the deltas in the source code due to insertions
- /// and deletions.
- DeltaTree Deltas;
-
- /// Buffer - This is the actual buffer itself. Note that using a vector or
- /// string is a horribly inefficient way to do this, we should use a rope
- /// instead.
- typedef RewriteRope BufferTy;
- BufferTy Buffer;
-public:
- typedef BufferTy::const_iterator iterator;
- iterator begin() const { return Buffer.begin(); }
- iterator end() const { return Buffer.end(); }
- unsigned size() const { return Buffer.size(); }
-
- /// RemoveText - Remove the specified text.
- void RemoveText(unsigned OrigOffset, unsigned Size);
-
- /// InsertText - Insert some text at the specified point, where the offset in
- /// the buffer is specified relative to the original SourceBuffer. The
- /// text is inserted after the specified location.
- ///
- void InsertText(unsigned OrigOffset, const char *StrData, unsigned StrLen,
- bool InsertAfter = true);
-
-
- /// InsertTextBefore - Insert some text before the specified point,
- /// where the offset in the buffer is specified relative to the original
- /// SourceBuffer.
- ///
- void InsertTextBefore(unsigned OrigOffset, const char *StrData,
- unsigned StrLen) {
- InsertText(OrigOffset, StrData, StrLen, false);
- }
-
- /// InsertText - Insert some text at the specified point, where the offset in
- /// the buffer is specified relative to the original SourceBuffer. The
- /// text is inserted after the specified location. This is method is the
- /// same as InsertText with "InsertAfter == false".
- void InsertTextAfter(unsigned OrigOffset, const char *StrData,
- unsigned StrLen) {
- InsertText(OrigOffset, StrData, StrLen);
- }
-
- /// ReplaceText - This method replaces a range of characters in the input
- /// buffer with a new string. This is effectively a combined "remove/insert"
- /// operation.
- void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
- const char *NewStr, unsigned NewLength);
-
-private: // Methods only usable by Rewriter.
-
- /// Initialize - Start this rewrite buffer out with a copy of the unmodified
- /// input buffer.
- void Initialize(const char *BufStart, const char *BufEnd) {
- Buffer.assign(BufStart, BufEnd);
- }
-
- /// getMappedOffset - Given an offset into the original SourceBuffer that this
- /// RewriteBuffer is based on, map it into the offset space of the
- /// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a
- /// position where text is inserted, the location returned will be after any
- /// inserted text at the position.
- unsigned getMappedOffset(unsigned OrigOffset,
- bool AfterInserts = false) const{
- return Deltas.getDeltaAt(OrigOffset+AfterInserts)+OrigOffset;
- }
-
- /// AddDelta - When a change is made that shifts around the text buffer, this
- /// method is used to record that info.
- void AddDelta(unsigned OrigOffset, int Change) {
- return Deltas.AddDelta(OrigOffset, Change);
- }
-};
-
-
-/// Rewriter - This is the main interface to the rewrite buffers. Its primary
-/// job is to dispatch high-level requests to the low-level RewriteBuffers that
-/// are involved.
-class Rewriter {
- SourceManager *SourceMgr;
-
- std::map<unsigned, RewriteBuffer> RewriteBuffers;
-public:
- explicit Rewriter(SourceManager &SM) : SourceMgr(&SM) {}
- explicit Rewriter() : SourceMgr(0) {}
-
- void setSourceMgr(SourceManager &SM) { SourceMgr = &SM; }
- SourceManager& getSourceMgr() { return *SourceMgr; }
-
- /// isRewritable - Return true if this location is a raw file location, which
- /// is rewritable. Locations from macros, etc are not rewritable.
- static bool isRewritable(SourceLocation Loc) {
- return Loc.isFileID();
- }
-
- /// getRangeSize - Return the size in bytes of the specified range if they
- /// are in the same file. If not, this returns -1.
- int getRangeSize(SourceRange Range) const;
-
- /// getRewritenText - Return the rewritten form of the text in the specified
- /// range. If the start or end of the range was unrewritable or if they are
- /// in different buffers, this returns an empty string.
- ///
- /// Note that this method is not particularly efficient.
- ///
- std::string getRewritenText(SourceRange Range) const;
-
- /// InsertText - Insert the specified string at the specified location in the
- /// original buffer. This method returns true (and does nothing) if the input
- /// location was not rewritable, false otherwise.
- bool InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen,
- bool InsertAfter = true);
-
- /// InsertTextAfter - Insert the specified string at the specified location in
- /// the original buffer. This method returns true (and does nothing) if
- /// the input location was not rewritable, false otherwise. Text is
- /// inserted after any other text that has been previously inserted
- /// at the some point (the default behavior for InsertText).
- bool InsertTextAfter(SourceLocation Loc, const char *StrData,
- unsigned StrLen) {
- return InsertText(Loc, StrData, StrLen);
- }
-
- /// InsertText - Insert the specified string at the specified location in the
- /// original buffer. This method returns true (and does nothing) if the input
- /// location was not rewritable, false otherwise. Text is
- /// inserted before any other text that has been previously inserted
- /// at the some point.
- bool InsertTextBefore(SourceLocation Loc, const char *StrData,
- unsigned StrLen) {
- return InsertText(Loc, StrData, StrLen, false);
- }
-
-
- bool InsertCStrBefore(SourceLocation Loc, const char* Str) {
- return InsertTextBefore(Loc, Str, strlen(Str));
- }
-
-
- bool InsertCStrAfter(SourceLocation Loc, const char* Str) {
- return InsertTextAfter(Loc, Str, strlen(Str));
- }
-
- bool InsertStrBefore(SourceLocation Loc, const std::string& S) {
- return S.empty() ? false : InsertTextBefore(Loc, &S[0], S.size());
- }
-
- bool InsertStrAfter(SourceLocation Loc, const std::string& S) {
- return S.empty() ? false : InsertTextAfter(Loc, &S[0], S.size());
- }
-
-
- /// RemoveText - Remove the specified text region.
- bool RemoveText(SourceLocation Start, unsigned Length);
-
- /// ReplaceText - This method replaces a range of characters in the input
- /// buffer with a new string. This is effectively a combined "remove/insert"
- /// operation.
- bool ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength);
-
- /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
- /// printer to generate the replacement code. This returns true if the input
- /// could not be rewritten, or false if successful.
- bool ReplaceStmt(Stmt *From, Stmt *To);
-
- /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
- /// If no modification has been made to it, return null.
- const RewriteBuffer *getRewriteBufferFor(unsigned FileID) const {
- std::map<unsigned, RewriteBuffer>::const_iterator I =
- RewriteBuffers.find(FileID);
- return I == RewriteBuffers.end() ? 0 : &I->second;
- }
-
- /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
- /// buffer, and allows you to write on it directly. This is useful if you
- /// want efficient low-level access to apis for scribbling on one specific
- /// FileID's buffer.
- RewriteBuffer &getEditBuffer(unsigned FileID);
-
-private:
- unsigned getLocationOffsetAndFileID(SourceLocation Loc,
- unsigned &FileID) const;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Sema/ParseAST.h b/clang/include/clang/Sema/ParseAST.h
deleted file mode 100644
index 907372ddef4d..000000000000
--- a/clang/include/clang/Sema/ParseAST.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- ParseAST.h - Define the ParseAST method ----------------*- 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 clang::ParseAST method.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_PARSEAST_H
-#define LLVM_CLANG_SEMA_PARSEAST_H
-
-namespace clang {
- class Preprocessor;
- class ASTConsumer;
-
- /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
- /// the file is parsed. This takes ownership of the ASTConsumer and
- /// ultimately deletes it.
- void ParseAST(Preprocessor &pp, ASTConsumer *C, bool PrintStats = false);
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/AST/ASTConsumer.cpp b/clang/lib/AST/ASTConsumer.cpp
deleted file mode 100644
index bf6a0cb76137..000000000000
--- a/clang/lib/AST/ASTConsumer.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===--- ASTConsumer.cpp - Abstract interface for reading ASTs --*- 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 ASTConsumer class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/TranslationUnit.h"
-
-using namespace clang;
-
-ASTConsumer::~ASTConsumer() {}
-
-void ASTConsumer::InitializeTU(TranslationUnit& TU) {
- Initialize(TU.getContext());
-}
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
deleted file mode 100644
index fc24f5fe3109..000000000000
--- a/clang/lib/AST/ASTContext.cpp
+++ /dev/null
@@ -1,2191 +0,0 @@
-//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the ASTContext interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using namespace clang;
-
-enum FloatingRank {
- FloatRank, DoubleRank, LongDoubleRank
-};
-
-ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
- TargetInfo &t,
- IdentifierTable &idents, SelectorTable &sels,
- unsigned size_reserve) :
- CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0),
- SourceMgr(SM), LangOpts(LOpts), Target(t),
- Idents(idents), Selectors(sels)
-{
- if (size_reserve > 0) Types.reserve(size_reserve);
- InitBuiltinTypes();
- BuiltinInfo.InitializeBuiltins(idents, Target);
- TUDecl = TranslationUnitDecl::Create(*this);
-}
-
-ASTContext::~ASTContext() {
- // Deallocate all the types.
- while (!Types.empty()) {
- Types.back()->Destroy(*this);
- Types.pop_back();
- }
-
- TUDecl->Destroy(*this);
-}
-
-void ASTContext::PrintStats() const {
- fprintf(stderr, "*** AST Context Stats:\n");
- fprintf(stderr, " %d types total.\n", (int)Types.size());
- unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
- unsigned NumVector = 0, NumComplex = 0, NumBlockPointer = 0;
- unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
-
- unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
- unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0;
- unsigned NumObjCQualifiedIds = 0;
- unsigned NumTypeOfTypes = 0, NumTypeOfExprs = 0;
-
- for (unsigned i = 0, e = Types.size(); i != e; ++i) {
- Type *T = Types[i];
- if (isa<BuiltinType>(T))
- ++NumBuiltin;
- else if (isa<PointerType>(T))
- ++NumPointer;
- else if (isa<BlockPointerType>(T))
- ++NumBlockPointer;
- else if (isa<ReferenceType>(T))
- ++NumReference;
- else if (isa<ComplexType>(T))
- ++NumComplex;
- else if (isa<ArrayType>(T))
- ++NumArray;
- else if (isa<VectorType>(T))
- ++NumVector;
- else if (isa<FunctionTypeNoProto>(T))
- ++NumFunctionNP;
- else if (isa<FunctionTypeProto>(T))
- ++NumFunctionP;
- else if (isa<TypedefType>(T))
- ++NumTypeName;
- else if (TagType *TT = dyn_cast<TagType>(T)) {
- ++NumTagged;
- switch (TT->getDecl()->getTagKind()) {
- default: assert(0 && "Unknown tagged type!");
- case TagDecl::TK_struct: ++NumTagStruct; break;
- case TagDecl::TK_union: ++NumTagUnion; break;
- case TagDecl::TK_class: ++NumTagClass; break;
- case TagDecl::TK_enum: ++NumTagEnum; break;
- }
- } else if (isa<ObjCInterfaceType>(T))
- ++NumObjCInterfaces;
- else if (isa<ObjCQualifiedInterfaceType>(T))
- ++NumObjCQualifiedInterfaces;
- else if (isa<ObjCQualifiedIdType>(T))
- ++NumObjCQualifiedIds;
- else if (isa<TypeOfType>(T))
- ++NumTypeOfTypes;
- else if (isa<TypeOfExpr>(T))
- ++NumTypeOfExprs;
- else {
- QualType(T, 0).dump();
- assert(0 && "Unknown type!");
- }
- }
-
- fprintf(stderr, " %d builtin types\n", NumBuiltin);
- fprintf(stderr, " %d pointer types\n", NumPointer);
- fprintf(stderr, " %d block pointer types\n", NumBlockPointer);
- fprintf(stderr, " %d reference types\n", NumReference);
- fprintf(stderr, " %d complex types\n", NumComplex);
- fprintf(stderr, " %d array types\n", NumArray);
- fprintf(stderr, " %d vector types\n", NumVector);
- fprintf(stderr, " %d function types with proto\n", NumFunctionP);
- fprintf(stderr, " %d function types with no proto\n", NumFunctionNP);
- fprintf(stderr, " %d typename (typedef) types\n", NumTypeName);
- fprintf(stderr, " %d tagged types\n", NumTagged);
- fprintf(stderr, " %d struct types\n", NumTagStruct);
- fprintf(stderr, " %d union types\n", NumTagUnion);
- fprintf(stderr, " %d class types\n", NumTagClass);
- fprintf(stderr, " %d enum types\n", NumTagEnum);
- fprintf(stderr, " %d interface types\n", NumObjCInterfaces);
- fprintf(stderr, " %d protocol qualified interface types\n",
- NumObjCQualifiedInterfaces);
- fprintf(stderr, " %d protocol qualified id types\n",
- NumObjCQualifiedIds);
- fprintf(stderr, " %d typeof types\n", NumTypeOfTypes);
- fprintf(stderr, " %d typeof exprs\n", NumTypeOfExprs);
-
- fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
- NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
- NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
- NumFunctionP*sizeof(FunctionTypeProto)+
- NumFunctionNP*sizeof(FunctionTypeNoProto)+
- NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+
- NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprs*sizeof(TypeOfExpr)));
-}
-
-
-void ASTContext::InitBuiltinType(QualType &R, BuiltinType::Kind K) {
- Types.push_back((R = QualType(new BuiltinType(K),0)).getTypePtr());
-}
-
-void ASTContext::InitBuiltinTypes() {
- assert(VoidTy.isNull() && "Context reinitialized?");
-
- // C99 6.2.5p19.
- InitBuiltinType(VoidTy, BuiltinType::Void);
-
- // C99 6.2.5p2.
- InitBuiltinType(BoolTy, BuiltinType::Bool);
- // C99 6.2.5p3.
- if (Target.isCharSigned())
- InitBuiltinType(CharTy, BuiltinType::Char_S);
- else
- InitBuiltinType(CharTy, BuiltinType::Char_U);
- // C99 6.2.5p4.
- InitBuiltinType(SignedCharTy, BuiltinType::SChar);
- InitBuiltinType(ShortTy, BuiltinType::Short);
- InitBuiltinType(IntTy, BuiltinType::Int);
- InitBuiltinType(LongTy, BuiltinType::Long);
- InitBuiltinType(LongLongTy, BuiltinType::LongLong);
-
- // C99 6.2.5p6.
- InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
- InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
- InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
- InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
- InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
-
- // C99 6.2.5p10.
- InitBuiltinType(FloatTy, BuiltinType::Float);
- InitBuiltinType(DoubleTy, BuiltinType::Double);
- InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
-
- // C++ 3.9.1p5
- InitBuiltinType(WCharTy, BuiltinType::WChar);
-
- // C99 6.2.5p11.
- FloatComplexTy = getComplexType(FloatTy);
- DoubleComplexTy = getComplexType(DoubleTy);
- LongDoubleComplexTy = getComplexType(LongDoubleTy);
-
- BuiltinVaListType = QualType();
- ObjCIdType = QualType();
- IdStructType = 0;
- ObjCClassType = QualType();
- ClassStructType = 0;
-
- ObjCConstantStringType = QualType();
-
- // void * type
- VoidPtrTy = getPointerType(VoidTy);
-}
-
-//===----------------------------------------------------------------------===//
-// Type Sizing and Analysis
-//===----------------------------------------------------------------------===//
-
-/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
-/// scalar floating point type.
-const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
- const BuiltinType *BT = T->getAsBuiltinType();
- assert(BT && "Not a floating point type!");
- switch (BT->getKind()) {
- default: assert(0 && "Not a floating point type!");
- case BuiltinType::Float: return Target.getFloatFormat();
- case BuiltinType::Double: return Target.getDoubleFormat();
- case BuiltinType::LongDouble: return Target.getLongDoubleFormat();
- }
-}
-
-
-/// getTypeSize - Return the size of the specified type, in bits. This method
-/// does not work on incomplete types.
-std::pair<uint64_t, unsigned>
-ASTContext::getTypeInfo(QualType T) {
- T = getCanonicalType(T);
- uint64_t Width;
- unsigned Align;
- switch (T->getTypeClass()) {
- case Type::TypeName: assert(0 && "Not a canonical type!");
- case Type::FunctionNoProto:
- case Type::FunctionProto:
- default:
- assert(0 && "Incomplete types have no size!");
- case Type::VariableArray:
- assert(0 && "VLAs not implemented yet!");
- case Type::ConstantArray: {
- ConstantArrayType *CAT = cast<ConstantArrayType>(T);
-
- std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
- Width = EltInfo.first*CAT->getSize().getZExtValue();
- Align = EltInfo.second;
- break;
- }
- case Type::ExtVector:
- case Type::Vector: {
- std::pair<uint64_t, unsigned> EltInfo =
- getTypeInfo(cast<VectorType>(T)->getElementType());
- Width = EltInfo.first*cast<VectorType>(T)->getNumElements();
- // FIXME: This isn't right for unusual vectors
- Align = Width;
- break;
- }
-
- case Type::Builtin:
- switch (cast<BuiltinType>(T)->getKind()) {
- default: assert(0 && "Unknown builtin type!");
- case BuiltinType::Void:
- assert(0 && "Incomplete types have no size!");
- case BuiltinType::Bool:
- Width = Target.getBoolWidth();
- Align = Target.getBoolAlign();
- break;
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::UChar:
- case BuiltinType::SChar:
- Width = Target.getCharWidth();
- Align = Target.getCharAlign();
- break;
- case BuiltinType::WChar:
- Width = Target.getWCharWidth();
- Align = Target.getWCharAlign();
- break;
- case BuiltinType::UShort:
- case BuiltinType::Short:
- Width = Target.getShortWidth();
- Align = Target.getShortAlign();
- break;
- case BuiltinType::UInt:
- case BuiltinType::Int:
- Width = Target.getIntWidth();
- Align = Target.getIntAlign();
- break;
- case BuiltinType::ULong:
- case BuiltinType::Long:
- Width = Target.getLongWidth();
- Align = Target.getLongAlign();
- break;
- case BuiltinType::ULongLong:
- case BuiltinType::LongLong:
- Width = Target.getLongLongWidth();
- Align = Target.getLongLongAlign();
- break;
- case BuiltinType::Float:
- Width = Target.getFloatWidth();
- Align = Target.getFloatAlign();
- break;
- case BuiltinType::Double:
- Width = Target.getDoubleWidth();
- Align = Target.getDoubleAlign();
- break;
- case BuiltinType::LongDouble:
- Width = Target.getLongDoubleWidth();
- Align = Target.getLongDoubleAlign();
- break;
- }
- break;
- case Type::ASQual:
- // FIXME: Pointers into different addr spaces could have different sizes and
- // alignment requirements: getPointerInfo should take an AddrSpace.
- return getTypeInfo(QualType(cast<ASQualType>(T)->getBaseType(), 0));
- case Type::ObjCQualifiedId:
- Width = Target.getPointerWidth(0);
- Align = Target.getPointerAlign(0);
- break;
- case Type::BlockPointer: {
- unsigned AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace();
- Width = Target.getPointerWidth(AS);
- Align = Target.getPointerAlign(AS);
- break;
- }
- case Type::Pointer: {
- unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
- Width = Target.getPointerWidth(AS);
- Align = Target.getPointerAlign(AS);
- break;
- }
- case Type::Reference:
- // "When applied to a reference or a reference type, the result is the size
- // of the referenced type." C++98 5.3.3p2: expr.sizeof.
- // FIXME: This is wrong for struct layout: a reference in a struct has
- // pointer size.
- return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
-
- case Type::Complex: {
- // Complex types have the same alignment as their elements, but twice the
- // size.
- std::pair<uint64_t, unsigned> EltInfo =
- getTypeInfo(cast<ComplexType>(T)->getElementType());
- Width = EltInfo.first*2;
- Align = EltInfo.second;
- break;
- }
- case Type::ObjCInterface: {
- ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
- const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
- Width = Layout.getSize();
- Align = Layout.getAlignment();
- break;
- }
- case Type::Tagged: {
- if (cast<TagType>(T)->getDecl()->isInvalidDecl()) {
- Width = 1;
- Align = 1;
- break;
- }
-
- if (EnumType *ET = dyn_cast<EnumType>(cast<TagType>(T)))
- return getTypeInfo(ET->getDecl()->getIntegerType());
-
- RecordType *RT = cast<RecordType>(T);
- const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl());
- Width = Layout.getSize();
- Align = Layout.getAlignment();
- break;
- }
- }
-
- assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
- return std::make_pair(Width, Align);
-}
-
-/// LayoutField - Field layout.
-void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
- bool IsUnion, bool StructIsPacked,
- ASTContext &Context) {
- bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
- uint64_t FieldOffset = IsUnion ? 0 : Size;
- uint64_t FieldSize;
- unsigned FieldAlign;
-
- if (const Expr *BitWidthExpr = FD->getBitWidth()) {
- // TODO: Need to check this algorithm on other targets!
- // (tested on Linux-X86)
- FieldSize =
- BitWidthExpr->getIntegerConstantExprValue(Context).getZExtValue();
-
- std::pair<uint64_t, unsigned> FieldInfo =
- Context.getTypeInfo(FD->getType());
- uint64_t TypeSize = FieldInfo.first;
-
- FieldAlign = FieldInfo.second;
- if (FieldIsPacked)
- FieldAlign = 1;
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
-
- // Check if we need to add padding to give the field the correct
- // alignment.
- if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
-
- // Padding members don't affect overall alignment
- if (!FD->getIdentifier())
- FieldAlign = 1;
- } else {
- if (FD->getType()->isIncompleteArrayType()) {
- // This is a flexible array member; we can't directly
- // query getTypeInfo about these, so we figure it out here.
- // Flexible array members don't have any size, but they
- // have to be aligned appropriately for their element type.
- FieldSize = 0;
- const ArrayType* ATy = Context.getAsArrayType(FD->getType());
- FieldAlign = Context.getTypeAlign(ATy->getElementType());
- } else {
- std::pair<uint64_t, unsigned> FieldInfo =
- Context.getTypeInfo(FD->getType());
- FieldSize = FieldInfo.first;
- FieldAlign = FieldInfo.second;
- }
-
- if (FieldIsPacked)
- FieldAlign = 8;
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
-
- // Round up the current record size to the field's alignment boundary.
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
- }
-
- // Place this field at the current location.
- FieldOffsets[FieldNo] = FieldOffset;
-
- // Reserve space for this field.
- if (IsUnion) {
- Size = std::max(Size, FieldSize);
- } else {
- Size = FieldOffset + FieldSize;
- }
-
- // Remember max struct/class alignment.
- Alignment = std::max(Alignment, FieldAlign);
-}
-
-
-/// getASTObjcInterfaceLayout - Get or compute information about the layout of
-/// the specified Objective C, which indicates its size and ivar
-/// position information.
-const ASTRecordLayout &
-ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) {
- // Look up this layout, if already laid out, return what we have.
- const ASTRecordLayout *&Entry = ASTObjCInterfaces[D];
- if (Entry) return *Entry;
-
- // Allocate and assign into ASTRecordLayouts here. The "Entry" reference can
- // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
- ASTRecordLayout *NewEntry = NULL;
- unsigned FieldCount = D->ivar_size();
- if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
- FieldCount++;
- const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD);
- unsigned Alignment = SL.getAlignment();
- uint64_t Size = SL.getSize();
- NewEntry = new ASTRecordLayout(Size, Alignment);
- NewEntry->InitializeLayout(FieldCount);
- // Super class is at the beginning of the layout.
- NewEntry->SetFieldOffset(0, 0);
- } else {
- NewEntry = new ASTRecordLayout();
- NewEntry->InitializeLayout(FieldCount);
- }
- Entry = NewEntry;
-
- bool IsPacked = D->getAttr<PackedAttr>();
-
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
- AA->getAlignment()));
-
- // Layout each ivar sequentially.
- unsigned i = 0;
- for (ObjCInterfaceDecl::ivar_iterator IVI = D->ivar_begin(),
- IVE = D->ivar_end(); IVI != IVE; ++IVI) {
- const ObjCIvarDecl* Ivar = (*IVI);
- NewEntry->LayoutField(Ivar, i++, false, IsPacked, *this);
- }
-
- // Finally, round the size of the total struct up to the alignment of the
- // struct itself.
- NewEntry->FinalizeLayout();
- return *NewEntry;
-}
-
-/// getASTRecordLayout - Get or compute information about the layout of the
-/// specified record (struct/union/class), which indicates its size and field
-/// position information.
-const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
- D = D->getDefinition(*this);
- assert(D && "Cannot get layout of forward declarations!");
-
- // Look up this layout, if already laid out, return what we have.
- const ASTRecordLayout *&Entry = ASTRecordLayouts[D];
- if (Entry) return *Entry;
-
- // Allocate and assign into ASTRecordLayouts here. The "Entry" reference can
- // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
- ASTRecordLayout *NewEntry = new ASTRecordLayout();
- Entry = NewEntry;
-
- NewEntry->InitializeLayout(D->getNumMembers());
- bool StructIsPacked = D->getAttr<PackedAttr>();
- bool IsUnion = D->isUnion();
-
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
- AA->getAlignment()));
-
- // Layout each field, for now, just sequentially, respecting alignment. In
- // the future, this will need to be tweakable by targets.
- for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
- const FieldDecl *FD = D->getMember(i);
- NewEntry->LayoutField(FD, i, IsUnion, StructIsPacked, *this);
- }
-
- // Finally, round the size of the total struct up to the alignment of the
- // struct itself.
- NewEntry->FinalizeLayout();
- return *NewEntry;
-}
-
-//===----------------------------------------------------------------------===//
-// Type creation/memoization methods
-//===----------------------------------------------------------------------===//
-
-QualType ASTContext::getASQualType(QualType T, unsigned AddressSpace) {
- QualType CanT = getCanonicalType(T);
- if (CanT.getAddressSpace() == AddressSpace)
- return T;
-
- // Type's cannot have multiple ASQuals, therefore we know we only have to deal
- // with CVR qualifiers from here on out.
- assert(CanT.getAddressSpace() == 0 &&
- "Type is already address space qualified");
-
- // Check if we've already instantiated an address space qual'd type of this
- // type.
- llvm::FoldingSetNodeID ID;
- ASQualType::Profile(ID, T.getTypePtr(), AddressSpace);
- void *InsertPos = 0;
- if (ASQualType *ASQy = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(ASQy, 0);
-
- // If the base type isn't canonical, this won't be a canonical type either,
- // so fill in the canonical type field.
- QualType Canonical;
- if (!T->isCanonical()) {
- Canonical = getASQualType(CanT, AddressSpace);
-
- // Get the new insert position for the node we care about.
- ASQualType *NewIP = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
- ASQualType *New = new ASQualType(T.getTypePtr(), Canonical, AddressSpace);
- ASQualTypes.InsertNode(New, InsertPos);
- Types.push_back(New);
- return QualType(New, T.getCVRQualifiers());
-}
-
-
-/// getComplexType - Return the uniqued reference to the type for a complex
-/// number with the specified element type.
-QualType ASTContext::getComplexType(QualType T) {
- // Unique pointers, to guarantee there is only one pointer of a particular
- // structure.
- llvm::FoldingSetNodeID ID;
- ComplexType::Profile(ID, T);
-
- void *InsertPos = 0;
- if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(CT, 0);
-
- // If the pointee type isn't canonical, this won't be a canonical type either,
- // so fill in the canonical type field.
- QualType Canonical;
- if (!T->isCanonical()) {
- Canonical = getComplexType(getCanonicalType(T));
-
- // Get the new insert position for the node we care about.
- ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
- ComplexType *New = new ComplexType(T, Canonical);
- Types.push_back(New);
- ComplexTypes.InsertNode(New, InsertPos);
- return QualType(New, 0);
-}
-
-
-/// getPointerType - Return the uniqued reference to the type for a pointer to
-/// the specified type.
-QualType ASTContext::getPointerType(QualType T) {
- // Unique pointers, to guarantee there is only one pointer of a particular
- // structure.
- llvm::FoldingSetNodeID ID;
- PointerType::Profile(ID, T);
-
- void *InsertPos = 0;
- if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(PT, 0);
-
- // If the pointee type isn't canonical, this won't be a canonical type either,
- // so fill in the canonical type field.
- QualType Canonical;
- if (!T->isCanonical()) {
- Canonical = getPointerType(getCanonicalType(T));
-
- // Get the new insert position for the node we care about.
- PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
- PointerType *New = new PointerType(T, Canonical);
- Types.push_back(New);
- PointerTypes.InsertNode(New, InsertPos);
- return QualType(New, 0);
-}
-
-/// getBlockPointerType - Return the uniqued reference to the type for
-/// a pointer to the specified block.
-QualType ASTContext::getBlockPointerType(QualType T) {
- assert(T->isFunctionType() && "block of function types only");
- // Unique pointers, to guarantee there is only one block of a particular
- // structure.
- llvm::FoldingSetNodeID ID;
- BlockPointerType::Profile(ID, T);
-
- void *InsertPos = 0;
- if (BlockPointerType *PT =
- BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(PT, 0);
-
- // If the block pointee type isn't canonical, this won't be a canonical
- // type either so fill in the canonical type field.
- QualType Canonical;
- if (!T->isCanonical()) {
- Canonical = getBlockPointerType(getCanonicalType(T));
-
- // Get the new insert position for the node we care about.
- BlockPointerType *NewIP =
- BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
- BlockPointerType *New = new BlockPointerType(T, Canonical);
- Types.push_back(New);
- BlockPointerTypes.InsertNode(New, InsertPos);
- return QualType(New, 0);
-}
-
-/// getReferenceType - Return the uniqued reference to the type for a reference
-/// to the specified type.
-QualType ASTContext::getReferenceType(QualType T) {
- // Unique pointers, to guarantee there is only one pointer of a particular
- // structure.
- llvm::FoldingSetNodeID ID;
- ReferenceType::Profile(ID, T);
-
- void *InsertPos = 0;
- if (ReferenceType *RT = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(RT, 0);
-
- // If the referencee type isn't canonical, this won't be a canonical type
- // either, so fill in the canonical type field.
- QualType Canonical;
- if (!T->isCanonical()) {
- Canonical = getReferenceType(getCanonicalType(T));
-
- // Get the new insert position for the node we care about.
- ReferenceType *NewIP = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
-
- ReferenceType *New = new ReferenceType(T, Canonical);
- Types.push_back(New);
- ReferenceTypes.InsertNode(New, InsertPos);
- return QualType(New, 0);
-}
-
-/// getConstantArrayType - Return the unique reference to the type for an
-/// array of the specified element type.
-QualType ASTContext::getConstantArrayType(QualType EltTy,
- const llvm::APInt &ArySize,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals) {
- llvm::FoldingSetNodeID ID;
- ConstantArrayType::Profile(ID, EltTy, ArySize);
-
- void *InsertPos = 0;
- if (ConstantArrayType *ATP =
- ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(ATP, 0);
-
- // If the element type isn't canonical, this won't be a canonical type either,
- // so fill in the canonical type field.
- QualType Canonical;
- if (!EltTy->isCanonical()) {
- Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize,
- ASM, EltTypeQuals);
- // Get the new insert position for the node we care about.
- ConstantArrayType *NewIP =
- ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
-
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
-
- ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize,
- ASM, EltTypeQuals);
- ConstantArrayTypes.InsertNode(New, InsertPos);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-/// getVariableArrayType - Returns a non-unique reference to the type for a
-/// variable array of the specified element type.
-QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals) {
- // Since we don't unique expressions, it isn't possible to unique VLA's
- // that have an expression provided for their size.
-
- VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
- ASM, EltTypeQuals);
-
- VariableArrayTypes.push_back(New);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-QualType ASTContext::getIncompleteArrayType(QualType EltTy,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals) {
- llvm::FoldingSetNodeID ID;
- IncompleteArrayType::Profile(ID, EltTy);
-
- void *InsertPos = 0;
- if (IncompleteArrayType *ATP =
- IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(ATP, 0);
-
- // If the element type isn't canonical, this won't be a canonical type
- // either, so fill in the canonical type field.
- QualType Canonical;
-
- if (!EltTy->isCanonical()) {
- Canonical = getIncompleteArrayType(getCanonicalType(EltTy),
- ASM, EltTypeQuals);
-
- // Get the new insert position for the node we care about.
- IncompleteArrayType *NewIP =
- IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
-
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
-
- IncompleteArrayType *New = new IncompleteArrayType(EltTy, Canonical,
- ASM, EltTypeQuals);
-
- IncompleteArrayTypes.InsertNode(New, InsertPos);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-/// getVectorType - Return the unique reference to a vector type of
-/// the specified element type and size. VectorType must be a built-in type.
-QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
- BuiltinType *baseType;
-
- baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
- assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
-
- // Check if we've already instantiated a vector of this type.
- llvm::FoldingSetNodeID ID;
- VectorType::Profile(ID, vecType, NumElts, Type::Vector);
- void *InsertPos = 0;
- if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(VTP, 0);
-
- // If the element type isn't canonical, this won't be a canonical type either,
- // so fill in the canonical type field.
- QualType Canonical;
- if (!vecType->isCanonical()) {
- Canonical = getVectorType(getCanonicalType(vecType), NumElts);
-
- // Get the new insert position for the node we care about.
- VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
- VectorType *New = new VectorType(vecType, NumElts, Canonical);
- VectorTypes.InsertNode(New, InsertPos);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-/// getExtVectorType - Return the unique reference to an extended vector type of
-/// the specified element type and size. VectorType must be a built-in type.
-QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
- BuiltinType *baseType;
-
- baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
- assert(baseType != 0 && "getExtVectorType(): Expecting a built-in type");
-
- // Check if we've already instantiated a vector of this type.
- llvm::FoldingSetNodeID ID;
- VectorType::Profile(ID, vecType, NumElts, Type::ExtVector);
- void *InsertPos = 0;
- if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(VTP, 0);
-
- // If the element type isn't canonical, this won't be a canonical type either,
- // so fill in the canonical type field.
- QualType Canonical;
- if (!vecType->isCanonical()) {
- Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);
-
- // Get the new insert position for the node we care about.
- VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
- ExtVectorType *New = new ExtVectorType(vecType, NumElts, Canonical);
- VectorTypes.InsertNode(New, InsertPos);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
-///
-QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {
- // Unique functions, to guarantee there is only one function of a particular
- // structure.
- llvm::FoldingSetNodeID ID;
- FunctionTypeNoProto::Profile(ID, ResultTy);
-
- void *InsertPos = 0;
- if (FunctionTypeNoProto *FT =
- FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(FT, 0);
-
- QualType Canonical;
- if (!ResultTy->isCanonical()) {
- Canonical = getFunctionTypeNoProto(getCanonicalType(ResultTy));
-
- // Get the new insert position for the node we care about.
- FunctionTypeNoProto *NewIP =
- FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
-
- FunctionTypeNoProto *New = new FunctionTypeNoProto(ResultTy, Canonical);
- Types.push_back(New);
- FunctionTypeNoProtos.InsertNode(New, InsertPos);
- return QualType(New, 0);
-}
-
-/// getFunctionType - Return a normal function type with a typed argument
-/// list. isVariadic indicates whether the argument list includes '...'.
-QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
- unsigned NumArgs, bool isVariadic) {
- // Unique functions, to guarantee there is only one function of a particular
- // structure.
- llvm::FoldingSetNodeID ID;
- FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
-
- void *InsertPos = 0;
- if (FunctionTypeProto *FTP =
- FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(FTP, 0);
-
- // Determine whether the type being created is already canonical or not.
- bool isCanonical = ResultTy->isCanonical();
- for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
- if (!ArgArray[i]->isCanonical())
- isCanonical = false;
-
- // If this type isn't canonical, get the canonical version of it.
- QualType Canonical;
- if (!isCanonical) {
- llvm::SmallVector<QualType, 16> CanonicalArgs;
- CanonicalArgs.reserve(NumArgs);
- for (unsigned i = 0; i != NumArgs; ++i)
- CanonicalArgs.push_back(getCanonicalType(ArgArray[i]));
-
- Canonical = getFunctionType(getCanonicalType(ResultTy),
- &CanonicalArgs[0], NumArgs,
- isVariadic);
-
- // Get the new insert position for the node we care about.
- FunctionTypeProto *NewIP =
- FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!");
- }
-
- // FunctionTypeProto objects are not allocated with new because they have a
- // variable size array (for parameter types) at the end of them.
- FunctionTypeProto *FTP =
- (FunctionTypeProto*)malloc(sizeof(FunctionTypeProto) +
- NumArgs*sizeof(QualType));
- new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
- Canonical);
- Types.push_back(FTP);
- FunctionTypeProtos.InsertNode(FTP, InsertPos);
- return QualType(FTP, 0);
-}
-
-/// getTypeDeclType - Return the unique reference to the type for the
-/// specified type declaration.
-QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) {
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
- if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(Decl))
- return getTypedefType(Typedef);
- else if (ObjCInterfaceDecl *ObjCInterface
- = dyn_cast_or_null<ObjCInterfaceDecl>(Decl))
- return getObjCInterfaceType(ObjCInterface);
-
- if (CXXRecordDecl *CXXRecord = dyn_cast_or_null<CXXRecordDecl>(Decl)) {
- Decl->TypeForDecl = PrevDecl ? PrevDecl->TypeForDecl
- : new CXXRecordType(CXXRecord);
- }
- else if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Decl)) {
- Decl->TypeForDecl = PrevDecl ? PrevDecl->TypeForDecl
- : new RecordType(Record);
- }
- else if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Decl))
- Decl->TypeForDecl = new EnumType(Enum);
- else
- assert(false && "TypeDecl without a type?");
-
- if (!PrevDecl) Types.push_back(Decl->TypeForDecl);
- return QualType(Decl->TypeForDecl, 0);
-}
-
-/// setTagDefinition - Used by RecordDecl::defineBody to inform ASTContext
-/// about which RecordDecl serves as the definition of a particular
-/// struct/union/class. This will eventually be used by enums as well.
-void ASTContext::setTagDefinition(TagDecl* D) {
- assert (D->isDefinition());
- cast<TagType>(D->TypeForDecl)->decl = D;
-}
-
-/// getTypedefType - Return the unique reference to the type for the
-/// specified typename decl.
-QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
- QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
- Decl->TypeForDecl = new TypedefType(Type::TypeName, Decl, Canonical);
- Types.push_back(Decl->TypeForDecl);
- return QualType(Decl->TypeForDecl, 0);
-}
-
-/// getObjCInterfaceType - Return the unique reference to the type for the
-/// specified ObjC interface decl.
-QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
- Decl->TypeForDecl = new ObjCInterfaceType(Type::ObjCInterface, Decl);
- Types.push_back(Decl->TypeForDecl);
- return QualType(Decl->TypeForDecl, 0);
-}
-
-/// CmpProtocolNames - Comparison predicate for sorting protocols
-/// alphabetically.
-static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
- const ObjCProtocolDecl *RHS) {
- return strcmp(LHS->getName(), RHS->getName()) < 0;
-}
-
-static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols,
- unsigned &NumProtocols) {
- ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols;
-
- // Sort protocols, keyed by name.
- std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames);
-
- // Remove duplicates.
- ProtocolsEnd = std::unique(Protocols, ProtocolsEnd);
- NumProtocols = ProtocolsEnd-Protocols;
-}
-
-
-/// getObjCQualifiedInterfaceType - Return a ObjCQualifiedInterfaceType type for
-/// the given interface decl and the conforming protocol list.
-QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **Protocols, unsigned NumProtocols) {
- // Sort the protocol list alphabetically to canonicalize it.
- SortAndUniqueProtocols(Protocols, NumProtocols);
-
- llvm::FoldingSetNodeID ID;
- ObjCQualifiedInterfaceType::Profile(ID, Decl, Protocols, NumProtocols);
-
- void *InsertPos = 0;
- if (ObjCQualifiedInterfaceType *QT =
- ObjCQualifiedInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(QT, 0);
-
- // No Match;
- ObjCQualifiedInterfaceType *QType =
- new ObjCQualifiedInterfaceType(Decl, Protocols, NumProtocols);
- Types.push_back(QType);
- ObjCQualifiedInterfaceTypes.InsertNode(QType, InsertPos);
- return QualType(QType, 0);
-}
-
-/// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for the 'id' decl
-/// and the conforming protocol list.
-QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,
- unsigned NumProtocols) {
- // Sort the protocol list alphabetically to canonicalize it.
- SortAndUniqueProtocols(Protocols, NumProtocols);
-
- llvm::FoldingSetNodeID ID;
- ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols);
-
- void *InsertPos = 0;
- if (ObjCQualifiedIdType *QT =
- ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(QT, 0);
-
- // No Match;
- ObjCQualifiedIdType *QType = new ObjCQualifiedIdType(Protocols, NumProtocols);
- Types.push_back(QType);
- ObjCQualifiedIdTypes.InsertNode(QType, InsertPos);
- return QualType(QType, 0);
-}
-
-/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
-/// TypeOfExpr AST's (since expression's are never shared). For example,
-/// multiple declarations that refer to "typeof(x)" all contain different
-/// DeclRefExpr's. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
-QualType ASTContext::getTypeOfExpr(Expr *tofExpr) {
- QualType Canonical = getCanonicalType(tofExpr->getType());
- TypeOfExpr *toe = new TypeOfExpr(tofExpr, Canonical);
- Types.push_back(toe);
- return QualType(toe, 0);
-}
-
-/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
-/// TypeOfType AST's. The only motivation to unique these nodes would be
-/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
-QualType ASTContext::getTypeOfType(QualType tofType) {
- QualType Canonical = getCanonicalType(tofType);
- TypeOfType *tot = new TypeOfType(tofType, Canonical);
- Types.push_back(tot);
- return QualType(tot, 0);
-}
-
-/// getTagDeclType - Return the unique reference to the type for the
-/// specified TagDecl (struct/union/class/enum) decl.
-QualType ASTContext::getTagDeclType(TagDecl *Decl) {
- assert (Decl);
- return getTypeDeclType(Decl);
-}
-
-/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
-/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
-/// needs to agree with the definition in <stddef.h>.
-QualType ASTContext::getSizeType() const {
- // On Darwin, size_t is defined as a "long unsigned int".
- // FIXME: should derive from "Target".
- return UnsignedLongTy;
-}
-
-/// getWCharType - Return the unique type for "wchar_t" (C99 7.17), the
-/// width of characters in wide strings, The value is target dependent and
-/// needs to agree with the definition in <stddef.h>.
-QualType ASTContext::getWCharType() const {
- if (LangOpts.CPlusPlus)
- return WCharTy;
-
- // On Darwin, wchar_t is defined as a "int".
- // FIXME: should derive from "Target".
- return IntTy;
-}
-
-/// getSignedWCharType - Return the type of "signed wchar_t".
-/// Used when in C++, as a GCC extension.
-QualType ASTContext::getSignedWCharType() const {
- // FIXME: derive from "Target" ?
- return WCharTy;
-}
-
-/// getUnsignedWCharType - Return the type of "unsigned wchar_t".
-/// Used when in C++, as a GCC extension.
-QualType ASTContext::getUnsignedWCharType() const {
- // FIXME: derive from "Target" ?
- return UnsignedIntTy;
-}
-
-/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
-/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
-QualType ASTContext::getPointerDiffType() const {
- // On Darwin, ptrdiff_t is defined as a "int". This seems like a bug...
- // FIXME: should derive from "Target".
- return IntTy;
-}
-
-//===----------------------------------------------------------------------===//
-// Type Operators
-//===----------------------------------------------------------------------===//
-
-/// getCanonicalType - Return the canonical (structural) type corresponding to
-/// the specified potentially non-canonical type. The non-canonical version
-/// of a type may have many "decorated" versions of types. Decorators can
-/// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
-/// to be free of any of these, allowing two canonical types to be compared
-/// for exact equality with a simple pointer comparison.
-QualType ASTContext::getCanonicalType(QualType T) {
- QualType CanType = T.getTypePtr()->getCanonicalTypeInternal();
-
- // If the result has type qualifiers, make sure to canonicalize them as well.
- unsigned TypeQuals = T.getCVRQualifiers() | CanType.getCVRQualifiers();
- if (TypeQuals == 0) return CanType;
-
- // If the type qualifiers are on an array type, get the canonical type of the
- // array with the qualifiers applied to the element type.
- ArrayType *AT = dyn_cast<ArrayType>(CanType);
- if (!AT)
- return CanType.getQualifiedType(TypeQuals);
-
- // Get the canonical version of the element with the extra qualifiers on it.
- // This can recursively sink qualifiers through multiple levels of arrays.
- QualType NewEltTy=AT->getElementType().getWithAdditionalQualifiers(TypeQuals);
- NewEltTy = getCanonicalType(NewEltTy);
-
- if (ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
- return getConstantArrayType(NewEltTy, CAT->getSize(),CAT->getSizeModifier(),
- CAT->getIndexTypeQualifier());
- if (IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT))
- return getIncompleteArrayType(NewEltTy, IAT->getSizeModifier(),
- IAT->getIndexTypeQualifier());
-
- // FIXME: What is the ownership of size expressions in VLAs?
- VariableArrayType *VAT = cast<VariableArrayType>(AT);
- return getVariableArrayType(NewEltTy, VAT->getSizeExpr(),
- VAT->getSizeModifier(),
- VAT->getIndexTypeQualifier());
-}
-
-
-const ArrayType *ASTContext::getAsArrayType(QualType T) {
- // Handle the non-qualified case efficiently.
- if (T.getCVRQualifiers() == 0) {
- // Handle the common positive case fast.
- if (const ArrayType *AT = dyn_cast<ArrayType>(T))
- return AT;
- }
-
- // Handle the common negative case fast, ignoring CVR qualifiers.
- QualType CType = T->getCanonicalTypeInternal();
-
- // Make sure to look through type qualifiers (like ASQuals) for the negative
- // test.
- if (!isa<ArrayType>(CType) &&
- !isa<ArrayType>(CType.getUnqualifiedType()))
- return 0;
-
- // Apply any CVR qualifiers from the array type to the element type. This
- // implements C99 6.7.3p8: "If the specification of an array type includes
- // any type qualifiers, the element type is so qualified, not the array type."
-
- // If we get here, we either have type qualifiers on the type, or we have
- // sugar such as a typedef in the way. If we have type qualifiers on the type
- // we must propagate them down into the elemeng type.
- unsigned CVRQuals = T.getCVRQualifiers();
- unsigned AddrSpace = 0;
- Type *Ty = T.getTypePtr();
-
- // Rip through ASQualType's and typedefs to get to a concrete type.
- while (1) {
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(Ty)) {
- AddrSpace = ASQT->getAddressSpace();
- Ty = ASQT->getBaseType();
- } else {
- T = Ty->getDesugaredType();
- if (T.getTypePtr() == Ty && T.getCVRQualifiers() == 0)
- break;
- CVRQuals |= T.getCVRQualifiers();
- Ty = T.getTypePtr();
- }
- }
-
- // If we have a simple case, just return now.
- const ArrayType *ATy = dyn_cast<ArrayType>(Ty);
- if (ATy == 0 || (AddrSpace == 0 && CVRQuals == 0))
- return ATy;
-
- // Otherwise, we have an array and we have qualifiers on it. Push the
- // qualifiers into the array element type and return a new array type.
- // Get the canonical version of the element with the extra qualifiers on it.
- // This can recursively sink qualifiers through multiple levels of arrays.
- QualType NewEltTy = ATy->getElementType();
- if (AddrSpace)
- NewEltTy = getASQualType(NewEltTy, AddrSpace);
- NewEltTy = NewEltTy.getWithAdditionalQualifiers(CVRQuals);
-
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy))
- return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
- CAT->getSizeModifier(),
- CAT->getIndexTypeQualifier()));
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy))
- return cast<ArrayType>(getIncompleteArrayType(NewEltTy,
- IAT->getSizeModifier(),
- IAT->getIndexTypeQualifier()));
-
- // FIXME: What is the ownership of size expressions in VLAs?
- const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
- return cast<ArrayType>(getVariableArrayType(NewEltTy, VAT->getSizeExpr(),
- VAT->getSizeModifier(),
- VAT->getIndexTypeQualifier()));
-}
-
-
-/// getArrayDecayedType - Return the properly qualified result of decaying the
-/// specified array type to a pointer. This operation is non-trivial when
-/// handling typedefs etc. The canonical type of "T" must be an array type,
-/// this returns a pointer to a properly qualified element of the array.
-///
-/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
-QualType ASTContext::getArrayDecayedType(QualType Ty) {
- // Get the element type with 'getAsArrayType' so that we don't lose any
- // typedefs in the element type of the array. This also handles propagation
- // of type qualifiers from the array type into the element type if present
- // (C99 6.7.3p8).
- const ArrayType *PrettyArrayType = getAsArrayType(Ty);
- assert(PrettyArrayType && "Not an array type!");
-
- QualType PtrTy = getPointerType(PrettyArrayType->getElementType());
-
- // int x[restrict 4] -> int *restrict
- return PtrTy.getQualifiedType(PrettyArrayType->getIndexTypeQualifier());
-}
-
-/// getFloatingRank - Return a relative rank for floating point types.
-/// This routine will assert if passed a built-in type that isn't a float.
-static FloatingRank getFloatingRank(QualType T) {
- if (const ComplexType *CT = T->getAsComplexType())
- return getFloatingRank(CT->getElementType());
-
- switch (T->getAsBuiltinType()->getKind()) {
- default: assert(0 && "getFloatingRank(): not a floating type");
- case BuiltinType::Float: return FloatRank;
- case BuiltinType::Double: return DoubleRank;
- case BuiltinType::LongDouble: return LongDoubleRank;
- }
-}
-
-/// getFloatingTypeOfSizeWithinDomain - Returns a real floating
-/// point or a complex type (based on typeDomain/typeSize).
-/// 'typeDomain' is a real floating point or complex type.
-/// 'typeSize' is a real floating point or complex type.
-QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
- QualType Domain) const {
- FloatingRank EltRank = getFloatingRank(Size);
- if (Domain->isComplexType()) {
- switch (EltRank) {
- default: assert(0 && "getFloatingRank(): illegal value for rank");
- case FloatRank: return FloatComplexTy;
- case DoubleRank: return DoubleComplexTy;
- case LongDoubleRank: return LongDoubleComplexTy;
- }
- }
-
- assert(Domain->isRealFloatingType() && "Unknown domain!");
- switch (EltRank) {
- default: assert(0 && "getFloatingRank(): illegal value for rank");
- case FloatRank: return FloatTy;
- case DoubleRank: return DoubleTy;
- case LongDoubleRank: return LongDoubleTy;
- }
-}
-
-/// getFloatingTypeOrder - Compare the rank of the two specified floating
-/// point types, ignoring the domain of the type (i.e. 'double' ==
-/// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If
-/// LHS < RHS, return -1.
-int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) {
- FloatingRank LHSR = getFloatingRank(LHS);
- FloatingRank RHSR = getFloatingRank(RHS);
-
- if (LHSR == RHSR)
- return 0;
- if (LHSR > RHSR)
- return 1;
- return -1;
-}
-
-/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
-/// routine will assert if passed a built-in type that isn't an integer or enum,
-/// or if it is not canonicalized.
-static unsigned getIntegerRank(Type *T) {
- assert(T->isCanonical() && "T should be canonicalized");
- if (isa<EnumType>(T))
- return 4;
-
- switch (cast<BuiltinType>(T)->getKind()) {
- default: assert(0 && "getIntegerRank(): not a built-in integer");
- case BuiltinType::Bool:
- return 1;
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- return 2;
- case BuiltinType::Short:
- case BuiltinType::UShort:
- return 3;
- case BuiltinType::Int:
- case BuiltinType::UInt:
- return 4;
- case BuiltinType::Long:
- case BuiltinType::ULong:
- return 5;
- case BuiltinType::LongLong:
- case BuiltinType::ULongLong:
- return 6;
- }
-}
-
-/// getIntegerTypeOrder - Returns the highest ranked integer type:
-/// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
-/// LHS < RHS, return -1.
-int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) {
- Type *LHSC = getCanonicalType(LHS).getTypePtr();
- Type *RHSC = getCanonicalType(RHS).getTypePtr();
- if (LHSC == RHSC) return 0;
-
- bool LHSUnsigned = LHSC->isUnsignedIntegerType();
- bool RHSUnsigned = RHSC->isUnsignedIntegerType();
-
- unsigned LHSRank = getIntegerRank(LHSC);
- unsigned RHSRank = getIntegerRank(RHSC);
-
- if (LHSUnsigned == RHSUnsigned) { // Both signed or both unsigned.
- if (LHSRank == RHSRank) return 0;
- return LHSRank > RHSRank ? 1 : -1;
- }
-
- // Otherwise, the LHS is signed and the RHS is unsigned or visa versa.
- if (LHSUnsigned) {
- // If the unsigned [LHS] type is larger, return it.
- if (LHSRank >= RHSRank)
- return 1;
-
- // If the signed type can represent all values of the unsigned type, it
- // wins. Because we are dealing with 2's complement and types that are
- // powers of two larger than each other, this is always safe.
- return -1;
- }
-
- // If the unsigned [RHS] type is larger, return it.
- if (RHSRank >= LHSRank)
- return -1;
-
- // If the signed type can represent all values of the unsigned type, it
- // wins. Because we are dealing with 2's complement and types that are
- // powers of two larger than each other, this is always safe.
- return 1;
-}
-
-// 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"));
- QualType FieldTypes[4];
-
- // const int *isa;
- FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));
- // int flags;
- FieldTypes[1] = IntTy;
- // const char *str;
- FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));
- // long length;
- FieldTypes[3] = LongTy;
- // Create fields
- FieldDecl *FieldDecls[4];
-
- for (unsigned i = 0; i < 4; ++i)
- FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0,
- FieldTypes[i]);
-
- CFConstantStringTypeDecl->defineBody(*this, FieldDecls, 4);
- }
-
- return getTagDeclType(CFConstantStringTypeDecl);
-}
-
-QualType ASTContext::getObjCFastEnumerationStateType()
-{
- if (!ObjCFastEnumerationStateTypeDecl) {
- QualType FieldTypes[] = {
- UnsignedLongTy,
- getPointerType(ObjCIdType),
- getPointerType(UnsignedLongTy),
- getConstantArrayType(UnsignedLongTy,
- llvm::APInt(32, 5), ArrayType::Normal, 0)
- };
-
- FieldDecl *FieldDecls[4];
- for (size_t i = 0; i < 4; ++i)
- FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0,
- FieldTypes[i]);
-
- ObjCFastEnumerationStateTypeDecl =
- RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
- &Idents.get("__objcFastEnumerationState"));
-
- ObjCFastEnumerationStateTypeDecl->defineBody(*this, FieldDecls, 4);
- }
-
- return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
-}
-
-// This returns true if a type has been typedefed to BOOL:
-// typedef <type> BOOL;
-static bool isTypeTypedefedAsBOOL(QualType T) {
- if (const TypedefType *TT = dyn_cast<TypedefType>(T))
- return !strcmp(TT->getDecl()->getName(), "BOOL");
-
- return false;
-}
-
-/// getObjCEncodingTypeSize returns size of type for objective-c encoding
-/// purpose.
-int ASTContext::getObjCEncodingTypeSize(QualType type) {
- uint64_t sz = getTypeSize(type);
-
- // Make all integer and enum types at least as large as an int
- if (sz > 0 && type->isIntegralType())
- sz = std::max(sz, getTypeSize(IntTy));
- // Treat arrays as pointers, since that's how they're passed in.
- else if (type->isArrayType())
- sz = getTypeSize(VoidPtrTy);
- return sz / getTypeSize(CharTy);
-}
-
-/// getObjCEncodingForMethodDecl - Return the encoded type for this method
-/// declaration.
-void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
- std::string& S)
-{
- // FIXME: This is not very efficient.
- // Encode type qualifer, 'in', 'inout', etc. for the return type.
- getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S);
- // Encode result type.
- getObjCEncodingForType(Decl->getResultType(), S, EncodingRecordTypes);
- // 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);
- // The first two arguments (self and _cmd) are pointers; account for
- // their size.
- int ParmOffset = 2 * PtrSize;
- int NumOfParams = Decl->getNumParams();
- for (int i = 0; i < NumOfParams; i++) {
- QualType PType = Decl->getParamDecl(i)->getType();
- int sz = getObjCEncodingTypeSize (PType);
- assert (sz > 0 && "getObjCEncodingForMethodDecl - Incomplete param type");
- ParmOffset += sz;
- }
- S += llvm::utostr(ParmOffset);
- S += "@0:";
- S += llvm::utostr(PtrSize);
-
- // Argument types.
- ParmOffset = 2 * PtrSize;
- for (int i = 0; i < NumOfParams; i++) {
- QualType PType = Decl->getParamDecl(i)->getType();
- // Process argument qualifiers for user supplied arguments; such as,
- // 'in', 'inout', etc.
- getObjCEncodingForTypeQualifier(
- Decl->getParamDecl(i)->getObjCDeclQualifier(), S);
- getObjCEncodingForType(PType, S, EncodingRecordTypes);
- S += llvm::utostr(ParmOffset);
- ParmOffset += getObjCEncodingTypeSize(PType);
- }
-}
-
-/// getObjCEncodingForPropertyDecl - Return the encoded type for this
-/// method declaration. If non-NULL, Container must be either an
-/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
-/// NULL when getting encodings for protocol properties.
-void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
- const Decl *Container,
- std::string& S)
-{
- // Collect information from the property implementation decl(s).
- bool Dynamic = false;
- ObjCPropertyImplDecl *SynthesizePID = 0;
-
- // FIXME: Duplicated code due to poor abstraction.
- if (Container) {
- if (const ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(Container)) {
- for (ObjCCategoryImplDecl::propimpl_iterator
- i = CID->propimpl_begin(), e = CID->propimpl_end(); i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
- if (PID->getPropertyDecl() == PD) {
- if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
- Dynamic = true;
- } else {
- SynthesizePID = PID;
- }
- }
- }
- } else {
- const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
- for (ObjCCategoryImplDecl::propimpl_iterator
- i = OID->propimpl_begin(), e = OID->propimpl_end(); i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
- if (PID->getPropertyDecl() == PD) {
- if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
- Dynamic = true;
- } else {
- SynthesizePID = PID;
- }
- }
- }
- }
- }
-
- // FIXME: This is not very efficient.
- S = "T";
-
- // Encode result type.
- // FIXME: GCC uses a generating_property_type_encoding mode during
- // this part. Investigate.
- getObjCEncodingForType(PD->getType(), S, EncodingRecordTypes);
-
- if (PD->isReadOnly()) {
- S += ",R";
- } else {
- switch (PD->getSetterKind()) {
- case ObjCPropertyDecl::Assign: break;
- case ObjCPropertyDecl::Copy: S += ",C"; break;
- case ObjCPropertyDecl::Retain: S += ",&"; break;
- }
- }
-
- // It really isn't clear at all what this means, since properties
- // are "dynamic by default".
- if (Dynamic)
- S += ",D";
-
- if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
- S += ",G";
- S += PD->getGetterName().getName();
- }
-
- if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
- S += ",S";
- S += PD->getSetterName().getName();
- }
-
- if (SynthesizePID) {
- const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl();
- S += ",V";
- S += OID->getName();
- }
-
- // FIXME: OBJCGC: weak & strong
-}
-
-void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
- llvm::SmallVector<const RecordType *, 8> &ERType) const {
- // FIXME: This currently doesn't encode:
- // @ An object (whether statically typed or typed id)
- // # A class object (Class)
- // : A method selector (SEL)
- // {name=type...} A structure
- // (name=type...) A union
- // bnum A bit field of num bits
-
- if (const BuiltinType *BT = T->getAsBuiltinType()) {
- char encoding;
- switch (BT->getKind()) {
- default: assert(0 && "Unhandled builtin type kind");
- case BuiltinType::Void: encoding = 'v'; break;
- case BuiltinType::Bool: encoding = 'B'; break;
- case BuiltinType::Char_U:
- case BuiltinType::UChar: encoding = 'C'; break;
- case BuiltinType::UShort: encoding = 'S'; break;
- case BuiltinType::UInt: encoding = 'I'; break;
- case BuiltinType::ULong: encoding = 'L'; break;
- case BuiltinType::ULongLong: encoding = 'Q'; break;
- case BuiltinType::Char_S:
- case BuiltinType::SChar: encoding = 'c'; break;
- case BuiltinType::Short: encoding = 's'; break;
- case BuiltinType::Int: encoding = 'i'; break;
- case BuiltinType::Long: encoding = 'l'; break;
- case BuiltinType::LongLong: encoding = 'q'; break;
- case BuiltinType::Float: encoding = 'f'; break;
- case BuiltinType::Double: encoding = 'd'; break;
- case BuiltinType::LongDouble: encoding = 'd'; break;
- }
-
- S += encoding;
- }
- else if (T->isObjCQualifiedIdType()) {
- // Treat id<P...> same as 'id' for encoding purposes.
- return getObjCEncodingForType(getObjCIdType(), S, ERType);
-
- }
- else if (const PointerType *PT = T->getAsPointerType()) {
- QualType PointeeTy = PT->getPointeeType();
- if (isObjCIdType(PointeeTy) || PointeeTy->isObjCInterfaceType()) {
- S += '@';
- return;
- } else if (isObjCClassType(PointeeTy)) {
- S += '#';
- return;
- } else if (isObjCSelType(PointeeTy)) {
- S += ':';
- return;
- }
-
- if (PointeeTy->isCharType()) {
- // char pointer types should be encoded as '*' unless it is a
- // type that has been typedef'd to 'BOOL'.
- if (!isTypeTypedefedAsBOOL(PointeeTy)) {
- S += '*';
- return;
- }
- }
-
- S += '^';
- getObjCEncodingForType(PT->getPointeeType(), S, ERType);
- } else if (const ArrayType *AT =
- // Ignore type qualifiers etc.
- dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
- S += '[';
-
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
- S += llvm::utostr(CAT->getSize().getZExtValue());
- else
- assert(0 && "Unhandled array type!");
-
- getObjCEncodingForType(AT->getElementType(), S, ERType);
- S += ']';
- } else if (T->getAsFunctionType()) {
- S += '?';
- } else if (const RecordType *RTy = T->getAsRecordType()) {
- RecordDecl *RDecl= RTy->getDecl();
- // This mimics the behavior in gcc's encode_aggregate_within().
- // The idea is to only inline structure definitions for top level pointers
- // to structures and embedded structures.
- bool inlining = (S.size() == 1 && S[0] == '^' ||
- S.size() > 1 && S[S.size()-1] != '^');
- S += '{';
- S += RDecl->getName();
- bool found = false;
- for (unsigned i = 0, e = ERType.size(); i != e; ++i)
- if (ERType[i] == RTy) {
- found = true;
- break;
- }
- if (!found && inlining) {
- ERType.push_back(RTy);
- S += '=';
- for (int i = 0; i < RDecl->getNumMembers(); i++) {
- FieldDecl *field = RDecl->getMember(i);
- getObjCEncodingForType(field->getType(), S, ERType);
- }
- assert(ERType.back() == RTy && "Record Type stack mismatch.");
- ERType.pop_back();
- }
- S += '}';
- } else if (T->isEnumeralType()) {
- S += 'i';
- } else if (T->isBlockPointerType()) {
- S += '^'; // This type string is the same as general pointers.
- } else
- assert(0 && "@encode for type not implemented!");
-}
-
-void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
- std::string& S) const {
- if (QT & Decl::OBJC_TQ_In)
- S += 'n';
- if (QT & Decl::OBJC_TQ_Inout)
- S += 'N';
- if (QT & Decl::OBJC_TQ_Out)
- S += 'o';
- if (QT & Decl::OBJC_TQ_Bycopy)
- S += 'O';
- if (QT & Decl::OBJC_TQ_Byref)
- S += 'R';
- if (QT & Decl::OBJC_TQ_Oneway)
- S += 'V';
-}
-
-void ASTContext::setBuiltinVaListType(QualType T)
-{
- assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");
-
- BuiltinVaListType = T;
-}
-
-void ASTContext::setObjCIdType(TypedefDecl *TD)
-{
- ObjCIdType = getTypedefType(TD);
-
- // typedef struct objc_object *id;
- const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
- assert(ptr && "'id' incorrectly typed");
- const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
- assert(rec && "'id' incorrectly typed");
- IdStructType = rec;
-}
-
-void ASTContext::setObjCSelType(TypedefDecl *TD)
-{
- ObjCSelType = getTypedefType(TD);
-
- // typedef struct objc_selector *SEL;
- const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
- assert(ptr && "'SEL' incorrectly typed");
- const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
- assert(rec && "'SEL' incorrectly typed");
- SelStructType = rec;
-}
-
-void ASTContext::setObjCProtoType(QualType QT)
-{
- ObjCProtoType = QT;
-}
-
-void ASTContext::setObjCClassType(TypedefDecl *TD)
-{
- ObjCClassType = getTypedefType(TD);
-
- // typedef struct objc_class *Class;
- const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
- assert(ptr && "'Class' incorrectly typed");
- const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
- assert(rec && "'Class' incorrectly typed");
- ClassStructType = rec;
-}
-
-void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
- assert(ObjCConstantStringType.isNull() &&
- "'NSConstantString' type already set!");
-
- ObjCConstantStringType = getObjCInterfaceType(Decl);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Type Predicates.
-//===----------------------------------------------------------------------===//
-
-/// isObjCObjectPointerType - Returns true if type is an Objective-C pointer
-/// to an object type. This includes "id" and "Class" (two 'special' pointers
-/// to struct), Interface* (pointer to ObjCInterfaceType) and id<P> (qualified
-/// ID type).
-bool ASTContext::isObjCObjectPointerType(QualType Ty) const {
- if (Ty->isObjCQualifiedIdType())
- return true;
-
- if (!Ty->isPointerType())
- return false;
-
- // Check to see if this is 'id' or 'Class', both of which are typedefs for
- // pointer types. This looks for the typedef specifically, not for the
- // underlying type.
- if (Ty == getObjCIdType() || Ty == getObjCClassType())
- return true;
-
- // If this a pointer to an interface (e.g. NSString*), it is ok.
- return Ty->getAsPointerType()->getPointeeType()->isObjCInterfaceType();
-}
-
-//===----------------------------------------------------------------------===//
-// Type Compatibility Testing
-//===----------------------------------------------------------------------===//
-
-/// typesAreBlockCompatible - This routine is called when comparing two
-/// block types. Types must be strictly compatible here. For example,
-/// C unfortunately doesn't produce an error for the following:
-///
-/// int (*emptyArgFunc)();
-/// int (*intArgList)(int) = emptyArgFunc;
-///
-/// For blocks, we will produce an error for the following (similar to C++):
-///
-/// int (^emptyArgBlock)();
-/// int (^intArgBlock)(int) = emptyArgBlock;
-///
-/// FIXME: When the dust settles on this integration, fold this into mergeTypes.
-///
-bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
- return getCanonicalType(lhs) == getCanonicalType(rhs);
-}
-
-/// areCompatVectorTypes - Return true if the two specified vector types are
-/// compatible.
-static bool areCompatVectorTypes(const VectorType *LHS,
- const VectorType *RHS) {
- assert(LHS->isCanonical() && RHS->isCanonical());
- return LHS->getElementType() == RHS->getElementType() &&
- LHS->getNumElements() == RHS->getNumElements();
-}
-
-/// canAssignObjCInterfaces - Return true if the two interface types are
-/// compatible for assignment from RHS to LHS. This handles validation of any
-/// protocol qualifiers on the LHS or RHS.
-///
-bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
- const ObjCInterfaceType *RHS) {
- // Verify that the base decls are compatible: the RHS must be a subclass of
- // the LHS.
- if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
- return false;
-
- // RHS must have a superset of the protocols in the LHS. If the LHS is not
- // protocol qualified at all, then we are good.
- if (!isa<ObjCQualifiedInterfaceType>(LHS))
- return true;
-
- // Okay, we know the LHS has protocol qualifiers. If the RHS doesn't, then it
- // isn't a superset.
- if (!isa<ObjCQualifiedInterfaceType>(RHS))
- return true; // FIXME: should return false!
-
- // Finally, we must have two protocol-qualified interfaces.
- const ObjCQualifiedInterfaceType *LHSP =cast<ObjCQualifiedInterfaceType>(LHS);
- const ObjCQualifiedInterfaceType *RHSP =cast<ObjCQualifiedInterfaceType>(RHS);
- ObjCQualifiedInterfaceType::qual_iterator LHSPI = LHSP->qual_begin();
- ObjCQualifiedInterfaceType::qual_iterator LHSPE = LHSP->qual_end();
- ObjCQualifiedInterfaceType::qual_iterator RHSPI = RHSP->qual_begin();
- ObjCQualifiedInterfaceType::qual_iterator RHSPE = RHSP->qual_end();
-
- // All protocols in LHS must have a presence in RHS. Since the protocol lists
- // are both sorted alphabetically and have no duplicates, we can scan RHS and
- // LHS in a single parallel scan until we run out of elements in LHS.
- assert(LHSPI != LHSPE && "Empty LHS protocol list?");
- ObjCProtocolDecl *LHSProto = *LHSPI;
-
- while (RHSPI != RHSPE) {
- ObjCProtocolDecl *RHSProto = *RHSPI++;
- // If the RHS has a protocol that the LHS doesn't, ignore it.
- if (RHSProto != LHSProto)
- continue;
-
- // Otherwise, the RHS does have this element.
- ++LHSPI;
- if (LHSPI == LHSPE)
- return true; // All protocols in LHS exist in RHS.
-
- LHSProto = *LHSPI;
- }
-
- // If we got here, we didn't find one of the LHS's protocols in the RHS list.
- return false;
-}
-
-/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
-/// both shall have the identically qualified version of a compatible type.
-/// C99 6.2.7p1: Two types have compatible types if their types are the
-/// same. See 6.7.[2,3,5] for additional rules.
-bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) {
- return !mergeTypes(LHS, RHS).isNull();
-}
-
-QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
- const FunctionType *lbase = lhs->getAsFunctionType();
- const FunctionType *rbase = rhs->getAsFunctionType();
- const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
- const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
- bool allLTypes = true;
- bool allRTypes = true;
-
- // Check return type
- QualType retType = mergeTypes(lbase->getResultType(), rbase->getResultType());
- if (retType.isNull()) return QualType();
- if (getCanonicalType(retType) != getCanonicalType(lbase->getResultType()))
- allLTypes = false;
- if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType()))
- allRTypes = false;
-
- if (lproto && rproto) { // two C99 style function prototypes
- unsigned lproto_nargs = lproto->getNumArgs();
- unsigned rproto_nargs = rproto->getNumArgs();
-
- // Compatible functions must have the same number of arguments
- if (lproto_nargs != rproto_nargs)
- return QualType();
-
- // Variadic and non-variadic functions aren't compatible
- if (lproto->isVariadic() != rproto->isVariadic())
- return QualType();
-
- // Check argument compatibility
- llvm::SmallVector<QualType, 10> types;
- for (unsigned i = 0; i < lproto_nargs; i++) {
- QualType largtype = lproto->getArgType(i).getUnqualifiedType();
- QualType rargtype = rproto->getArgType(i).getUnqualifiedType();
- QualType argtype = mergeTypes(largtype, rargtype);
- if (argtype.isNull()) return QualType();
- types.push_back(argtype);
- if (getCanonicalType(argtype) != getCanonicalType(largtype))
- allLTypes = false;
- if (getCanonicalType(argtype) != getCanonicalType(rargtype))
- allRTypes = false;
- }
- if (allLTypes) return lhs;
- if (allRTypes) return rhs;
- return getFunctionType(retType, types.begin(), types.size(),
- lproto->isVariadic());
- }
-
- if (lproto) allRTypes = false;
- if (rproto) allLTypes = false;
-
- const FunctionTypeProto *proto = lproto ? lproto : rproto;
- if (proto) {
- if (proto->isVariadic()) return QualType();
- // Check that the types are compatible with the types that
- // would result from default argument promotions (C99 6.7.5.3p15).
- // The only types actually affected are promotable integer
- // types and floats, which would be passed as a different
- // type depending on whether the prototype is visible.
- unsigned proto_nargs = proto->getNumArgs();
- for (unsigned i = 0; i < proto_nargs; ++i) {
- QualType argTy = proto->getArgType(i);
- if (argTy->isPromotableIntegerType() ||
- getCanonicalType(argTy).getUnqualifiedType() == FloatTy)
- return QualType();
- }
-
- if (allLTypes) return lhs;
- if (allRTypes) return rhs;
- return getFunctionType(retType, proto->arg_type_begin(),
- proto->getNumArgs(), lproto->isVariadic());
- }
-
- if (allLTypes) return lhs;
- if (allRTypes) return rhs;
- return getFunctionTypeNoProto(retType);
-}
-
-QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
- // C++ [expr]: If an expression initially has the type "reference to T", the
- // type is adjusted to "T" prior to any further analysis, the expression
- // designates the object or function denoted by the reference, and the
- // expression is an lvalue.
- // FIXME: C++ shouldn't be going through here! The rules are different
- // enough that they should be handled separately.
- if (const ReferenceType *RT = LHS->getAsReferenceType())
- LHS = RT->getPointeeType();
- if (const ReferenceType *RT = RHS->getAsReferenceType())
- RHS = RT->getPointeeType();
-
- QualType LHSCan = getCanonicalType(LHS),
- RHSCan = getCanonicalType(RHS);
-
- // If two types are identical, they are compatible.
- if (LHSCan == RHSCan)
- return LHS;
-
- // If the qualifiers are different, the types aren't compatible
- if (LHSCan.getCVRQualifiers() != RHSCan.getCVRQualifiers() ||
- LHSCan.getAddressSpace() != RHSCan.getAddressSpace())
- return QualType();
-
- Type::TypeClass LHSClass = LHSCan->getTypeClass();
- Type::TypeClass RHSClass = RHSCan->getTypeClass();
-
- // We want to consider the two function types to be the same for these
- // comparisons, just force one to the other.
- if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto;
- if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto;
-
- // Same as above for arrays
- if (LHSClass == Type::VariableArray || LHSClass == Type::IncompleteArray)
- LHSClass = Type::ConstantArray;
- if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray)
- RHSClass = Type::ConstantArray;
-
- // Canonicalize ExtVector -> Vector.
- if (LHSClass == Type::ExtVector) LHSClass = Type::Vector;
- if (RHSClass == Type::ExtVector) RHSClass = Type::Vector;
-
- // Consider qualified interfaces and interfaces the same.
- if (LHSClass == Type::ObjCQualifiedInterface) LHSClass = Type::ObjCInterface;
- if (RHSClass == Type::ObjCQualifiedInterface) RHSClass = Type::ObjCInterface;
-
- // If the canonical type classes don't match.
- if (LHSClass != RHSClass) {
- // ID is compatible with all qualified id types.
- if (LHS->isObjCQualifiedIdType()) {
- if (const PointerType *PT = RHS->getAsPointerType())
- if (isObjCIdType(PT->getPointeeType()))
- return LHS;
- }
- if (RHS->isObjCQualifiedIdType()) {
- if (const PointerType *PT = LHS->getAsPointerType())
- if (isObjCIdType(PT->getPointeeType()))
- return RHS;
- }
-
- // C99 6.7.2.2p4: Each enumerated type shall be compatible with char,
- // a signed integer type, or an unsigned integer type.
- if (const EnumType* ETy = LHS->getAsEnumType()) {
- if (ETy->getDecl()->getIntegerType() == RHSCan.getUnqualifiedType())
- return RHS;
- }
- if (const EnumType* ETy = RHS->getAsEnumType()) {
- if (ETy->getDecl()->getIntegerType() == LHSCan.getUnqualifiedType())
- return LHS;
- }
-
- return QualType();
- }
-
- // The canonical type classes match.
- switch (LHSClass) {
- case Type::Pointer:
- {
- // Merge two pointer types, while trying to preserve typedef info
- QualType LHSPointee = LHS->getAsPointerType()->getPointeeType();
- QualType RHSPointee = RHS->getAsPointerType()->getPointeeType();
- QualType ResultType = mergeTypes(LHSPointee, RHSPointee);
- if (ResultType.isNull()) return QualType();
- if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
- return LHS;
- if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
- return RHS;
- return getPointerType(ResultType);
- }
- case Type::ConstantArray:
- {
- const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
- const ConstantArrayType* RCAT = getAsConstantArrayType(RHS);
- if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize())
- return QualType();
-
- QualType LHSElem = getAsArrayType(LHS)->getElementType();
- QualType RHSElem = getAsArrayType(RHS)->getElementType();
- QualType ResultType = mergeTypes(LHSElem, RHSElem);
- if (ResultType.isNull()) return QualType();
- if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
- return LHS;
- if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
- return RHS;
- if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(),
- ArrayType::ArraySizeModifier(), 0);
- if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(),
- ArrayType::ArraySizeModifier(), 0);
- const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
- const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
- if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
- return LHS;
- if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
- return RHS;
- if (LVAT) {
- // FIXME: This isn't correct! But tricky to implement because
- // the array's size has to be the size of LHS, but the type
- // has to be different.
- return LHS;
- }
- if (RVAT) {
- // FIXME: This isn't correct! But tricky to implement because
- // the array's size has to be the size of RHS, but the type
- // has to be different.
- return RHS;
- }
- if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS;
- if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS;
- return getIncompleteArrayType(ResultType, ArrayType::ArraySizeModifier(),0);
- }
- case Type::FunctionNoProto:
- return mergeFunctionTypes(LHS, RHS);
- case Type::Tagged:
- // FIXME: Why are these compatible?
- if (isObjCIdType(LHS) && isObjCClassType(RHS)) return LHS;
- if (isObjCClassType(LHS) && isObjCIdType(RHS)) return LHS;
- return QualType();
- case Type::Builtin:
- // Only exactly equal builtin types are compatible, which is tested above.
- return QualType();
- case Type::Vector:
- if (areCompatVectorTypes(LHS->getAsVectorType(), RHS->getAsVectorType()))
- return LHS;
- return QualType();
- case Type::ObjCInterface:
- // Distinct ObjC interfaces are not compatible; see canAssignObjCInterfaces
- // for checking assignment/comparison safety
- return QualType();
- default:
- assert(0 && "unexpected type");
- return QualType();
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Integer Predicates
-//===----------------------------------------------------------------------===//
-unsigned ASTContext::getIntWidth(QualType T) {
- if (T == BoolTy)
- return 1;
- // At the moment, only bool has padding bits
- return (unsigned)getTypeSize(T);
-}
-
-QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
- assert(T->isSignedIntegerType() && "Unexpected type");
- if (const EnumType* ETy = T->getAsEnumType())
- T = ETy->getDecl()->getIntegerType();
- const BuiltinType* BTy = T->getAsBuiltinType();
- assert (BTy && "Unexpected signed integer type");
- switch (BTy->getKind()) {
- case BuiltinType::Char_S:
- case BuiltinType::SChar:
- return UnsignedCharTy;
- case BuiltinType::Short:
- return UnsignedShortTy;
- case BuiltinType::Int:
- return UnsignedIntTy;
- case BuiltinType::Long:
- return UnsignedLongTy;
- case BuiltinType::LongLong:
- return UnsignedLongLongTy;
- default:
- assert(0 && "Unexpected signed integer type");
- return QualType();
- }
-}
-
-
-//===----------------------------------------------------------------------===//
-// Serialization Support
-//===----------------------------------------------------------------------===//
-
-/// Emit - Serialize an ASTContext object to Bitcode.
-void ASTContext::Emit(llvm::Serializer& S) const {
- S.Emit(LangOpts);
- S.EmitRef(SourceMgr);
- S.EmitRef(Target);
- S.EmitRef(Idents);
- S.EmitRef(Selectors);
-
- // Emit the size of the type vector so that we can reserve that size
- // when we reconstitute the ASTContext object.
- S.EmitInt(Types.size());
-
- for (std::vector<Type*>::const_iterator I=Types.begin(), E=Types.end();
- I!=E;++I)
- (*I)->Emit(S);
-
- S.EmitOwnedPtr(TUDecl);
-
- // FIXME: S.EmitOwnedPtr(CFConstantStringTypeDecl);
-}
-
-ASTContext* ASTContext::Create(llvm::Deserializer& D) {
-
- // Read the language options.
- LangOptions LOpts;
- LOpts.Read(D);
-
- SourceManager &SM = D.ReadRef<SourceManager>();
- TargetInfo &t = D.ReadRef<TargetInfo>();
- IdentifierTable &idents = D.ReadRef<IdentifierTable>();
- SelectorTable &sels = D.ReadRef<SelectorTable>();
-
- unsigned size_reserve = D.ReadInt();
-
- ASTContext* A = new ASTContext(LOpts, SM, t, idents, sels, size_reserve);
-
- for (unsigned i = 0; i < size_reserve; ++i)
- Type::Create(*A,i,D);
-
- A->TUDecl = cast<TranslationUnitDecl>(D.ReadOwnedPtr<Decl>(*A));
-
- // FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
-
- return A;
-}
diff --git a/clang/lib/AST/Builtins.cpp b/clang/lib/AST/Builtins.cpp
deleted file mode 100644
index 3980d2052179..000000000000
--- a/clang/lib/AST/Builtins.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-//===--- Builtins.cpp - Builtin function implementation -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements various things for builtin functions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Builtins.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/TargetInfo.h"
-using namespace clang;
-
-static const Builtin::Info BuiltinInfo[] = {
- { "not a builtin function", 0, 0 },
-#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
-#include "clang/AST/Builtins.def"
-};
-
-const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
- if (ID < Builtin::FirstTSBuiltin)
- return BuiltinInfo[ID];
- assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!");
- return TSRecords[ID - Builtin::FirstTSBuiltin];
-}
-
-
-/// InitializeBuiltins - Mark the identifiers for all the builtins with their
-/// appropriate builtin ID # and mark any non-portable builtin identifiers as
-/// such.
-void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
- const TargetInfo &Target) {
- // Step #1: mark all target-independent builtins with their ID's.
- for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
- Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
-
- // Step #2: Get target builtins.
- Target.getTargetBuiltins(TSRecords, NumTSRecords);
-
- // Step #3: Register target-specific builtins.
- for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
- Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
-}
-
-/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
-/// pointer over the consumed characters. This returns the resultant type.
-static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
- bool AllowTypeModifiers = true) {
- // Modifiers.
- bool Long = false, LongLong = false, Signed = false, Unsigned = false;
-
- // Read the modifiers first.
- bool Done = false;
- while (!Done) {
- switch (*Str++) {
- default: Done = true; --Str; break;
- case 'S':
- assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
- assert(!Signed && "Can't use 'S' modifier multiple times!");
- Signed = true;
- break;
- case 'U':
- assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
- assert(!Unsigned && "Can't use 'S' modifier multiple times!");
- Unsigned = true;
- break;
- case 'L':
- assert(!LongLong && "Can't have LLL modifier");
- if (Long)
- LongLong = true;
- else
- Long = true;
- break;
- }
- }
-
- QualType Type;
-
- // Read the base type.
- switch (*Str++) {
- default: assert(0 && "Unknown builtin type letter!");
- case 'v':
- assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'v'!");
- Type = Context.VoidTy;
- break;
- case 'f':
- assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
- Type = Context.FloatTy;
- break;
- case 'd':
- assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!");
- if (Long)
- Type = Context.LongDoubleTy;
- else
- Type = Context.DoubleTy;
- break;
- case 's':
- assert(!LongLong && "Bad modifiers used with 's'!");
- if (Unsigned)
- Type = Context.UnsignedShortTy;
- else
- Type = Context.ShortTy;
- break;
- case 'i':
- if (LongLong)
- Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
- else if (Long)
- Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy;
- else if (Unsigned)
- Type = Context.UnsignedIntTy;
- else
- Type = Context.IntTy; // default is signed.
- break;
- case 'c':
- assert(!Long && !LongLong && "Bad modifiers used with 'c'!");
- if (Signed)
- Type = Context.SignedCharTy;
- else if (Unsigned)
- Type = Context.UnsignedCharTy;
- else
- Type = Context.CharTy;
- break;
- case 'z': // size_t.
- assert(!Long && !Signed && !Unsigned && "Bad modifiers for 'z'!");
- Type = Context.getSizeType();
- break;
- case 'F':
- Type = Context.getCFConstantStringType();
- break;
- case 'a':
- Type = Context.getBuiltinVaListType();
- assert(!Type.isNull() && "builtin va list type not initialized!");
- break;
- case 'V': {
- char *End;
-
- unsigned NumElements = strtoul(Str, &End, 10);
- assert(End != Str && "Missing vector size");
-
- Str = End;
-
- QualType ElementType = DecodeTypeFromStr(Str, Context, false);
- Type = Context.getVectorType(ElementType, NumElements);
- break;
- }
- }
-
- if (!AllowTypeModifiers)
- return Type;
-
- Done = false;
- while (!Done) {
- switch (*Str++) {
- default: Done = true; --Str; break;
- case '*':
- Type = Context.getPointerType(Type);
- break;
- case '&':
- Type = Context.getReferenceType(Type);
- break;
- case 'C':
- Type = Type.getQualifiedType(QualType::Const);
- break;
- }
- }
-
- return Type;
-}
-
-/// GetBuiltinType - Return the type for the specified builtin.
-QualType Builtin::Context::GetBuiltinType(unsigned id,
- ASTContext &Context) const {
- const char *TypeStr = GetRecord(id).Type;
-
- llvm::SmallVector<QualType, 8> ArgTypes;
-
- QualType ResType = DecodeTypeFromStr(TypeStr, Context);
- while (TypeStr[0] && TypeStr[0] != '.') {
- QualType Ty = DecodeTypeFromStr(TypeStr, Context);
-
- // Do array -> pointer decay. The builtin should use the decayed type.
- if (Ty->isArrayType())
- Ty = Context.getArrayDecayedType(Ty);
-
- ArgTypes.push_back(Ty);
- }
-
- assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
- "'.' should only occur at end of builtin type list!");
-
- // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);".
- if (ArgTypes.size() == 0 && TypeStr[0] == '.')
- return Context.getFunctionTypeNoProto(ResType);
- return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
- TypeStr[0] == '.');
-}
diff --git a/clang/lib/AST/CFG.cpp b/clang/lib/AST/CFG.cpp
deleted file mode 100644
index 2eea6492cd0f..000000000000
--- a/clang/lib/AST/CFG.cpp
+++ /dev/null
@@ -1,1692 +0,0 @@
-//===--- CFG.cpp - Classes for representing and building CFGs----*- 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 CFG and CFGBuilder classes for representing and
-// building Control-Flow Graphs (CFGs) from ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/CFG.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Support/GraphWriter.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/Compiler.h"
-#include <llvm/Support/Allocator.h>
-#include <llvm/Support/Format.h>
-#include <iomanip>
-#include <algorithm>
-#include <sstream>
-
-using namespace clang;
-
-namespace {
-
-// SaveAndRestore - A utility class that uses RIIA to save and restore
-// the value of a variable.
-template<typename T>
-struct VISIBILITY_HIDDEN SaveAndRestore {
- SaveAndRestore(T& x) : X(x), old_value(x) {}
- ~SaveAndRestore() { X = old_value; }
- T get() { return old_value; }
-
- T& X;
- T old_value;
-};
-
-static SourceLocation GetEndLoc(ScopedDecl* D) {
- if (VarDecl* VD = dyn_cast<VarDecl>(D))
- if (Expr* Ex = VD->getInit())
- return Ex->getSourceRange().getEnd();
-
- return D->getLocation();
-}
-
-class VISIBILITY_HIDDEN UnaryDeclStmt : public DeclStmt {
- Stmt* Ex;
-public:
- UnaryDeclStmt(ScopedDecl* D)
- : DeclStmt(D, D->getLocation(), GetEndLoc(D)), Ex(0) {
- if (VarDecl* VD = dyn_cast<VarDecl>(D))
- Ex = VD->getInit();
- }
-
- virtual ~UnaryDeclStmt() {}
- virtual void Destroy(ASTContext& Ctx) { assert(false && "Do not call"); }
-
- virtual child_iterator child_begin() {
- return Ex ? &Ex : 0;
- }
- virtual child_iterator child_end() {
- return Ex ? &Ex + 1 : 0;
- }
- virtual decl_iterator decl_begin() {
- return TheDecl;
- }
- virtual decl_iterator decl_end() {
- return TheDecl ? TheDecl->getNextDeclarator() : 0;
- }
-};
-
-/// CFGBuilder - This class implements CFG construction from an AST.
-/// The builder is stateful: an instance of the builder should be used to only
-/// construct a single CFG.
-///
-/// Example usage:
-///
-/// CFGBuilder builder;
-/// CFG* cfg = builder.BuildAST(stmt1);
-///
-/// CFG construction is done via a recursive walk of an AST.
-/// We actually parse the AST in reverse order so that the successor
-/// of a basic block is constructed prior to its predecessor. This
-/// allows us to nicely capture implicit fall-throughs without extra
-/// basic blocks.
-///
-class VISIBILITY_HIDDEN CFGBuilder : public StmtVisitor<CFGBuilder,CFGBlock*> {
- CFG* cfg;
- CFGBlock* Block;
- CFGBlock* Succ;
- CFGBlock* ContinueTargetBlock;
- CFGBlock* BreakTargetBlock;
- CFGBlock* SwitchTerminatedBlock;
- CFGBlock* DefaultCaseBlock;
-
- // LabelMap records the mapping from Label expressions to their blocks.
- typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy;
- LabelMapTy LabelMap;
-
- // A list of blocks that end with a "goto" that must be backpatched to
- // their resolved targets upon completion of CFG construction.
- typedef std::vector<CFGBlock*> BackpatchBlocksTy;
- BackpatchBlocksTy BackpatchBlocks;
-
- // A list of labels whose address has been taken (for indirect gotos).
- typedef llvm::SmallPtrSet<LabelStmt*,5> LabelSetTy;
- LabelSetTy AddressTakenLabels;
-
-public:
- explicit CFGBuilder() : cfg(NULL), Block(NULL), Succ(NULL),
- ContinueTargetBlock(NULL), BreakTargetBlock(NULL),
- SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL) {
- // Create an empty CFG.
- cfg = new CFG();
- }
-
- ~CFGBuilder() { delete cfg; }
-
- // buildCFG - Used by external clients to construct the CFG.
- CFG* buildCFG(Stmt* Statement);
-
- // Visitors to walk an AST and construct the CFG. Called by
- // buildCFG. Do not call directly!
-
- CFGBlock* VisitStmt(Stmt* Statement);
- CFGBlock* VisitNullStmt(NullStmt* Statement);
- CFGBlock* VisitCompoundStmt(CompoundStmt* C);
- CFGBlock* VisitIfStmt(IfStmt* I);
- CFGBlock* VisitReturnStmt(ReturnStmt* R);
- CFGBlock* VisitLabelStmt(LabelStmt* L);
- CFGBlock* VisitGotoStmt(GotoStmt* G);
- CFGBlock* VisitForStmt(ForStmt* F);
- CFGBlock* VisitWhileStmt(WhileStmt* W);
- CFGBlock* VisitDoStmt(DoStmt* D);
- CFGBlock* VisitContinueStmt(ContinueStmt* C);
- CFGBlock* VisitBreakStmt(BreakStmt* B);
- CFGBlock* VisitSwitchStmt(SwitchStmt* Terminator);
- CFGBlock* VisitCaseStmt(CaseStmt* Terminator);
- CFGBlock* VisitDefaultStmt(DefaultStmt* D);
- CFGBlock* VisitIndirectGotoStmt(IndirectGotoStmt* I);
-
- // FIXME: Add support for ObjC-specific control-flow structures.
-
- // NYS == Not Yet Supported
- CFGBlock* NYS() {
- badCFG = true;
- return Block;
- }
-
- CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* S){ return NYS();}
- CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) { return NYS(); }
- CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) { return NYS(); }
- CFGBlock* VisitObjCAtFinallyStmt(ObjCAtFinallyStmt* S) { return NYS(); }
- CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) { return NYS(); }
-
- CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S){
- return NYS();
- }
-
- // Blocks.
- CFGBlock* VisitBlockExpr(BlockExpr* E) { return NYS(); }
- CFGBlock* VisitBlockDeclRefExpr(BlockDeclRefExpr* E) { return NYS(); }
-
-private:
- CFGBlock* createBlock(bool add_successor = true);
- CFGBlock* addStmt(Stmt* Terminator);
- CFGBlock* WalkAST(Stmt* Terminator, bool AlwaysAddStmt);
- CFGBlock* WalkAST_VisitChildren(Stmt* Terminator);
- CFGBlock* WalkAST_VisitDeclSubExpr(ScopedDecl* D);
- CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* Terminator);
- void FinishBlock(CFGBlock* B);
-
- bool badCFG;
-};
-
-static VariableArrayType* FindVA(Type* t) {
- while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
- if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
- if (vat->getSizeExpr())
- return vat;
-
- t = vt->getElementType().getTypePtr();
- }
-
- return 0;
-}
-
-/// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can
-/// represent an arbitrary statement. Examples include a single expression
-/// or a function body (compound statement). The ownership of the returned
-/// CFG is transferred to the caller. If CFG construction fails, this method
-/// returns NULL.
-CFG* CFGBuilder::buildCFG(Stmt* Statement) {
- assert (cfg);
- if (!Statement) return NULL;
-
- badCFG = false;
-
- // Create an empty block that will serve as the exit block for the CFG.
- // Since this is the first block added to the CFG, it will be implicitly
- // registered as the exit block.
- Succ = createBlock();
- assert (Succ == &cfg->getExit());
- Block = NULL; // the EXIT block is empty. Create all other blocks lazily.
-
- // Visit the statements and create the CFG.
- CFGBlock* B = Visit(Statement);
- if (!B) B = Succ;
-
- if (B) {
- // Finalize the last constructed block. This usually involves
- // reversing the order of the statements in the block.
- if (Block) FinishBlock(B);
-
- // Backpatch the gotos whose label -> block mappings we didn't know
- // when we encountered them.
- for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
- E = BackpatchBlocks.end(); I != E; ++I ) {
-
- CFGBlock* B = *I;
- GotoStmt* G = cast<GotoStmt>(B->getTerminator());
- LabelMapTy::iterator LI = LabelMap.find(G->getLabel());
-
- // If there is no target for the goto, then we are looking at an
- // incomplete AST. Handle this by not registering a successor.
- if (LI == LabelMap.end()) continue;
-
- B->addSuccessor(LI->second);
- }
-
- // Add successors to the Indirect Goto Dispatch block (if we have one).
- if (CFGBlock* B = cfg->getIndirectGotoBlock())
- for (LabelSetTy::iterator I = AddressTakenLabels.begin(),
- E = AddressTakenLabels.end(); I != E; ++I ) {
-
- // Lookup the target block.
- LabelMapTy::iterator LI = LabelMap.find(*I);
-
- // If there is no target block that contains label, then we are looking
- // at an incomplete AST. Handle this by not registering a successor.
- if (LI == LabelMap.end()) continue;
-
- B->addSuccessor(LI->second);
- }
-
- Succ = B;
- }
-
- // Create an empty entry block that has no predecessors.
- cfg->setEntry(createBlock());
-
- if (badCFG) {
- delete cfg;
- cfg = NULL;
- return NULL;
- }
-
- // NULL out cfg so that repeated calls to the builder will fail and that
- // the ownership of the constructed CFG is passed to the caller.
- CFG* t = cfg;
- cfg = NULL;
- return t;
-}
-
-/// createBlock - Used to lazily create blocks that are connected
-/// to the current (global) succcessor.
-CFGBlock* CFGBuilder::createBlock(bool add_successor) {
- CFGBlock* B = cfg->createBlock();
- if (add_successor && Succ) B->addSuccessor(Succ);
- return B;
-}
-
-/// FinishBlock - When the last statement has been added to the block,
-/// we must reverse the statements because they have been inserted
-/// in reverse order.
-void CFGBuilder::FinishBlock(CFGBlock* B) {
- assert (B);
- B->reverseStmts();
-}
-
-/// addStmt - Used to add statements/expressions to the current CFGBlock
-/// "Block". This method calls WalkAST on the passed statement to see if it
-/// contains any short-circuit expressions. If so, it recursively creates
-/// the necessary blocks for such expressions. It returns the "topmost" block
-/// of the created blocks, or the original value of "Block" when this method
-/// was called if no additional blocks are created.
-CFGBlock* CFGBuilder::addStmt(Stmt* Terminator) {
- if (!Block) Block = createBlock();
- return WalkAST(Terminator,true);
-}
-
-/// WalkAST - Used by addStmt to walk the subtree of a statement and
-/// add extra blocks for ternary operators, &&, and ||. We also
-/// process "," and DeclStmts (which may contain nested control-flow).
-CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {
- switch (Terminator->getStmtClass()) {
- case Stmt::ConditionalOperatorClass: {
- ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
-
- // Create the confluence block that will "merge" the results
- // of the ternary expression.
- CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();
- ConfluenceBlock->appendStmt(C);
- FinishBlock(ConfluenceBlock);
-
- // Create a block for the LHS expression if there is an LHS expression.
- // A GCC extension allows LHS to be NULL, causing the condition to
- // be the value that is returned instead.
- // e.g: x ?: y is shorthand for: x ? x : y;
- Succ = ConfluenceBlock;
- Block = NULL;
- CFGBlock* LHSBlock = NULL;
- if (C->getLHS()) {
- LHSBlock = Visit(C->getLHS());
- FinishBlock(LHSBlock);
- Block = NULL;
- }
-
- // Create the block for the RHS expression.
- Succ = ConfluenceBlock;
- CFGBlock* RHSBlock = Visit(C->getRHS());
- FinishBlock(RHSBlock);
-
- // Create the block that will contain the condition.
- Block = createBlock(false);
-
- if (LHSBlock)
- Block->addSuccessor(LHSBlock);
- else {
- // If we have no LHS expression, add the ConfluenceBlock as a direct
- // successor for the block containing the condition. Moreover,
- // we need to reverse the order of the predecessors in the
- // ConfluenceBlock because the RHSBlock will have been added to
- // the succcessors already, and we want the first predecessor to the
- // the block containing the expression for the case when the ternary
- // expression evaluates to true.
- Block->addSuccessor(ConfluenceBlock);
- assert (ConfluenceBlock->pred_size() == 2);
- std::reverse(ConfluenceBlock->pred_begin(),
- ConfluenceBlock->pred_end());
- }
-
- Block->addSuccessor(RHSBlock);
-
- Block->setTerminator(C);
- return addStmt(C->getCond());
- }
-
- case Stmt::ChooseExprClass: {
- ChooseExpr* C = cast<ChooseExpr>(Terminator);
-
- CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();
- ConfluenceBlock->appendStmt(C);
- FinishBlock(ConfluenceBlock);
-
- Succ = ConfluenceBlock;
- Block = NULL;
- CFGBlock* LHSBlock = Visit(C->getLHS());
- FinishBlock(LHSBlock);
-
- Succ = ConfluenceBlock;
- Block = NULL;
- CFGBlock* RHSBlock = Visit(C->getRHS());
- FinishBlock(RHSBlock);
-
- Block = createBlock(false);
- Block->addSuccessor(LHSBlock);
- Block->addSuccessor(RHSBlock);
- Block->setTerminator(C);
- return addStmt(C->getCond());
- }
-
- case Stmt::DeclStmtClass: {
- DeclStmt *DS = cast<DeclStmt>(Terminator);
- if (DS->hasSolitaryDecl()) {
- Block->appendStmt(Terminator);
- return WalkAST_VisitDeclSubExpr(DS->getSolitaryDecl());
- }
- else {
- typedef llvm::SmallVector<ScopedDecl*,10> BufTy;
- BufTy Buf;
- CFGBlock* B = 0;
-
- // FIXME: Add a reverse iterator for DeclStmt to avoid this
- // extra copy.
- for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
- DI != DE; ++DI)
- Buf.push_back(*DI);
-
- for (BufTy::reverse_iterator I=Buf.rbegin(), E=Buf.rend(); I!=E; ++I) {
- // Get the alignment of UnaryDeclStmt, padding out to >=8 bytes.
- unsigned A = llvm::AlignOf<UnaryDeclStmt>::Alignment < 8
- ? 8 : llvm::AlignOf<UnaryDeclStmt>::Alignment;
-
- // Allocate the UnaryDeclStmt using the BumpPtrAllocator. It will
- // get automatically freed with the CFG.
- void* Mem = cfg->getAllocator().Allocate(sizeof(UnaryDeclStmt), A);
- // Append the fake DeclStmt to block.
- Block->appendStmt(new (Mem) UnaryDeclStmt(*I));
- B = WalkAST_VisitDeclSubExpr(*I);
- }
- return B;
- }
- }
-
- case Stmt::AddrLabelExprClass: {
- AddrLabelExpr* A = cast<AddrLabelExpr>(Terminator);
- AddressTakenLabels.insert(A->getLabel());
-
- if (AlwaysAddStmt) Block->appendStmt(Terminator);
- return Block;
- }
-
- case Stmt::StmtExprClass:
- return WalkAST_VisitStmtExpr(cast<StmtExpr>(Terminator));
-
- case Stmt::SizeOfAlignOfTypeExprClass: {
- SizeOfAlignOfTypeExpr* E = cast<SizeOfAlignOfTypeExpr>(Terminator);
-
- // VLA types have expressions that must be evaluated.
- for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr());
- VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
- addStmt(VA->getSizeExpr());
-
- return Block;
- }
-
- case Stmt::UnaryOperatorClass: {
- UnaryOperator* U = cast<UnaryOperator>(Terminator);
-
- // sizeof(expressions). For such expressions,
- // the subexpression is not really evaluated, so
- // we don't care about control-flow within the sizeof.
- if (U->getOpcode() == UnaryOperator::SizeOf) {
- Block->appendStmt(Terminator);
- return Block;
- }
-
- break;
- }
-
- case Stmt::BinaryOperatorClass: {
- BinaryOperator* B = cast<BinaryOperator>(Terminator);
-
- if (B->isLogicalOp()) { // && or ||
- CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();
- ConfluenceBlock->appendStmt(B);
- FinishBlock(ConfluenceBlock);
-
- // create the block evaluating the LHS
- CFGBlock* LHSBlock = createBlock(false);
- LHSBlock->setTerminator(B);
-
- // create the block evaluating the RHS
- Succ = ConfluenceBlock;
- Block = NULL;
- CFGBlock* RHSBlock = Visit(B->getRHS());
- FinishBlock(RHSBlock);
-
- // Now link the LHSBlock with RHSBlock.
- if (B->getOpcode() == BinaryOperator::LOr) {
- LHSBlock->addSuccessor(ConfluenceBlock);
- LHSBlock->addSuccessor(RHSBlock);
- }
- else {
- assert (B->getOpcode() == BinaryOperator::LAnd);
- LHSBlock->addSuccessor(RHSBlock);
- LHSBlock->addSuccessor(ConfluenceBlock);
- }
-
- // Generate the blocks for evaluating the LHS.
- Block = LHSBlock;
- return addStmt(B->getLHS());
- }
- else if (B->getOpcode() == BinaryOperator::Comma) { // ,
- Block->appendStmt(B);
- addStmt(B->getRHS());
- return addStmt(B->getLHS());
- }
-
- break;
- }
-
- // Blocks: No support for blocks ... yet
- case Stmt::BlockExprClass:
- case Stmt::BlockDeclRefExprClass:
- return NYS();
-
- case Stmt::ParenExprClass:
- return WalkAST(cast<ParenExpr>(Terminator)->getSubExpr(), AlwaysAddStmt);
-
- default:
- break;
- };
-
- if (AlwaysAddStmt) Block->appendStmt(Terminator);
- return WalkAST_VisitChildren(Terminator);
-}
-
-/// WalkAST_VisitDeclSubExpr - Utility method to add block-level expressions
-/// for initializers in Decls.
-CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(ScopedDecl* D) {
- VarDecl* VD = dyn_cast<VarDecl>(D);
-
- if (!VD)
- return Block;
-
- Expr* Init = VD->getInit();
-
- if (Init) {
- // Optimization: Don't create separate block-level statements for literals.
- switch (Init->getStmtClass()) {
- case Stmt::IntegerLiteralClass:
- case Stmt::CharacterLiteralClass:
- case Stmt::StringLiteralClass:
- break;
- default:
- Block = addStmt(Init);
- }
- }
-
- // If the type of VD is a VLA, then we must process its size expressions.
- for (VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); VA != 0;
- VA = FindVA(VA->getElementType().getTypePtr()))
- Block = addStmt(VA->getSizeExpr());
-
- return Block;
-}
-
-/// WalkAST_VisitChildren - Utility method to call WalkAST on the
-/// children of a Stmt.
-CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* Terminator) {
- CFGBlock* B = Block;
- for (Stmt::child_iterator I = Terminator->child_begin(), E = Terminator->child_end() ;
- I != E; ++I)
- if (*I) B = WalkAST(*I);
-
- return B;
-}
-
-/// WalkAST_VisitStmtExpr - Utility method to handle (nested) statement
-/// expressions (a GCC extension).
-CFGBlock* CFGBuilder::WalkAST_VisitStmtExpr(StmtExpr* Terminator) {
- Block->appendStmt(Terminator);
- return VisitCompoundStmt(Terminator->getSubStmt());
-}
-
-/// VisitStmt - Handle statements with no branching control flow.
-CFGBlock* CFGBuilder::VisitStmt(Stmt* Statement) {
- // We cannot assume that we are in the middle of a basic block, since
- // the CFG might only be constructed for this single statement. If
- // we have no current basic block, just create one lazily.
- if (!Block) Block = createBlock();
-
- // Simply add the statement to the current block. We actually
- // insert statements in reverse order; this order is reversed later
- // when processing the containing element in the AST.
- addStmt(Statement);
-
- return Block;
-}
-
-CFGBlock* CFGBuilder::VisitNullStmt(NullStmt* Statement) {
- return Block;
-}
-
-CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
-
- CFGBlock* LastBlock = NULL;
-
- for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
- I != E; ++I ) {
- LastBlock = Visit(*I);
- }
-
- return LastBlock;
-}
-
-CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
- // We may see an if statement in the middle of a basic block, or
- // it may be the first statement we are processing. In either case,
- // we create a new basic block. First, we create the blocks for
- // the then...else statements, and then we create the block containing
- // the if statement. If we were in the middle of a block, we
- // stop processing that block and reverse its statements. That block
- // is then the implicit successor for the "then" and "else" clauses.
-
- // The block we were proccessing is now finished. Make it the
- // successor block.
- if (Block) {
- Succ = Block;
- FinishBlock(Block);
- }
-
- // Process the false branch. NULL out Block so that the recursive
- // call to Visit will create a new basic block.
- // Null out Block so that all successor
- CFGBlock* ElseBlock = Succ;
-
- if (Stmt* Else = I->getElse()) {
- SaveAndRestore<CFGBlock*> sv(Succ);
-
- // NULL out Block so that the recursive call to Visit will
- // create a new basic block.
- Block = NULL;
- ElseBlock = Visit(Else);
-
- if (!ElseBlock) // Can occur when the Else body has all NullStmts.
- ElseBlock = sv.get();
- else if (Block)
- FinishBlock(ElseBlock);
- }
-
- // Process the true branch. NULL out Block so that the recursive
- // call to Visit will create a new basic block.
- // Null out Block so that all successor
- CFGBlock* ThenBlock;
- {
- Stmt* Then = I->getThen();
- assert (Then);
- SaveAndRestore<CFGBlock*> sv(Succ);
- Block = NULL;
- ThenBlock = Visit(Then);
-
- if (!ThenBlock) // Can occur when the Then body has all NullStmts.
- ThenBlock = sv.get();
- else if (Block)
- FinishBlock(ThenBlock);
- }
-
- // Now create a new block containing the if statement.
- Block = createBlock(false);
-
- // Set the terminator of the new block to the If statement.
- Block->setTerminator(I);
-
- // Now add the successors.
- Block->addSuccessor(ThenBlock);
- Block->addSuccessor(ElseBlock);
-
- // Add the condition as the last statement in the new block. This
- // may create new blocks as the condition may contain control-flow. Any
- // newly created blocks will be pointed to be "Block".
- return addStmt(I->getCond()->IgnoreParens());
-}
-
-
-CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) {
- // If we were in the middle of a block we stop processing that block
- // and reverse its statements.
- //
- // NOTE: If a "return" appears in the middle of a block, this means
- // that the code afterwards is DEAD (unreachable). We still
- // keep a basic block for that code; a simple "mark-and-sweep"
- // from the entry block will be able to report such dead
- // blocks.
- if (Block) FinishBlock(Block);
-
- // Create the new block.
- Block = createBlock(false);
-
- // The Exit block is the only successor.
- Block->addSuccessor(&cfg->getExit());
-
- // Add the return statement to the block. This may create new blocks
- // if R contains control-flow (short-circuit operations).
- return addStmt(R);
-}
-
-CFGBlock* CFGBuilder::VisitLabelStmt(LabelStmt* L) {
- // Get the block of the labeled statement. Add it to our map.
- Visit(L->getSubStmt());
- CFGBlock* LabelBlock = Block;
-
- if (!LabelBlock) // This can happen when the body is empty, i.e.
- LabelBlock=createBlock(); // scopes that only contains NullStmts.
-
- assert (LabelMap.find(L) == LabelMap.end() && "label already in map");
- LabelMap[ L ] = LabelBlock;
-
- // Labels partition blocks, so this is the end of the basic block
- // we were processing (L is the block's label). Because this is
- // label (and we have already processed the substatement) there is no
- // extra control-flow to worry about.
- LabelBlock->setLabel(L);
- FinishBlock(LabelBlock);
-
- // We set Block to NULL to allow lazy creation of a new block
- // (if necessary);
- Block = NULL;
-
- // This block is now the implicit successor of other blocks.
- Succ = LabelBlock;
-
- return LabelBlock;
-}
-
-CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) {
- // Goto is a control-flow statement. Thus we stop processing the
- // current block and create a new one.
- if (Block) FinishBlock(Block);
- Block = createBlock(false);
- Block->setTerminator(G);
-
- // If we already know the mapping to the label block add the
- // successor now.
- LabelMapTy::iterator I = LabelMap.find(G->getLabel());
-
- if (I == LabelMap.end())
- // We will need to backpatch this block later.
- BackpatchBlocks.push_back(Block);
- else
- Block->addSuccessor(I->second);
-
- return Block;
-}
-
-CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
- // "for" is a control-flow statement. Thus we stop processing the
- // current block.
-
- CFGBlock* LoopSuccessor = NULL;
-
- if (Block) {
- FinishBlock(Block);
- LoopSuccessor = Block;
- }
- else LoopSuccessor = Succ;
-
- // Because of short-circuit evaluation, the condition of the loop
- // can span multiple basic blocks. Thus we need the "Entry" and "Exit"
- // blocks that evaluate the condition.
- CFGBlock* ExitConditionBlock = createBlock(false);
- CFGBlock* EntryConditionBlock = ExitConditionBlock;
-
- // Set the terminator for the "exit" condition block.
- ExitConditionBlock->setTerminator(F);
-
- // Now add the actual condition to the condition block. Because the
- // condition itself may contain control-flow, new blocks may be created.
- if (Stmt* C = F->getCond()) {
- Block = ExitConditionBlock;
- EntryConditionBlock = addStmt(C);
- if (Block) FinishBlock(EntryConditionBlock);
- }
-
- // The condition block is the implicit successor for the loop body as
- // well as any code above the loop.
- Succ = EntryConditionBlock;
-
- // Now create the loop body.
- {
- assert (F->getBody());
-
- // Save the current values for Block, Succ, and continue and break targets
- SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
- save_continue(ContinueTargetBlock),
- save_break(BreakTargetBlock);
-
- // Create a new block to contain the (bottom) of the loop body.
- Block = NULL;
-
- if (Stmt* I = F->getInc()) {
- // Generate increment code in its own basic block. This is the target
- // of continue statements.
- Succ = addStmt(I);
- Block = 0;
- ContinueTargetBlock = Succ;
- }
- else {
- // No increment code. Continues should go the the entry condition block.
- ContinueTargetBlock = EntryConditionBlock;
- }
-
- // All breaks should go to the code following the loop.
- BreakTargetBlock = LoopSuccessor;
-
- // Now populate the body block, and in the process create new blocks
- // as we walk the body of the loop.
- CFGBlock* BodyBlock = Visit(F->getBody());
-
- if (!BodyBlock)
- BodyBlock = EntryConditionBlock; // can happen for "for (...;...; ) ;"
- else if (Block)
- FinishBlock(BodyBlock);
-
- // This new body block is a successor to our "exit" condition block.
- ExitConditionBlock->addSuccessor(BodyBlock);
- }
-
- // Link up the condition block with the code that follows the loop.
- // (the false branch).
- ExitConditionBlock->addSuccessor(LoopSuccessor);
-
- // If the loop contains initialization, create a new block for those
- // statements. This block can also contain statements that precede
- // the loop.
- if (Stmt* I = F->getInit()) {
- Block = createBlock();
- return addStmt(I);
- }
- else {
- // There is no loop initialization. We are thus basically a while
- // loop. NULL out Block to force lazy block construction.
- Block = NULL;
- Succ = EntryConditionBlock;
- return EntryConditionBlock;
- }
-}
-
-CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
- // "while" is a control-flow statement. Thus we stop processing the
- // current block.
-
- CFGBlock* LoopSuccessor = NULL;
-
- if (Block) {
- FinishBlock(Block);
- LoopSuccessor = Block;
- }
- else LoopSuccessor = Succ;
-
- // Because of short-circuit evaluation, the condition of the loop
- // can span multiple basic blocks. Thus we need the "Entry" and "Exit"
- // blocks that evaluate the condition.
- CFGBlock* ExitConditionBlock = createBlock(false);
- CFGBlock* EntryConditionBlock = ExitConditionBlock;
-
- // Set the terminator for the "exit" condition block.
- ExitConditionBlock->setTerminator(W);
-
- // Now add the actual condition to the condition block. Because the
- // condition itself may contain control-flow, new blocks may be created.
- // Thus we update "Succ" after adding the condition.
- if (Stmt* C = W->getCond()) {
- Block = ExitConditionBlock;
- EntryConditionBlock = addStmt(C);
- assert (Block == EntryConditionBlock);
- if (Block) FinishBlock(EntryConditionBlock);
- }
-
- // The condition block is the implicit successor for the loop body as
- // well as any code above the loop.
- Succ = EntryConditionBlock;
-
- // Process the loop body.
- {
- assert (W->getBody());
-
- // Save the current values for Block, Succ, and continue and break targets
- SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
- save_continue(ContinueTargetBlock),
- save_break(BreakTargetBlock);
-
- // All continues within this loop should go to the condition block
- ContinueTargetBlock = EntryConditionBlock;
-
- // All breaks should go to the code following the loop.
- BreakTargetBlock = LoopSuccessor;
-
- // NULL out Block to force lazy instantiation of blocks for the body.
- Block = NULL;
-
- // Create the body. The returned block is the entry to the loop body.
- CFGBlock* BodyBlock = Visit(W->getBody());
-
- if (!BodyBlock)
- BodyBlock = EntryConditionBlock; // can happen for "while(...) ;"
- else if (Block)
- FinishBlock(BodyBlock);
-
- // Add the loop body entry as a successor to the condition.
- ExitConditionBlock->addSuccessor(BodyBlock);
- }
-
- // Link up the condition block with the code that follows the loop.
- // (the false branch).
- ExitConditionBlock->addSuccessor(LoopSuccessor);
-
- // There can be no more statements in the condition block
- // since we loop back to this block. NULL out Block to force
- // lazy creation of another block.
- Block = NULL;
-
- // Return the condition block, which is the dominating block for the loop.
- Succ = EntryConditionBlock;
- return EntryConditionBlock;
-}
-
-CFGBlock* CFGBuilder::VisitDoStmt(DoStmt* D) {
- // "do...while" is a control-flow statement. Thus we stop processing the
- // current block.
-
- CFGBlock* LoopSuccessor = NULL;
-
- if (Block) {
- FinishBlock(Block);
- LoopSuccessor = Block;
- }
- else LoopSuccessor = Succ;
-
- // Because of short-circuit evaluation, the condition of the loop
- // can span multiple basic blocks. Thus we need the "Entry" and "Exit"
- // blocks that evaluate the condition.
- CFGBlock* ExitConditionBlock = createBlock(false);
- CFGBlock* EntryConditionBlock = ExitConditionBlock;
-
- // Set the terminator for the "exit" condition block.
- ExitConditionBlock->setTerminator(D);
-
- // Now add the actual condition to the condition block. Because the
- // condition itself may contain control-flow, new blocks may be created.
- if (Stmt* C = D->getCond()) {
- Block = ExitConditionBlock;
- EntryConditionBlock = addStmt(C);
- if (Block) FinishBlock(EntryConditionBlock);
- }
-
- // The condition block is the implicit successor for the loop body.
- Succ = EntryConditionBlock;
-
- // Process the loop body.
- CFGBlock* BodyBlock = NULL;
- {
- assert (D->getBody());
-
- // Save the current values for Block, Succ, and continue and break targets
- SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
- save_continue(ContinueTargetBlock),
- save_break(BreakTargetBlock);
-
- // All continues within this loop should go to the condition block
- ContinueTargetBlock = EntryConditionBlock;
-
- // All breaks should go to the code following the loop.
- BreakTargetBlock = LoopSuccessor;
-
- // NULL out Block to force lazy instantiation of blocks for the body.
- Block = NULL;
-
- // Create the body. The returned block is the entry to the loop body.
- BodyBlock = Visit(D->getBody());
-
- if (!BodyBlock)
- BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)"
- else if (Block)
- FinishBlock(BodyBlock);
-
- // Add the loop body entry as a successor to the condition.
- ExitConditionBlock->addSuccessor(BodyBlock);
- }
-
- // Link up the condition block with the code that follows the loop.
- // (the false branch).
- ExitConditionBlock->addSuccessor(LoopSuccessor);
-
- // There can be no more statements in the body block(s)
- // since we loop back to the body. NULL out Block to force
- // lazy creation of another block.
- Block = NULL;
-
- // Return the loop body, which is the dominating block for the loop.
- Succ = BodyBlock;
- return BodyBlock;
-}
-
-CFGBlock* CFGBuilder::VisitContinueStmt(ContinueStmt* C) {
- // "continue" is a control-flow statement. Thus we stop processing the
- // current block.
- if (Block) FinishBlock(Block);
-
- // Now create a new block that ends with the continue statement.
- Block = createBlock(false);
- Block->setTerminator(C);
-
- // If there is no target for the continue, then we are looking at an
- // incomplete AST. Handle this by not registering a successor.
- if (ContinueTargetBlock) Block->addSuccessor(ContinueTargetBlock);
-
- return Block;
-}
-
-CFGBlock* CFGBuilder::VisitBreakStmt(BreakStmt* B) {
- // "break" is a control-flow statement. Thus we stop processing the
- // current block.
- if (Block) FinishBlock(Block);
-
- // Now create a new block that ends with the continue statement.
- Block = createBlock(false);
- Block->setTerminator(B);
-
- // If there is no target for the break, then we are looking at an
- // incomplete AST. Handle this by not registering a successor.
- if (BreakTargetBlock) Block->addSuccessor(BreakTargetBlock);
-
- return Block;
-}
-
-CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
- // "switch" is a control-flow statement. Thus we stop processing the
- // current block.
- CFGBlock* SwitchSuccessor = NULL;
-
- if (Block) {
- FinishBlock(Block);
- SwitchSuccessor = Block;
- }
- else SwitchSuccessor = Succ;
-
- // Save the current "switch" context.
- SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),
- save_break(BreakTargetBlock),
- save_default(DefaultCaseBlock);
-
- // Set the "default" case to be the block after the switch statement.
- // If the switch statement contains a "default:", this value will
- // be overwritten with the block for that code.
- DefaultCaseBlock = SwitchSuccessor;
-
- // Create a new block that will contain the switch statement.
- SwitchTerminatedBlock = createBlock(false);
-
- // Now process the switch body. The code after the switch is the implicit
- // successor.
- Succ = SwitchSuccessor;
- BreakTargetBlock = SwitchSuccessor;
-
- // When visiting the body, the case statements should automatically get
- // linked up to the switch. We also don't keep a pointer to the body,
- // since all control-flow from the switch goes to case/default statements.
- assert (Terminator->getBody() && "switch must contain a non-NULL body");
- Block = NULL;
- CFGBlock *BodyBlock = Visit(Terminator->getBody());
- if (Block) FinishBlock(BodyBlock);
-
- // If we have no "default:" case, the default transition is to the
- // code following the switch body.
- SwitchTerminatedBlock->addSuccessor(DefaultCaseBlock);
-
- // Add the terminator and condition in the switch block.
- SwitchTerminatedBlock->setTerminator(Terminator);
- assert (Terminator->getCond() && "switch condition must be non-NULL");
- Block = SwitchTerminatedBlock;
-
- return addStmt(Terminator->getCond());
-}
-
-CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* Terminator) {
- // CaseStmts are essentially labels, so they are the
- // first statement in a block.
-
- if (Terminator->getSubStmt()) Visit(Terminator->getSubStmt());
- CFGBlock* CaseBlock = Block;
- if (!CaseBlock) CaseBlock = createBlock();
-
- // Cases statements partition blocks, so this is the top of
- // the basic block we were processing (the "case XXX:" is the label).
- CaseBlock->setLabel(Terminator);
- FinishBlock(CaseBlock);
-
- // Add this block to the list of successors for the block with the
- // switch statement.
- assert (SwitchTerminatedBlock);
- SwitchTerminatedBlock->addSuccessor(CaseBlock);
-
- // We set Block to NULL to allow lazy creation of a new block (if necessary)
- Block = NULL;
-
- // This block is now the implicit successor of other blocks.
- Succ = CaseBlock;
-
- return CaseBlock;
-}
-
-CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {
- if (Terminator->getSubStmt()) Visit(Terminator->getSubStmt());
- DefaultCaseBlock = Block;
- if (!DefaultCaseBlock) DefaultCaseBlock = createBlock();
-
- // Default statements partition blocks, so this is the top of
- // the basic block we were processing (the "default:" is the label).
- DefaultCaseBlock->setLabel(Terminator);
- FinishBlock(DefaultCaseBlock);
-
- // Unlike case statements, we don't add the default block to the
- // successors for the switch statement immediately. This is done
- // when we finish processing the switch statement. This allows for
- // the default case (including a fall-through to the code after the
- // switch statement) to always be the last successor of a switch-terminated
- // block.
-
- // We set Block to NULL to allow lazy creation of a new block (if necessary)
- Block = NULL;
-
- // This block is now the implicit successor of other blocks.
- Succ = DefaultCaseBlock;
-
- return DefaultCaseBlock;
-}
-
-CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) {
- // Lazily create the indirect-goto dispatch block if there isn't one
- // already.
- CFGBlock* IBlock = cfg->getIndirectGotoBlock();
-
- if (!IBlock) {
- IBlock = createBlock(false);
- cfg->setIndirectGotoBlock(IBlock);
- }
-
- // IndirectGoto is a control-flow statement. Thus we stop processing the
- // current block and create a new one.
- if (Block) FinishBlock(Block);
- Block = createBlock(false);
- Block->setTerminator(I);
- Block->addSuccessor(IBlock);
- return addStmt(I->getTarget());
-}
-
-
-} // end anonymous namespace
-
-/// createBlock - Constructs and adds a new CFGBlock to the CFG. The
-/// block has no successors or predecessors. If this is the first block
-/// created in the CFG, it is automatically set to be the Entry and Exit
-/// of the CFG.
-CFGBlock* CFG::createBlock() {
- bool first_block = begin() == end();
-
- // Create the block.
- Blocks.push_front(CFGBlock(NumBlockIDs++));
-
- // If this is the first block, set it as the Entry and Exit.
- if (first_block) Entry = Exit = &front();
-
- // Return the block.
- return &front();
-}
-
-/// buildCFG - Constructs a CFG from an AST. Ownership of the returned
-/// CFG is returned to the caller.
-CFG* CFG::buildCFG(Stmt* Statement) {
- CFGBuilder Builder;
- return Builder.buildCFG(Statement);
-}
-
-/// reverseStmts - Reverses the orders of statements within a CFGBlock.
-void CFGBlock::reverseStmts() { std::reverse(Stmts.begin(),Stmts.end()); }
-
-//===----------------------------------------------------------------------===//
-// CFG: Queries for BlkExprs.
-//===----------------------------------------------------------------------===//
-
-namespace {
- typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
-}
-
-static void FindSubExprAssignments(Stmt* Terminator, llvm::SmallPtrSet<Expr*,50>& Set) {
- if (!Terminator)
- return;
-
- for (Stmt::child_iterator I=Terminator->child_begin(), E=Terminator->child_end(); I!=E; ++I) {
- if (!*I) continue;
-
- if (BinaryOperator* B = dyn_cast<BinaryOperator>(*I))
- if (B->isAssignmentOp()) Set.insert(B);
-
- FindSubExprAssignments(*I, Set);
- }
-}
-
-static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {
- BlkExprMapTy* M = new BlkExprMapTy();
-
- // Look for assignments that are used as subexpressions. These are the
- // only assignments that we want to *possibly* register as a block-level
- // expression. Basically, if an assignment occurs both in a subexpression
- // and at the block-level, it is a block-level expression.
- llvm::SmallPtrSet<Expr*,50> SubExprAssignments;
-
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)
- for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)
- FindSubExprAssignments(*BI, SubExprAssignments);
-
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
-
- // Iterate over the statements again on identify the Expr* and Stmt* at
- // the block-level that are block-level expressions.
-
- for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI)
- if (Expr* Exp = dyn_cast<Expr>(*BI)) {
-
- if (BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
- // Assignment expressions that are not nested within another
- // expression are really "statements" whose value is never
- // used by another expression.
- if (B->isAssignmentOp() && !SubExprAssignments.count(Exp))
- continue;
- }
- else if (const StmtExpr* Terminator = dyn_cast<StmtExpr>(Exp)) {
- // Special handling for statement expressions. The last statement
- // in the statement expression is also a block-level expr.
- const CompoundStmt* C = Terminator->getSubStmt();
- if (!C->body_empty()) {
- unsigned x = M->size();
- (*M)[C->body_back()] = x;
- }
- }
-
- unsigned x = M->size();
- (*M)[Exp] = x;
- }
-
- // Look at terminators. The condition is a block-level expression.
-
- Expr* Exp = I->getTerminatorCondition();
-
- if (Exp && M->find(Exp) == M->end()) {
- unsigned x = M->size();
- (*M)[Exp] = x;
- }
- }
-
- return M;
-}
-
-CFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt* S) {
- assert(S != NULL);
- if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); }
-
- BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap);
- BlkExprMapTy::iterator I = M->find(S);
-
- if (I == M->end()) return CFG::BlkExprNumTy();
- else return CFG::BlkExprNumTy(I->second);
-}
-
-unsigned CFG::getNumBlkExprs() {
- if (const BlkExprMapTy* M = reinterpret_cast<const BlkExprMapTy*>(BlkExprMap))
- return M->size();
- else {
- // We assume callers interested in the number of BlkExprs will want
- // the map constructed if it doesn't already exist.
- BlkExprMap = (void*) PopulateBlkExprMap(*this);
- return reinterpret_cast<BlkExprMapTy*>(BlkExprMap)->size();
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Cleanup: CFG dstor.
-//===----------------------------------------------------------------------===//
-
-CFG::~CFG() {
- delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
-}
-
-//===----------------------------------------------------------------------===//
-// CFG pretty printing
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN StmtPrinterHelper : public PrinterHelper {
-
- typedef llvm::DenseMap<Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;
- StmtMapTy StmtMap;
- signed CurrentBlock;
- unsigned CurrentStmt;
-
-public:
-
- StmtPrinterHelper(const CFG* cfg) : CurrentBlock(0), CurrentStmt(0) {
- for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
- unsigned j = 1;
- for (CFGBlock::const_iterator BI = I->begin(), BEnd = I->end() ;
- BI != BEnd; ++BI, ++j )
- StmtMap[*BI] = std::make_pair(I->getBlockID(),j);
- }
- }
-
- virtual ~StmtPrinterHelper() {}
-
- void setBlockID(signed i) { CurrentBlock = i; }
- void setStmtID(unsigned i) { CurrentStmt = i; }
-
- virtual bool handledStmt(Stmt* Terminator, llvm::raw_ostream& OS) {
-
- StmtMapTy::iterator I = StmtMap.find(Terminator);
-
- if (I == StmtMap.end())
- return false;
-
- if (CurrentBlock >= 0 && I->second.first == (unsigned) CurrentBlock
- && I->second.second == CurrentStmt)
- return false;
-
- OS << "[B" << I->second.first << "." << I->second.second << "]";
- return true;
- }
-};
-
-class VISIBILITY_HIDDEN CFGBlockTerminatorPrint
- : public StmtVisitor<CFGBlockTerminatorPrint,void> {
-
- llvm::raw_ostream& OS;
- StmtPrinterHelper* Helper;
-public:
- CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper)
- : OS(os), Helper(helper) {}
-
- void VisitIfStmt(IfStmt* I) {
- OS << "if ";
- I->getCond()->printPretty(OS,Helper);
- }
-
- // Default case.
- void VisitStmt(Stmt* Terminator) { Terminator->printPretty(OS); }
-
- void VisitForStmt(ForStmt* F) {
- OS << "for (" ;
- if (F->getInit()) OS << "...";
- OS << "; ";
- if (Stmt* C = F->getCond()) C->printPretty(OS,Helper);
- OS << "; ";
- if (F->getInc()) OS << "...";
- OS << ")";
- }
-
- void VisitWhileStmt(WhileStmt* W) {
- OS << "while " ;
- if (Stmt* C = W->getCond()) C->printPretty(OS,Helper);
- }
-
- void VisitDoStmt(DoStmt* D) {
- OS << "do ... while ";
- if (Stmt* C = D->getCond()) C->printPretty(OS,Helper);
- }
-
- void VisitSwitchStmt(SwitchStmt* Terminator) {
- OS << "switch ";
- Terminator->getCond()->printPretty(OS,Helper);
- }
-
- void VisitConditionalOperator(ConditionalOperator* C) {
- C->getCond()->printPretty(OS,Helper);
- OS << " ? ... : ...";
- }
-
- void VisitChooseExpr(ChooseExpr* C) {
- OS << "__builtin_choose_expr( ";
- C->getCond()->printPretty(OS,Helper);
- OS << " )";
- }
-
- void VisitIndirectGotoStmt(IndirectGotoStmt* I) {
- OS << "goto *";
- I->getTarget()->printPretty(OS,Helper);
- }
-
- void VisitBinaryOperator(BinaryOperator* B) {
- if (!B->isLogicalOp()) {
- VisitExpr(B);
- return;
- }
-
- B->getLHS()->printPretty(OS,Helper);
-
- switch (B->getOpcode()) {
- case BinaryOperator::LOr:
- OS << " || ...";
- return;
- case BinaryOperator::LAnd:
- OS << " && ...";
- return;
- default:
- assert(false && "Invalid logical operator.");
- }
- }
-
- void VisitExpr(Expr* E) {
- E->printPretty(OS,Helper);
- }
-};
-
-
-void print_stmt(llvm::raw_ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminator) {
- if (Helper) {
- // special printing for statement-expressions.
- if (StmtExpr* SE = dyn_cast<StmtExpr>(Terminator)) {
- CompoundStmt* Sub = SE->getSubStmt();
-
- if (Sub->child_begin() != Sub->child_end()) {
- OS << "({ ... ; ";
- Helper->handledStmt(*SE->getSubStmt()->body_rbegin(),OS);
- OS << " })\n";
- return;
- }
- }
-
- // special printing for comma expressions.
- if (BinaryOperator* B = dyn_cast<BinaryOperator>(Terminator)) {
- if (B->getOpcode() == BinaryOperator::Comma) {
- OS << "... , ";
- Helper->handledStmt(B->getRHS(),OS);
- OS << '\n';
- return;
- }
- }
- }
-
- Terminator->printPretty(OS, Helper);
-
- // Expressions need a newline.
- if (isa<Expr>(Terminator)) OS << '\n';
-}
-
-void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
- StmtPrinterHelper* Helper, bool print_edges) {
-
- if (Helper) Helper->setBlockID(B.getBlockID());
-
- // Print the header.
- OS << "\n [ B" << B.getBlockID();
-
- if (&B == &cfg->getEntry())
- OS << " (ENTRY) ]\n";
- else if (&B == &cfg->getExit())
- OS << " (EXIT) ]\n";
- else if (&B == cfg->getIndirectGotoBlock())
- OS << " (INDIRECT GOTO DISPATCH) ]\n";
- else
- OS << " ]\n";
-
- // Print the label of this block.
- if (Stmt* Terminator = const_cast<Stmt*>(B.getLabel())) {
-
- if (print_edges)
- OS << " ";
-
- if (LabelStmt* L = dyn_cast<LabelStmt>(Terminator))
- OS << L->getName();
- else if (CaseStmt* C = dyn_cast<CaseStmt>(Terminator)) {
- OS << "case ";
- C->getLHS()->printPretty(OS);
- if (C->getRHS()) {
- OS << " ... ";
- C->getRHS()->printPretty(OS);
- }
- }
- else if (isa<DefaultStmt>(Terminator))
- OS << "default";
- else
- assert(false && "Invalid label statement in CFGBlock.");
-
- OS << ":\n";
- }
-
- // Iterate through the statements in the block and print them.
- unsigned j = 1;
-
- for (CFGBlock::const_iterator I = B.begin(), E = B.end() ;
- I != E ; ++I, ++j ) {
-
- // Print the statement # in the basic block and the statement itself.
- if (print_edges)
- OS << " ";
-
- OS << llvm::format("%3d", j) << ": ";
-
- if (Helper)
- Helper->setStmtID(j);
-
- print_stmt(OS,Helper,*I);
- }
-
- // Print the terminator of this block.
- if (B.getTerminator()) {
- if (print_edges)
- OS << " ";
-
- OS << " T: ";
-
- if (Helper) Helper->setBlockID(-1);
-
- CFGBlockTerminatorPrint TPrinter(OS,Helper);
- TPrinter.Visit(const_cast<Stmt*>(B.getTerminator()));
- OS << '\n';
- }
-
- if (print_edges) {
- // Print the predecessors of this block.
- OS << " Predecessors (" << B.pred_size() << "):";
- unsigned i = 0;
-
- for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end();
- I != E; ++I, ++i) {
-
- if (i == 8 || (i-8) == 0)
- OS << "\n ";
-
- OS << " B" << (*I)->getBlockID();
- }
-
- OS << '\n';
-
- // Print the successors of this block.
- OS << " Successors (" << B.succ_size() << "):";
- i = 0;
-
- for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end();
- I != E; ++I, ++i) {
-
- if (i == 8 || (i-8) % 10 == 0)
- OS << "\n ";
-
- OS << " B" << (*I)->getBlockID();
- }
-
- OS << '\n';
- }
-}
-
-} // end anonymous namespace
-
-/// dump - A simple pretty printer of a CFG that outputs to stderr.
-void CFG::dump() const { print(llvm::errs()); }
-
-/// print - A simple pretty printer of a CFG that outputs to an ostream.
-void CFG::print(llvm::raw_ostream& OS) const {
-
- StmtPrinterHelper Helper(this);
-
- // Print the entry block.
- print_block(OS, this, getEntry(), &Helper, true);
-
- // Iterate through the CFGBlocks and print them one by one.
- for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) {
- // Skip the entry block, because we already printed it.
- if (&(*I) == &getEntry() || &(*I) == &getExit())
- continue;
-
- print_block(OS, this, *I, &Helper, true);
- }
-
- // Print the exit block.
- print_block(OS, this, getExit(), &Helper, true);
-}
-
-/// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
-void CFGBlock::dump(const CFG* cfg) const { print(llvm::errs(), cfg); }
-
-/// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
-/// Generally this will only be called from CFG::print.
-void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg) const {
- StmtPrinterHelper Helper(cfg);
- print_block(OS, cfg, *this, &Helper, true);
-}
-
-/// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
-void CFGBlock::printTerminator(llvm::raw_ostream& OS) const {
- CFGBlockTerminatorPrint TPrinter(OS,NULL);
- TPrinter.Visit(const_cast<Stmt*>(getTerminator()));
-}
-
-Expr* CFGBlock::getTerminatorCondition() {
-
- if (!Terminator)
- return NULL;
-
- Expr* E = NULL;
-
- switch (Terminator->getStmtClass()) {
- default:
- break;
-
- case Stmt::ForStmtClass:
- E = cast<ForStmt>(Terminator)->getCond();
- break;
-
- case Stmt::WhileStmtClass:
- E = cast<WhileStmt>(Terminator)->getCond();
- break;
-
- case Stmt::DoStmtClass:
- E = cast<DoStmt>(Terminator)->getCond();
- break;
-
- case Stmt::IfStmtClass:
- E = cast<IfStmt>(Terminator)->getCond();
- break;
-
- case Stmt::ChooseExprClass:
- E = cast<ChooseExpr>(Terminator)->getCond();
- break;
-
- case Stmt::IndirectGotoStmtClass:
- E = cast<IndirectGotoStmt>(Terminator)->getTarget();
- break;
-
- case Stmt::SwitchStmtClass:
- E = cast<SwitchStmt>(Terminator)->getCond();
- break;
-
- case Stmt::ConditionalOperatorClass:
- E = cast<ConditionalOperator>(Terminator)->getCond();
- break;
-
- case Stmt::BinaryOperatorClass: // '&&' and '||'
- E = cast<BinaryOperator>(Terminator)->getLHS();
- break;
- }
-
- return E ? E->IgnoreParens() : NULL;
-}
-
-bool CFGBlock::hasBinaryBranchTerminator() const {
-
- if (!Terminator)
- return false;
-
- Expr* E = NULL;
-
- switch (Terminator->getStmtClass()) {
- default:
- return false;
-
- case Stmt::ForStmtClass:
- case Stmt::WhileStmtClass:
- case Stmt::DoStmtClass:
- case Stmt::IfStmtClass:
- case Stmt::ChooseExprClass:
- case Stmt::ConditionalOperatorClass:
- case Stmt::BinaryOperatorClass:
- return true;
- }
-
- return E ? E->IgnoreParens() : NULL;
-}
-
-
-//===----------------------------------------------------------------------===//
-// CFG Graphviz Visualization
-//===----------------------------------------------------------------------===//
-
-
-#ifndef NDEBUG
-static StmtPrinterHelper* GraphHelper;
-#endif
-
-void CFG::viewCFG() const {
-#ifndef NDEBUG
- StmtPrinterHelper H(this);
- GraphHelper = &H;
- llvm::ViewGraph(this,"CFG");
- GraphHelper = NULL;
-#endif
-}
-
-namespace llvm {
-template<>
-struct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits {
- static std::string getNodeLabel(const CFGBlock* Node, const CFG* Graph) {
-
-#ifndef NDEBUG
- std::string OutSStr;
- llvm::raw_string_ostream Out(OutSStr);
- print_block(Out,Graph, *Node, GraphHelper, false);
- std::string& OutStr = Out.str();
-
- if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
-
- // Process string output to make it nicer...
- for (unsigned i = 0; i != OutStr.length(); ++i)
- if (OutStr[i] == '\n') { // Left justify
- OutStr[i] = '\\';
- OutStr.insert(OutStr.begin()+i+1, 'l');
- }
-
- return OutStr;
-#else
- return "";
-#endif
- }
-};
-} // end namespace llvm
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
deleted file mode 100644
index 3ddf81974b68..000000000000
--- a/clang/lib/AST/Decl.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Decl subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/IdentifierTable.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Decl Allocation/Deallocation Method Implementations
-//===----------------------------------------------------------------------===//
-
-TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
- void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
- return new (Mem) TranslationUnitDecl();
-}
-
-NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id) {
- void *Mem = C.getAllocator().Allocate<NamespaceDecl>();
- return new (Mem) NamespaceDecl(DC, L, Id);
-}
-
-void NamespaceDecl::Destroy(ASTContext& C) {
- // NamespaceDecl uses "NextDeclarator" to chain namespace declarations
- // together. They are all top-level Decls.
-
- this->~NamespaceDecl();
- C.getAllocator().Deallocate((void *)this);
-}
-
-
-ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<ImplicitParamDecl>();
- return new (Mem) ImplicitParamDecl(ImplicitParam, DC, L, Id, T, PrevDecl);
-}
-
-VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S, ScopedDecl *PrevDecl,
- SourceLocation TypeSpecStartLoc) {
- void *Mem = C.getAllocator().Allocate<VarDecl>();
- return new (Mem) VarDecl(Var, DC, L, Id, T, S, PrevDecl, TypeSpecStartLoc);
-}
-
-ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, StorageClass S,
- Expr *DefArg, ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
- return new (Mem) ParmVarDecl(DC, L, Id, T, S, DefArg, PrevDecl);
-}
-
-FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S, bool isInline,
- ScopedDecl *PrevDecl,
- SourceLocation TypeSpecStartLoc) {
- void *Mem = C.getAllocator().Allocate<FunctionDecl>();
- return new (Mem) FunctionDecl(Function, DC, L, Id, T, S, isInline, PrevDecl,
- TypeSpecStartLoc);
-}
-
-FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *BW) {
- void *Mem = C.getAllocator().Allocate<FieldDecl>();
- return new (Mem) FieldDecl(L, Id, T, BW);
-}
-
-
-EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
- SourceLocation L,
- IdentifierInfo *Id, QualType T,
- Expr *E, const llvm::APSInt &V,
- ScopedDecl *PrevDecl){
- void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
- return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
-}
-
-void EnumConstantDecl::Destroy(ASTContext& C) {
- if (Init) Init->Destroy(C);
- Decl::Destroy(C);
-}
-
-TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, QualType T,
- ScopedDecl *PD) {
- void *Mem = C.getAllocator().Allocate<TypedefDecl>();
- return new (Mem) TypedefDecl(DC, L, Id, T, PD);
-}
-
-EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id,
- ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<EnumDecl>();
- return new (Mem) EnumDecl(DC, L, Id, PrevDecl);
-}
-
-void EnumDecl::Destroy(ASTContext& C) {
- if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
- Decl::Destroy(C);
-}
-
-FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
- SourceLocation L,
- StringLiteral *Str) {
- void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
- return new (Mem) FileScopeAsmDecl(L, Str);
-}
-
-LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
- SourceLocation L,
- LanguageIDs Lang, Decl *D) {
- void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
- return new (Mem) LinkageSpecDecl(L, Lang, D);
-}
-
-//===----------------------------------------------------------------------===//
-// NamedDecl Implementation
-//===----------------------------------------------------------------------===//
-
-const char *NamedDecl::getName() const {
- if (const IdentifierInfo *II = getIdentifier())
- return II->getName();
- return "";
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionDecl Implementation
-//===----------------------------------------------------------------------===//
-
-FunctionDecl::~FunctionDecl() {
- delete[] ParamInfo;
-}
-
-void FunctionDecl::Destroy(ASTContext& C) {
- if (Body)
- Body->Destroy(C);
-
- for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
- (*I)->Destroy(C);
-
- Decl::Destroy(C);
-}
-
-
-Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
- for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) {
- if (FD->Body) {
- Definition = FD;
- return FD->Body;
- }
- }
-
- return 0;
-}
-
-unsigned FunctionDecl::getNumParams() const {
- const FunctionType *FT = getType()->getAsFunctionType();
- if (isa<FunctionTypeNoProto>(FT))
- return 0;
- return cast<FunctionTypeProto>(FT)->getNumArgs();
-}
-
-void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
- assert(ParamInfo == 0 && "Already has param info!");
- assert(NumParams == getNumParams() && "Parameter count mismatch!");
-
- // Zero params -> null pointer.
- if (NumParams) {
- ParamInfo = new ParmVarDecl*[NumParams];
- memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
- }
-}
-
-/// getMinRequiredArguments - Returns the minimum number of arguments
-/// needed to call this function. This may be fewer than the number of
-/// function parameters, if some of the parameters have default
-/// arguments (in C++).
-unsigned FunctionDecl::getMinRequiredArguments() const {
- unsigned NumRequiredArgs = getNumParams();
- while (NumRequiredArgs > 0
- && getParamDecl(NumRequiredArgs-1)->getDefaultArg())
- --NumRequiredArgs;
-
- return NumRequiredArgs;
-}
-
-//===----------------------------------------------------------------------===//
-// TagdDecl Implementation
-//===----------------------------------------------------------------------===//
-
-TagDecl* TagDecl::getDefinition(ASTContext& C) const {
- QualType T = C.getTypeDeclType(const_cast<TagDecl*>(this));
- TagDecl* D = cast<TagDecl>(cast<TagType>(T)->getDecl());
- return D->isDefinition() ? D : 0;
-}
-
-//===----------------------------------------------------------------------===//
-// RecordDecl Implementation
-//===----------------------------------------------------------------------===//
-
-RecordDecl::RecordDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id)
-: TagDecl(DK, DC, L, Id, 0) {
-
- HasFlexibleArrayMember = false;
- assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
- Members = 0;
- NumMembers = -1;
-}
-
-RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- RecordDecl* PrevDecl) {
-
- void *Mem = C.getAllocator().Allocate<RecordDecl>();
- Kind DK;
- switch (TK) {
- default: assert(0 && "Invalid TagKind!");
- case TK_enum: assert(0 && "Enum TagKind passed for Record!");
- case TK_struct: DK = Struct; break;
- case TK_union: DK = Union; break;
- case TK_class: DK = Class; break;
- }
-
- RecordDecl* R = new (Mem) RecordDecl(DK, DC, L, Id);
- C.getTypeDeclType(R, PrevDecl);
- return R;
-}
-
-RecordDecl::~RecordDecl() {
- delete[] Members;
-}
-
-void RecordDecl::Destroy(ASTContext& C) {
- if (isDefinition())
- for (field_iterator I=field_begin(), E=field_end(); I!=E; ++I)
- (*I)->Destroy(C);
-
- TagDecl::Destroy(C);
-}
-
-/// defineBody - When created, RecordDecl's correspond to a forward declared
-/// record. This method is used to mark the decl as being defined, with the
-/// specified contents.
-void RecordDecl::defineBody(ASTContext& C, FieldDecl **members,
- unsigned numMembers) {
- assert(!isDefinition() && "Cannot redefine record!");
- setDefinition(true);
- NumMembers = numMembers;
- if (numMembers) {
- Members = new FieldDecl*[numMembers];
- memcpy(Members, members, numMembers*sizeof(Decl*));
- }
-
- // Let ASTContext know that this is the defining RecordDecl this type.
- C.setTagDefinition(this);
-}
-
-
-FieldDecl *RecordDecl::getMember(IdentifierInfo *II) {
- if (Members == 0 || NumMembers < 0)
- return 0;
-
- // Linear search. When C++ classes come along, will likely need to revisit.
- for (int i = 0; i != NumMembers; ++i)
- if (Members[i]->getIdentifier() == II)
- return Members[i];
- return 0;
-}
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
deleted file mode 100644
index db179fec3ecc..000000000000
--- a/clang/lib/AST/DeclBase.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Decl and DeclContext classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/ADT/DenseMap.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Statistics
-//===----------------------------------------------------------------------===//
-
-// temporary statistics gathering
-static unsigned nFuncs = 0;
-static unsigned nVars = 0;
-static unsigned nParmVars = 0;
-static unsigned nSUC = 0;
-static unsigned nCXXSUC = 0;
-static unsigned nEnumConst = 0;
-static unsigned nEnumDecls = 0;
-static unsigned nNamespaces = 0;
-static unsigned nTypedef = 0;
-static unsigned nFieldDecls = 0;
-static unsigned nCXXFieldDecls = 0;
-static unsigned nInterfaceDecls = 0;
-static unsigned nClassDecls = 0;
-static unsigned nMethodDecls = 0;
-static unsigned nProtocolDecls = 0;
-static unsigned nForwardProtocolDecls = 0;
-static unsigned nCategoryDecls = 0;
-static unsigned nIvarDecls = 0;
-static unsigned nAtDefsFieldDecls = 0;
-static unsigned nObjCImplementationDecls = 0;
-static unsigned nObjCCategoryImpl = 0;
-static unsigned nObjCCompatibleAlias = 0;
-static unsigned nObjCPropertyDecl = 0;
-static unsigned nObjCPropertyImplDecl = 0;
-static unsigned nLinkageSpecDecl = 0;
-static unsigned nFileScopeAsmDecl = 0;
-
-static bool StatSwitch = false;
-
-// This keeps track of all decl attributes. Since so few decls have attrs, we
-// keep them in a hash map instead of wasting space in the Decl class.
-typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
-
-static DeclAttrMapTy *DeclAttrs = 0;
-
-const char *Decl::getDeclKindName() const {
- switch (DeclKind) {
- default: assert(0 && "Unknown decl kind!");
- case Namespace: return "Namespace";
- case Typedef: return "Typedef";
- case Function: return "Function";
- case Var: return "Var";
- case ParmVar: return "ParmVar";
- case EnumConstant: return "EnumConstant";
- case ObjCIvar: return "ObjCIvar";
- case ObjCInterface: return "ObjCInterface";
- case ObjCClass: return "ObjCClass";
- case ObjCMethod: return "ObjCMethod";
- case ObjCProtocol: return "ObjCProtocol";
- case ObjCForwardProtocol: return "ObjCForwardProtocol";
- case Struct: return "Struct";
- case Union: return "Union";
- case Class: return "Class";
- case Enum: return "Enum";
- }
-}
-
-bool Decl::CollectingStats(bool Enable) {
- if (Enable)
- StatSwitch = true;
- return StatSwitch;
-}
-
-void Decl::PrintStats() {
- fprintf(stderr, "*** Decl Stats:\n");
- fprintf(stderr, " %d decls total.\n",
- int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXFieldDecls+nCXXSUC+
- nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
- nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
- nAtDefsFieldDecls+nNamespaces));
- fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n",
- nNamespaces, (int)sizeof(NamespaceDecl),
- int(nNamespaces*sizeof(NamespaceDecl)));
- fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
- nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
- fprintf(stderr, " %d variable decls, %d each (%d bytes)\n",
- nVars, (int)sizeof(VarDecl),
- int(nVars*sizeof(VarDecl)));
- fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n",
- nParmVars, (int)sizeof(ParmVarDecl),
- int(nParmVars*sizeof(ParmVarDecl)));
- fprintf(stderr, " %d field decls, %d each (%d bytes)\n",
- nFieldDecls, (int)sizeof(FieldDecl),
- int(nFieldDecls*sizeof(FieldDecl)));
- fprintf(stderr, " %d @defs generated field decls, %d each (%d bytes)\n",
- nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl),
- int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl)));
- fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n",
- nSUC, (int)sizeof(RecordDecl),
- int(nSUC*sizeof(RecordDecl)));
- fprintf(stderr, " %d C++ field decls, %d each (%d bytes)\n",
- nCXXFieldDecls, (int)sizeof(CXXFieldDecl),
- int(nCXXFieldDecls*sizeof(CXXFieldDecl)));
- fprintf(stderr, " %d C++ struct/union/class decls, %d each (%d bytes)\n",
- nCXXSUC, (int)sizeof(CXXRecordDecl),
- int(nCXXSUC*sizeof(CXXRecordDecl)));
- fprintf(stderr, " %d enum decls, %d each (%d bytes)\n",
- nEnumDecls, (int)sizeof(EnumDecl),
- int(nEnumDecls*sizeof(EnumDecl)));
- fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n",
- nEnumConst, (int)sizeof(EnumConstantDecl),
- int(nEnumConst*sizeof(EnumConstantDecl)));
- fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n",
- nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
- // Objective-C decls...
- fprintf(stderr, " %d interface decls, %d each (%d bytes)\n",
- nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
- int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
- fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n",
- nIvarDecls, (int)sizeof(ObjCIvarDecl),
- int(nIvarDecls*sizeof(ObjCIvarDecl)));
- fprintf(stderr, " %d class decls, %d each (%d bytes)\n",
- nClassDecls, (int)sizeof(ObjCClassDecl),
- int(nClassDecls*sizeof(ObjCClassDecl)));
- fprintf(stderr, " %d method decls, %d each (%d bytes)\n",
- nMethodDecls, (int)sizeof(ObjCMethodDecl),
- int(nMethodDecls*sizeof(ObjCMethodDecl)));
- fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n",
- nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
- int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
- fprintf(stderr, " %d forward protocol decls, %d each (%d bytes)\n",
- nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
- int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
- fprintf(stderr, " %d category decls, %d each (%d bytes)\n",
- nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
- int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
-
- fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n",
- nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
- int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
-
- fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n",
- nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
- int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
-
- fprintf(stderr, " %d compatibility alias decls, %d each (%d bytes)\n",
- nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
- int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
-
- fprintf(stderr, " %d property decls, %d each (%d bytes)\n",
- nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
- int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
-
- fprintf(stderr, " %d property implementation decls, %d each (%d bytes)\n",
- nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
- int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
-
- fprintf(stderr, "Total bytes = %d\n",
- int(nFuncs*sizeof(FunctionDecl)+
- nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
- nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
- nCXXFieldDecls*sizeof(CXXFieldDecl)+nCXXSUC*sizeof(CXXRecordDecl)+
- nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
- nTypedef*sizeof(TypedefDecl)+
- nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
- nIvarDecls*sizeof(ObjCIvarDecl)+
- nClassDecls*sizeof(ObjCClassDecl)+
- nMethodDecls*sizeof(ObjCMethodDecl)+
- nProtocolDecls*sizeof(ObjCProtocolDecl)+
- nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
- nCategoryDecls*sizeof(ObjCCategoryDecl)+
- nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
- nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
- nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
- nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
- nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
- nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
- nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
- nNamespaces*sizeof(NamespaceDecl)));
-
-}
-
-void Decl::addDeclKind(Kind k) {
- switch (k) {
- case Namespace: nNamespaces++; break;
- case Typedef: nTypedef++; break;
- case Function: nFuncs++; break;
- case Var: nVars++; break;
- case ParmVar: nParmVars++; break;
- case EnumConstant: nEnumConst++; break;
- case Field: nFieldDecls++; break;
- case Struct: case Union: case Class: nSUC++; break;
- case Enum: nEnumDecls++; break;
- case ObjCInterface: nInterfaceDecls++; break;
- case ObjCClass: nClassDecls++; break;
- case ObjCMethod: nMethodDecls++; break;
- case ObjCProtocol: nProtocolDecls++; break;
- case ObjCForwardProtocol: nForwardProtocolDecls++; break;
- case ObjCCategory: nCategoryDecls++; break;
- case ObjCIvar: nIvarDecls++; break;
- case ObjCAtDefsField: nAtDefsFieldDecls++; break;
- case ObjCImplementation: nObjCImplementationDecls++; break;
- case ObjCCategoryImpl: nObjCCategoryImpl++; break;
- case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
- case ObjCProperty: nObjCPropertyDecl++; break;
- case ObjCPropertyImpl: nObjCPropertyImplDecl++; break;
- case LinkageSpec: nLinkageSpecDecl++; break;
- case FileScopeAsm: nFileScopeAsmDecl++; break;
- case ImplicitParam:
- case TranslationUnit: break;
-
- case CXXField: nCXXFieldDecls++; break;
- case CXXStruct: case CXXUnion: case CXXClass: nCXXSUC++; break;
- // FIXME: Statistics for C++ decls.
- case CXXMethod:
- case CXXClassVar:
- break;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Decl Implementation
-//===----------------------------------------------------------------------===//
-
-// Out-of-line virtual method providing a home for Decl.
-Decl::~Decl() {
- if (!HasAttrs)
- return;
-
- DeclAttrMapTy::iterator it = DeclAttrs->find(this);
- assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
-
- // release attributes.
- delete it->second;
- invalidateAttrs();
-}
-
-void Decl::addAttr(Attr *NewAttr) {
- if (!DeclAttrs)
- DeclAttrs = new DeclAttrMapTy();
-
- Attr *&ExistingAttr = (*DeclAttrs)[this];
-
- NewAttr->setNext(ExistingAttr);
- ExistingAttr = NewAttr;
-
- HasAttrs = true;
-}
-
-void Decl::invalidateAttrs() {
- if (!HasAttrs) return;
-
- HasAttrs = false;
- (*DeclAttrs)[this] = 0;
- DeclAttrs->erase(this);
-
- if (DeclAttrs->empty()) {
- delete DeclAttrs;
- DeclAttrs = 0;
- }
-}
-
-const Attr *Decl::getAttrs() const {
- if (!HasAttrs)
- return 0;
-
- return (*DeclAttrs)[this];
-}
-
-void Decl::swapAttrs(Decl *RHS) {
- bool HasLHSAttr = this->HasAttrs;
- bool HasRHSAttr = RHS->HasAttrs;
-
- // Usually, neither decl has attrs, nothing to do.
- if (!HasLHSAttr && !HasRHSAttr) return;
-
- // If 'this' has no attrs, swap the other way.
- if (!HasLHSAttr)
- return RHS->swapAttrs(this);
-
- // Handle the case when both decls have attrs.
- if (HasRHSAttr) {
- std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
- return;
- }
-
- // Otherwise, LHS has an attr and RHS doesn't.
- (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
- (*DeclAttrs).erase(this);
- this->HasAttrs = false;
- RHS->HasAttrs = true;
-}
-
-
-void Decl::Destroy(ASTContext& C) {
-
- if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
-
- // Observe the unrolled recursion. By setting N->NextDeclarator = 0x0
- // within the loop, only the Destroy method for the first ScopedDecl
- // will deallocate all of the ScopedDecls in a chain.
-
- ScopedDecl* N = SD->getNextDeclarator();
-
- while (N) {
- ScopedDecl* Tmp = N->getNextDeclarator();
- N->NextDeclarator = 0x0;
- N->Destroy(C);
- N = Tmp;
- }
- }
-
- this->~Decl();
- C.getAllocator().Deallocate((void *)this);
-}
-
-//===----------------------------------------------------------------------===//
-// DeclContext Implementation
-//===----------------------------------------------------------------------===//
-
-DeclContext *DeclContext::getParent() const {
- if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
- return SD->getDeclContext();
- else
- return NULL;
-}
-
-Decl *DeclContext::ToDecl (const DeclContext *D) {
- return CastTo<Decl>(D);
-}
-
-DeclContext *DeclContext::FromDecl (const Decl *D) {
- return CastTo<DeclContext>(D);
-}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
deleted file mode 100644
index 0a65ab34f0ee..000000000000
--- a/clang/lib/AST/DeclCXX.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the C++ related Decl classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ASTContext.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Decl Allocation/Deallocation Method Implementations
-//===----------------------------------------------------------------------===//
-
-CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *BW) {
- void *Mem = C.getAllocator().Allocate<CXXFieldDecl>();
- return new (Mem) CXXFieldDecl(RD, L, Id, T, BW);
-}
-
-CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- CXXRecordDecl* PrevDecl) {
- Kind DK;
- switch (TK) {
- default: assert(0 && "Invalid TagKind!");
- case TK_enum: assert(0 && "Enum TagKind passed for Record!");
- case TK_struct: DK = CXXStruct; break;
- case TK_union: DK = CXXUnion; break;
- case TK_class: DK = CXXClass; break;
- }
- void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();
- CXXRecordDecl* R = new (Mem) CXXRecordDecl(DK, DC, L, Id);
- C.getTypeDeclType(R, PrevDecl);
- return R;
-}
-
-CXXMethodDecl *
-CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, bool isStatic, bool isInline,
- ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<CXXMethodDecl>();
- return new (Mem) CXXMethodDecl(RD, L, Id, T, isStatic, isInline, PrevDecl);
-}
-
-QualType CXXMethodDecl::getThisType(ASTContext &C) const {
- assert(isInstance() && "No 'this' for static methods!");
- QualType ClassTy = C.getTagDeclType(cast<CXXRecordDecl>(getParent()));
- QualType ThisTy = C.getPointerType(ClassTy);
- ThisTy.addConst();
- return ThisTy;
-}
-
-CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();
- return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);
-}
diff --git a/clang/lib/AST/DeclGroup.cpp b/clang/lib/AST/DeclGroup.cpp
deleted file mode 100644
index bd79fafc8f33..000000000000
--- a/clang/lib/AST/DeclGroup.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-//===--- DeclGroup.cpp - Classes for representing groups of Decls -*- 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 DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using namespace clang;
-
-DeclGroup* DeclGroup::Create(ASTContext& C, unsigned numdecls, Decl** decls) {
- unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * numdecls;
- unsigned alignment = llvm::AlignOf<DeclGroup>::Alignment;
- void* mem = C.getAllocator().Allocate(size, alignment);
- new (mem) DeclGroup(numdecls, decls);
- return static_cast<DeclGroup*>(mem);
-}
-
-/// Emit - Serialize a DeclGroup to Bitcode.
-void DeclGroup::Emit(llvm::Serializer& S) const {
- S.EmitInt(NumDecls);
- S.BatchEmitOwnedPtrs(NumDecls, &(*this)[0]);
-}
-
-/// Read - Deserialize a DeclGroup from Bitcode.
-DeclGroup* DeclGroup::Create(llvm::Deserializer& D, ASTContext& C) {
- unsigned NumDecls = (unsigned) D.ReadInt();
- unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
- unsigned alignment = llvm::AlignOf<DeclGroup>::Alignment;
- DeclGroup* DG = (DeclGroup*) C.getAllocator().Allocate(size, alignment);
- new (DG) DeclGroup();
- DG->NumDecls = NumDecls;
- D.BatchReadOwnedPtrs(NumDecls, &(*DG)[0], C);
- return DG;
-}
-
-DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) {
- assert (numdecls > 0);
- assert (decls);
- memcpy(this+1, decls, numdecls * sizeof(*decls));
-}
-
-void DeclGroup::Destroy(ASTContext& C) {
- Decl** Decls = (Decl**) this + 1;
-
- for (unsigned i = 0; i < NumDecls; ++i)
- Decls[i]->Destroy(C);
-
- this->~DeclGroup();
- C.getAllocator().Deallocate((void*) this);
-}
-
-DeclGroupOwningRef::~DeclGroupOwningRef() {
- assert (D == 0 && "Destroy method not called.");
-}
-
-void DeclGroupOwningRef::Destroy(ASTContext& C) {
- if (!D)
- return;
-
- if (getKind() == DeclKind)
- D->Destroy(C);
- else
- reinterpret_cast<DeclGroup*>(reinterpret_cast<uintptr_t>(D) &
- ~Mask)->Destroy(C);
-
- D = 0;
-}
-
-void DeclGroupRef::Emit(llvm::Serializer& S) const {
- if (getKind() == DeclKind) {
- S.EmitBool(false);
- S.EmitPtr(D);
- }
- else {
- S.EmitBool(true);
- S.EmitPtr(reinterpret_cast<DeclGroup*>(reinterpret_cast<uintptr_t>(D)
- & ~Mask));
- }
-}
-
-DeclGroupRef DeclGroupRef::ReadVal(llvm::Deserializer& D) {
- if (D.ReadBool())
- return DeclGroupRef(D.ReadPtr<Decl>());
-
- return DeclGroupRef(D.ReadPtr<DeclGroup>());
-}
-
-void DeclGroupOwningRef::Emit(llvm::Serializer& S) const {
- if (getKind() == DeclKind) {
- S.EmitBool(false);
- S.EmitOwnedPtr(D);
- }
- else {
- S.EmitBool(true);
- S.EmitOwnedPtr(reinterpret_cast<DeclGroup*>(reinterpret_cast<uintptr_t>(D)
- & ~Mask));
- }
-}
-
-DeclGroupOwningRef DeclGroupOwningRef::ReadVal(llvm::Deserializer& D,
- ASTContext& C) {
- if (D.ReadBool()) {
- DeclGroupOwningRef DG(D.ReadOwnedPtr<Decl>(C));
- return DG;
- }
-
- DeclGroupOwningRef DG(D.ReadOwnedPtr<DeclGroup>(C));
- return DG;
-}
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
deleted file mode 100644
index 0d006d676d73..000000000000
--- a/clang/lib/AST/DeclObjC.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Objective-C related Decl classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Stmt.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// ObjC Decl Allocation/Deallocation Method Implementations
-//===----------------------------------------------------------------------===//
-
-ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc,
- Selector SelInfo, QualType T,
- Decl *contextDecl,
- bool isInstance,
- bool isVariadic,
- bool isSynthesized,
- ImplementationControl impControl) {
- void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
- return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
- SelInfo, T, contextDecl,
- isInstance,
- isVariadic, isSynthesized, impControl);
-}
-
-ObjCMethodDecl::~ObjCMethodDecl() {
- delete [] ParamInfo;
-}
-
-void ObjCMethodDecl::Destroy(ASTContext& C) {
- if (Body) Body->Destroy(C);
- if (SelfDecl) SelfDecl->Destroy(C);
-
- for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- Decl::Destroy(C);
-}
-
-ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
- SourceLocation atLoc,
- IdentifierInfo *Id,
- SourceLocation ClassLoc,
- bool ForwardDecl, bool isInternal){
- void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
- return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
- isInternal);
-}
-
-ObjCInterfaceDecl::~ObjCInterfaceDecl() {
- delete [] Ivars;
- delete [] InstanceMethods;
- delete [] ClassMethods;
- delete [] PropertyDecl;
- // FIXME: CategoryList?
-}
-
-void ObjCInterfaceDecl::Destroy(ASTContext& C) {
- for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- // FIXME: Because there is no clear ownership
- // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
- // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
-
- Decl::Destroy(C);
-}
-
-
-ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- AccessControl ac, Expr *BW) {
- void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
- return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
-}
-
-
-ObjCAtDefsFieldDecl
-*ObjCAtDefsFieldDecl::Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *BW) {
- void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
- return new (Mem) ObjCAtDefsFieldDecl(L, Id, T, BW);
-}
-
-void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
- this->~ObjCAtDefsFieldDecl();
- C.getAllocator().Deallocate((void *)this);
-}
-
-ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
- SourceLocation L,
- IdentifierInfo *Id) {
- void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
- return new (Mem) ObjCProtocolDecl(L, Id);
-}
-
-ObjCProtocolDecl::~ObjCProtocolDecl() {
- delete [] InstanceMethods;
- delete [] ClassMethods;
- delete [] PropertyDecl;
-}
-
-void ObjCProtocolDecl::Destroy(ASTContext& C) {
-
- // Referenced Protocols are not owned, so don't Destroy them.
-
- for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- // FIXME: Because there is no clear ownership
- // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
- // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
-
- Decl::Destroy(C);
-}
-
-
-ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
- SourceLocation L,
- ObjCInterfaceDecl **Elts, unsigned nElts) {
- void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
- return new (Mem) ObjCClassDecl(L, Elts, nElts);
-}
-
-ObjCClassDecl::~ObjCClassDecl() {
- delete [] ForwardDecls;
-}
-
-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.
-
- Decl::Destroy(C);
-}
-
-ObjCForwardProtocolDecl *
-ObjCForwardProtocolDecl::Create(ASTContext &C,
- SourceLocation L,
- ObjCProtocolDecl **Elts, unsigned NumElts) {
- void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
- return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
-}
-
-ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
- delete [] ReferencedProtocols;
-}
-
-ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
- SourceLocation L,
- IdentifierInfo *Id) {
- void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
- return new (Mem) ObjCCategoryDecl(L, Id);
-}
-
-ObjCCategoryImplDecl *
-ObjCCategoryImplDecl::Create(ASTContext &C,
- SourceLocation L,IdentifierInfo *Id,
- ObjCInterfaceDecl *ClassInterface) {
- void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
- return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
-}
-
-ObjCImplementationDecl *
-ObjCImplementationDecl::Create(ASTContext &C,
- SourceLocation L,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *ClassInterface,
- ObjCInterfaceDecl *SuperDecl) {
- void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
- return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
-}
-
-ObjCCompatibleAliasDecl *
-ObjCCompatibleAliasDecl::Create(ASTContext &C,
- SourceLocation L,
- IdentifierInfo *Id,
- ObjCInterfaceDecl* AliasedClass) {
- void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
- return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
-}
-
-ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
- SourceLocation L,
- IdentifierInfo *Id,
- QualType T,
- PropertyControl propControl) {
- void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
- return new (Mem) ObjCPropertyDecl(L, Id, T);
-}
-
-//===----------------------------------------------------------------------===//
-// Objective-C Decl Implementation
-//===----------------------------------------------------------------------===//
-
-void ObjCMethodDecl::createImplicitParams(ASTContext &Context) {
- QualType selfTy;
- if (isInstance()) {
- // There may be no interface context due to error in declaration
- // of the interface (which has been reported). Recover gracefully.
- if (ObjCInterfaceDecl *OID = getClassInterface()) {
- selfTy = Context.getObjCInterfaceType(OID);
- selfTy = Context.getPointerType(selfTy);
- } else {
- selfTy = Context.getObjCIdType();
- }
- } else // we have a factory method.
- selfTy = Context.getObjCClassType();
-
- SelfDecl = ImplicitParamDecl::Create(Context, this,
- SourceLocation(),
- &Context.Idents.get("self"),
- selfTy, 0);
-
- CmdDecl = ImplicitParamDecl::Create(Context, this,
- SourceLocation(),
- &Context.Idents.get("_cmd"),
- Context.getObjCSelType(), 0);
-}
-
-void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
- unsigned NumParams) {
- assert(ParamInfo == 0 && "Already has param info!");
-
- // Zero params -> null pointer.
- if (NumParams) {
- ParamInfo = new ParmVarDecl*[NumParams];
- memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
- NumMethodParams = NumParams;
- }
-}
-
-/// FindPropertyDeclaration - Finds declaration of the property given its name
-/// in 'PropertyId' and returns it. It returns 0, if not found.
-///
-ObjCPropertyDecl *
- ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
- for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
- E = classprop_end(); I != E; ++I) {
- ObjCPropertyDecl *property = *I;
- if (property->getIdentifier() == PropertyId)
- return property;
- }
- // Look through categories.
- for (ObjCCategoryDecl *Category = getCategoryList();
- Category; Category = Category->getNextClassCategory()) {
- ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
- if (property)
- return property;
- }
- // Look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
- E = protocol_end(); I != E; ++I) {
- ObjCProtocolDecl *Protocol = *I;
- ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
- if (property)
- return property;
- }
- if (getSuperClass())
- return getSuperClass()->FindPropertyDeclaration(PropertyId);
- return 0;
-}
-
-/// FindCategoryDeclaration - Finds category declaration in the list of
-/// categories for this class and returns it. Name of the category is passed
-/// in 'CategoryId'. If category not found, return 0;
-///
-ObjCCategoryDecl *
- ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
- for (ObjCCategoryDecl *Category = getCategoryList();
- Category; Category = Category->getNextClassCategory())
- if (Category->getIdentifier() == CategoryId)
- return Category;
- return 0;
-}
-
-/// FindIvarDeclaration - Find an Ivar declaration in this class given its
-/// name in 'IvarId'. On failure to find, return 0;
-///
-ObjCIvarDecl *
- ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
- for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
- IVE = ivar_end(); IVI != IVE; ++IVI) {
- ObjCIvarDecl* Ivar = (*IVI);
- if (Ivar->getIdentifier() == IvarId)
- return Ivar;
- }
- if (getSuperClass())
- return getSuperClass()->FindIvarDeclaration(IvarId);
- return 0;
-}
-
-/// ObjCAddInstanceVariablesToClass - Inserts instance variables
-/// into ObjCInterfaceDecl's fields.
-///
-void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
- unsigned numIvars,
- SourceLocation RBrac) {
- NumIvars = numIvars;
- if (numIvars) {
- Ivars = new ObjCIvarDecl*[numIvars];
- memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
- }
- setLocEnd(RBrac);
-}
-
-/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
-/// Variables (Ivars) relative to what declared in @implementation;s class.
-/// Ivars into ObjCImplementationDecl's fields.
-///
-void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
- ObjCIvarDecl **ivars, unsigned numIvars) {
- NumIvars = numIvars;
- if (numIvars) {
- Ivars = new ObjCIvarDecl*[numIvars];
- memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
- }
-}
-
-/// addMethods - Insert instance and methods declarations into
-/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
-///
-void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
- unsigned numInsMembers,
- ObjCMethodDecl **clsMethods,
- unsigned numClsMembers,
- SourceLocation endLoc) {
- NumInstanceMethods = numInsMembers;
- if (numInsMembers) {
- InstanceMethods = new ObjCMethodDecl*[numInsMembers];
- memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
- }
- NumClassMethods = numClsMembers;
- if (numClsMembers) {
- ClassMethods = new ObjCMethodDecl*[numClsMembers];
- memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
- }
- AtEndLoc = endLoc;
-}
-
-/// addProperties - Insert property declaration AST nodes into
-/// ObjCInterfaceDecl's PropertyDecl field.
-///
-void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
- unsigned NumProperties) {
- if (NumProperties == 0) return;
-
- NumPropertyDecl = NumProperties;
- PropertyDecl = new ObjCPropertyDecl*[NumProperties];
- memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
-}
-
-/// mergeProperties - Adds properties to the end of list of current properties
-/// for this class.
-
-void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
- unsigned NumNewProperties) {
- if (NumNewProperties == 0) return;
-
- if (PropertyDecl) {
- ObjCPropertyDecl **newPropertyDecl =
- new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
- ObjCPropertyDecl **buf = newPropertyDecl;
- // put back original properties in buffer.
- memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
- // Add new properties to this buffer.
- memcpy(buf+NumPropertyDecl, Properties,
- NumNewProperties*sizeof(ObjCPropertyDecl*));
- delete[] PropertyDecl;
- PropertyDecl = newPropertyDecl;
- NumPropertyDecl += NumNewProperties;
- }
- else {
- addProperties(Properties, NumNewProperties);
- }
-}
-
-static void
-addPropertyMethods(Decl *D,
- ASTContext &Context,
- ObjCPropertyDecl *property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
- ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
-
- if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
- GetterDecl = OID->getInstanceMethod(property->getGetterName());
- if (!property->isReadOnly())
- SetterDecl = OID->getInstanceMethod(property->getSetterName());
- } else if (ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(D)) {
- GetterDecl = OCD->getInstanceMethod(property->getGetterName());
- if (!property->isReadOnly())
- SetterDecl = OCD->getInstanceMethod(property->getSetterName());
- } else {
- ObjCProtocolDecl *OPD = cast<ObjCProtocolDecl>(D);
- GetterDecl = OPD->getInstanceMethod(property->getGetterName());
- if (!property->isReadOnly())
- SetterDecl = OPD->getInstanceMethod(property->getSetterName());
- }
-
- // FIXME: The synthesized property we set here is misleading. We
- // almost always synthesize these methods unless the user explicitly
- // provided prototypes (which is odd, but allowed). Sema should be
- // typechecking that the declarations jive in that situation (which
- // it is not currently).
-
- // Find the default getter and if one not found, add one.
- if (!GetterDecl) {
- // No instance method of same name as property getter name was found.
- // Declare a getter method and add it to the list of methods
- // for this class.
- GetterDecl =
- ObjCMethodDecl::Create(Context, property->getLocation(),
- property->getLocation(),
- property->getGetterName(),
- property->getType(),
- D,
- true, false, true, ObjCMethodDecl::Required);
- insMethods.push_back(GetterDecl);
- }
- property->setGetterMethodDecl(GetterDecl);
-
- // Skip setter if property is read-only.
- if (property->isReadOnly())
- return;
-
- // Find the default setter and if one not found, add one.
- if (!SetterDecl) {
- // No instance method of same name as property setter name was found.
- // Declare a setter method and add it to the list of methods
- // for this class.
- SetterDecl =
- ObjCMethodDecl::Create(Context, property->getLocation(),
- property->getLocation(),
- property->getSetterName(),
- Context.VoidTy,
- D,
- true, false, true, ObjCMethodDecl::Required);
- insMethods.push_back(SetterDecl);
-
- // Invent the arguments for the setter. We don't bother making a
- // nice name for the argument.
- ParmVarDecl *Argument = ParmVarDecl::Create(Context,
- SetterDecl,
- SourceLocation(),
- property->getIdentifier(),
- property->getType(),
- VarDecl::None,
- 0, 0);
- SetterDecl->setMethodParams(&Argument, 1);
- }
- property->setSetterMethodDecl(SetterDecl);
-}
-
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCInterfaceDecl::addPropertyMethods(
- ASTContext &Context,
- ObjCPropertyDecl *property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
- ::addPropertyMethods(this, Context, property, insMethods);
-}
-
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCCategoryDecl::addPropertyMethods(
- ASTContext &Context,
- ObjCPropertyDecl *property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
- ::addPropertyMethods(this, Context, property, insMethods);
-}
-
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCProtocolDecl::addPropertyMethods(
- ASTContext &Context,
- ObjCPropertyDecl *property,
- llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
- ::addPropertyMethods(this, Context, property, insMethods);
-}
-
-/// addProperties - Insert property declaration AST nodes into
-/// ObjCProtocolDecl's PropertyDecl field.
-///
-void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
- unsigned NumProperties) {
- if (NumProperties == 0) return;
-
- NumPropertyDecl = NumProperties;
- PropertyDecl = new ObjCPropertyDecl*[NumProperties];
- memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
-}
-
-/// addProperties - Insert property declaration AST nodes into
-/// ObjCCategoryDecl's PropertyDecl field.
-///
-void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
- unsigned NumProperties) {
- if (NumProperties == 0) return;
-
- NumPropertyDecl = NumProperties;
- PropertyDecl = new ObjCPropertyDecl*[NumProperties];
- memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
-}
-
-/// addMethods - Insert instance and methods declarations into
-/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
-///
-void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
- unsigned numInsMembers,
- ObjCMethodDecl **clsMethods,
- unsigned numClsMembers,
- SourceLocation endLoc) {
- NumInstanceMethods = numInsMembers;
- if (numInsMembers) {
- InstanceMethods = new ObjCMethodDecl*[numInsMembers];
- memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
- }
- NumClassMethods = numClsMembers;
- if (numClsMembers) {
- ClassMethods = new ObjCMethodDecl*[numClsMembers];
- memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
- }
- AtEndLoc = endLoc;
-}
-
-
-
-/// addMethods - Insert instance and methods declarations into
-/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
-///
-void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
- unsigned numInsMembers,
- ObjCMethodDecl **clsMethods,
- unsigned numClsMembers,
- SourceLocation endLoc) {
- NumInstanceMethods = numInsMembers;
- if (numInsMembers) {
- InstanceMethods = new ObjCMethodDecl*[numInsMembers];
- memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
- }
- NumClassMethods = numClsMembers;
- if (numClsMembers) {
- ClassMethods = new ObjCMethodDecl*[numClsMembers];
- memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
- }
- AtEndLoc = endLoc;
-}
-
-/// FindPropertyDeclaration - Finds declaration of the property given its name
-/// in 'PropertyId' and returns it. It returns 0, if not found.
-///
-ObjCPropertyDecl *
-ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
- for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
- E = classprop_end(); I != E; ++I) {
- ObjCPropertyDecl *property = *I;
- if (property->getIdentifier() == PropertyId)
- return property;
- }
- return 0;
-}
-
-/// FindPropertyDeclaration - Finds declaration of the property given its name
-/// in 'PropertyId' and returns it. It returns 0, if not found.
-///
-ObjCPropertyDecl *
-ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
- for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
- E = classprop_end(); I != E; ++I) {
- ObjCPropertyDecl *property = *I;
- if (property->getIdentifier() == PropertyId)
- return property;
- }
- return 0;
-}
-
-ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
- IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
- ObjCInterfaceDecl* ClassDecl = this;
- while (ClassDecl != NULL) {
- for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
- I != E; ++I) {
- if ((*I)->getIdentifier() == ID) {
- clsDeclared = ClassDecl;
- return *I;
- }
- }
- ClassDecl = ClassDecl->getSuperClass();
- }
- return NULL;
-}
-
-/// lookupInstanceMethod - This method returns an instance method by looking in
-/// the class, its categories, and its super classes (using a linear search).
-ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
- ObjCInterfaceDecl* ClassDecl = this;
- ObjCMethodDecl *MethodDecl = 0;
-
- while (ClassDecl != NULL) {
- if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
- return MethodDecl;
-
- // Didn't find one yet - look through protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- ClassDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
- return MethodDecl;
-
- // Didn't find one yet - now look through categories.
- ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
- while (CatDecl) {
- if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
- return MethodDecl;
- CatDecl = CatDecl->getNextClassCategory();
- }
- ClassDecl = ClassDecl->getSuperClass();
- }
- return NULL;
-}
-
-// lookupClassMethod - This method returns a class method by looking in the
-// class, its categories, and its super classes (using a linear search).
-ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
- ObjCInterfaceDecl* ClassDecl = this;
- ObjCMethodDecl *MethodDecl = 0;
-
- while (ClassDecl != NULL) {
- if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
- return MethodDecl;
-
- // Didn't find one yet - look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
- E = ClassDecl->protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->getClassMethod(Sel)))
- return MethodDecl;
-
- // Didn't find one yet - now look through categories.
- ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
- while (CatDecl) {
- if ((MethodDecl = CatDecl->getClassMethod(Sel)))
- return MethodDecl;
- CatDecl = CatDecl->getNextClassCategory();
- }
- ClassDecl = ClassDecl->getSuperClass();
- }
- return NULL;
-}
-
-/// getInstanceMethod - This method returns an instance method by
-/// looking in the class implementation. Unlike interfaces, we don't
-/// look outside the implementation.
-ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
-}
-
-/// getClassMethod - This method returns a class method by looking in
-/// the class implementation. Unlike interfaces, we don't look outside
-/// the implementation.
-ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
-}
-
-// lookupInstanceMethod - This method returns an instance method by looking in
-// the class implementation. Unlike interfaces, we don't look outside the
-// implementation.
-ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
-}
-
-// lookupClassMethod - This method returns an instance method by looking in
-// the class implementation. Unlike interfaces, we don't look outside the
-// implementation.
-ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
- for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
-}
-
-// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
-// it inherited.
-ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
- ObjCMethodDecl *MethodDecl = NULL;
-
- if ((MethodDecl = getInstanceMethod(Sel)))
- return MethodDecl;
-
- for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
- return MethodDecl;
- return NULL;
-}
-
-// lookupInstanceMethod - Lookup a class method in the protocol and protocols
-// it inherited.
-ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
- ObjCMethodDecl *MethodDecl = NULL;
-
- if ((MethodDecl = getClassMethod(Sel)))
- return MethodDecl;
-
- for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->getClassMethod(Sel)))
- return MethodDecl;
- return NULL;
-}
-
-/// getSynthesizedMethodSize - Compute size of synthesized method name
-/// as done be the rewrite.
-///
-unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
- // syntesized method name is a concatenation of -/+[class-name selector]
- // Get length of this name.
- unsigned length = 3; // _I_ or _C_
- length += strlen(getClassInterface()->getName()) +1; // extra for _
- NamedDecl *MethodContext = getMethodContext();
- if (ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(MethodContext))
- length += strlen(CID->getName()) +1;
- length += getSelector().getName().size(); // selector name
- return length;
-}
-
-ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
- return ID;
- if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
- return CD->getClassInterface();
- if (ObjCImplementationDecl *IMD =
- dyn_cast<ObjCImplementationDecl>(MethodContext))
- return IMD->getClassInterface();
- if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
- return CID->getClassInterface();
- assert(false && "unknown method context");
- return 0;
-}
-
-ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
- SourceLocation atLoc,
- SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivar) {
- void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
- return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, PK, ivar);
-}
-
-
diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp
deleted file mode 100644
index 3f36e3ac89db..000000000000
--- a/clang/lib/AST/DeclSerialization.cpp
+++ /dev/null
@@ -1,541 +0,0 @@
-//===--- DeclSerialization.cpp - Serialization of Decls ---------*- 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 methods that implement bitcode serialization for Decls.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using llvm::Serializer;
-using llvm::Deserializer;
-using llvm::SerializedPtrID;
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Decl Serialization: Dispatch code to handle specialized decl types.
-//===----------------------------------------------------------------------===//
-
-void Decl::Emit(Serializer& S) const {
- S.EmitInt(getKind());
- EmitImpl(S);
- if (const DeclContext *DC = dyn_cast<const DeclContext>(this))
- DC->EmitOutRec(S);
-}
-
-Decl* Decl::Create(Deserializer& D, ASTContext& C) {
-
- Decl *Dcl;
- Kind k = static_cast<Kind>(D.ReadInt());
-
- switch (k) {
- default:
- assert (false && "Not implemented.");
- break;
-
- case TranslationUnit:
- Dcl = TranslationUnitDecl::CreateImpl(D, C);
- break;
-
- case Namespace:
- Dcl = NamespaceDecl::CreateImpl(D, C);
- break;
-
- case Var:
- Dcl = VarDecl::CreateImpl(D, C);
- break;
-
- case Enum:
- Dcl = EnumDecl::CreateImpl(D, C);
- break;
-
- case EnumConstant:
- Dcl = EnumConstantDecl::CreateImpl(D, C);
- break;
-
- case Field:
- Dcl = FieldDecl::CreateImpl(D, C);
- break;
-
- case ParmVar:
- Dcl = ParmVarDecl::CreateImpl(D, C);
- break;
-
- case Function:
- Dcl = FunctionDecl::CreateImpl(D, C);
- break;
-
- case Class:
- case Union:
- case Struct:
- Dcl = RecordDecl::CreateImpl(k, D, C);
- break;
-
- case Typedef:
- Dcl = TypedefDecl::CreateImpl(D, C);
- break;
-
- case FileScopeAsm:
- Dcl = FileScopeAsmDecl::CreateImpl(D, C);
- break;
- }
-
- if (DeclContext *DC = dyn_cast<DeclContext>(Dcl))
- DC->ReadOutRec(D, C);
-
- return Dcl;
-}
-
-//===----------------------------------------------------------------------===//
-// Common serialization logic for subclasses of Decl.
-//===----------------------------------------------------------------------===//
-
-void Decl::EmitInRec(Serializer& S) const {
- S.Emit(getLocation()); // From Decl.
-}
-
-void Decl::ReadInRec(Deserializer& D, ASTContext& C) {
- Loc = SourceLocation::ReadVal(D); // From Decl.
-}
-
-//===----------------------------------------------------------------------===//
-// Common serialization logic for subclasses of DeclContext.
-//===----------------------------------------------------------------------===//
-
-void DeclContext::EmitOutRec(Serializer& S) const {
- S.EmitPtr(DeclChain);
-}
-
-void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
- D.ReadPtr(DeclChain);
-}
-
-//===----------------------------------------------------------------------===//
-// Common serialization logic for subclasses of NamedDecl.
-//===----------------------------------------------------------------------===//
-
-void NamedDecl::EmitInRec(Serializer& S) const {
- Decl::EmitInRec(S);
- S.EmitPtr(getIdentifier()); // From NamedDecl.
-}
-
-void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
- Decl::ReadInRec(D, C);
- D.ReadPtr(Identifier); // From NamedDecl.
-}
-
-//===----------------------------------------------------------------------===//
-// Common serialization logic for subclasses of ScopedDecl.
-//===----------------------------------------------------------------------===//
-
-void ScopedDecl::EmitInRec(Serializer& S) const {
- NamedDecl::EmitInRec(S);
- S.EmitPtr(getNext()); // From ScopedDecl.
- S.EmitPtr(cast_or_null<Decl>(getDeclContext())); // From ScopedDecl.
-}
-
-void ScopedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
- NamedDecl::ReadInRec(D, C);
- D.ReadPtr(Next); // From ScopedDecl.
-
- assert(DeclCtx == 0); // Allow back-patching. Observe that we register
- D.ReadPtr(DeclCtx); // the variable of the *object* for back-patching.
- // Its actual value will get filled in later.
-}
-
- //===------------------------------------------------------------===//
- // NOTE: Not all subclasses of ScopedDecl will use the "OutRec" //
- // methods. This is because owned pointers are usually "batched" //
- // together for efficiency. //
- //===------------------------------------------------------------===//
-
-void ScopedDecl::EmitOutRec(Serializer& S) const {
- S.EmitOwnedPtr(getNextDeclarator()); // From ScopedDecl.
-}
-
-void ScopedDecl::ReadOutRec(Deserializer& D, ASTContext& C) {
- NextDeclarator =
- cast_or_null<ScopedDecl>(D.ReadOwnedPtr<Decl>(C)); // From ScopedDecl.
-}
-
-//===----------------------------------------------------------------------===//
-// Common serialization logic for subclasses of ValueDecl.
-//===----------------------------------------------------------------------===//
-
-void ValueDecl::EmitInRec(Serializer& S) const {
- ScopedDecl::EmitInRec(S);
- S.Emit(getType()); // From ValueDecl.
-}
-
-void ValueDecl::ReadInRec(Deserializer& D, ASTContext& C) {
- ScopedDecl::ReadInRec(D, C);
- DeclType = QualType::ReadVal(D); // From ValueDecl.
-}
-
-//===----------------------------------------------------------------------===//
-// Common serialization logic for subclasses of VarDecl.
-//===----------------------------------------------------------------------===//
-
-void VarDecl::EmitInRec(Serializer& S) const {
- ValueDecl::EmitInRec(S);
- S.EmitInt(getStorageClass()); // From VarDecl.
-}
-
-void VarDecl::ReadInRec(Deserializer& D, ASTContext& C) {
- ValueDecl::ReadInRec(D, C);
- SClass = static_cast<StorageClass>(D.ReadInt()); // From VarDecl.
-}
-
- //===------------------------------------------------------------===//
- // NOTE: VarDecl has its own "OutRec" methods that doesn't use //
- // the one define in ScopedDecl. This is to batch emit the //
- // owned pointers, which results in a smaller output.
- //===------------------------------------------------------------===//
-
-void VarDecl::EmitOutRec(Serializer& S) const {
- // Emit these last because they will create records of their own.
- S.BatchEmitOwnedPtrs(getInit(), // From VarDecl.
- getNextDeclarator()); // From ScopedDecl.
-}
-
-void VarDecl::ReadOutRec(Deserializer& D, ASTContext& C) {
- Decl* next_declarator;
-
- D.BatchReadOwnedPtrs(Init, // From VarDecl.
- next_declarator, // From ScopedDecl.
- C);
-
- setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
-}
-
-
-void VarDecl::EmitImpl(Serializer& S) const {
- VarDecl::EmitInRec(S);
- VarDecl::EmitOutRec(S);
-}
-
-void VarDecl::ReadImpl(Deserializer& D, ASTContext& C) {
- ReadInRec(D, C);
- ReadOutRec(D, C);
-}
-
-//===----------------------------------------------------------------------===//
-// TranslationUnitDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void TranslationUnitDecl::EmitImpl(llvm::Serializer& S) const
-{
- Decl::EmitInRec(S);
-}
-
-TranslationUnitDecl* TranslationUnitDecl::CreateImpl(Deserializer& D,
- ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
- TranslationUnitDecl* decl = new (Mem) TranslationUnitDecl();
-
- decl->Decl::ReadInRec(D, C);
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// NamespaceDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void NamespaceDecl::EmitImpl(llvm::Serializer& S) const
-{
- ScopedDecl::EmitInRec(S);
- S.Emit(getLBracLoc());
- S.Emit(getRBracLoc());
- ScopedDecl::EmitOutRec(S);
-}
-
-NamespaceDecl* NamespaceDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<NamespaceDecl>();
- NamespaceDecl* decl = new (Mem) NamespaceDecl(0, SourceLocation(), 0);
-
- decl->ScopedDecl::ReadInRec(D, C);
- decl->LBracLoc = SourceLocation::ReadVal(D);
- decl->RBracLoc = SourceLocation::ReadVal(D);
- decl->ScopedDecl::ReadOutRec(D, C);
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// VarDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-VarDecl* VarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<VarDecl>();
- VarDecl* decl =
- new (Mem) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None, NULL);
-
- decl->VarDecl::ReadImpl(D, C);
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// ParmVarDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
- VarDecl::EmitImpl(S);
- S.EmitInt(getObjCDeclQualifier()); // From ParmVarDecl.
- S.EmitOwnedPtr(getDefaultArg()); // From ParmVarDecl.
-}
-
-ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
- ParmVarDecl* decl = new (Mem)
- ParmVarDecl(0, SourceLocation(), NULL, QualType(), None, NULL, NULL);
-
- decl->VarDecl::ReadImpl(D, C);
- decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
- decl->DefaultArg = D.ReadOwnedPtr<Expr>(C);
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// EnumDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void EnumDecl::EmitImpl(Serializer& S) const {
- ScopedDecl::EmitInRec(S);
- S.EmitBool(isDefinition());
- S.Emit(IntegerType);
- S.BatchEmitOwnedPtrs(getEnumConstantList(),getNextDeclarator());
-}
-
-EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<EnumDecl>();
- EnumDecl* decl = new (Mem) EnumDecl(0, SourceLocation(), NULL, NULL);
-
- decl->ScopedDecl::ReadInRec(D, C);
- decl->setDefinition(D.ReadBool());
- decl->IntegerType = QualType::ReadVal(D);
-
- Decl* next_declarator;
- Decl* Elist;
-
- D.BatchReadOwnedPtrs(Elist, next_declarator, C);
-
- decl->setDeclChain(cast_or_null<EnumConstantDecl>(Elist));
- decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// EnumConstantDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void EnumConstantDecl::EmitImpl(Serializer& S) const {
- S.Emit(Val);
- ValueDecl::EmitInRec(S);
- S.BatchEmitOwnedPtrs(getNextDeclarator(),Init);
-}
-
-EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- llvm::APSInt val(1);
- D.Read(val);
-
- void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
- EnumConstantDecl* decl = new (Mem)
- EnumConstantDecl(0, SourceLocation(), NULL, QualType(), NULL, val, NULL);
-
- decl->ValueDecl::ReadInRec(D, C);
-
- Decl* next_declarator;
-
- D.BatchReadOwnedPtrs(next_declarator, decl->Init, C);
-
- decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// FieldDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void FieldDecl::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- NamedDecl::EmitInRec(S);
- S.EmitOwnedPtr(BitWidth);
-}
-
-FieldDecl* FieldDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<FieldDecl>();
- FieldDecl* decl = new (Mem) FieldDecl(SourceLocation(), NULL, QualType(), 0);
- decl->DeclType.ReadBackpatch(D);
- decl->ReadInRec(D, C);
- decl->BitWidth = D.ReadOwnedPtr<Expr>(C);
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void FunctionDecl::EmitImpl(Serializer& S) const {
- S.EmitInt(SClass); // From FunctionDecl.
- S.EmitBool(IsInline); // From FunctionDecl.
- ValueDecl::EmitInRec(S);
- S.EmitPtr(PreviousDeclaration);
-
- // NOTE: We do not need to serialize out the number of parameters, because
- // that is encoded in the type (accessed via getNumParams()).
-
- if (ParamInfo != NULL) {
- S.EmitBool(true);
- S.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body,
- getNextDeclarator());
- }
- else {
- S.EmitBool(false);
- S.BatchEmitOwnedPtrs(Body,getNextDeclarator());
- }
-}
-
-FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- StorageClass SClass = static_cast<StorageClass>(D.ReadInt());
- bool IsInline = D.ReadBool();
-
- void *Mem = C.getAllocator().Allocate<FunctionDecl>();
- FunctionDecl* decl = new (Mem)
- FunctionDecl(Function, 0, SourceLocation(), NULL,
- QualType(), SClass, IsInline, 0);
-
- decl->ValueDecl::ReadInRec(D, C);
- D.ReadPtr(decl->PreviousDeclaration);
-
- Decl* next_declarator;
-
- bool hasParamDecls = D.ReadBool();
-
- decl->ParamInfo = hasParamDecls
- ? new ParmVarDecl*[decl->getNumParams()]
- : NULL;
-
- if (hasParamDecls)
- D.BatchReadOwnedPtrs(decl->getNumParams(),
- reinterpret_cast<Decl**>(&decl->ParamInfo[0]),
- decl->Body, next_declarator, C);
- else
- D.BatchReadOwnedPtrs(decl->Body, next_declarator, C);
-
- decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// RecordDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void RecordDecl::EmitImpl(Serializer& S) const {
- ScopedDecl::EmitInRec(S);
- S.EmitBool(isDefinition());
- S.EmitBool(hasFlexibleArrayMember());
- S.EmitSInt(getNumMembers());
- if (getNumMembers() > 0) {
- assert (Members);
- S.BatchEmitOwnedPtrs((unsigned) getNumMembers(), (Decl**) &Members[0]);
- }
- else
- ScopedDecl::EmitOutRec(S);
-}
-
-RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D,
- ASTContext& C) {
-
- void *Mem = C.getAllocator().Allocate<RecordDecl>();
- RecordDecl* decl = new (Mem) RecordDecl(DK, 0, SourceLocation(), NULL);
-
- decl->ScopedDecl::ReadInRec(D, C);
- decl->setDefinition(D.ReadBool());
- decl->setHasFlexibleArrayMember(D.ReadBool());
- decl->NumMembers = D.ReadSInt();
-
- if (decl->getNumMembers() > 0) {
- decl->Members = new FieldDecl*[(unsigned) decl->getNumMembers()];
-
- D.BatchReadOwnedPtrs((unsigned) decl->getNumMembers(),
- (Decl**) &decl->Members[0], C);
- }
- else
- decl->ScopedDecl::ReadOutRec(D, C);
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// TypedefDecl Serialization.
-//===----------------------------------------------------------------------===//
-
-void TypedefDecl::EmitImpl(Serializer& S) const {
- S.Emit(UnderlyingType);
- ScopedDecl::EmitInRec(S);
- ScopedDecl::EmitOutRec(S);
-}
-
-TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType T = QualType::ReadVal(D);
-
- void *Mem = C.getAllocator().Allocate<TypedefDecl>();
- TypedefDecl* decl = new (Mem) TypedefDecl(0, SourceLocation(), NULL, T, NULL);
-
- decl->ScopedDecl::ReadInRec(D, C);
- decl->ScopedDecl::ReadOutRec(D, C);
-
- return decl;
-}
-
-//===----------------------------------------------------------------------===//
-// LinkageSpec Serialization.
-//===----------------------------------------------------------------------===//
-
-void LinkageSpecDecl::EmitInRec(Serializer& S) const {
- Decl::EmitInRec(S);
- S.EmitInt(getLanguage());
- S.EmitPtr(D);
-}
-
-void LinkageSpecDecl::ReadInRec(Deserializer& D, ASTContext& C) {
- Decl::ReadInRec(D, C);
- Language = static_cast<LanguageIDs>(D.ReadInt());
- D.ReadPtr(this->D);
-}
-
-//===----------------------------------------------------------------------===//
-// FileScopeAsm Serialization.
-//===----------------------------------------------------------------------===//
-
-void FileScopeAsmDecl::EmitImpl(llvm::Serializer& S) const
-{
- Decl::EmitInRec(S);
- S.EmitOwnedPtr(AsmString);
-}
-
-FileScopeAsmDecl* FileScopeAsmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
- void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
- FileScopeAsmDecl* decl = new (Mem) FileScopeAsmDecl(SourceLocation(), 0);
-
- decl->Decl::ReadInRec(D, C);
- decl->AsmString = cast<StringLiteral>(D.ReadOwnedPtr<Expr>(C));
-// D.ReadOwnedPtr(D.ReadOwnedPtr<StringLiteral>())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString);
-
- return decl;
-}
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
deleted file mode 100644
index 6cdaacd68979..000000000000
--- a/clang/lib/AST/Expr.cpp
+++ /dev/null
@@ -1,1407 +0,0 @@
-//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Expr class and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/TargetInfo.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Primary Expressions.
-//===----------------------------------------------------------------------===//
-
-/// getValueAsApproximateDouble - This returns the value as an inaccurate
-/// double. Note that this may cause loss of precision, but is useful for
-/// debugging dumps, etc.
-double FloatingLiteral::getValueAsApproximateDouble() const {
- llvm::APFloat V = getValue();
- V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven);
- return V.convertToDouble();
-}
-
-
-StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
- bool Wide, QualType t, SourceLocation firstLoc,
- SourceLocation lastLoc) :
- Expr(StringLiteralClass, t) {
- // OPTIMIZE: could allocate this appended to the StringLiteral.
- char *AStrData = new char[byteLength];
- memcpy(AStrData, strData, byteLength);
- StrData = AStrData;
- ByteLength = byteLength;
- IsWide = Wide;
- firstTokLoc = firstLoc;
- lastTokLoc = lastLoc;
-}
-
-StringLiteral::~StringLiteral() {
- delete[] StrData;
-}
-
-bool UnaryOperator::isPostfix(Opcode Op) {
- switch (Op) {
- case PostInc:
- case PostDec:
- return true;
- default:
- return false;
- }
-}
-
-bool UnaryOperator::isPrefix(Opcode Op) {
- switch (Op) {
- case PreInc:
- case PreDec:
- return true;
- default:
- return false;
- }
-}
-
-/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
-/// corresponds to, e.g. "sizeof" or "[pre]++".
-const char *UnaryOperator::getOpcodeStr(Opcode Op) {
- switch (Op) {
- default: assert(0 && "Unknown unary operator");
- case PostInc: return "++";
- case PostDec: return "--";
- case PreInc: return "++";
- case PreDec: return "--";
- case AddrOf: return "&";
- case Deref: return "*";
- case Plus: return "+";
- case Minus: return "-";
- case Not: return "~";
- case LNot: return "!";
- case Real: return "__real";
- case Imag: return "__imag";
- case SizeOf: return "sizeof";
- case AlignOf: return "alignof";
- case Extension: return "__extension__";
- case OffsetOf: return "__builtin_offsetof";
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Postfix Operators.
-//===----------------------------------------------------------------------===//
-
-
-CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
- SourceLocation rparenloc)
- : Expr(CallExprClass, t), NumArgs(numargs) {
- SubExprs = new Stmt*[numargs+1];
- SubExprs[FN] = fn;
- for (unsigned i = 0; i != numargs; ++i)
- SubExprs[i+ARGS_START] = args[i];
- RParenLoc = rparenloc;
-}
-
-/// setNumArgs - This changes the number of arguments present in this call.
-/// Any orphaned expressions are deleted by this, and any new operands are set
-/// to null.
-void CallExpr::setNumArgs(unsigned NumArgs) {
- // No change, just return.
- if (NumArgs == getNumArgs()) return;
-
- // If shrinking # arguments, just delete the extras and forgot them.
- if (NumArgs < getNumArgs()) {
- for (unsigned i = NumArgs, e = getNumArgs(); i != e; ++i)
- delete getArg(i);
- this->NumArgs = NumArgs;
- return;
- }
-
- // Otherwise, we are growing the # arguments. New an bigger argument array.
- Stmt **NewSubExprs = new Stmt*[NumArgs+1];
- // Copy over args.
- for (unsigned i = 0; i != getNumArgs()+ARGS_START; ++i)
- NewSubExprs[i] = SubExprs[i];
- // Null out new args.
- for (unsigned i = getNumArgs()+ARGS_START; i != NumArgs+ARGS_START; ++i)
- NewSubExprs[i] = 0;
-
- delete[] SubExprs;
- SubExprs = NewSubExprs;
- this->NumArgs = NumArgs;
-}
-
-/// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
-/// not, return 0.
-unsigned CallExpr::isBuiltinCall() const {
- // All simple function calls (e.g. func()) are implicitly cast to pointer to
- // function. As a result, we try and obtain the DeclRefExpr from the
- // ImplicitCastExpr.
- const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(getCallee());
- if (!ICE) // FIXME: deal with more complex calls (e.g. (func)(), (*func)()).
- return 0;
-
- const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
- if (!DRE)
- return 0;
-
- const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
- if (!FDecl)
- return 0;
-
- return FDecl->getIdentifier()->getBuiltinID();
-}
-
-
-/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
-/// corresponds to, e.g. "<<=".
-const char *BinaryOperator::getOpcodeStr(Opcode Op) {
- switch (Op) {
- default: assert(0 && "Unknown binary operator");
- case Mul: return "*";
- case Div: return "/";
- case Rem: return "%";
- case Add: return "+";
- case Sub: return "-";
- case Shl: return "<<";
- case Shr: return ">>";
- case LT: return "<";
- case GT: return ">";
- case LE: return "<=";
- case GE: return ">=";
- case EQ: return "==";
- case NE: return "!=";
- case And: return "&";
- case Xor: return "^";
- case Or: return "|";
- case LAnd: return "&&";
- case LOr: return "||";
- case Assign: return "=";
- case MulAssign: return "*=";
- case DivAssign: return "/=";
- case RemAssign: return "%=";
- case AddAssign: return "+=";
- case SubAssign: return "-=";
- case ShlAssign: return "<<=";
- case ShrAssign: return ">>=";
- case AndAssign: return "&=";
- case XorAssign: return "^=";
- case OrAssign: return "|=";
- case Comma: return ",";
- }
-}
-
-InitListExpr::InitListExpr(SourceLocation lbraceloc,
- Expr **initexprs, unsigned numinits,
- SourceLocation rbraceloc)
- : Expr(InitListExprClass, QualType()),
- LBraceLoc(lbraceloc), RBraceLoc(rbraceloc)
-{
- for (unsigned i = 0; i != numinits; i++)
- InitExprs.push_back(initexprs[i]);
-}
-
-/// getFunctionType - Return the underlying function type for this block.
-///
-const FunctionType *BlockExpr::getFunctionType() const {
- return getType()->getAsBlockPointerType()->
- getPointeeType()->getAsFunctionType();
-}
-
-//===----------------------------------------------------------------------===//
-// Generic Expression Routines
-//===----------------------------------------------------------------------===//
-
-/// hasLocalSideEffect - Return true if this immediate expression has side
-/// effects, not counting any sub-expressions.
-bool Expr::hasLocalSideEffect() const {
- switch (getStmtClass()) {
- default:
- return false;
- case ParenExprClass:
- return cast<ParenExpr>(this)->getSubExpr()->hasLocalSideEffect();
- case UnaryOperatorClass: {
- const UnaryOperator *UO = cast<UnaryOperator>(this);
-
- switch (UO->getOpcode()) {
- default: return false;
- case UnaryOperator::PostInc:
- case UnaryOperator::PostDec:
- case UnaryOperator::PreInc:
- case UnaryOperator::PreDec:
- return true; // ++/--
-
- case UnaryOperator::Deref:
- // Dereferencing a volatile pointer is a side-effect.
- return getType().isVolatileQualified();
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- // accessing a piece of a volatile complex is a side-effect.
- return UO->getSubExpr()->getType().isVolatileQualified();
-
- case UnaryOperator::Extension:
- return UO->getSubExpr()->hasLocalSideEffect();
- }
- }
- case BinaryOperatorClass: {
- const BinaryOperator *BinOp = cast<BinaryOperator>(this);
- // Consider comma to have side effects if the LHS and RHS both do.
- if (BinOp->getOpcode() == BinaryOperator::Comma)
- return BinOp->getLHS()->hasLocalSideEffect() &&
- BinOp->getRHS()->hasLocalSideEffect();
-
- return BinOp->isAssignmentOp();
- }
- case CompoundAssignOperatorClass:
- return true;
-
- case ConditionalOperatorClass: {
- const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
- return Exp->getCond()->hasLocalSideEffect()
- || (Exp->getLHS() && Exp->getLHS()->hasLocalSideEffect())
- || (Exp->getRHS() && Exp->getRHS()->hasLocalSideEffect());
- }
-
- case MemberExprClass:
- case ArraySubscriptExprClass:
- // If the base pointer or element is to a volatile pointer/field, accessing
- // if is a side effect.
- return getType().isVolatileQualified();
-
- case CallExprClass:
- // TODO: check attributes for pure/const. "void foo() { strlen("bar"); }"
- // should warn.
- return true;
- case ObjCMessageExprClass:
- return true;
- case StmtExprClass: {
- // Statement exprs don't logically have side effects themselves, but are
- // sometimes used in macros in ways that give them a type that is unused.
- // For example ({ blah; foo(); }) will end up with a type if foo has a type.
- // however, if the result of the stmt expr is dead, we don't want to emit a
- // warning.
- const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
- if (!CS->body_empty())
- if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
- return E->hasLocalSideEffect();
- return false;
- }
- case ExplicitCastExprClass:
- case CXXFunctionalCastExprClass:
- // If this is a cast to void, check the operand. Otherwise, the result of
- // the cast is unused.
- if (getType()->isVoidType())
- return cast<CastExpr>(this)->getSubExpr()->hasLocalSideEffect();
- return false;
-
- case ImplicitCastExprClass:
- // Check the operand, since implicit casts are inserted by Sema
- return cast<ImplicitCastExpr>(this)->getSubExpr()->hasLocalSideEffect();
-
- case CXXDefaultArgExprClass:
- return cast<CXXDefaultArgExpr>(this)->getExpr()->hasLocalSideEffect();
- }
-}
-
-/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or an
-/// incomplete type other than void. Nonarray expressions that can be lvalues:
-/// - name, where name must be a variable
-/// - e[i]
-/// - (e), where e must be an lvalue
-/// - e.name, where e must be an lvalue
-/// - e->name
-/// - *e, the type of e cannot be a function type
-/// - string-constant
-/// - (__real__ e) and (__imag__ e) where e is an lvalue [GNU extension]
-/// - reference type [C++ [expr]]
-///
-Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
- // first, check the type (C99 6.3.2.1)
- if (TR->isFunctionType()) // from isObjectType()
- return LV_NotObjectType;
-
- // Allow qualified void which is an incomplete type other than void (yuck).
- if (TR->isVoidType() && !Ctx.getCanonicalType(TR).getCVRQualifiers())
- return LV_IncompleteVoidType;
-
- if (TR->isReferenceType()) // C++ [expr]
- return LV_Valid;
-
- // the type looks fine, now check the expression
- switch (getStmtClass()) {
- case StringLiteralClass: // C99 6.5.1p4
- return LV_Valid;
- case ArraySubscriptExprClass: // C99 6.5.3p4 (e1[e2] == (*((e1)+(e2))))
- // For vectors, make sure base is an lvalue (i.e. not a function call).
- if (cast<ArraySubscriptExpr>(this)->getBase()->getType()->isVectorType())
- return cast<ArraySubscriptExpr>(this)->getBase()->isLvalue(Ctx);
- return LV_Valid;
- case DeclRefExprClass: { // C99 6.5.1p2
- const Decl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
- if (isa<VarDecl>(RefdDecl) || isa<ImplicitParamDecl>(RefdDecl))
- return LV_Valid;
- break;
- }
- case BlockDeclRefExprClass: {
- const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
- if (isa<VarDecl>(BDR->getDecl()))
- return LV_Valid;
- break;
- }
- case MemberExprClass: { // C99 6.5.2.3p4
- const MemberExpr *m = cast<MemberExpr>(this);
- return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
- }
- case UnaryOperatorClass:
- if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Deref)
- return LV_Valid; // C99 6.5.3p4
-
- if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Real ||
- cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Imag ||
- cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Extension)
- return cast<UnaryOperator>(this)->getSubExpr()->isLvalue(Ctx); // GNU.
- break;
- case ParenExprClass: // C99 6.5.1p5
- return cast<ParenExpr>(this)->getSubExpr()->isLvalue(Ctx);
- case CompoundLiteralExprClass: // C99 6.5.2.5p5
- return LV_Valid;
- case ExtVectorElementExprClass:
- if (cast<ExtVectorElementExpr>(this)->containsDuplicateElements())
- return LV_DuplicateVectorComponents;
- return LV_Valid;
- case ObjCIvarRefExprClass: // ObjC instance variables are lvalues.
- return LV_Valid;
- case ObjCPropertyRefExprClass: // FIXME: check if read-only property.
- return LV_Valid;
- case PredefinedExprClass:
- return (cast<PredefinedExpr>(this)->getIdentType()
- == PredefinedExpr::CXXThis
- ? LV_InvalidExpression : LV_Valid);
- case CXXDefaultArgExprClass:
- return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
- case CXXConditionDeclExprClass:
- return LV_Valid;
- default:
- break;
- }
- return LV_InvalidExpression;
-}
-
-/// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
-/// does not have an incomplete type, does not have a const-qualified type, and
-/// if it is a structure or union, does not have any member (including,
-/// recursively, any member or element of all contained aggregates or unions)
-/// with a const-qualified type.
-Expr::isModifiableLvalueResult Expr::isModifiableLvalue(ASTContext &Ctx) const {
- isLvalueResult lvalResult = isLvalue(Ctx);
-
- switch (lvalResult) {
- case LV_Valid: break;
- case LV_NotObjectType: return MLV_NotObjectType;
- case LV_IncompleteVoidType: return MLV_IncompleteVoidType;
- case LV_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
- case LV_InvalidExpression: return MLV_InvalidExpression;
- }
-
- QualType CT = Ctx.getCanonicalType(getType());
-
- if (CT.isConstQualified())
- return MLV_ConstQualified;
- if (CT->isArrayType())
- return MLV_ArrayType;
- if (CT->isIncompleteType())
- return MLV_IncompleteType;
-
- if (const RecordType *r = CT->getAsRecordType()) {
- if (r->hasConstFields())
- return MLV_ConstQualified;
- }
- // The following is illegal:
- // void takeclosure(void (^C)(void));
- // void func() { int x = 1; takeclosure(^{ x = 7 }); }
- //
- if (getStmtClass() == BlockDeclRefExprClass) {
- const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
- if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
- return MLV_NotBlockQualified;
- }
- return MLV_Valid;
-}
-
-/// hasGlobalStorage - Return true if this expression has static storage
-/// duration. This means that the address of this expression is a link-time
-/// constant.
-bool Expr::hasGlobalStorage() const {
- switch (getStmtClass()) {
- default:
- return false;
- case ParenExprClass:
- return cast<ParenExpr>(this)->getSubExpr()->hasGlobalStorage();
- case ImplicitCastExprClass:
- return cast<ImplicitCastExpr>(this)->getSubExpr()->hasGlobalStorage();
- case CompoundLiteralExprClass:
- return cast<CompoundLiteralExpr>(this)->isFileScope();
- case DeclRefExprClass: {
- const Decl *D = cast<DeclRefExpr>(this)->getDecl();
- if (const VarDecl *VD = dyn_cast<VarDecl>(D))
- return VD->hasGlobalStorage();
- if (isa<FunctionDecl>(D))
- return true;
- return false;
- }
- case MemberExprClass: {
- const MemberExpr *M = cast<MemberExpr>(this);
- return !M->isArrow() && M->getBase()->hasGlobalStorage();
- }
- case ArraySubscriptExprClass:
- return cast<ArraySubscriptExpr>(this)->getBase()->hasGlobalStorage();
- case PredefinedExprClass:
- return true;
- case CXXDefaultArgExprClass:
- return cast<CXXDefaultArgExpr>(this)->getExpr()->hasGlobalStorage();
- }
-}
-
-Expr* Expr::IgnoreParens() {
- Expr* E = this;
- while (ParenExpr* P = dyn_cast<ParenExpr>(E))
- E = P->getSubExpr();
-
- return E;
-}
-
-/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
-/// or CastExprs or ImplicitCastExprs, returning their operand.
-Expr *Expr::IgnoreParenCasts() {
- Expr *E = this;
- while (true) {
- if (ParenExpr *P = dyn_cast<ParenExpr>(E))
- E = P->getSubExpr();
- else if (CastExpr *P = dyn_cast<CastExpr>(E))
- E = P->getSubExpr();
- else
- return E;
- }
-}
-
-
-bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
- switch (getStmtClass()) {
- default:
- if (Loc) *Loc = getLocStart();
- return false;
- case ParenExprClass:
- return cast<ParenExpr>(this)->getSubExpr()->isConstantExpr(Ctx, Loc);
- case StringLiteralClass:
- case ObjCStringLiteralClass:
- case FloatingLiteralClass:
- case IntegerLiteralClass:
- case CharacterLiteralClass:
- case ImaginaryLiteralClass:
- case TypesCompatibleExprClass:
- case CXXBoolLiteralExprClass:
- case AddrLabelExprClass:
- return true;
- case CallExprClass: {
- const CallExpr *CE = cast<CallExpr>(this);
-
- // Allow any constant foldable calls to builtins.
- if (CE->isBuiltinCall() && CE->isEvaluatable(Ctx))
- return true;
-
- if (Loc) *Loc = getLocStart();
- return false;
- }
- case DeclRefExprClass: {
- const Decl *D = cast<DeclRefExpr>(this)->getDecl();
- // Accept address of function.
- if (isa<EnumConstantDecl>(D) || isa<FunctionDecl>(D))
- return true;
- if (Loc) *Loc = getLocStart();
- if (isa<VarDecl>(D))
- return TR->isArrayType();
- return false;
- }
- case CompoundLiteralExprClass:
- if (Loc) *Loc = getLocStart();
- // Allow "(int []){2,4}", since the array will be converted to a pointer.
- // Allow "(vector type){2,4}" since the elements are all constant.
- return TR->isArrayType() || TR->isVectorType();
- case UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(this);
-
- // C99 6.6p9
- if (Exp->getOpcode() == UnaryOperator::AddrOf) {
- if (!Exp->getSubExpr()->hasGlobalStorage()) {
- if (Loc) *Loc = getLocStart();
- return false;
- }
- return true;
- }
-
- // Get the operand value. If this is sizeof/alignof, do not evalute the
- // operand. This affects C99 6.6p3.
- if (!Exp->isSizeOfAlignOfOp() &&
- Exp->getOpcode() != UnaryOperator::OffsetOf &&
- !Exp->getSubExpr()->isConstantExpr(Ctx, Loc))
- return false;
-
- switch (Exp->getOpcode()) {
- // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
- // See C99 6.6p3.
- default:
- if (Loc) *Loc = Exp->getOperatorLoc();
- return false;
- case UnaryOperator::Extension:
- return true; // FIXME: this is wrong.
- case UnaryOperator::SizeOf:
- case UnaryOperator::AlignOf:
- case UnaryOperator::OffsetOf:
- // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
- if (!Exp->getSubExpr()->getType()->isConstantSizeType()) {
- if (Loc) *Loc = Exp->getOperatorLoc();
- return false;
- }
- return true;
- case UnaryOperator::LNot:
- case UnaryOperator::Plus:
- case UnaryOperator::Minus:
- case UnaryOperator::Not:
- return true;
- }
- }
- case SizeOfAlignOfTypeExprClass: {
- const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
- // alignof always evaluates to a constant.
- if (Exp->isSizeOf() && !Exp->getArgumentType()->isVoidType() &&
- !Exp->getArgumentType()->isConstantSizeType()) {
- if (Loc) *Loc = Exp->getOperatorLoc();
- return false;
- }
- return true;
- }
- case BinaryOperatorClass: {
- const BinaryOperator *Exp = cast<BinaryOperator>(this);
-
- // The LHS of a constant expr is always evaluated and needed.
- if (!Exp->getLHS()->isConstantExpr(Ctx, Loc))
- return false;
-
- if (!Exp->getRHS()->isConstantExpr(Ctx, Loc))
- return false;
- return true;
- }
- case ImplicitCastExprClass:
- case ExplicitCastExprClass:
- case CXXFunctionalCastExprClass: {
- const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
- SourceLocation CastLoc = getLocStart();
- if (!SubExpr->isConstantExpr(Ctx, Loc)) {
- if (Loc) *Loc = SubExpr->getLocStart();
- return false;
- }
- return true;
- }
- case ConditionalOperatorClass: {
- const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
- if (!Exp->getCond()->isConstantExpr(Ctx, Loc) ||
- // Handle the GNU extension for missing LHS.
- !(Exp->getLHS() && Exp->getLHS()->isConstantExpr(Ctx, Loc)) ||
- !Exp->getRHS()->isConstantExpr(Ctx, Loc))
- return false;
- return true;
- }
- case InitListExprClass: {
- const InitListExpr *Exp = cast<InitListExpr>(this);
- unsigned numInits = Exp->getNumInits();
- for (unsigned i = 0; i < numInits; i++) {
- if (!Exp->getInit(i)->isConstantExpr(Ctx, Loc)) {
- if (Loc) *Loc = Exp->getInit(i)->getLocStart();
- return false;
- }
- }
- return true;
- }
- case CXXDefaultArgExprClass:
- return cast<CXXDefaultArgExpr>(this)->getExpr()->isConstantExpr(Ctx, Loc);
- }
-}
-
-/// isIntegerConstantExpr - this recursive routine will test if an expression is
-/// an integer constant expression. Note: With the introduction of VLA's in
-/// C99 the result of the sizeof operator is no longer always a constant
-/// expression. The generalization of the wording to include any subexpression
-/// that is not evaluated (C99 6.6p3) means that nonconstant subexpressions
-/// can appear as operands to other operators (e.g. &&, ||, ?:). For instance,
-/// "0 || f()" can be treated as a constant expression. In C90 this expression,
-/// occurring in a context requiring a constant, would have been a constraint
-/// violation. FIXME: This routine currently implements C90 semantics.
-/// To properly implement C99 semantics this routine will need to evaluate
-/// expressions involving operators previously mentioned.
-
-/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero,
-/// comma, etc
-///
-/// FIXME: This should ext-warn on overflow during evaluation! ISO C does not
-/// permit this. This includes things like (int)1e1000
-///
-/// FIXME: Handle offsetof. Two things to do: Handle GCC's __builtin_offsetof
-/// to support gcc 4.0+ and handle the idiom GCC recognizes with a null pointer
-/// cast+dereference.
-bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
- SourceLocation *Loc, bool isEvaluated) const {
- switch (getStmtClass()) {
- default:
- if (Loc) *Loc = getLocStart();
- return false;
- case ParenExprClass:
- return cast<ParenExpr>(this)->getSubExpr()->
- isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
- case IntegerLiteralClass:
- Result = cast<IntegerLiteral>(this)->getValue();
- break;
- case CharacterLiteralClass: {
- const CharacterLiteral *CL = cast<CharacterLiteral>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = CL->getValue();
- Result.setIsUnsigned(!getType()->isSignedIntegerType());
- break;
- }
- case CXXBoolLiteralExprClass: {
- const CXXBoolLiteralExpr *BL = cast<CXXBoolLiteralExpr>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = BL->getValue();
- Result.setIsUnsigned(!getType()->isSignedIntegerType());
- break;
- }
- case CXXZeroInitValueExprClass:
- Result.clear();
- break;
- case TypesCompatibleExprClass: {
- const TypesCompatibleExpr *TCE = cast<TypesCompatibleExpr>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = Ctx.typesAreCompatible(TCE->getArgType1(), TCE->getArgType2());
- break;
- }
- case CallExprClass: {
- const CallExpr *CE = cast<CallExpr>(this);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
-
- // If this is a call to a builtin function, constant fold it otherwise
- // reject it.
- if (CE->isBuiltinCall()) {
- APValue ResultAP;
- if (CE->tryEvaluate(ResultAP, Ctx)) {
- Result = ResultAP.getInt();
- break; // It is a constant, expand it.
- }
- }
-
- if (Loc) *Loc = getLocStart();
- return false;
- }
- case DeclRefExprClass:
- if (const EnumConstantDecl *D =
- dyn_cast<EnumConstantDecl>(cast<DeclRefExpr>(this)->getDecl())) {
- Result = D->getInitVal();
- break;
- }
- if (Loc) *Loc = getLocStart();
- return false;
- case UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(this);
-
- // Get the operand value. If this is sizeof/alignof, do not evalute the
- // operand. This affects C99 6.6p3.
- if (!Exp->isSizeOfAlignOfOp() && !Exp->isOffsetOfOp() &&
- !Exp->getSubExpr()->isIntegerConstantExpr(Result, Ctx, Loc,isEvaluated))
- return false;
-
- switch (Exp->getOpcode()) {
- // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
- // See C99 6.6p3.
- default:
- if (Loc) *Loc = Exp->getOperatorLoc();
- return false;
- case UnaryOperator::Extension:
- return true; // FIXME: this is wrong.
- case UnaryOperator::SizeOf:
- case UnaryOperator::AlignOf:
- // Return the result in the right width.
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
-
- // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
- if (Exp->getSubExpr()->getType()->isVoidType()) {
- Result = 1;
- break;
- }
-
- // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
- if (!Exp->getSubExpr()->getType()->isConstantSizeType()) {
- if (Loc) *Loc = Exp->getOperatorLoc();
- return false;
- }
-
- // Get information about the size or align.
- if (Exp->getSubExpr()->getType()->isFunctionType()) {
- // GCC extension: sizeof(function) = 1.
- Result = Exp->getOpcode() == UnaryOperator::AlignOf ? 4 : 1;
- } else {
- unsigned CharSize = Ctx.Target.getCharWidth();
- if (Exp->getOpcode() == UnaryOperator::AlignOf)
- Result = Ctx.getTypeAlign(Exp->getSubExpr()->getType()) / CharSize;
- else
- Result = Ctx.getTypeSize(Exp->getSubExpr()->getType()) / CharSize;
- }
- break;
- case UnaryOperator::LNot: {
- bool Val = Result == 0;
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = Val;
- break;
- }
- case UnaryOperator::Plus:
- break;
- case UnaryOperator::Minus:
- Result = -Result;
- break;
- case UnaryOperator::Not:
- Result = ~Result;
- break;
- case UnaryOperator::OffsetOf:
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- Result = Exp->evaluateOffsetOf(Ctx);
- }
- break;
- }
- case SizeOfAlignOfTypeExprClass: {
- const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(this);
-
- // Return the result in the right width.
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
-
- // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
- if (Exp->getArgumentType()->isVoidType()) {
- Result = 1;
- break;
- }
-
- // alignof always evaluates to a constant, sizeof does if arg is not VLA.
- if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
- if (Loc) *Loc = Exp->getOperatorLoc();
- return false;
- }
-
- // Get information about the size or align.
- if (Exp->getArgumentType()->isFunctionType()) {
- // GCC extension: sizeof(function) = 1.
- Result = Exp->isSizeOf() ? 1 : 4;
- } else {
- unsigned CharSize = Ctx.Target.getCharWidth();
- if (Exp->isSizeOf())
- Result = Ctx.getTypeSize(Exp->getArgumentType()) / CharSize;
- else
- Result = Ctx.getTypeAlign(Exp->getArgumentType()) / CharSize;
- }
- break;
- }
- case BinaryOperatorClass: {
- const BinaryOperator *Exp = cast<BinaryOperator>(this);
- llvm::APSInt LHS, RHS;
-
- // Initialize result to have correct signedness and width.
- Result = llvm::APSInt(static_cast<uint32_t>(Ctx.getTypeSize(getType())),
- !getType()->isSignedIntegerType());
-
- // The LHS of a constant expr is always evaluated and needed.
- if (!Exp->getLHS()->isIntegerConstantExpr(LHS, Ctx, Loc, isEvaluated))
- return false;
-
- // The short-circuiting &&/|| operators don't necessarily evaluate their
- // RHS. Make sure to pass isEvaluated down correctly.
- if (Exp->isLogicalOp()) {
- bool RHSEval;
- if (Exp->getOpcode() == BinaryOperator::LAnd)
- RHSEval = LHS != 0;
- else {
- assert(Exp->getOpcode() == BinaryOperator::LOr &&"Unexpected logical");
- RHSEval = LHS == 0;
- }
-
- if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc,
- isEvaluated & RHSEval))
- return false;
- } else {
- if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc, isEvaluated))
- return false;
- }
-
- switch (Exp->getOpcode()) {
- default:
- if (Loc) *Loc = getLocStart();
- return false;
- case BinaryOperator::Mul:
- Result = LHS * RHS;
- break;
- case BinaryOperator::Div:
- if (RHS == 0) {
- if (!isEvaluated) break;
- if (Loc) *Loc = getLocStart();
- return false;
- }
- Result = LHS / RHS;
- break;
- case BinaryOperator::Rem:
- if (RHS == 0) {
- if (!isEvaluated) break;
- if (Loc) *Loc = getLocStart();
- return false;
- }
- Result = LHS % RHS;
- break;
- case BinaryOperator::Add: Result = LHS + RHS; break;
- case BinaryOperator::Sub: Result = LHS - RHS; break;
- case BinaryOperator::Shl:
- Result = LHS <<
- static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1));
- break;
- case BinaryOperator::Shr:
- Result = LHS >>
- static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1));
- break;
- case BinaryOperator::LT: Result = LHS < RHS; break;
- case BinaryOperator::GT: Result = LHS > RHS; break;
- case BinaryOperator::LE: Result = LHS <= RHS; break;
- case BinaryOperator::GE: Result = LHS >= RHS; break;
- case BinaryOperator::EQ: Result = LHS == RHS; break;
- case BinaryOperator::NE: Result = LHS != RHS; break;
- case BinaryOperator::And: Result = LHS & RHS; break;
- case BinaryOperator::Xor: Result = LHS ^ RHS; break;
- case BinaryOperator::Or: Result = LHS | RHS; break;
- case BinaryOperator::LAnd:
- Result = LHS != 0 && RHS != 0;
- break;
- case BinaryOperator::LOr:
- Result = LHS != 0 || RHS != 0;
- break;
-
- case BinaryOperator::Comma:
- // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
- // *except* when they are contained within a subexpression that is not
- // evaluated". Note that Assignment can never happen due to constraints
- // on the LHS subexpr, so we don't need to check it here.
- if (isEvaluated) {
- if (Loc) *Loc = getLocStart();
- return false;
- }
-
- // The result of the constant expr is the RHS.
- Result = RHS;
- return true;
- }
-
- assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
- break;
- }
- case ImplicitCastExprClass:
- case ExplicitCastExprClass:
- case CXXFunctionalCastExprClass: {
- const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
- SourceLocation CastLoc = getLocStart();
-
- // C99 6.6p6: shall only convert arithmetic types to integer types.
- if (!SubExpr->getType()->isArithmeticType() ||
- !getType()->isIntegerType()) {
- if (Loc) *Loc = SubExpr->getLocStart();
- return false;
- }
-
- uint32_t DestWidth = static_cast<uint32_t>(Ctx.getTypeSize(getType()));
-
- // Handle simple integer->integer casts.
- if (SubExpr->getType()->isIntegerType()) {
- if (!SubExpr->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
- return false;
-
- // Figure out if this is a truncate, extend or noop cast.
- // If the input is signed, do a sign extend, noop, or truncate.
- if (getType()->isBooleanType()) {
- // Conversion to bool compares against zero.
- Result = Result != 0;
- Result.zextOrTrunc(DestWidth);
- } else if (SubExpr->getType()->isSignedIntegerType())
- Result.sextOrTrunc(DestWidth);
- else // If the input is unsigned, do a zero extend, noop, or truncate.
- Result.zextOrTrunc(DestWidth);
- break;
- }
-
- // Allow floating constants that are the immediate operands of casts or that
- // are parenthesized.
- const Expr *Operand = SubExpr;
- while (const ParenExpr *PE = dyn_cast<ParenExpr>(Operand))
- Operand = PE->getSubExpr();
-
- // If this isn't a floating literal, we can't handle it.
- const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Operand);
- if (!FL) {
- if (Loc) *Loc = Operand->getLocStart();
- return false;
- }
-
- // If the destination is boolean, compare against zero.
- if (getType()->isBooleanType()) {
- Result = !FL->getValue().isZero();
- Result.zextOrTrunc(DestWidth);
- break;
- }
-
- // Determine whether we are converting to unsigned or signed.
- bool DestSigned = getType()->isSignedIntegerType();
-
- // TODO: Warn on overflow, but probably not here: isIntegerConstantExpr can
- // be called multiple times per AST.
- uint64_t Space[4];
- (void)FL->getValue().convertToInteger(Space, DestWidth, DestSigned,
- llvm::APFloat::rmTowardZero);
- Result = llvm::APInt(DestWidth, 4, Space);
- break;
- }
- case ConditionalOperatorClass: {
- const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
-
- if (!Exp->getCond()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
- return false;
-
- const Expr *TrueExp = Exp->getLHS();
- const Expr *FalseExp = Exp->getRHS();
- if (Result == 0) std::swap(TrueExp, FalseExp);
-
- // Evaluate the false one first, discard the result.
- if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
- return false;
- // Evalute the true one, capture the result.
- if (TrueExp &&
- !TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
- return false;
- break;
- }
- case CXXDefaultArgExprClass:
- return cast<CXXDefaultArgExpr>(this)
- ->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
- }
-
- // Cases that are valid constant exprs fall through to here.
- Result.setIsUnsigned(getType()->isUnsignedIntegerType());
- return true;
-}
-
-/// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an
-/// integer constant expression with the value zero, or if this is one that is
-/// cast to void*.
-bool Expr::isNullPointerConstant(ASTContext &Ctx) const {
- // Strip off a cast to void*, if it exists.
- if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
- // Check that it is a cast to void*.
- if (const PointerType *PT = CE->getType()->getAsPointerType()) {
- QualType Pointee = PT->getPointeeType();
- if (Pointee.getCVRQualifiers() == 0 &&
- Pointee->isVoidType() && // to void*
- CE->getSubExpr()->getType()->isIntegerType()) // from int.
- return CE->getSubExpr()->isNullPointerConstant(Ctx);
- }
- } else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(this)) {
- // Ignore the ImplicitCastExpr type entirely.
- return ICE->getSubExpr()->isNullPointerConstant(Ctx);
- } else if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) {
- // Accept ((void*)0) as a null pointer constant, as many other
- // implementations do.
- return PE->getSubExpr()->isNullPointerConstant(Ctx);
- } else if (const CXXDefaultArgExpr *DefaultArg
- = dyn_cast<CXXDefaultArgExpr>(this)) {
- // See through default argument expressions
- return DefaultArg->getExpr()->isNullPointerConstant(Ctx);
- }
-
- // This expression must be an integer type.
- if (!getType()->isIntegerType())
- return false;
-
- // If we have an integer constant expression, we need to *evaluate* it and
- // test for the value 0.
- llvm::APSInt Val(32);
- return isIntegerConstantExpr(Val, Ctx, 0, true) && Val == 0;
-}
-
-unsigned ExtVectorElementExpr::getNumElements() const {
- if (const VectorType *VT = getType()->getAsVectorType())
- return VT->getNumElements();
- return 1;
-}
-
-/// containsDuplicateElements - Return true if any element access is repeated.
-bool ExtVectorElementExpr::containsDuplicateElements() const {
- const char *compStr = Accessor.getName();
- unsigned length = strlen(compStr);
-
- for (unsigned i = 0; i < length-1; i++) {
- const char *s = compStr+i;
- for (const char c = *s++; *s; s++)
- if (c == *s)
- return true;
- }
- return false;
-}
-
-/// getEncodedElementAccess - We encode the fields as a llvm ConstantArray.
-void ExtVectorElementExpr::getEncodedElementAccess(
- llvm::SmallVectorImpl<unsigned> &Elts) const {
- const char *compStr = Accessor.getName();
-
- bool isHi = !strcmp(compStr, "hi");
- bool isLo = !strcmp(compStr, "lo");
- bool isEven = !strcmp(compStr, "e");
- bool isOdd = !strcmp(compStr, "o");
-
- for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
- uint64_t Index;
-
- if (isHi)
- Index = e + i;
- else if (isLo)
- Index = i;
- else if (isEven)
- Index = 2 * i;
- else if (isOdd)
- Index = 2 * i + 1;
- else
- Index = ExtVectorType::getAccessorIdx(compStr[i]);
-
- Elts.push_back(Index);
- }
-}
-
-// constructor for instance messages.
-ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo,
- QualType retType, ObjCMethodDecl *mproto,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType), SelName(selInfo),
- MethodProto(mproto) {
- NumArgs = nargs;
- SubExprs = new Stmt*[NumArgs+1];
- SubExprs[RECEIVER] = receiver;
- if (NumArgs) {
- for (unsigned i = 0; i != NumArgs; ++i)
- SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
- }
- LBracloc = LBrac;
- RBracloc = RBrac;
-}
-
-// constructor for class messages.
-// FIXME: clsName should be typed to ObjCInterfaceType
-ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
- QualType retType, ObjCMethodDecl *mproto,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType), SelName(selInfo),
- MethodProto(mproto) {
- NumArgs = nargs;
- SubExprs = new Stmt*[NumArgs+1];
- SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
- if (NumArgs) {
- for (unsigned i = 0; i != NumArgs; ++i)
- SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
- }
- LBracloc = LBrac;
- RBracloc = RBrac;
-}
-
-// constructor for class messages.
-ObjCMessageExpr::ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
- QualType retType, ObjCMethodDecl *mproto,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned nargs)
-: Expr(ObjCMessageExprClass, retType), SelName(selInfo),
-MethodProto(mproto) {
- NumArgs = nargs;
- SubExprs = new Stmt*[NumArgs+1];
- SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
- if (NumArgs) {
- for (unsigned i = 0; i != NumArgs; ++i)
- SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
- }
- LBracloc = LBrac;
- RBracloc = RBrac;
-}
-
-ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
- uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- switch (x & Flags) {
- default:
- assert(false && "Invalid ObjCMessageExpr.");
- case IsInstMeth:
- return ClassInfo(0, 0);
- case IsClsMethDeclUnknown:
- return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
- case IsClsMethDeclKnown: {
- ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
- return ClassInfo(D, D->getIdentifier());
- }
- }
-}
-
-bool ChooseExpr::isConditionTrue(ASTContext &C) const {
- return getCond()->getIntegerConstantExprValue(C) != 0;
-}
-
-static int64_t evaluateOffsetOf(ASTContext& C, const Expr *E)
-{
- if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
- QualType Ty = ME->getBase()->getType();
-
- RecordDecl *RD = Ty->getAsRecordType()->getDecl();
- const ASTRecordLayout &RL = C.getASTRecordLayout(RD);
- FieldDecl *FD = ME->getMemberDecl();
-
- // FIXME: This is linear time.
- unsigned i = 0, e = 0;
- for (i = 0, e = RD->getNumMembers(); i != e; i++) {
- if (RD->getMember(i) == FD)
- break;
- }
-
- return RL.getFieldOffset(i) + evaluateOffsetOf(C, ME->getBase());
- } else if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
- const Expr *Base = ASE->getBase();
-
- int64_t size = C.getTypeSize(ASE->getType());
- size *= ASE->getIdx()->getIntegerConstantExprValue(C).getSExtValue();
-
- return size + evaluateOffsetOf(C, Base);
- } else if (isa<CompoundLiteralExpr>(E))
- return 0;
-
- assert(0 && "Unknown offsetof subexpression!");
- return 0;
-}
-
-int64_t UnaryOperator::evaluateOffsetOf(ASTContext& C) const
-{
- assert(Opc == OffsetOf && "Unary operator not offsetof!");
-
- unsigned CharSize = C.Target.getCharWidth();
- return ::evaluateOffsetOf(C, cast<Expr>(Val)) / CharSize;
-}
-
-void SizeOfAlignOfTypeExpr::Destroy(ASTContext& C) {
- // Override default behavior of traversing children. We do not want
- // to delete the type.
-}
-
-//===----------------------------------------------------------------------===//
-// Child Iterators for iterating over subexpressions/substatements
-//===----------------------------------------------------------------------===//
-
-// DeclRefExpr
-Stmt::child_iterator DeclRefExpr::child_begin() { return child_iterator(); }
-Stmt::child_iterator DeclRefExpr::child_end() { return child_iterator(); }
-
-// ObjCIvarRefExpr
-Stmt::child_iterator ObjCIvarRefExpr::child_begin() { return &Base; }
-Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; }
-
-// ObjCPropertyRefExpr
-Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { return &Base; }
-Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; }
-
-// PredefinedExpr
-Stmt::child_iterator PredefinedExpr::child_begin() { return child_iterator(); }
-Stmt::child_iterator PredefinedExpr::child_end() { return child_iterator(); }
-
-// IntegerLiteral
-Stmt::child_iterator IntegerLiteral::child_begin() { return child_iterator(); }
-Stmt::child_iterator IntegerLiteral::child_end() { return child_iterator(); }
-
-// CharacterLiteral
-Stmt::child_iterator CharacterLiteral::child_begin() { return child_iterator(); }
-Stmt::child_iterator CharacterLiteral::child_end() { return child_iterator(); }
-
-// FloatingLiteral
-Stmt::child_iterator FloatingLiteral::child_begin() { return child_iterator(); }
-Stmt::child_iterator FloatingLiteral::child_end() { return child_iterator(); }
-
-// ImaginaryLiteral
-Stmt::child_iterator ImaginaryLiteral::child_begin() { return &Val; }
-Stmt::child_iterator ImaginaryLiteral::child_end() { return &Val+1; }
-
-// StringLiteral
-Stmt::child_iterator StringLiteral::child_begin() { return child_iterator(); }
-Stmt::child_iterator StringLiteral::child_end() { return child_iterator(); }
-
-// ParenExpr
-Stmt::child_iterator ParenExpr::child_begin() { return &Val; }
-Stmt::child_iterator ParenExpr::child_end() { return &Val+1; }
-
-// UnaryOperator
-Stmt::child_iterator UnaryOperator::child_begin() { return &Val; }
-Stmt::child_iterator UnaryOperator::child_end() { return &Val+1; }
-
-// SizeOfAlignOfTypeExpr
-Stmt::child_iterator SizeOfAlignOfTypeExpr::child_begin() {
- // If the type is a VLA type (and not a typedef), the size expression of the
- // VLA needs to be treated as an executable expression.
- if (VariableArrayType* T = dyn_cast<VariableArrayType>(Ty.getTypePtr()))
- return child_iterator(T);
- else
- return child_iterator();
-}
-Stmt::child_iterator SizeOfAlignOfTypeExpr::child_end() {
- return child_iterator();
-}
-
-// ArraySubscriptExpr
-Stmt::child_iterator ArraySubscriptExpr::child_begin() {
- return &SubExprs[0];
-}
-Stmt::child_iterator ArraySubscriptExpr::child_end() {
- return &SubExprs[0]+END_EXPR;
-}
-
-// CallExpr
-Stmt::child_iterator CallExpr::child_begin() {
- return &SubExprs[0];
-}
-Stmt::child_iterator CallExpr::child_end() {
- return &SubExprs[0]+NumArgs+ARGS_START;
-}
-
-// MemberExpr
-Stmt::child_iterator MemberExpr::child_begin() { return &Base; }
-Stmt::child_iterator MemberExpr::child_end() { return &Base+1; }
-
-// ExtVectorElementExpr
-Stmt::child_iterator ExtVectorElementExpr::child_begin() { return &Base; }
-Stmt::child_iterator ExtVectorElementExpr::child_end() { return &Base+1; }
-
-// CompoundLiteralExpr
-Stmt::child_iterator CompoundLiteralExpr::child_begin() { return &Init; }
-Stmt::child_iterator CompoundLiteralExpr::child_end() { return &Init+1; }
-
-// CastExpr
-Stmt::child_iterator CastExpr::child_begin() { return &Op; }
-Stmt::child_iterator CastExpr::child_end() { return &Op+1; }
-
-// BinaryOperator
-Stmt::child_iterator BinaryOperator::child_begin() {
- return &SubExprs[0];
-}
-Stmt::child_iterator BinaryOperator::child_end() {
- return &SubExprs[0]+END_EXPR;
-}
-
-// ConditionalOperator
-Stmt::child_iterator ConditionalOperator::child_begin() {
- return &SubExprs[0];
-}
-Stmt::child_iterator ConditionalOperator::child_end() {
- return &SubExprs[0]+END_EXPR;
-}
-
-// AddrLabelExpr
-Stmt::child_iterator AddrLabelExpr::child_begin() { return child_iterator(); }
-Stmt::child_iterator AddrLabelExpr::child_end() { return child_iterator(); }
-
-// StmtExpr
-Stmt::child_iterator StmtExpr::child_begin() { return &SubStmt; }
-Stmt::child_iterator StmtExpr::child_end() { return &SubStmt+1; }
-
-// TypesCompatibleExpr
-Stmt::child_iterator TypesCompatibleExpr::child_begin() {
- return child_iterator();
-}
-
-Stmt::child_iterator TypesCompatibleExpr::child_end() {
- return child_iterator();
-}
-
-// ChooseExpr
-Stmt::child_iterator ChooseExpr::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; }
-
-// OverloadExpr
-Stmt::child_iterator OverloadExpr::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator OverloadExpr::child_end() { return &SubExprs[0]+NumExprs; }
-
-// ShuffleVectorExpr
-Stmt::child_iterator ShuffleVectorExpr::child_begin() {
- return &SubExprs[0];
-}
-Stmt::child_iterator ShuffleVectorExpr::child_end() {
- return &SubExprs[0]+NumExprs;
-}
-
-// VAArgExpr
-Stmt::child_iterator VAArgExpr::child_begin() { return &Val; }
-Stmt::child_iterator VAArgExpr::child_end() { return &Val+1; }
-
-// InitListExpr
-Stmt::child_iterator InitListExpr::child_begin() {
- return InitExprs.size() ? &InitExprs[0] : 0;
-}
-Stmt::child_iterator InitListExpr::child_end() {
- return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
-}
-
-// ObjCStringLiteral
-Stmt::child_iterator ObjCStringLiteral::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator ObjCStringLiteral::child_end() {
- return child_iterator();
-}
-
-// ObjCEncodeExpr
-Stmt::child_iterator ObjCEncodeExpr::child_begin() { return child_iterator(); }
-Stmt::child_iterator ObjCEncodeExpr::child_end() { return child_iterator(); }
-
-// ObjCSelectorExpr
-Stmt::child_iterator ObjCSelectorExpr::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator ObjCSelectorExpr::child_end() {
- return child_iterator();
-}
-
-// ObjCProtocolExpr
-Stmt::child_iterator ObjCProtocolExpr::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator ObjCProtocolExpr::child_end() {
- return child_iterator();
-}
-
-// ObjCMessageExpr
-Stmt::child_iterator ObjCMessageExpr::child_begin() {
- return getReceiver() ? &SubExprs[0] : &SubExprs[0] + ARGS_START;
-}
-Stmt::child_iterator ObjCMessageExpr::child_end() {
- return &SubExprs[0]+ARGS_START+getNumArgs();
-}
-
-// Blocks
-Stmt::child_iterator BlockExpr::child_begin() { return &Body; }
-Stmt::child_iterator BlockExpr::child_end() { return &Body+1; }
-
-Stmt::child_iterator BlockDeclRefExpr::child_begin() { return child_iterator();}
-Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator(); }
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
deleted file mode 100644
index 0c374ff5cce8..000000000000
--- a/clang/lib/AST/ExprCXX.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the subclesses of Expr class declared in ExprCXX.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ExprCXX.h"
-using namespace clang;
-
-void CXXConditionDeclExpr::Destroy(ASTContext& C) {
- getVarDecl()->Destroy(C);
- delete this;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Child Iterators for iterating over subexpressions/substatements
-//===----------------------------------------------------------------------===//
-
-
-// CXXCastExpr
-Stmt::child_iterator CXXCastExpr::child_begin() { return &Op; }
-Stmt::child_iterator CXXCastExpr::child_end() { return &Op+1; }
-
-// CXXBoolLiteralExpr
-Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
- return child_iterator();
-}
-
-// CXXThrowExpr
-Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
-Stmt::child_iterator CXXThrowExpr::child_end() {
- // If Op is 0, we are processing throw; which has no children.
- return Op ? &Op+1 : &Op;
-}
-
-// CXXDefaultArgExpr
-Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator CXXDefaultArgExpr::child_end() {
- return child_iterator();
-}
-
-// CXXZeroInitValueExpr
-Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
- return child_iterator();
-}
-
-// CXXConditionDeclExpr
-Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
- return getVarDecl();
-}
-Stmt::child_iterator CXXConditionDeclExpr::child_end() {
- return child_iterator();
-}
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
deleted file mode 100644
index 01dad74fa185..000000000000
--- a/clang/lib/AST/ExprConstant.cpp
+++ /dev/null
@@ -1,699 +0,0 @@
-//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Expr constant evaluator.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Support/Compiler.h"
-using namespace clang;
-using llvm::APSInt;
-using llvm::APFloat;
-
-/// EvalInfo - This is a private struct used by the evaluator to capture
-/// information about a subexpression as it is folded. It retains information
-/// about the AST context, but also maintains information about the folded
-/// expression.
-///
-/// If an expression could be evaluated, it is still possible it is not a C
-/// "integer constant expression" or constant expression. If not, this struct
-/// captures information about how and why not.
-///
-/// One bit of information passed *into* the request for constant folding
-/// indicates whether the subexpression is "evaluated" or not according to C
-/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
-/// evaluate the expression regardless of what the RHS is, but C only allows
-/// certain things in certain situations.
-struct EvalInfo {
- ASTContext &Ctx;
-
- /// isEvaluated - True if the subexpression is required to be evaluated, false
- /// if it is short-circuited (according to C rules).
- bool isEvaluated;
-
- /// ICEDiag - If the expression is unfoldable, then ICEDiag contains the
- /// error diagnostic indicating why it is not foldable and DiagLoc indicates a
- /// caret position for the error. If it is foldable, but the expression is
- /// not an integer constant expression, ICEDiag contains the extension
- /// diagnostic to emit which describes why it isn't an integer constant
- /// expression. If this expression *is* an integer-constant-expr, then
- /// ICEDiag is zero.
- ///
- /// The caller can choose to emit this diagnostic or not, depending on whether
- /// they require an i-c-e or a constant or not. DiagLoc indicates the caret
- /// position for the report.
- ///
- /// If ICEDiag is zero, then this expression is an i-c-e.
- unsigned ICEDiag;
- SourceLocation DiagLoc;
-
- EvalInfo(ASTContext &ctx) : Ctx(ctx), isEvaluated(true), ICEDiag(0) {}
-};
-
-
-static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
-static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
-static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
-
-//===----------------------------------------------------------------------===//
-// Pointer Evaluation
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN PointerExprEvaluator
- : public StmtVisitor<PointerExprEvaluator, APValue> {
- EvalInfo &Info;
-public:
-
- PointerExprEvaluator(EvalInfo &info) : Info(info) {}
-
- APValue VisitStmt(Stmt *S) {
- return APValue();
- }
-
- APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
-
- APValue VisitBinaryOperator(const BinaryOperator *E);
- APValue VisitCastExpr(const CastExpr* E);
-};
-} // end anonymous namespace
-
-static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
- if (!E->getType()->isPointerType())
- return false;
- Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
- return Result.isLValue();
-}
-
-APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
- if (E->getOpcode() != BinaryOperator::Add &&
- E->getOpcode() != BinaryOperator::Sub)
- return APValue();
-
- const Expr *PExp = E->getLHS();
- const Expr *IExp = E->getRHS();
- if (IExp->getType()->isPointerType())
- std::swap(PExp, IExp);
-
- APValue ResultLValue;
- if (!EvaluatePointer(PExp, ResultLValue, Info))
- return APValue();
-
- llvm::APSInt AdditionalOffset(32);
- if (!EvaluateInteger(IExp, AdditionalOffset, Info))
- return APValue();
-
- uint64_t Offset = ResultLValue.getLValueOffset();
- if (E->getOpcode() == BinaryOperator::Add)
- Offset += AdditionalOffset.getZExtValue();
- else
- Offset -= AdditionalOffset.getZExtValue();
-
- return APValue(ResultLValue.getLValueBase(), Offset);
-}
-
-
-APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
- const Expr* SubExpr = E->getSubExpr();
-
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType()) {
- APValue Result;
- if (EvaluatePointer(SubExpr, Result, Info))
- return Result;
- return APValue();
- }
-
- if (SubExpr->getType()->isIntegralType()) {
- llvm::APSInt Result(32);
- if (EvaluateInteger(SubExpr, Result, Info)) {
- Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
- return APValue(0, Result.getZExtValue());
- }
- }
-
- assert(0 && "Unhandled cast");
- return APValue();
-}
-
-
-//===----------------------------------------------------------------------===//
-// Integer Evaluation
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN IntExprEvaluator
- : public StmtVisitor<IntExprEvaluator, bool> {
- EvalInfo &Info;
- APSInt &Result;
-public:
- IntExprEvaluator(EvalInfo &info, APSInt &result)
- : Info(info), Result(result) {}
-
- unsigned getIntTypeSizeInBits(QualType T) const {
- return (unsigned)Info.Ctx.getIntWidth(T);
- }
-
- bool Extension(SourceLocation L, diag::kind D) {
- Info.DiagLoc = L;
- Info.ICEDiag = D;
- return true; // still a constant.
- }
-
- bool Error(SourceLocation L, diag::kind D) {
- // If this is in an unevaluated portion of the subexpression, ignore the
- // error.
- if (!Info.isEvaluated)
- return true;
-
- Info.DiagLoc = L;
- Info.ICEDiag = D;
- return false;
- }
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- bool VisitStmt(Stmt *S) {
- return Error(S->getLocStart(), diag::err_expr_not_constant);
- }
-
- bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
-
- bool VisitIntegerLiteral(const IntegerLiteral *E) {
- Result = E->getValue();
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
- }
- bool VisitCharacterLiteral(const CharacterLiteral *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = E->getValue();
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
- }
- bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = Info.Ctx.typesAreCompatible(E->getArgType1(), E->getArgType2());
- return true;
- }
- bool VisitDeclRefExpr(const DeclRefExpr *E);
- bool VisitCallExpr(const CallExpr *E);
- bool VisitBinaryOperator(const BinaryOperator *E);
- bool VisitUnaryOperator(const UnaryOperator *E);
-
- bool VisitCastExpr(CastExpr* E) {
- return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType());
- }
- bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
- return EvaluateSizeAlignOf(E->isSizeOf(), E->getArgumentType(),
- E->getType());
- }
-
-private:
- bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType);
- bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy);
-};
-} // end anonymous namespace
-
-static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
- return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
-}
-
-bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
- // Enums are integer constant exprs.
- if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
- Result = D->getInitVal();
- return true;
- }
-
- // Otherwise, random variable references are not constants.
- return Error(E->getLocStart(), diag::err_expr_not_constant);
-}
-
-/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
-/// as GCC.
-static int EvaluateBuiltinClassifyType(const CallExpr *E) {
- // The following enum mimics the values returned by GCC.
- enum gcc_type_class {
- no_type_class = -1,
- void_type_class, integer_type_class, char_type_class,
- enumeral_type_class, boolean_type_class,
- pointer_type_class, reference_type_class, offset_type_class,
- real_type_class, complex_type_class,
- function_type_class, method_type_class,
- record_type_class, union_type_class,
- array_type_class, string_type_class,
- lang_type_class
- };
-
- // If no argument was supplied, default to "no_type_class". This isn't
- // ideal, however it is what gcc does.
- if (E->getNumArgs() == 0)
- return no_type_class;
-
- QualType ArgTy = E->getArg(0)->getType();
- if (ArgTy->isVoidType())
- return void_type_class;
- else if (ArgTy->isEnumeralType())
- return enumeral_type_class;
- else if (ArgTy->isBooleanType())
- return boolean_type_class;
- else if (ArgTy->isCharType())
- return string_type_class; // gcc doesn't appear to use char_type_class
- else if (ArgTy->isIntegerType())
- return integer_type_class;
- else if (ArgTy->isPointerType())
- return pointer_type_class;
- else if (ArgTy->isReferenceType())
- return reference_type_class;
- else if (ArgTy->isRealType())
- return real_type_class;
- else if (ArgTy->isComplexType())
- return complex_type_class;
- else if (ArgTy->isFunctionType())
- return function_type_class;
- else if (ArgTy->isStructureType())
- return record_type_class;
- else if (ArgTy->isUnionType())
- return union_type_class;
- else if (ArgTy->isArrayType())
- return array_type_class;
- else if (ArgTy->isUnionType())
- return union_type_class;
- else // FIXME: offset_type_class, method_type_class, & lang_type_class?
- assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
- return -1;
-}
-
-bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
-
- switch (E->isBuiltinCall()) {
- default:
- return Error(E->getLocStart(), diag::err_expr_not_constant);
- case Builtin::BI__builtin_classify_type:
- Result.setIsSigned(true);
- Result = EvaluateBuiltinClassifyType(E);
- return true;
-
- case Builtin::BI__builtin_constant_p: {
- // __builtin_constant_p always has one operand: it returns true if that
- // operand can be folded, false otherwise.
- APValue Res;
- Result = E->getArg(0)->tryEvaluate(Res, Info.Ctx);
- return true;
- }
- }
-}
-
-bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
- // The LHS of a constant expr is always evaluated and needed.
- llvm::APSInt RHS(32);
- if (!Visit(E->getLHS()))
- return false; // error in subexpression.
-
- bool OldEval = Info.isEvaluated;
-
- // The short-circuiting &&/|| operators don't necessarily evaluate their
- // RHS. Make sure to pass isEvaluated down correctly.
- if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) ||
- (E->getOpcode() == BinaryOperator::LOr && Result != 0))
- Info.isEvaluated = false;
-
- // FIXME: Handle pointer subtraction
-
- // FIXME Maybe we want to succeed even where we can't evaluate the
- // right side of LAnd/LOr?
- // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525
- if (!EvaluateInteger(E->getRHS(), RHS, Info))
- return false;
- Info.isEvaluated = OldEval;
-
- switch (E->getOpcode()) {
- default: return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
- case BinaryOperator::Mul: Result *= RHS; return true;
- case BinaryOperator::Add: Result += RHS; return true;
- case BinaryOperator::Sub: Result -= RHS; return true;
- case BinaryOperator::And: Result &= RHS; return true;
- case BinaryOperator::Xor: Result ^= RHS; return true;
- case BinaryOperator::Or: Result |= RHS; return true;
- case BinaryOperator::Div:
- if (RHS == 0)
- return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
- Result /= RHS;
- return true;
- case BinaryOperator::Rem:
- if (RHS == 0)
- return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero);
- Result %= RHS;
- return true;
- case BinaryOperator::Shl:
- // FIXME: Warn about out of range shift amounts!
- Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
- break;
- case BinaryOperator::Shr:
- Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1);
- break;
-
- case BinaryOperator::LT:
- Result = Result < RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::GT:
- Result = Result > RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::LE:
- Result = Result <= RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::GE:
- Result = Result >= RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::EQ:
- Result = Result == RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::NE:
- Result = Result != RHS;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::LAnd:
- Result = Result != 0 && RHS != 0;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
- case BinaryOperator::LOr:
- Result = Result != 0 || RHS != 0;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- break;
-
-
- case BinaryOperator::Comma:
- // Result of the comma is just the result of the RHS.
- Result = RHS;
-
- // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
- // *except* when they are contained within a subexpression that is not
- // evaluated". Note that Assignment can never happen due to constraints
- // on the LHS subexpr, so we don't need to check it here.
- if (!Info.isEvaluated)
- return true;
-
- // If the value is evaluated, we can accept it as an extension.
- return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
- }
-
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
-}
-
-/// EvaluateSizeAlignOf - Evaluate sizeof(SrcTy) or alignof(SrcTy) with a result
-/// as a DstTy type.
-bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy,
- QualType DstTy) {
- // Return the result in the right width.
- Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
- Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
-
- // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
- if (SrcTy->isVoidType())
- Result = 1;
-
- // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
- if (!SrcTy->isConstantSizeType()) {
- // FIXME: Should we attempt to evaluate this?
- return false;
- }
-
- // GCC extension: sizeof(function) = 1.
- if (SrcTy->isFunctionType()) {
- // FIXME: AlignOf shouldn't be unconditionally 4!
- Result = isSizeOf ? 1 : 4;
- return true;
- }
-
- // Get information about the size or align.
- unsigned CharSize = Info.Ctx.Target.getCharWidth();
- if (isSizeOf)
- Result = getIntTypeSizeInBits(SrcTy) / CharSize;
- else
- Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
- return true;
-}
-
-bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
- // Special case unary operators that do not need their subexpression
- // evaluated. offsetof/sizeof/alignof are all special.
- if (E->isOffsetOfOp()) {
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = E->evaluateOffsetOf(Info.Ctx);
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
- }
-
- if (E->isSizeOfAlignOfOp())
- return EvaluateSizeAlignOf(E->getOpcode() == UnaryOperator::SizeOf,
- E->getSubExpr()->getType(), E->getType());
-
- // Get the operand value into 'Result'.
- if (!Visit(E->getSubExpr()))
- return false;
-
- switch (E->getOpcode()) {
- default:
- // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
- // See C99 6.6p3.
- return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
- case UnaryOperator::LNot: {
- bool Val = Result == 0;
- Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
- Result = Val;
- break;
- }
- case UnaryOperator::Extension:
- // FIXME: Should extension allow i-c-e extension expressions in its scope?
- // If so, we could clear the diagnostic ID.
- case UnaryOperator::Plus:
- // The result is always just the subexpr.
- break;
- case UnaryOperator::Minus:
- Result = -Result;
- break;
- case UnaryOperator::Not:
- Result = ~Result;
- break;
- }
-
- Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
- return true;
-}
-
-/// HandleCast - This is used to evaluate implicit or explicit casts where the
-/// result type is integer.
-bool IntExprEvaluator::HandleCast(SourceLocation CastLoc,
- Expr *SubExpr, QualType DestType) {
- unsigned DestWidth = getIntTypeSizeInBits(DestType);
-
- // Handle simple integer->integer casts.
- if (SubExpr->getType()->isIntegerType()) {
- if (!Visit(SubExpr))
- return false;
-
- // Figure out if this is a truncate, extend or noop cast.
- // If the input is signed, do a sign extend, noop, or truncate.
- if (DestType->isBooleanType()) {
- // Conversion to bool compares against zero.
- Result = Result != 0;
- Result.zextOrTrunc(DestWidth);
- } else
- Result.extOrTrunc(DestWidth);
- Result.setIsUnsigned(DestType->isUnsignedIntegerType());
- return true;
- }
-
- // FIXME: Clean this up!
- if (SubExpr->getType()->isPointerType()) {
- APValue LV;
- if (!EvaluatePointer(SubExpr, LV, Info))
- return false;
- if (LV.getLValueBase())
- return false;
-
- Result.extOrTrunc(DestWidth);
- Result = LV.getLValueOffset();
- Result.setIsUnsigned(DestType->isUnsignedIntegerType());
- return true;
- }
-
- if (!SubExpr->getType()->isRealFloatingType())
- return Error(CastLoc, diag::err_expr_not_constant);
-
- APFloat F(0.0);
- if (!EvaluateFloat(SubExpr, F, Info))
- return Error(CastLoc, diag::err_expr_not_constant);
-
- // If the destination is boolean, compare against zero.
- if (DestType->isBooleanType()) {
- Result = !F.isZero();
- Result.zextOrTrunc(DestWidth);
- Result.setIsUnsigned(DestType->isUnsignedIntegerType());
- return true;
- }
-
- // Determine whether we are converting to unsigned or signed.
- bool DestSigned = DestType->isSignedIntegerType();
-
- // FIXME: Warning for overflow.
- uint64_t Space[4];
- (void)F.convertToInteger(Space, DestWidth, DestSigned,
- llvm::APFloat::rmTowardZero);
- Result = llvm::APInt(DestWidth, 4, Space);
- Result.setIsUnsigned(!DestSigned);
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Float Evaluation
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN FloatExprEvaluator
- : public StmtVisitor<FloatExprEvaluator, bool> {
- EvalInfo &Info;
- APFloat &Result;
-public:
- FloatExprEvaluator(EvalInfo &info, APFloat &result)
- : Info(info), Result(result) {}
-
- bool VisitStmt(Stmt *S) {
- return false;
- }
-
- bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
- bool VisitCallExpr(const CallExpr *E);
-
- bool VisitBinaryOperator(const BinaryOperator *E);
- bool VisitFloatingLiteral(const FloatingLiteral *E);
-};
-} // end anonymous namespace
-
-static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
- return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
-}
-
-bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
- const llvm::fltSemantics &Sem =
- Info.Ctx.getFloatTypeSemantics(E->getType());
-
- switch (E->isBuiltinCall()) {
- default: return false;
- case Builtin::BI__builtin_huge_val:
- case Builtin::BI__builtin_huge_valf:
- case Builtin::BI__builtin_huge_vall:
- case Builtin::BI__builtin_inf:
- case Builtin::BI__builtin_inff:
- case Builtin::BI__builtin_infl:
- Result = llvm::APFloat::getInf(Sem);
- return true;
-
- case Builtin::BI__builtin_nan:
- case Builtin::BI__builtin_nanf:
- case Builtin::BI__builtin_nanl:
- // If this is __builtin_nan("") turn this into a simple nan, otherwise we
- // can't constant fold it.
- if (const StringLiteral *S =
- dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
- if (!S->isWide() && S->getByteLength() == 0) { // empty string.
- Result = llvm::APFloat::getNaN(Sem);
- return true;
- }
- }
- return false;
- }
-}
-
-
-bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
- // FIXME: Diagnostics? I really don't understand how the warnings
- // and errors are supposed to work.
- APFloat LHS(0.0), RHS(0.0);
- if (!EvaluateFloat(E->getLHS(), Result, Info))
- return false;
- if (!EvaluateFloat(E->getRHS(), RHS, Info))
- return false;
-
- switch (E->getOpcode()) {
- default: return false;
- case BinaryOperator::Mul:
- Result.multiply(RHS, APFloat::rmNearestTiesToEven);
- return true;
- case BinaryOperator::Add:
- Result.add(RHS, APFloat::rmNearestTiesToEven);
- return true;
- case BinaryOperator::Sub:
- Result.subtract(RHS, APFloat::rmNearestTiesToEven);
- return true;
- case BinaryOperator::Div:
- Result.divide(RHS, APFloat::rmNearestTiesToEven);
- return true;
- case BinaryOperator::Rem:
- Result.mod(RHS, APFloat::rmNearestTiesToEven);
- return true;
- }
-}
-
-bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
- Result = E->getValue();
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Top level TryEvaluate.
-//===----------------------------------------------------------------------===//
-
-/// tryEvaluate - Return true if this is a constant which we can fold using
-/// any crazy technique (that has nothing to do with language standards) that
-/// we want to. If this function returns true, it returns the folded constant
-/// in Result.
-bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const {
- EvalInfo Info(Ctx);
- if (getType()->isIntegerType()) {
- llvm::APSInt sInt(32);
- if (EvaluateInteger(this, sInt, Info)) {
- Result = APValue(sInt);
- return true;
- }
- } else if (getType()->isPointerType()) {
- if (EvaluatePointer(this, Result, Info)) {
- return true;
- }
- } else if (getType()->isRealFloatingType()) {
- llvm::APFloat f(0.0);
- if (EvaluateFloat(this, f, Info)) {
- Result = APValue(f);
- return true;
- }
- }
-
- return false;
-}
-
-/// isEvaluatable - Call tryEvaluate to see if this expression can be constant
-/// folded, but discard the result.
-bool Expr::isEvaluatable(ASTContext &Ctx) const {
- APValue V;
- return tryEvaluate(V, Ctx);
-}
diff --git a/clang/lib/AST/Makefile b/clang/lib/AST/Makefile
deleted file mode 100644
index cdfc64cacaf6..000000000000
--- a/clang/lib/AST/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- clang/lib/AST/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the AST library for the C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangAST
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/AST/ParentMap.cpp b/clang/lib/AST/ParentMap.cpp
deleted file mode 100644
index 82341c78f827..000000000000
--- a/clang/lib/AST/ParentMap.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- 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 ParentMap class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ParentMap.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "llvm/ADT/DenseMap.h"
-
-using namespace clang;
-
-typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
-
-static void BuildParentMap(MapTy& M, Stmt* S) {
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
- if (*I) {
- M[*I] = S;
- BuildParentMap(M, *I);
- }
-}
-
-ParentMap::ParentMap(Stmt* S) : Impl(0) {
- if (S) {
- MapTy *M = new MapTy();
- BuildParentMap(*M, S);
- Impl = M;
- }
-}
-
-ParentMap::~ParentMap() {
- delete (MapTy*) Impl;
-}
-
-Stmt* ParentMap::getParent(Stmt* S) const {
- MapTy* M = (MapTy*) Impl;
- MapTy::iterator I = M->find(S);
- return I == M->end() ? 0 : I->second;
-}
-
-bool ParentMap::isSubExpr(Stmt* S) const {
- if (!isa<Expr>(S))
- return false;
-
- Stmt* P = getParent(S);
- return P ? !isa<CompoundStmt>(P) : false;
-}
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
deleted file mode 100644
index fbb369f387e2..000000000000
--- a/clang/lib/AST/Stmt.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Stmt class and statement subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Stmt.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-using namespace clang;
-
-static struct StmtClassNameTable {
- const char *Name;
- unsigned Counter;
- unsigned Size;
-} StmtClassInfo[Stmt::lastExprConstant+1];
-
-static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
- static bool Initialized = false;
- if (Initialized)
- return StmtClassInfo[E];
-
- // Intialize the table on the first use.
- Initialized = true;
-#define STMT(N, CLASS, PARENT) \
- StmtClassInfo[N].Name = #CLASS; \
- StmtClassInfo[N].Size = sizeof(CLASS);
-#include "clang/AST/StmtNodes.def"
-
- return StmtClassInfo[E];
-}
-
-const char *Stmt::getStmtClassName() const {
- return getStmtInfoTableEntry(sClass).Name;
-}
-
-void Stmt::DestroyChildren(ASTContext& C) {
- for (child_iterator I = child_begin(), E = child_end(); I !=E; ++I)
- if (Stmt* Child = *I) Child->Destroy(C);
-}
-
-void Stmt::Destroy(ASTContext& C) {
- DestroyChildren(C);
- // FIXME: Eventually all Stmts should be allocated with the allocator
- // in ASTContext, just like with Decls.
- // this->~Stmt();
- delete this;
-}
-
-void DeclStmt::Destroy(ASTContext& C) {
- TheDecl->Destroy(C);
- delete this;
-}
-
-void Stmt::PrintStats() {
- // Ensure the table is primed.
- getStmtInfoTableEntry(Stmt::NullStmtClass);
-
- unsigned sum = 0;
- fprintf(stderr, "*** Stmt/Expr Stats:\n");
- for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
- if (StmtClassInfo[i].Name == 0) continue;
- sum += StmtClassInfo[i].Counter;
- }
- fprintf(stderr, " %d stmts/exprs total.\n", sum);
- sum = 0;
- for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
- if (StmtClassInfo[i].Name == 0) continue;
- fprintf(stderr, " %d %s, %d each (%d bytes)\n",
- StmtClassInfo[i].Counter, StmtClassInfo[i].Name,
- StmtClassInfo[i].Size,
- StmtClassInfo[i].Counter*StmtClassInfo[i].Size);
- sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
- }
- fprintf(stderr, "Total bytes = %d\n", sum);
-}
-
-void Stmt::addStmtClass(StmtClass s) {
- ++getStmtInfoTableEntry(s).Counter;
-}
-
-static bool StatSwitch = false;
-
-bool Stmt::CollectingStats(bool enable) {
- if (enable) StatSwitch = true;
- return StatSwitch;
-}
-
-
-const char *LabelStmt::getName() const {
- return getID()->getName();
-}
-
-// This is defined here to avoid polluting Stmt.h with importing Expr.h
-SourceRange ReturnStmt::getSourceRange() const {
- if (RetExpr)
- return SourceRange(RetLoc, RetExpr->getLocEnd());
- else
- return SourceRange(RetLoc);
-}
-
-bool Stmt::hasImplicitControlFlow() const {
- switch (sClass) {
- default:
- return false;
-
- case CallExprClass:
- case ConditionalOperatorClass:
- case ChooseExprClass:
- case StmtExprClass:
- case DeclStmtClass:
- return true;
-
- case Stmt::BinaryOperatorClass: {
- const BinaryOperator* B = cast<BinaryOperator>(this);
- if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
- return true;
- else
- return false;
- }
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Constructors
-//===----------------------------------------------------------------------===//
-
-AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
- unsigned numoutputs, unsigned numinputs,
- std::string *names, StringLiteral **constraints,
- Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc)
- : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
- , IsSimple(issimple), IsVolatile(isvolatile)
- , NumOutputs(numoutputs), NumInputs(numinputs) {
- for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) {
- Names.push_back(names[i]);
- Exprs.push_back(exprs[i]);
- Constraints.push_back(constraints[i]);
- }
-
- for (unsigned i = 0; i != numclobbers; i++)
- Clobbers.push_back(clobbers[i]);
-}
-
-ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
- Stmt *Body, SourceLocation FCL,
- SourceLocation RPL)
-: Stmt(ObjCForCollectionStmtClass) {
- SubExprs[ELEM] = Elem;
- SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
- SubExprs[BODY] = Body;
- ForLoc = FCL;
- RParenLoc = RPL;
-}
-
-
-ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
- SourceLocation rparenloc,
- Stmt *catchVarStmtDecl, Stmt *atCatchStmt,
- Stmt *atCatchList)
-: Stmt(ObjCAtCatchStmtClass) {
- SubExprs[SELECTOR] = catchVarStmtDecl;
- SubExprs[BODY] = atCatchStmt;
- SubExprs[NEXT_CATCH] = NULL;
- if (atCatchList) {
- ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
-
- while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
- AtCatchList = NextCatch;
-
- AtCatchList->SubExprs[NEXT_CATCH] = this;
- }
- AtCatchLoc = atCatchLoc;
- RParenLoc = rparenloc;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Child Iterators for iterating over subexpressions/substatements
-//===----------------------------------------------------------------------===//
-
-// DeclStmt
-Stmt::child_iterator DeclStmt::child_begin() { return TheDecl; }
-Stmt::child_iterator DeclStmt::child_end() { return child_iterator(); }
-
-DeclStmt::decl_iterator& DeclStmt::decl_iterator::operator++() {
- D = D->getNextDeclarator();
- return *this;
-}
-
-bool DeclStmt::hasSolitaryDecl() const {
- return TheDecl->getNextDeclarator() == 0;
-}
-
-// NullStmt
-Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
-Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
-
-// CompoundStmt
-Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
-Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+Body.size(); }
-
-// CaseStmt
-Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
-
-// DefaultStmt
-Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
-Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
-
-// LabelStmt
-Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
-Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
-
-// IfStmt
-Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; }
-
-// SwitchStmt
-Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; }
-
-// WhileStmt
-Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; }
-
-// DoStmt
-Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
-
-// ForStmt
-Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
-
-// ObjCForCollectionStmt
-Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
- return &SubExprs[0];
-}
-Stmt::child_iterator ObjCForCollectionStmt::child_end() {
- return &SubExprs[0]+END_EXPR;
-}
-
-// GotoStmt
-Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
-Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
-
-// IndirectGotoStmt
-Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
-const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
-
-Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
-Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
-
-// ContinueStmt
-Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
-Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
-
-// BreakStmt
-Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
-Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
-
-// ReturnStmt
-const Expr* ReturnStmt::getRetValue() const {
- return cast_or_null<Expr>(RetExpr);
-}
-Expr* ReturnStmt::getRetValue() {
- return cast_or_null<Expr>(RetExpr);
-}
-
-Stmt::child_iterator ReturnStmt::child_begin() {
- return &RetExpr;
-}
-Stmt::child_iterator ReturnStmt::child_end() {
- return RetExpr ? &RetExpr+1 : &RetExpr;
-}
-
-// AsmStmt
-Stmt::child_iterator AsmStmt::child_begin() { return child_iterator(); }
-Stmt::child_iterator AsmStmt::child_end() { return child_iterator(); }
-
-// ObjCAtCatchStmt
-Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator ObjCAtCatchStmt::child_end() {
- return &SubExprs[0]+END_EXPR;
-}
-
-// ObjCAtFinallyStmt
-Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
-Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
-
-// ObjCAtTryStmt
-Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
-Stmt::child_iterator ObjCAtTryStmt::child_end() {
- return &SubStmts[0]+END_EXPR;
-}
-
-// ObjCAtThrowStmt
-Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
- return &Throw;
-}
-
-Stmt::child_iterator ObjCAtThrowStmt::child_end() {
- return &Throw+1;
-}
-
-// ObjCAtSynchronizedStmt
-Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
- return &SubStmts[0];
-}
-
-Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
- return &SubStmts[0]+END_EXPR;
-}
-
diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp
deleted file mode 100644
index dd92e84e9d27..000000000000
--- a/clang/lib/AST/StmtDumper.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-//===--- StmtDumper.cpp - Dumping implementation for Stmt ASTs ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Stmt::dump/Stmt::print methods, which dump out the
-// AST in a form that exposes type details and other fields.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/Compiler.h"
-#include <cstdio>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// StmtDumper Visitor
-//===----------------------------------------------------------------------===//
-
-namespace {
- class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor<StmtDumper> {
- SourceManager *SM;
- FILE *F;
- unsigned IndentLevel;
-
- /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump
- /// the first few levels of an AST. This keeps track of how many ast levels
- /// are left.
- unsigned MaxDepth;
-
- /// LastLocFilename/LastLocLine - Keep track of the last location we print
- /// out so that we can print out deltas from then on out.
- const char *LastLocFilename;
- unsigned LastLocLine;
- public:
- StmtDumper(SourceManager *sm, FILE *f, unsigned maxDepth)
- : SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {
- LastLocFilename = "";
- LastLocLine = ~0U;
- }
-
- void DumpSubTree(Stmt *S) {
- // Prune the recursion if not using dump all.
- if (MaxDepth == 0) return;
-
- ++IndentLevel;
- if (S) {
- if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
- VisitDeclStmt(DS);
- else {
- Visit(S);
-
- // Print out children.
- Stmt::child_iterator CI = S->child_begin(), CE = S->child_end();
- if (CI != CE) {
- while (CI != CE) {
- fprintf(F, "\n");
- DumpSubTree(*CI++);
- }
- }
- fprintf(F, ")");
- }
- } else {
- Indent();
- fprintf(F, "<<<NULL>>>");
- }
- --IndentLevel;
- }
-
- void DumpDeclarator(Decl *D);
-
- void Indent() const {
- for (int i = 0, e = IndentLevel; i < e; ++i)
- fprintf(F, " ");
- }
-
- void DumpType(QualType T) {
- fprintf(F, "'%s'", T.getAsString().c_str());
-
- // If the type is directly a typedef, strip off typedefness to give at
- // least one level of concreteness.
- if (TypedefType *TDT = dyn_cast<TypedefType>(T)) {
- QualType Simplified =
- TDT->LookThroughTypedefs().getQualifiedType(T.getCVRQualifiers());
- fprintf(F, ":'%s'", Simplified.getAsString().c_str());
- }
- }
- void DumpStmt(const Stmt *Node) {
- Indent();
- fprintf(F, "(%s %p", Node->getStmtClassName(), (void*)Node);
- DumpSourceRange(Node);
- }
- void DumpExpr(const Expr *Node) {
- DumpStmt(Node);
- fprintf(F, " ");
- DumpType(Node->getType());
- }
- void DumpSourceRange(const Stmt *Node);
- void DumpLocation(SourceLocation Loc);
-
- // Stmts.
- void VisitStmt(Stmt *Node);
- void VisitDeclStmt(DeclStmt *Node);
- void VisitLabelStmt(LabelStmt *Node);
- void VisitGotoStmt(GotoStmt *Node);
-
- // Exprs
- void VisitExpr(Expr *Node);
- void VisitDeclRefExpr(DeclRefExpr *Node);
- void VisitPredefinedExpr(PredefinedExpr *Node);
- void VisitCharacterLiteral(CharacterLiteral *Node);
- void VisitIntegerLiteral(IntegerLiteral *Node);
- void VisitFloatingLiteral(FloatingLiteral *Node);
- void VisitStringLiteral(StringLiteral *Str);
- void VisitUnaryOperator(UnaryOperator *Node);
- void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node);
- void VisitMemberExpr(MemberExpr *Node);
- void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
- void VisitBinaryOperator(BinaryOperator *Node);
- void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
- void VisitAddrLabelExpr(AddrLabelExpr *Node);
- void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
-
- // C++
- void VisitCXXCastExpr(CXXCastExpr *Node);
- void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
-
- // ObjC
- void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
- void VisitObjCMessageExpr(ObjCMessageExpr* Node);
- void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
- void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
- void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
- void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
- };
-}
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-void StmtDumper::DumpLocation(SourceLocation Loc) {
- SourceLocation PhysLoc = SM->getPhysicalLoc(Loc);
-
- // The general format we print out is filename:line:col, but we drop pieces
- // that haven't changed since the last loc printed.
- const char *Filename = SM->getSourceName(PhysLoc);
- unsigned LineNo = SM->getLineNumber(PhysLoc);
- if (strcmp(Filename, LastLocFilename) != 0) {
- fprintf(stderr, "%s:%u:%u", Filename, LineNo, SM->getColumnNumber(PhysLoc));
- LastLocFilename = Filename;
- LastLocLine = LineNo;
- } else if (LineNo != LastLocLine) {
- fprintf(stderr, "line:%u:%u", LineNo, SM->getColumnNumber(PhysLoc));
- LastLocLine = LineNo;
- } else {
- fprintf(stderr, "col:%u", SM->getColumnNumber(PhysLoc));
- }
-}
-
-void StmtDumper::DumpSourceRange(const Stmt *Node) {
- // Can't translate locations if a SourceManager isn't available.
- if (SM == 0) return;
-
- // TODO: If the parent expression is available, we can print a delta vs its
- // location.
- SourceRange R = Node->getSourceRange();
-
- fprintf(stderr, " <");
- DumpLocation(R.getBegin());
- if (R.getBegin() != R.getEnd()) {
- fprintf(stderr, ", ");
- DumpLocation(R.getEnd());
- }
- fprintf(stderr, ">");
-
- // <t2.c:123:421[blah], t2.c:412:321>
-
-}
-
-
-//===----------------------------------------------------------------------===//
-// Stmt printing methods.
-//===----------------------------------------------------------------------===//
-
-void StmtDumper::VisitStmt(Stmt *Node) {
- DumpStmt(Node);
-}
-
-void StmtDumper::DumpDeclarator(Decl *D) {
- // FIXME: Need to complete/beautify this... this code simply shows the
- // nodes are where they need to be.
- if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
- fprintf(F, "\"typedef %s %s\"",
- localType->getUnderlyingType().getAsString().c_str(),
- localType->getName());
- } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
- fprintf(F, "\"");
- // Emit storage class for vardecls.
- if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- switch (V->getStorageClass()) {
- default: assert(0 && "Unknown storage class!");
- case VarDecl::None: break;
- case VarDecl::Extern: fprintf(F, "extern "); break;
- case VarDecl::Static: fprintf(F, "static "); break;
- case VarDecl::Auto: fprintf(F, "auto "); break;
- case VarDecl::Register: fprintf(F, "register "); break;
- }
- }
-
- std::string Name = VD->getName();
- VD->getType().getAsStringInternal(Name);
- fprintf(F, "%s", Name.c_str());
-
- // If this is a vardecl with an initializer, emit it.
- if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- if (V->getInit()) {
- fprintf(F, " =\n");
- DumpSubTree(V->getInit());
- }
- }
- fprintf(F, "\"");
- } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- // print a free standing tag decl (e.g. "struct x;").
- const char *tagname;
- if (const IdentifierInfo *II = TD->getIdentifier())
- tagname = II->getName();
- else
- tagname = "<anonymous>";
- fprintf(F, "\"%s %s;\"", TD->getKindName(), tagname);
- // FIXME: print tag bodies.
- } else {
- assert(0 && "Unexpected decl");
- }
-}
-
-void StmtDumper::VisitDeclStmt(DeclStmt *Node) {
- DumpStmt(Node);
- fprintf(F,"\n");
- for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
- DI != DE; ++DI) {
- ScopedDecl* D = *DI;
- ++IndentLevel;
- Indent();
- fprintf(F, "%p ", (void*) D);
- DumpDeclarator(D);
- if (D->getNextDeclarator())
- fprintf(F,"\n");
- --IndentLevel;
- }
-}
-
-void StmtDumper::VisitLabelStmt(LabelStmt *Node) {
- DumpStmt(Node);
- fprintf(F, " '%s'", Node->getName());
-}
-
-void StmtDumper::VisitGotoStmt(GotoStmt *Node) {
- DumpStmt(Node);
- fprintf(F, " '%s':%p", Node->getLabel()->getName(), (void*)Node->getLabel());
-}
-
-//===----------------------------------------------------------------------===//
-// Expr printing methods.
-//===----------------------------------------------------------------------===//
-
-void StmtDumper::VisitExpr(Expr *Node) {
- DumpExpr(Node);
-}
-
-void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
- DumpExpr(Node);
-
- fprintf(F, " ");
- switch (Node->getDecl()->getKind()) {
- case Decl::Function: fprintf(F,"FunctionDecl"); break;
- case Decl::Var: fprintf(F,"Var"); break;
- case Decl::ParmVar: fprintf(F,"ParmVar"); break;
- case Decl::EnumConstant: fprintf(F,"EnumConstant"); break;
- case Decl::Typedef: fprintf(F,"Typedef"); break;
- case Decl::Struct: fprintf(F,"Struct"); break;
- case Decl::Union: fprintf(F,"Union"); break;
- case Decl::Class: fprintf(F,"Class"); break;
- case Decl::Enum: fprintf(F,"Enum"); break;
- case Decl::CXXStruct: fprintf(F,"CXXStruct"); break;
- case Decl::CXXUnion: fprintf(F,"CXXUnion"); break;
- case Decl::CXXClass: fprintf(F,"CXXClass"); break;
- case Decl::ObjCInterface: fprintf(F,"ObjCInterface"); break;
- case Decl::ObjCClass: fprintf(F,"ObjCClass"); break;
- default: fprintf(F,"Decl"); break;
- }
-
- fprintf(F, "='%s' %p", Node->getDecl()->getName(), (void*)Node->getDecl());
-}
-
-void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
- DumpExpr(Node);
-
- fprintf(F, " %sDecl='%s' %p", Node->getDecl()->getDeclKindName(),
- Node->getDecl()->getName(), (void*)Node->getDecl());
- if (Node->isFreeIvar())
- fprintf(F, " isFreeIvar");
-}
-
-void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) {
- DumpExpr(Node);
- switch (Node->getIdentType()) {
- default: assert(0 && "unknown case");
- case PredefinedExpr::Func: fprintf(F, " __func__"); break;
- case PredefinedExpr::Function: fprintf(F, " __FUNCTION__"); break;
- case PredefinedExpr::PrettyFunction: fprintf(F, " __PRETTY_FUNCTION__");break;
- case PredefinedExpr::ObjCSuper: fprintf(F, "super"); break;
- }
-}
-
-void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) {
- DumpExpr(Node);
- fprintf(F, " %d", Node->getValue());
-}
-
-void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) {
- DumpExpr(Node);
-
- bool isSigned = Node->getType()->isSignedIntegerType();
- fprintf(F, " %s", Node->getValue().toString(10, isSigned).c_str());
-}
-void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) {
- DumpExpr(Node);
- fprintf(F, " %f", Node->getValueAsApproximateDouble());
-}
-
-void StmtDumper::VisitStringLiteral(StringLiteral *Str) {
- DumpExpr(Str);
- // FIXME: this doesn't print wstrings right.
- fprintf(F, " %s\"", Str->isWide() ? "L" : "");
-
- for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
- switch (char C = Str->getStrData()[i]) {
- default:
- if (isprint(C))
- fputc(C, F);
- else
- fprintf(F, "\\%03o", C);
- break;
- // Handle some common ones to make dumps prettier.
- case '\\': fprintf(F, "\\\\"); break;
- case '"': fprintf(F, "\\\""); break;
- case '\n': fprintf(F, "\\n"); break;
- case '\t': fprintf(F, "\\t"); break;
- case '\a': fprintf(F, "\\a"); break;
- case '\b': fprintf(F, "\\b"); break;
- }
- }
- fprintf(F, "\"");
-}
-
-void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) {
- DumpExpr(Node);
- fprintf(F, " %s '%s'", Node->isPostfix() ? "postfix" : "prefix",
- UnaryOperator::getOpcodeStr(Node->getOpcode()));
-}
-void StmtDumper::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " %s ", Node->isSizeOf() ? "sizeof" : "alignof");
- DumpType(Node->getArgumentType());
-}
-
-void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " %s%s %p", Node->isArrow() ? "->" : ".",
- Node->getMemberDecl()->getName(), (void*)Node->getMemberDecl());
-}
-void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " %s", Node->getAccessor().getName());
-}
-void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) {
- DumpExpr(Node);
- fprintf(F, " '%s'", BinaryOperator::getOpcodeStr(Node->getOpcode()));
-}
-void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
- DumpExpr(Node);
- fprintf(F, " '%s' ComputeTy=",
- BinaryOperator::getOpcodeStr(Node->getOpcode()));
- DumpType(Node->getComputationType());
-}
-
-// GNU extensions.
-
-void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " %s %p", Node->getLabel()->getName(), (void*)Node->getLabel());
-}
-
-void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " ");
- DumpType(Node->getArgType1());
- fprintf(F, " ");
- DumpType(Node->getArgType2());
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Expressions
-//===----------------------------------------------------------------------===//
-
-void StmtDumper::VisitCXXCastExpr(CXXCastExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " %s", CXXCastExpr::getOpcodeStr(Node->getOpcode()));
-}
-
-void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
- DumpExpr(Node);
- fprintf(F, " %s", Node->getValue() ? "true" : "false");
-}
-
-//===----------------------------------------------------------------------===//
-// Obj-C Expressions
-//===----------------------------------------------------------------------===//
-
-void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
- DumpExpr(Node);
- fprintf(F, " selector=%s", Node->getSelector().getName().c_str());
- IdentifierInfo* clsName = Node->getClassName();
- if (clsName) fprintf(F, " class=%s", clsName->getName());
-}
-
-void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
- DumpExpr(Node);
-
- fprintf(F, " ");
- DumpType(Node->getEncodedType());
-}
-
-void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
- DumpExpr(Node);
-
- fprintf(F, " ");
- Selector selector = Node->getSelector();
- fprintf(F, "%s", selector.getName().c_str());
-}
-
-void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
- DumpExpr(Node);
-
- fprintf(F, " ");
- fprintf(F, "%s", Node->getProtocol()->getName());
-}
-
-void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
- DumpExpr(Node);
-
- if (Node->getKind() == ObjCPropertyRefExpr::MethodRef) {
- ObjCMethodDecl *Getter = Node->getGetterMethod();
- ObjCMethodDecl *Setter = Node->getSetterMethod();
- fprintf(F, " Kind=MethodRef Getter=\"%s\" Setter=\"%s\"",
- Getter->getSelector().getName().c_str(),
- Setter ? Setter->getSelector().getName().c_str() : "(null)");
- } else {
- fprintf(F, " Kind=PropertyRef Property=\"%s\"", Node->getProperty()->getName());
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Stmt method implementations
-//===----------------------------------------------------------------------===//
-
-/// dump - This does a local dump of the specified AST fragment. It dumps the
-/// specified node and a few nodes underneath it, but not the whole subtree.
-/// This is useful in a debugger.
-void Stmt::dump(SourceManager &SM) const {
- StmtDumper P(&SM, stderr, 4);
- P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
-}
-
-/// dump - This does a local dump of the specified AST fragment. It dumps the
-/// specified node and a few nodes underneath it, but not the whole subtree.
-/// This is useful in a debugger.
-void Stmt::dump() const {
- StmtDumper P(0, stderr, 4);
- P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
-}
-
-/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
-void Stmt::dumpAll(SourceManager &SM) const {
- StmtDumper P(&SM, stderr, ~0U);
- P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
-}
-
-/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
-void Stmt::dumpAll() const {
- StmtDumper P(0, stderr, ~0U);
- P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
-}
diff --git a/clang/lib/AST/StmtIterator.cpp b/clang/lib/AST/StmtIterator.cpp
deleted file mode 100644
index 3af66b30bf34..000000000000
--- a/clang/lib/AST/StmtIterator.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines internal methods for StmtIterator.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/StmtIterator.h"
-#include "clang/AST/Decl.h"
-
-using namespace clang;
-
-static inline VariableArrayType* FindVA(Type* t) {
- while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
- if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
- if (vat->getSizeExpr())
- return vat;
-
- t = vt->getElementType().getTypePtr();
- }
-
- return NULL;
-}
-
-void StmtIteratorBase::NextVA() {
- assert (getVAPtr());
-
- VariableArrayType* p = getVAPtr();
- p = FindVA(p->getElementType().getTypePtr());
- setVAPtr(p);
-
- if (!p && inDecl()) {
- if (VarDecl* VD = dyn_cast<VarDecl>(decl))
- if (VD->Init)
- return;
-
- NextDecl();
- } else if (inSizeOfTypeVA()) {
- assert(!decl);
- RawVAPtr = 0;
- }
-}
-
-void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
- assert (inDecl());
- assert (getVAPtr() == NULL);
- assert (decl);
-
- if (ImmediateAdvance) {
- decl = decl->getNextDeclarator();
-
- if (!decl) {
- RawVAPtr = 0;
- return;
- }
- }
-
- for ( ; decl ; decl = decl->getNextDeclarator()) {
- if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
- if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
- setVAPtr(VAPtr);
- return;
- }
-
- if (VD->getInit())
- return;
- }
- else if (TypedefDecl* TD = dyn_cast<TypedefDecl>(decl)) {
- if (VariableArrayType* VAPtr =
- FindVA(TD->getUnderlyingType().getTypePtr())) {
- setVAPtr(VAPtr);
- return;
- }
- }
- else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(decl))
- if (ECD->getInitExpr())
- return;
- }
-
- if (!decl) {
- RawVAPtr = 0;
- return;
- }
-}
-
-StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
- : decl(d), RawVAPtr(DeclMode) {
- assert (decl);
- NextDecl(false);
-}
-
-StmtIteratorBase::StmtIteratorBase(VariableArrayType* t)
-: decl(NULL), RawVAPtr(SizeOfTypeVAMode) {
- RawVAPtr |= reinterpret_cast<uintptr_t>(t);
-}
-
-Stmt*& StmtIteratorBase::GetDeclExpr() const {
- if (VariableArrayType* VAPtr = getVAPtr()) {
- assert (VAPtr->SizeExpr);
- return VAPtr->SizeExpr;
- }
-
- if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
- assert (VD->Init);
- return VD->Init;
- }
-
- EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
- return ECD->Init;
-}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
deleted file mode 100644
index 844a3e856015..000000000000
--- a/clang/lib/AST/StmtPrinter.cpp
+++ /dev/null
@@ -1,950 +0,0 @@
-//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
-// pretty print the AST back out to C code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/Format.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// StmtPrinter Visitor
-//===----------------------------------------------------------------------===//
-
-namespace {
- class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
- llvm::raw_ostream &OS;
- unsigned IndentLevel;
- clang::PrinterHelper* Helper;
- public:
- StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper) :
- OS(os), IndentLevel(0), Helper(helper) {}
-
- void PrintStmt(Stmt *S, int SubIndent = 1) {
- IndentLevel += SubIndent;
- if (S && isa<Expr>(S)) {
- // If this is an expr used in a stmt context, indent and newline it.
- Indent();
- Visit(S);
- OS << ";\n";
- } else if (S) {
- Visit(S);
- } else {
- Indent() << "<<<NULL STATEMENT>>>\n";
- }
- IndentLevel -= SubIndent;
- }
-
- void PrintRawCompoundStmt(CompoundStmt *S);
- void PrintRawDecl(Decl *D);
- void PrintRawDeclStmt(DeclStmt *S);
- void PrintRawIfStmt(IfStmt *If);
-
- void PrintExpr(Expr *E) {
- if (E)
- Visit(E);
- else
- OS << "<null expr>";
- }
-
- llvm::raw_ostream &Indent(int Delta = 0) const {
- for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
- OS << " ";
- return OS;
- }
-
- bool PrintOffsetOfDesignator(Expr *E);
- void VisitUnaryOffsetOf(UnaryOperator *Node);
-
- void Visit(Stmt* S) {
- if (Helper && Helper->handledStmt(S,OS))
- return;
- else StmtVisitor<StmtPrinter>::Visit(S);
- }
-
- void VisitStmt(Stmt *Node);
-#define STMT(N, CLASS, PARENT) \
- void Visit##CLASS(CLASS *Node);
-#include "clang/AST/StmtNodes.def"
- };
-}
-
-//===----------------------------------------------------------------------===//
-// Stmt printing methods.
-//===----------------------------------------------------------------------===//
-
-void StmtPrinter::VisitStmt(Stmt *Node) {
- Indent() << "<<unknown stmt type>>\n";
-}
-
-/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
-/// with no newline after the }.
-void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
- OS << "{\n";
- for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
- I != E; ++I)
- PrintStmt(*I);
-
- Indent() << "}";
-}
-
-void StmtPrinter::PrintRawDecl(Decl *D) {
- // FIXME: Need to complete/beautify this... this code simply shows the
- // nodes are where they need to be.
- if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
- OS << "typedef " << localType->getUnderlyingType().getAsString();
- OS << " " << localType->getName();
- } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
- // Emit storage class for vardecls.
- if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- switch (V->getStorageClass()) {
- default: assert(0 && "Unknown storage class!");
- case VarDecl::None: break;
- case VarDecl::Extern: OS << "extern "; break;
- case VarDecl::Static: OS << "static "; break;
- case VarDecl::Auto: OS << "auto "; break;
- case VarDecl::Register: OS << "register "; break;
- }
- }
-
- std::string Name = VD->getName();
- VD->getType().getAsStringInternal(Name);
- OS << Name;
-
- // If this is a vardecl with an initializer, emit it.
- if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- if (V->getInit()) {
- OS << " = ";
- PrintExpr(V->getInit());
- }
- }
- } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- // print a free standing tag decl (e.g. "struct x;").
- OS << TD->getKindName();
- OS << " ";
- if (const IdentifierInfo *II = TD->getIdentifier())
- OS << II->getName();
- else
- OS << "<anonymous>";
- // FIXME: print tag bodies.
- } else {
- assert(0 && "Unexpected decl");
- }
-}
-
-void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
- bool isFirst = false;
-
- for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
-
- if (!isFirst) OS << ", ";
- else isFirst = false;
-
- PrintRawDecl(*I);
- }
-}
-
-void StmtPrinter::VisitNullStmt(NullStmt *Node) {
- Indent() << ";\n";
-}
-
-void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
- for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end();
- I!=E; ++I) {
- Indent();
- PrintRawDecl(*I);
- OS << ";\n";
- }
-}
-
-void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
- Indent();
- PrintRawCompoundStmt(Node);
- OS << "\n";
-}
-
-void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
- Indent(-1) << "case ";
- PrintExpr(Node->getLHS());
- if (Node->getRHS()) {
- OS << " ... ";
- PrintExpr(Node->getRHS());
- }
- OS << ":\n";
-
- PrintStmt(Node->getSubStmt(), 0);
-}
-
-void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
- Indent(-1) << "default:\n";
- PrintStmt(Node->getSubStmt(), 0);
-}
-
-void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
- Indent(-1) << Node->getName() << ":\n";
- PrintStmt(Node->getSubStmt(), 0);
-}
-
-void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
- OS << "if ";
- PrintExpr(If->getCond());
-
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
- OS << ' ';
- PrintRawCompoundStmt(CS);
- OS << (If->getElse() ? ' ' : '\n');
- } else {
- OS << '\n';
- PrintStmt(If->getThen());
- if (If->getElse()) Indent();
- }
-
- if (Stmt *Else = If->getElse()) {
- OS << "else";
-
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
- OS << ' ';
- PrintRawCompoundStmt(CS);
- OS << '\n';
- } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
- OS << ' ';
- PrintRawIfStmt(ElseIf);
- } else {
- OS << '\n';
- PrintStmt(If->getElse());
- }
- }
-}
-
-void StmtPrinter::VisitIfStmt(IfStmt *If) {
- Indent();
- PrintRawIfStmt(If);
-}
-
-void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
- Indent() << "switch (";
- PrintExpr(Node->getCond());
- OS << ")";
-
- // Pretty print compoundstmt bodies (very common).
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
- OS << " ";
- PrintRawCompoundStmt(CS);
- OS << "\n";
- } else {
- OS << "\n";
- PrintStmt(Node->getBody());
- }
-}
-
-void StmtPrinter::VisitSwitchCase(SwitchCase*) {
- assert(0 && "SwitchCase is an abstract class");
-}
-
-void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
- Indent() << "while (";
- PrintExpr(Node->getCond());
- OS << ")\n";
- PrintStmt(Node->getBody());
-}
-
-void StmtPrinter::VisitDoStmt(DoStmt *Node) {
- Indent() << "do ";
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
- PrintRawCompoundStmt(CS);
- OS << " ";
- } else {
- OS << "\n";
- PrintStmt(Node->getBody());
- Indent();
- }
-
- OS << "while ";
- PrintExpr(Node->getCond());
- OS << ";\n";
-}
-
-void StmtPrinter::VisitForStmt(ForStmt *Node) {
- Indent() << "for (";
- if (Node->getInit()) {
- if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
- PrintRawDeclStmt(DS);
- else
- PrintExpr(cast<Expr>(Node->getInit()));
- }
- OS << ";";
- if (Node->getCond()) {
- OS << " ";
- PrintExpr(Node->getCond());
- }
- OS << ";";
- if (Node->getInc()) {
- OS << " ";
- PrintExpr(Node->getInc());
- }
- OS << ") ";
-
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
- PrintRawCompoundStmt(CS);
- OS << "\n";
- } else {
- OS << "\n";
- PrintStmt(Node->getBody());
- }
-}
-
-void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
- Indent() << "for (";
- if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
- PrintRawDeclStmt(DS);
- else
- PrintExpr(cast<Expr>(Node->getElement()));
- OS << " in ";
- PrintExpr(Node->getCollection());
- OS << ") ";
-
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
- PrintRawCompoundStmt(CS);
- OS << "\n";
- } else {
- OS << "\n";
- PrintStmt(Node->getBody());
- }
-}
-
-void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
- Indent() << "goto " << Node->getLabel()->getName() << ";\n";
-}
-
-void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
- Indent() << "goto *";
- PrintExpr(Node->getTarget());
- OS << ";\n";
-}
-
-void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
- Indent() << "continue;\n";
-}
-
-void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
- Indent() << "break;\n";
-}
-
-
-void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
- Indent() << "return";
- if (Node->getRetValue()) {
- OS << " ";
- PrintExpr(Node->getRetValue());
- }
- OS << ";\n";
-}
-
-
-void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
- Indent() << "asm ";
-
- if (Node->isVolatile())
- OS << "volatile ";
-
- OS << "(";
- VisitStringLiteral(Node->getAsmString());
-
- // Outputs
- if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
- Node->getNumClobbers() != 0)
- OS << " : ";
-
- for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
- if (i != 0)
- OS << ", ";
-
- if (!Node->getOutputName(i).empty()) {
- OS << '[';
- OS << Node->getOutputName(i);
- OS << "] ";
- }
-
- VisitStringLiteral(Node->getOutputConstraint(i));
- OS << " ";
- Visit(Node->getOutputExpr(i));
- }
-
- // Inputs
- if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
- OS << " : ";
-
- for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
- if (i != 0)
- OS << ", ";
-
- if (!Node->getInputName(i).empty()) {
- OS << '[';
- OS << Node->getInputName(i);
- OS << "] ";
- }
-
- VisitStringLiteral(Node->getInputConstraint(i));
- OS << " ";
- Visit(Node->getInputExpr(i));
- }
-
- // Clobbers
- if (Node->getNumClobbers() != 0)
- OS << " : ";
-
- for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
- if (i != 0)
- OS << ", ";
-
- VisitStringLiteral(Node->getClobber(i));
- }
-
- OS << ");\n";
-}
-
-void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
- Indent() << "@try";
- if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
- PrintRawCompoundStmt(TS);
- OS << "\n";
- }
-
- for (ObjCAtCatchStmt *catchStmt =
- static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
- catchStmt;
- catchStmt =
- static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
- Indent() << "@catch(";
- if (catchStmt->getCatchParamStmt()) {
- if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt()))
- PrintRawDeclStmt(DS);
- }
- OS << ")";
- if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody()))
- {
- PrintRawCompoundStmt(CS);
- OS << "\n";
- }
- }
-
- if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>(
- Node->getFinallyStmt())) {
- Indent() << "@finally";
- PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
- OS << "\n";
- }
-}
-
-void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
-}
-
-void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
- Indent() << "@catch (...) { /* todo */ } \n";
-}
-
-void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
- Indent() << "@throw";
- if (Node->getThrowExpr()) {
- OS << " ";
- PrintExpr(Node->getThrowExpr());
- }
- OS << ";\n";
-}
-
-void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
- Indent() << "@synchronized (";
- PrintExpr(Node->getSynchExpr());
- OS << ")";
- PrintRawCompoundStmt(Node->getSynchBody());
- OS << "\n";
-}
-
-//===----------------------------------------------------------------------===//
-// Expr printing methods.
-//===----------------------------------------------------------------------===//
-
-void StmtPrinter::VisitExpr(Expr *Node) {
- OS << "<<unknown expr type>>";
-}
-
-void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
- OS << Node->getDecl()->getName();
-}
-
-void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
- if (Node->getBase()) {
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
- }
- OS << Node->getDecl()->getName();
-}
-
-void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
- if (Node->getBase()) {
- PrintExpr(Node->getBase());
- OS << ".";
- }
- // FIXME: OS << Node->getDecl()->getName();
-}
-
-void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
- switch (Node->getIdentType()) {
- default:
- assert(0 && "unknown case");
- case PredefinedExpr::Func:
- OS << "__func__";
- break;
- case PredefinedExpr::Function:
- OS << "__FUNCTION__";
- break;
- case PredefinedExpr::PrettyFunction:
- OS << "__PRETTY_FUNCTION__";
- break;
- case PredefinedExpr::ObjCSuper:
- OS << "super";
- break;
- }
-}
-
-void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
- unsigned value = Node->getValue();
- if (Node->isWide())
- OS << "L";
- switch (value) {
- case '\\':
- OS << "'\\\\'";
- break;
- case '\'':
- OS << "'\\''";
- break;
- case '\a':
- // TODO: K&R: the meaning of '\\a' is different in traditional C
- OS << "'\\a'";
- break;
- case '\b':
- OS << "'\\b'";
- break;
- // Nonstandard escape sequence.
- /*case '\e':
- OS << "'\\e'";
- break;*/
- case '\f':
- OS << "'\\f'";
- break;
- case '\n':
- OS << "'\\n'";
- break;
- case '\r':
- OS << "'\\r'";
- break;
- case '\t':
- OS << "'\\t'";
- break;
- case '\v':
- OS << "'\\v'";
- break;
- default:
- if (value < 256 && isprint(value)) {
- OS << "'" << (char)value << "'";
- } else if (value < 256) {
- OS << "'\\x" << llvm::format("%x", value) << "'";
- } else {
- // FIXME what to really do here?
- OS << value;
- }
- }
-}
-
-void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
- bool isSigned = Node->getType()->isSignedIntegerType();
- OS << Node->getValue().toString(10, isSigned);
-
- // Emit suffixes. Integer literals are always a builtin integer type.
- switch (Node->getType()->getAsBuiltinType()->getKind()) {
- default: assert(0 && "Unexpected type for integer literal!");
- case BuiltinType::Int: break; // no suffix.
- case BuiltinType::UInt: OS << 'U'; break;
- case BuiltinType::Long: OS << 'L'; break;
- case BuiltinType::ULong: OS << "UL"; break;
- case BuiltinType::LongLong: OS << "LL"; break;
- case BuiltinType::ULongLong: OS << "ULL"; break;
- }
-}
-void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
- // FIXME: print value more precisely.
- OS << Node->getValueAsApproximateDouble();
-}
-
-void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
- PrintExpr(Node->getSubExpr());
- OS << "i";
-}
-
-void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
- if (Str->isWide()) OS << 'L';
- OS << '"';
-
- // FIXME: this doesn't print wstrings right.
- for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
- switch (Str->getStrData()[i]) {
- default: OS << Str->getStrData()[i]; break;
- // Handle some common ones to make dumps prettier.
- case '\\': OS << "\\\\"; break;
- case '"': OS << "\\\""; break;
- case '\n': OS << "\\n"; break;
- case '\t': OS << "\\t"; break;
- case '\a': OS << "\\a"; break;
- case '\b': OS << "\\b"; break;
- }
- }
- OS << '"';
-}
-void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
- OS << "(";
- PrintExpr(Node->getSubExpr());
- OS << ")";
-}
-void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
- if (!Node->isPostfix()) {
- OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
-
- // Print a space if this is an "identifier operator" like sizeof or __real.
- switch (Node->getOpcode()) {
- default: break;
- case UnaryOperator::SizeOf:
- case UnaryOperator::AlignOf:
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- case UnaryOperator::Extension:
- OS << ' ';
- break;
- }
- }
- PrintExpr(Node->getSubExpr());
-
- if (Node->isPostfix())
- OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
-}
-
-bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
- if (isa<CompoundLiteralExpr>(E)) {
- // Base case, print the type and comma.
- OS << E->getType().getAsString() << ", ";
- return true;
- } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
- PrintOffsetOfDesignator(ASE->getLHS());
- OS << "[";
- PrintExpr(ASE->getRHS());
- OS << "]";
- return false;
- } else {
- MemberExpr *ME = cast<MemberExpr>(E);
- bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
- OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName();
- return false;
- }
-}
-
-void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
- OS << "__builtin_offsetof(";
- PrintOffsetOfDesignator(Node->getSubExpr());
- OS << ")";
-}
-
-void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
- OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
- OS << Node->getArgumentType().getAsString() << ")";
-}
-void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
- PrintExpr(Node->getLHS());
- OS << "[";
- PrintExpr(Node->getRHS());
- OS << "]";
-}
-
-void StmtPrinter::VisitCallExpr(CallExpr *Call) {
- PrintExpr(Call->getCallee());
- OS << "(";
- for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
- if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
- // Don't print any defaulted arguments
- break;
- }
-
- if (i) OS << ", ";
- PrintExpr(Call->getArg(i));
- }
- OS << ")";
-}
-void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
-
- FieldDecl *Field = Node->getMemberDecl();
- assert(Field && "MemberExpr should alway reference a field!");
- OS << Field->getName();
-}
-void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
- PrintExpr(Node->getBase());
- OS << ".";
- OS << Node->getAccessor().getName();
-}
-void StmtPrinter::VisitCastExpr(CastExpr *) {
- assert(0 && "CastExpr is an abstract class");
-}
-void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *Node) {
- OS << "(" << Node->getType().getAsString() << ")";
- PrintExpr(Node->getSubExpr());
-}
-void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
- OS << "(" << Node->getType().getAsString() << ")";
- PrintExpr(Node->getInitializer());
-}
-void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
- // No need to print anything, simply forward to the sub expression.
- PrintExpr(Node->getSubExpr());
-}
-void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
- PrintExpr(Node->getLHS());
- OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
- PrintExpr(Node->getRHS());
-}
-void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
- PrintExpr(Node->getLHS());
- OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
- PrintExpr(Node->getRHS());
-}
-void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
- PrintExpr(Node->getCond());
-
- if (Node->getLHS()) {
- OS << " ? ";
- PrintExpr(Node->getLHS());
- OS << " : ";
- }
- else { // Handle GCC extention where LHS can be NULL.
- OS << " ?: ";
- }
-
- PrintExpr(Node->getRHS());
-}
-
-// GNU extensions.
-
-void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
- OS << "&&" << Node->getLabel()->getName();
-}
-
-void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
- OS << "(";
- PrintRawCompoundStmt(E->getSubStmt());
- OS << ")";
-}
-
-void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
- OS << "__builtin_types_compatible_p(";
- OS << Node->getArgType1().getAsString() << ",";
- OS << Node->getArgType2().getAsString() << ")";
-}
-
-void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
- OS << "__builtin_choose_expr(";
- PrintExpr(Node->getCond());
- OS << ", ";
- PrintExpr(Node->getLHS());
- OS << ", ";
- PrintExpr(Node->getRHS());
- OS << ")";
-}
-
-void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
- OS << "__builtin_overload(";
- for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
- if (i) OS << ", ";
- PrintExpr(Node->getExpr(i));
- }
- OS << ")";
-}
-
-void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
- OS << "__builtin_shufflevector(";
- for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
- if (i) OS << ", ";
- PrintExpr(Node->getExpr(i));
- }
- OS << ")";
-}
-
-void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
- OS << "{ ";
- for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
- if (i) OS << ", ";
- PrintExpr(Node->getInit(i));
- }
- OS << " }";
-}
-
-void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
- OS << "va_arg(";
- PrintExpr(Node->getSubExpr());
- OS << ", ";
- OS << Node->getType().getAsString();
- OS << ")";
-}
-
-// C++
-
-void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
- OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
- OS << Node->getDestType().getAsString() << ">(";
- PrintExpr(Node->getSubExpr());
- OS << ")";
-}
-
-void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
- OS << (Node->getValue() ? "true" : "false");
-}
-
-void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
- if (Node->getSubExpr() == 0)
- OS << "throw";
- else {
- OS << "throw ";
- PrintExpr(Node->getSubExpr());
- }
-}
-
-void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
- // Nothing to print: we picked up the default argument
-}
-
-void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
- OS << Node->getType().getAsString();
- OS << "(";
- PrintExpr(Node->getSubExpr());
- OS << ")";
-}
-
-void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
- OS << Node->getType().getAsString() << "()";
-}
-
-void
-StmtPrinter::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
- PrintRawDecl(E->getVarDecl());
-}
-
-// Obj-C
-
-void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
- OS << "@";
- VisitStringLiteral(Node->getString());
-}
-
-void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
- OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
-}
-
-void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
- OS << "@selector(" << Node->getSelector().getName() << ")";
-}
-
-void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
- OS << "@protocol(" << Node->getProtocol()->getName() << ")";
-}
-
-void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
- OS << "[";
- Expr *receiver = Mess->getReceiver();
- if (receiver) PrintExpr(receiver);
- else OS << Mess->getClassName()->getName();
- OS << ' ';
- Selector selector = Mess->getSelector();
- if (selector.isUnarySelector()) {
- OS << selector.getIdentifierInfoForSlot(0)->getName();
- } else {
- for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
- if (i < selector.getNumArgs()) {
- if (i > 0) OS << ' ';
- if (selector.getIdentifierInfoForSlot(i))
- OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
- else
- OS << ":";
- }
- else OS << ", "; // Handle variadic methods.
-
- PrintExpr(Mess->getArg(i));
- }
- }
- OS << "]";
-}
-
-void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
- OS << "^";
-
- const FunctionType *AFT = Node->getFunctionType();
-
- if (isa<FunctionTypeNoProto>(AFT)) {
- OS << "()";
- } else if (!Node->arg_empty() || cast<FunctionTypeProto>(AFT)->isVariadic()) {
- const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
- OS << '(';
- std::string ParamStr;
- for (BlockExpr::arg_iterator AI = Node->arg_begin(),
- E = Node->arg_end(); AI != E; ++AI) {
- if (AI != Node->arg_begin()) OS << ", ";
- ParamStr = (*AI)->getName();
- (*AI)->getType().getAsStringInternal(ParamStr);
- OS << ParamStr;
- }
-
- if (FT->isVariadic()) {
- if (!Node->arg_empty()) OS << ", ";
- OS << "...";
- }
- OS << ')';
- }
-}
-
-void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
- OS << Node->getDecl()->getName();
-}
-//===----------------------------------------------------------------------===//
-// Stmt method implementations
-//===----------------------------------------------------------------------===//
-
-void Stmt::dumpPretty() const {
- printPretty(llvm::errs());
-}
-
-void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper) const {
- if (this == 0) {
- OS << "<NULL>";
- return;
- }
-
- StmtPrinter P(OS, Helper);
- P.Visit(const_cast<Stmt*>(this));
-}
-
-//===----------------------------------------------------------------------===//
-// PrinterHelper
-//===----------------------------------------------------------------------===//
-
-// Implement virtual destructor.
-PrinterHelper::~PrinterHelper() {}
diff --git a/clang/lib/AST/StmtSerialization.cpp b/clang/lib/AST/StmtSerialization.cpp
deleted file mode 100644
index b226bdf8f9ad..000000000000
--- a/clang/lib/AST/StmtSerialization.cpp
+++ /dev/null
@@ -1,1184 +0,0 @@
-//===--- StmtSerialization.cpp - Serialization of Statements --------------===//
-//
-// 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 type-specific methods for serializing statements
-// and expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using namespace clang;
-using llvm::Serializer;
-using llvm::Deserializer;
-
-void Stmt::Emit(Serializer& S) const {
- S.FlushRecord();
- S.EmitInt(getStmtClass());
- EmitImpl(S);
- S.FlushRecord();
-}
-
-Stmt* Stmt::Create(Deserializer& D, ASTContext& C) {
- StmtClass SC = static_cast<StmtClass>(D.ReadInt());
-
- switch (SC) {
- default:
- assert (false && "Not implemented.");
- return NULL;
-
- case AddrLabelExprClass:
- return AddrLabelExpr::CreateImpl(D, C);
-
- case ArraySubscriptExprClass:
- return ArraySubscriptExpr::CreateImpl(D, C);
-
- case AsmStmtClass:
- return AsmStmt::CreateImpl(D, C);
-
- case BinaryOperatorClass:
- return BinaryOperator::CreateImpl(D, C);
-
- case BreakStmtClass:
- return BreakStmt::CreateImpl(D, C);
-
- case CallExprClass:
- return CallExpr::CreateImpl(D, C);
-
- case CaseStmtClass:
- return CaseStmt::CreateImpl(D, C);
-
- case CharacterLiteralClass:
- return CharacterLiteral::CreateImpl(D, C);
-
- case CompoundAssignOperatorClass:
- return CompoundAssignOperator::CreateImpl(D, C);
-
- case CompoundLiteralExprClass:
- return CompoundLiteralExpr::CreateImpl(D, C);
-
- case CompoundStmtClass:
- return CompoundStmt::CreateImpl(D, C);
-
- case ConditionalOperatorClass:
- return ConditionalOperator::CreateImpl(D, C);
-
- case ContinueStmtClass:
- return ContinueStmt::CreateImpl(D, C);
-
- case DeclRefExprClass:
- return DeclRefExpr::CreateImpl(D, C);
-
- case DeclStmtClass:
- return DeclStmt::CreateImpl(D, C);
-
- case DefaultStmtClass:
- return DefaultStmt::CreateImpl(D, C);
-
- case DoStmtClass:
- return DoStmt::CreateImpl(D, C);
-
- case FloatingLiteralClass:
- return FloatingLiteral::CreateImpl(D, C);
-
- case ForStmtClass:
- return ForStmt::CreateImpl(D, C);
-
- case GotoStmtClass:
- return GotoStmt::CreateImpl(D, C);
-
- case IfStmtClass:
- return IfStmt::CreateImpl(D, C);
-
- case ImaginaryLiteralClass:
- return ImaginaryLiteral::CreateImpl(D, C);
-
- case ImplicitCastExprClass:
- return ImplicitCastExpr::CreateImpl(D, C);
-
- case ExplicitCastExprClass:
- return ExplicitCastExpr::CreateImpl(D, C);
-
- case IndirectGotoStmtClass:
- return IndirectGotoStmt::CreateImpl(D, C);
-
- case InitListExprClass:
- return InitListExpr::CreateImpl(D, C);
-
- case IntegerLiteralClass:
- return IntegerLiteral::CreateImpl(D, C);
-
- case LabelStmtClass:
- return LabelStmt::CreateImpl(D, C);
-
- case MemberExprClass:
- return MemberExpr::CreateImpl(D, C);
-
- case NullStmtClass:
- return NullStmt::CreateImpl(D, C);
-
- case ParenExprClass:
- return ParenExpr::CreateImpl(D, C);
-
- case PredefinedExprClass:
- return PredefinedExpr::CreateImpl(D, C);
-
- case ReturnStmtClass:
- return ReturnStmt::CreateImpl(D, C);
-
- case SizeOfAlignOfTypeExprClass:
- return SizeOfAlignOfTypeExpr::CreateImpl(D, C);
-
- case StmtExprClass:
- return StmtExpr::CreateImpl(D, C);
-
- case StringLiteralClass:
- return StringLiteral::CreateImpl(D, C);
-
- case SwitchStmtClass:
- return SwitchStmt::CreateImpl(D, C);
-
- case UnaryOperatorClass:
- return UnaryOperator::CreateImpl(D, C);
-
- case WhileStmtClass:
- return WhileStmt::CreateImpl(D, C);
-
- //==--------------------------------------==//
- // Objective C
- //==--------------------------------------==//
-
- case ObjCAtCatchStmtClass:
- return ObjCAtCatchStmt::CreateImpl(D, C);
-
- case ObjCAtFinallyStmtClass:
- return ObjCAtFinallyStmt::CreateImpl(D, C);
-
- case ObjCAtSynchronizedStmtClass:
- return ObjCAtSynchronizedStmt::CreateImpl(D, C);
-
- case ObjCAtThrowStmtClass:
- return ObjCAtThrowStmt::CreateImpl(D, C);
-
- case ObjCAtTryStmtClass:
- return ObjCAtTryStmt::CreateImpl(D, C);
-
- case ObjCEncodeExprClass:
- return ObjCEncodeExpr::CreateImpl(D, C);
-
- case ObjCForCollectionStmtClass:
- return ObjCForCollectionStmt::CreateImpl(D, C);
-
- case ObjCIvarRefExprClass:
- return ObjCIvarRefExpr::CreateImpl(D, C);
-
- case ObjCMessageExprClass:
- return ObjCMessageExpr::CreateImpl(D, C);
-
- case ObjCSelectorExprClass:
- return ObjCSelectorExpr::CreateImpl(D, C);
-
- case ObjCStringLiteralClass:
- return ObjCStringLiteral::CreateImpl(D, C);
-
- //==--------------------------------------==//
- // C++
- //==--------------------------------------==//
-
- case CXXDefaultArgExprClass:
- return CXXDefaultArgExpr::CreateImpl(D, C);
-
- case CXXFunctionalCastExprClass:
- return CXXFunctionalCastExpr::CreateImpl(D, C);
-
- case CXXZeroInitValueExprClass:
- return CXXZeroInitValueExpr::CreateImpl(D, C);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// C Serialization
-//===----------------------------------------------------------------------===//
-
-void AddrLabelExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(AmpAmpLoc);
- S.Emit(LabelLoc);
- S.EmitPtr(Label);
-}
-
-AddrLabelExpr* AddrLabelExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation AALoc = SourceLocation::ReadVal(D);
- SourceLocation LLoc = SourceLocation::ReadVal(D);
- AddrLabelExpr* expr = new AddrLabelExpr(AALoc,LLoc,NULL,t);
- D.ReadPtr(expr->Label); // Pointer may be backpatched.
- return expr;
-}
-
-void ArraySubscriptExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(RBracketLoc);
- S.BatchEmitOwnedPtrs(getLHS(),getRHS());
-}
-
-ArraySubscriptExpr* ArraySubscriptExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- Expr *LHS, *RHS;
- D.BatchReadOwnedPtrs(LHS, RHS, C);
- return new ArraySubscriptExpr(LHS,RHS,t,L);
-}
-
-void AsmStmt::EmitImpl(Serializer& S) const {
- S.Emit(AsmLoc);
-
- getAsmString()->EmitImpl(S);
- S.Emit(RParenLoc);
-
- S.EmitBool(IsVolatile);
- S.EmitBool(IsSimple);
- S.EmitInt(NumOutputs);
- S.EmitInt(NumInputs);
-
- unsigned size = NumOutputs + NumInputs;
-
- for (unsigned i = 0; i < size; ++i)
- S.EmitCStr(Names[i].c_str());
-
- for (unsigned i = 0; i < size; ++i)
- Constraints[i]->EmitImpl(S);
-
- for (unsigned i = 0; i < size; ++i)
- S.EmitOwnedPtr(Exprs[i]);
-
- S.EmitInt(Clobbers.size());
- for (unsigned i = 0, e = Clobbers.size(); i != e; ++i)
- Clobbers[i]->EmitImpl(S);
-}
-
-AsmStmt* AsmStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation ALoc = SourceLocation::ReadVal(D);
- StringLiteral *AsmStr = StringLiteral::CreateImpl(D, C);
- SourceLocation PLoc = SourceLocation::ReadVal(D);
-
- bool IsVolatile = D.ReadBool();
- bool IsSimple = D.ReadBool();
- AsmStmt *Stmt = new AsmStmt(ALoc, IsSimple, IsVolatile, 0, 0, 0, 0, 0,
- AsmStr,
- 0, 0, PLoc);
-
- Stmt->NumOutputs = D.ReadInt();
- Stmt->NumInputs = D.ReadInt();
-
- unsigned size = Stmt->NumOutputs + Stmt->NumInputs;
-
- Stmt->Names.reserve(size);
- for (unsigned i = 0; i < size; ++i) {
- std::vector<char> data;
- D.ReadCStr(data, false);
-
- Stmt->Names.push_back(std::string(data.begin(), data.end()));
- }
-
- Stmt->Constraints.reserve(size);
- for (unsigned i = 0; i < size; ++i)
- Stmt->Constraints.push_back(StringLiteral::CreateImpl(D, C));
-
- Stmt->Exprs.reserve(size);
- for (unsigned i = 0; i < size; ++i)
- Stmt->Exprs.push_back(D.ReadOwnedPtr<Expr>(C));
-
- unsigned NumClobbers = D.ReadInt();
- Stmt->Clobbers.reserve(NumClobbers);
- for (unsigned i = 0; i < NumClobbers; ++i)
- Stmt->Clobbers.push_back(StringLiteral::CreateImpl(D, C));
-
- return Stmt;
-}
-
-void BinaryOperator::EmitImpl(Serializer& S) const {
- S.EmitInt(Opc);
- S.Emit(OpLoc);;
- S.Emit(getType());
- S.BatchEmitOwnedPtrs(getLHS(),getRHS());
-}
-
-BinaryOperator* BinaryOperator::CreateImpl(Deserializer& D, ASTContext& C) {
- Opcode Opc = static_cast<Opcode>(D.ReadInt());
- SourceLocation OpLoc = SourceLocation::ReadVal(D);
- QualType Result = QualType::ReadVal(D);
- Expr *LHS, *RHS;
- D.BatchReadOwnedPtrs(LHS, RHS, C);
-
- return new BinaryOperator(LHS,RHS,Opc,Result,OpLoc);
-}
-
-void BreakStmt::EmitImpl(Serializer& S) const {
- S.Emit(BreakLoc);
-}
-
-BreakStmt* BreakStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- return new BreakStmt(Loc);
-}
-
-void CallExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(RParenLoc);
- S.EmitInt(NumArgs);
- S.BatchEmitOwnedPtrs(NumArgs+1, SubExprs);
-}
-
-CallExpr* CallExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- unsigned NumArgs = D.ReadInt();
- Stmt** SubExprs = new Stmt*[NumArgs+1];
- D.BatchReadOwnedPtrs(NumArgs+1, SubExprs, C);
-
- return new CallExpr(SubExprs,NumArgs,t,L);
-}
-
-void CaseStmt::EmitImpl(Serializer& S) const {
- S.Emit(CaseLoc);
- S.EmitPtr(getNextSwitchCase());
- S.BatchEmitOwnedPtrs((unsigned) END_EXPR,&SubExprs[0]);
-}
-
-CaseStmt* CaseStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation CaseLoc = SourceLocation::ReadVal(D);
- CaseStmt* stmt = new CaseStmt(NULL,NULL,NULL,CaseLoc);
- D.ReadPtr(stmt->NextSwitchCase);
- D.BatchReadOwnedPtrs((unsigned) END_EXPR, &stmt->SubExprs[0], C);
- return stmt;
-}
-
-void ExplicitCastExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(Loc);
- S.EmitOwnedPtr(getSubExpr());
-}
-
-ExplicitCastExpr* ExplicitCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation Loc = SourceLocation::ReadVal(D);
- Expr* Op = D.ReadOwnedPtr<Expr>(C);
- return new ExplicitCastExpr(t,Op,Loc);
-}
-
-
-void CharacterLiteral::EmitImpl(Serializer& S) const {
- S.Emit(Value);
- S.Emit(Loc);
- S.EmitBool(IsWide);
- S.Emit(getType());
-}
-
-CharacterLiteral* CharacterLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- unsigned value = D.ReadInt();
- SourceLocation Loc = SourceLocation::ReadVal(D);
- bool iswide = D.ReadBool();
- QualType T = QualType::ReadVal(D);
- return new CharacterLiteral(value,iswide,T,Loc);
-}
-
-void CompoundAssignOperator::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(ComputationType);
- S.Emit(getOperatorLoc());
- S.EmitInt(getOpcode());
- S.BatchEmitOwnedPtrs(getLHS(),getRHS());
-}
-
-CompoundAssignOperator*
-CompoundAssignOperator::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- QualType c = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- Opcode Opc = static_cast<Opcode>(D.ReadInt());
- Expr* LHS, *RHS;
- D.BatchReadOwnedPtrs(LHS, RHS, C);
-
- return new CompoundAssignOperator(LHS,RHS,Opc,t,c,L);
-}
-
-void CompoundLiteralExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(getLParenLoc());
- S.EmitBool(isFileScope());
- S.EmitOwnedPtr(Init);
-}
-
-CompoundLiteralExpr* CompoundLiteralExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType Q = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- bool fileScope = D.ReadBool();
- Expr* Init = D.ReadOwnedPtr<Expr>(C);
- return new CompoundLiteralExpr(L, Q, Init, fileScope);
-}
-
-void CompoundStmt::EmitImpl(Serializer& S) const {
- S.Emit(LBracLoc);
- S.Emit(RBracLoc);
- S.Emit(Body.size());
-
- for (const_body_iterator I=body_begin(), E=body_end(); I!=E; ++I)
- S.EmitOwnedPtr(*I);
-}
-
-CompoundStmt* CompoundStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation LB = SourceLocation::ReadVal(D);
- SourceLocation RB = SourceLocation::ReadVal(D);
- unsigned size = D.ReadInt();
-
- CompoundStmt* stmt = new CompoundStmt(NULL,0,LB,RB);
-
- stmt->Body.reserve(size);
-
- for (unsigned i = 0; i < size; ++i)
- stmt->Body.push_back(D.ReadOwnedPtr<Stmt>(C));
-
- return stmt;
-}
-
-void ConditionalOperator::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.BatchEmitOwnedPtrs((unsigned) END_EXPR, SubExprs);
-}
-
-ConditionalOperator* ConditionalOperator::CreateImpl(Deserializer& D,
- ASTContext& C) {
-
- QualType t = QualType::ReadVal(D);
- ConditionalOperator* c = new ConditionalOperator(NULL,NULL,NULL,t);
- D.BatchReadOwnedPtrs((unsigned) END_EXPR, c->SubExprs, C);
- return c;
-}
-
-void ContinueStmt::EmitImpl(Serializer& S) const {
- S.Emit(ContinueLoc);
-}
-
-ContinueStmt* ContinueStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- return new ContinueStmt(Loc);
-}
-
-void DeclStmt::EmitImpl(Serializer& S) const {
- S.Emit(StartLoc);
- S.Emit(EndLoc);
- S.EmitOwnedPtr(TheDecl);
-}
-
-DeclStmt* DeclStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation StartLoc = SourceLocation::ReadVal(D);
- SourceLocation EndLoc = SourceLocation::ReadVal(D);
- ScopedDecl* decl = cast<ScopedDecl>(D.ReadOwnedPtr<Decl>(C));
- return new DeclStmt(decl, StartLoc, EndLoc);
-}
-
-void DeclRefExpr::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.Emit(getType());
-
- // Some DeclRefExprs can actually hold the owning reference to a FunctionDecl.
- // This occurs when an implicitly defined function is called, and
- // the decl does not appear in the source file. We thus check if the
- // decl pointer has been registered, and if not, emit an owned pointer.
-
- // FIXME: While this will work for serialization, it won't work for
- // memory management. The only reason this works for serialization is
- // because we are tracking all serialized pointers. Either DeclRefExpr
- // needs an explicit bit indicating that it owns the the object,
- // or we need a different ownership model.
-
- const Decl* d = getDecl();
-
- if (!S.isRegistered(d)) {
- assert (isa<FunctionDecl>(d)
- && "DeclRefExpr can only own FunctionDecls for implicitly def. funcs.");
-
- S.EmitBool(true);
- S.EmitOwnedPtr(d);
- }
- else {
- S.EmitBool(false);
- S.EmitPtr(d);
- }
-}
-
-DeclRefExpr* DeclRefExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- bool OwnsDecl = D.ReadBool();
- ValueDecl* decl;
-
- if (!OwnsDecl)
- D.ReadPtr(decl,false); // No backpatching.
- else
- decl = cast<ValueDecl>(D.ReadOwnedPtr<Decl>(C));
-
- return new DeclRefExpr(decl,T,Loc);
-}
-
-void DefaultStmt::EmitImpl(Serializer& S) const {
- S.Emit(DefaultLoc);
- S.EmitOwnedPtr(getSubStmt());
- S.EmitPtr(getNextSwitchCase());
-}
-
-DefaultStmt* DefaultStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- Stmt* SubStmt = D.ReadOwnedPtr<Stmt>(C);
-
- DefaultStmt* stmt = new DefaultStmt(Loc,SubStmt);
- stmt->setNextSwitchCase(D.ReadPtr<SwitchCase>());
-
- return stmt;
-}
-
-void DoStmt::EmitImpl(Serializer& S) const {
- S.Emit(DoLoc);
- S.EmitOwnedPtr(getCond());
- S.EmitOwnedPtr(getBody());
-}
-
-DoStmt* DoStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation DoLoc = SourceLocation::ReadVal(D);
- Expr* Cond = D.ReadOwnedPtr<Expr>(C);
- Stmt* Body = D.ReadOwnedPtr<Stmt>(C);
- return new DoStmt(Body,Cond,DoLoc);
-}
-
-void FloatingLiteral::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.Emit(getType());
- S.EmitBool(isExact());
- S.Emit(Value);
-}
-
-FloatingLiteral* FloatingLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- QualType t = QualType::ReadVal(D);
- bool isExact = D.ReadBool();
- llvm::APFloat Val = llvm::APFloat::ReadVal(D);
- FloatingLiteral* expr = new FloatingLiteral(Val,&isExact,t,Loc);
- return expr;
-}
-
-void ForStmt::EmitImpl(Serializer& S) const {
- S.Emit(ForLoc);
- S.EmitOwnedPtr(getInit());
- S.EmitOwnedPtr(getCond());
- S.EmitOwnedPtr(getInc());
- S.EmitOwnedPtr(getBody());
-}
-
-ForStmt* ForStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation ForLoc = SourceLocation::ReadVal(D);
- Stmt* Init = D.ReadOwnedPtr<Stmt>(C);
- Expr* Cond = D.ReadOwnedPtr<Expr>(C);
- Expr* Inc = D.ReadOwnedPtr<Expr>(C);
- Stmt* Body = D.ReadOwnedPtr<Stmt>(C);
- return new ForStmt(Init,Cond,Inc,Body,ForLoc);
-}
-
-void GotoStmt::EmitImpl(Serializer& S) const {
- S.Emit(GotoLoc);
- S.Emit(LabelLoc);
- S.EmitPtr(Label);
-}
-
-GotoStmt* GotoStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation GotoLoc = SourceLocation::ReadVal(D);
- SourceLocation LabelLoc = SourceLocation::ReadVal(D);
- GotoStmt* stmt = new GotoStmt(NULL,GotoLoc,LabelLoc);
- D.ReadPtr(stmt->Label); // This pointer may be backpatched later.
- return stmt;
-}
-
-void IfStmt::EmitImpl(Serializer& S) const {
- S.Emit(IfLoc);
- S.EmitOwnedPtr(getCond());
- S.EmitOwnedPtr(getThen());
- S.EmitOwnedPtr(getElse());
-}
-
-IfStmt* IfStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation L = SourceLocation::ReadVal(D);
- Expr* Cond = D.ReadOwnedPtr<Expr>(C);
- Stmt* Then = D.ReadOwnedPtr<Stmt>(C);
- Stmt* Else = D.ReadOwnedPtr<Stmt>(C);
- return new IfStmt(L,Cond,Then,Else);
-}
-
-void ImaginaryLiteral::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.EmitOwnedPtr(Val);
-}
-
-ImaginaryLiteral* ImaginaryLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- Expr* expr = D.ReadOwnedPtr<Expr>(C);
- assert (isa<FloatingLiteral>(expr) || isa<IntegerLiteral>(expr));
- return new ImaginaryLiteral(expr,t);
-}
-
-void ImplicitCastExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.EmitOwnedPtr(getSubExpr());
-}
-
-ImplicitCastExpr* ImplicitCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- Expr* Op = D.ReadOwnedPtr<Expr>(C);
- return new ImplicitCastExpr(t,Op);
-}
-
-void IndirectGotoStmt::EmitImpl(Serializer& S) const {
- S.EmitOwnedPtr(Target);
-}
-
-IndirectGotoStmt* IndirectGotoStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- Expr* Target = D.ReadOwnedPtr<Expr>(C);
- return new IndirectGotoStmt(Target);
-}
-
-void InitListExpr::EmitImpl(Serializer& S) const {
- S.Emit(LBraceLoc);
- S.Emit(RBraceLoc);
- S.EmitInt(InitExprs.size());
- if (!InitExprs.empty()) S.BatchEmitOwnedPtrs(InitExprs.size(), &InitExprs[0]);
-}
-
-InitListExpr* InitListExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- InitListExpr* expr = new InitListExpr();
- expr->LBraceLoc = SourceLocation::ReadVal(D);
- expr->RBraceLoc = SourceLocation::ReadVal(D);
- unsigned size = D.ReadInt();
- assert(size);
- expr->InitExprs.reserve(size);
- for (unsigned i = 0 ; i < size; ++i) expr->InitExprs.push_back(0);
-
- D.BatchReadOwnedPtrs(size, &expr->InitExprs[0], C);
- return expr;
-}
-
-void IntegerLiteral::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.Emit(getType());
- S.Emit(getValue());
-}
-
-IntegerLiteral* IntegerLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
-
- // Create a dummy APInt because it is more efficient to deserialize
- // it in place with the deserialized IntegerLiteral. (fewer copies)
- llvm::APInt temp;
- IntegerLiteral* expr = new IntegerLiteral(temp,T,Loc);
- D.Read(expr->Value);
-
- return expr;
-}
-
-void LabelStmt::EmitImpl(Serializer& S) const {
- S.EmitPtr(Label);
- S.Emit(IdentLoc);
- S.EmitOwnedPtr(SubStmt);
-}
-
-LabelStmt* LabelStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- IdentifierInfo* Label = D.ReadPtr<IdentifierInfo>();
- SourceLocation IdentLoc = SourceLocation::ReadVal(D);
- Stmt* SubStmt = D.ReadOwnedPtr<Stmt>(C);
- return new LabelStmt(IdentLoc,Label,SubStmt);
-}
-
-void MemberExpr::EmitImpl(Serializer& S) const {
- S.Emit(MemberLoc);
- S.EmitPtr(MemberDecl);
- S.EmitBool(IsArrow);
- S.Emit(getType());
- S.EmitOwnedPtr(Base);
-}
-
-MemberExpr* MemberExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation L = SourceLocation::ReadVal(D);
- FieldDecl* MemberDecl = cast<FieldDecl>(D.ReadPtr<Decl>());
- bool IsArrow = D.ReadBool();
- QualType T = QualType::ReadVal(D);
- Expr* base = D.ReadOwnedPtr<Expr>(C);
-
- return new MemberExpr(base,IsArrow,MemberDecl,L,T);
-}
-
-void NullStmt::EmitImpl(Serializer& S) const {
- S.Emit(SemiLoc);
-}
-
-NullStmt* NullStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation SemiLoc = SourceLocation::ReadVal(D);
- return new NullStmt(SemiLoc);
-}
-
-void ParenExpr::EmitImpl(Serializer& S) const {
- S.Emit(L);
- S.Emit(R);
- S.EmitOwnedPtr(Val);
-}
-
-ParenExpr* ParenExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation L = SourceLocation::ReadVal(D);
- SourceLocation R = SourceLocation::ReadVal(D);
- Expr* val = D.ReadOwnedPtr<Expr>(C);
- return new ParenExpr(L,R,val);
-}
-
-void PredefinedExpr::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.EmitInt(getIdentType());
- S.Emit(getType());
-}
-
-PredefinedExpr* PredefinedExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- IdentType it = static_cast<IdentType>(D.ReadInt());
- QualType Q = QualType::ReadVal(D);
- return new PredefinedExpr(Loc,Q,it);
-}
-
-void ReturnStmt::EmitImpl(Serializer& S) const {
- S.Emit(RetLoc);
- S.EmitOwnedPtr(RetExpr);
-}
-
-ReturnStmt* ReturnStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation RetLoc = SourceLocation::ReadVal(D);
- Expr* RetExpr = D.ReadOwnedPtr<Expr>(C);
- return new ReturnStmt(RetLoc,RetExpr);
-}
-
-void SizeOfAlignOfTypeExpr::EmitImpl(Serializer& S) const {
- S.EmitBool(isSizeof);
- S.Emit(Ty);
- S.Emit(getType());
- S.Emit(OpLoc);
- S.Emit(RParenLoc);
-}
-
-SizeOfAlignOfTypeExpr* SizeOfAlignOfTypeExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- bool isSizeof = D.ReadBool();
- QualType Ty = QualType::ReadVal(D);
- QualType Res = QualType::ReadVal(D);
- SourceLocation OpLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
-
- return new SizeOfAlignOfTypeExpr(isSizeof,Ty,Res,OpLoc,RParenLoc);
-}
-
-void StmtExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(LParenLoc);
- S.Emit(RParenLoc);
- S.EmitOwnedPtr(SubStmt);
-}
-
-StmtExpr* StmtExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- SourceLocation R = SourceLocation::ReadVal(D);
- CompoundStmt* SubStmt = cast<CompoundStmt>(D.ReadOwnedPtr<Stmt>(C));
- return new StmtExpr(SubStmt,t,L,R);
-}
-
-void StringLiteral::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(firstTokLoc);
- S.Emit(lastTokLoc);
- S.EmitBool(isWide());
- S.Emit(getByteLength());
-
- for (unsigned i = 0 ; i < ByteLength; ++i)
- S.EmitInt(StrData[i]);
-}
-
-StringLiteral* StringLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation firstTokLoc = SourceLocation::ReadVal(D);
- SourceLocation lastTokLoc = SourceLocation::ReadVal(D);
- bool isWide = D.ReadBool();
- unsigned ByteLength = D.ReadInt();
-
- StringLiteral* sl = new StringLiteral(NULL,0,isWide,t,firstTokLoc,lastTokLoc);
-
- char* StrData = new char[ByteLength];
- for (unsigned i = 0; i < ByteLength; ++i)
- StrData[i] = (char) D.ReadInt();
-
- sl->ByteLength = ByteLength;
- sl->StrData = StrData;
-
- return sl;
-}
-
-void SwitchStmt::EmitImpl(Serializer& S) const {
- S.Emit(SwitchLoc);
- S.EmitOwnedPtr(getCond());
- S.EmitOwnedPtr(getBody());
- S.EmitPtr(FirstCase);
-}
-
-SwitchStmt* SwitchStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- Stmt* Cond = D.ReadOwnedPtr<Stmt>(C);
- Stmt* Body = D.ReadOwnedPtr<Stmt>(C);
- SwitchCase* FirstCase = cast<SwitchCase>(D.ReadPtr<Stmt>());
-
- SwitchStmt* stmt = new SwitchStmt(cast<Expr>(Cond));
- stmt->setBody(Body,Loc);
- stmt->FirstCase = FirstCase;
-
- return stmt;
-}
-
-void UnaryOperator::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(Loc);
- S.EmitInt(Opc);
- S.EmitOwnedPtr(Val);
-}
-
-UnaryOperator* UnaryOperator::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- Opcode Opc = static_cast<Opcode>(D.ReadInt());
- Expr* Val = D.ReadOwnedPtr<Expr>(C);
- return new UnaryOperator(Val,Opc,t,L);
-}
-
-void WhileStmt::EmitImpl(Serializer& S) const {
- S.Emit(WhileLoc);
- S.EmitOwnedPtr(getCond());
- S.EmitOwnedPtr(getBody());
-}
-
-WhileStmt* WhileStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation WhileLoc = SourceLocation::ReadVal(D);
- Expr* Cond = D.ReadOwnedPtr<Expr>(C);
- Stmt* Body = D.ReadOwnedPtr<Stmt>(C);
- return new WhileStmt(Cond,Body,WhileLoc);
-}
-
-//===----------------------------------------------------------------------===//
-// Objective C Serialization
-//===----------------------------------------------------------------------===//
-
-void ObjCAtCatchStmt::EmitImpl(Serializer& S) const {
- S.Emit(AtCatchLoc);
- S.Emit(RParenLoc);
- S.BatchEmitOwnedPtrs((unsigned) END_EXPR, &SubExprs[0]);
-}
-
-ObjCAtCatchStmt* ObjCAtCatchStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation AtCatchLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
-
- ObjCAtCatchStmt* stmt = new ObjCAtCatchStmt(AtCatchLoc,RParenLoc);
- D.BatchReadOwnedPtrs((unsigned) END_EXPR, &stmt->SubExprs[0], C);
-
- return stmt;
-}
-
-void ObjCAtFinallyStmt::EmitImpl(Serializer& S) const {
- S.Emit(AtFinallyLoc);
- S.EmitOwnedPtr(AtFinallyStmt);
-}
-
-ObjCAtFinallyStmt* ObjCAtFinallyStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- Stmt* AtFinallyStmt = D.ReadOwnedPtr<Stmt>(C);
- return new ObjCAtFinallyStmt(Loc,AtFinallyStmt);
-}
-
-void ObjCAtSynchronizedStmt::EmitImpl(Serializer& S) const {
- S.Emit(AtSynchronizedLoc);
- S.BatchEmitOwnedPtrs((unsigned) END_EXPR,&SubStmts[0]);
- }
-
-ObjCAtSynchronizedStmt* ObjCAtSynchronizedStmt::CreateImpl(Deserializer& D,
- ASTContext& C) {
-
- SourceLocation L = SourceLocation::ReadVal(D);
- ObjCAtSynchronizedStmt* stmt = new ObjCAtSynchronizedStmt(L,0,0);
- D.BatchReadOwnedPtrs((unsigned) END_EXPR, &stmt->SubStmts[0], C);
- return stmt;
-}
-
-void ObjCAtThrowStmt::EmitImpl(Serializer& S) const {
- S.Emit(AtThrowLoc);
- S.EmitOwnedPtr(Throw);
-}
-
-ObjCAtThrowStmt* ObjCAtThrowStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation L = SourceLocation::ReadVal(D);
- Stmt* Throw = D.ReadOwnedPtr<Stmt>(C);
- return new ObjCAtThrowStmt(L,Throw);
-}
-
-void ObjCAtTryStmt::EmitImpl(Serializer& S) const {
- S.Emit(AtTryLoc);
- S.BatchEmitOwnedPtrs((unsigned) END_EXPR, &SubStmts[0]);
-}
-
-ObjCAtTryStmt* ObjCAtTryStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation L = SourceLocation::ReadVal(D);
- ObjCAtTryStmt* stmt = new ObjCAtTryStmt(L,NULL,NULL,NULL);
- D.BatchReadOwnedPtrs((unsigned) END_EXPR, &stmt->SubStmts[0], C);
- return stmt;
-}
-
-void ObjCEncodeExpr::EmitImpl(Serializer& S) const {
- S.Emit(AtLoc);
- S.Emit(RParenLoc);
- S.Emit(getType());
- S.Emit(EncType);
-}
-
-ObjCEncodeExpr* ObjCEncodeExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation AtLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- QualType ET = QualType::ReadVal(D);
- return new ObjCEncodeExpr(T,ET,AtLoc,RParenLoc);
-}
-
-void ObjCForCollectionStmt::EmitImpl(Serializer& S) const {
- S.Emit(ForLoc);
- S.Emit(RParenLoc);
- S.BatchEmitOwnedPtrs(getElement(),getCollection(),getBody());
-}
-
-ObjCForCollectionStmt* ObjCForCollectionStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation ForLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
- Stmt* Element;
- Expr* Collection;
- Stmt* Body;
- D.BatchReadOwnedPtrs(Element, Collection, Body, C);
- return new ObjCForCollectionStmt(Element,Collection,Body,ForLoc, RParenLoc);
-}
-
-void ObjCIvarRefExpr::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.Emit(getType());
- S.EmitPtr(getDecl());
-}
-
-ObjCIvarRefExpr* ObjCIvarRefExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- ObjCIvarRefExpr* dr = new ObjCIvarRefExpr(NULL,T,Loc);
- D.ReadPtr(dr->D,false);
- return dr;
-}
-
-void ObjCPropertyRefExpr::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.Emit(getType());
- unsigned Kind = getKind();
- S.Emit(Kind);
- if (Kind == PropertyRef) {
- S.EmitPtr(getProperty());
- } else {
- S.EmitPtr(getGetterMethod());
- S.EmitPtr(getSetterMethod());
- }
-}
-
-ObjCPropertyRefExpr* ObjCPropertyRefExpr::CreateImpl(Deserializer& D,
- ASTContext& C) {
- SourceLocation Loc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- ObjCPropertyRefExpr* dr = new ObjCPropertyRefExpr(NULL,T,Loc,0);
- unsigned Kind = D.ReadInt();
- if (Kind == PropertyRef) {
- D.ReadPtr(dr->Referent.AsProperty,false);
- } else {
- D.ReadPtr(dr->Referent.AsMethod.Setter,false);
- D.ReadPtr(dr->Referent.AsMethod.Getter,false);
- }
- return dr;
-}
-
-void ObjCMessageExpr::EmitImpl(Serializer& S) const {
- S.EmitInt(getFlag());
- S.Emit(getType());
- S.Emit(SelName);
- S.Emit(LBracloc);
- S.Emit(RBracloc);
- S.EmitInt(NumArgs);
- S.EmitPtr(MethodProto);
-
- if (getReceiver())
- S.BatchEmitOwnedPtrs(NumArgs+1, SubExprs);
- else {
- ClassInfo Info = getClassInfo();
-
- if (Info.first) S.EmitPtr(Info.first);
- else S.EmitPtr(Info.second);
-
- S.BatchEmitOwnedPtrs(NumArgs, &SubExprs[ARGS_START]);
- }
-}
-
-ObjCMessageExpr* ObjCMessageExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- unsigned flags = D.ReadInt();
- QualType t = QualType::ReadVal(D);
- Selector S = Selector::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- SourceLocation R = SourceLocation::ReadVal(D);
-
- // Construct an array for the subexpressions.
- unsigned NumArgs = D.ReadInt();
- Stmt** SubExprs = new Stmt*[NumArgs+1];
-
- // Construct the ObjCMessageExpr object using the special ctor.
- ObjCMessageExpr* ME = new ObjCMessageExpr(S, t, L, R, SubExprs, NumArgs);
-
- // Read in the MethodProto. Read the instance variable directly
- // allows it to be backpatched.
- D.ReadPtr(ME->MethodProto);
-
- // Now read in the arguments.
-
- if (flags & Flags == IsInstMeth)
- D.BatchReadOwnedPtrs(NumArgs+1, SubExprs, C);
- else {
- // Read the pointer for Cls/ClassName. The Deserializer will handle the
- // bit-mangling automatically.
- SubExprs[RECEIVER] = (Stmt*) ((uintptr_t) flags);
- D.ReadUIntPtr((uintptr_t&) SubExprs[RECEIVER]);
-
- // Read the arguments.
- D.BatchReadOwnedPtrs(NumArgs, &SubExprs[ARGS_START], C);
- }
-
- return ME;
-}
-
-void ObjCSelectorExpr::EmitImpl(Serializer& S) const {
- S.Emit(AtLoc);
- S.Emit(RParenLoc);
- S.Emit(getType());
- S.Emit(SelName);
-}
-
-ObjCSelectorExpr* ObjCSelectorExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation AtLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- Selector SelName = Selector::ReadVal(D);
-
- return new ObjCSelectorExpr(T,SelName,AtLoc,RParenLoc);
-}
-
-void ObjCStringLiteral::EmitImpl(Serializer& S) const {
- S.Emit(AtLoc);
- S.Emit(getType());
- S.EmitOwnedPtr(String);
-}
-
-ObjCStringLiteral* ObjCStringLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- SourceLocation L = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- StringLiteral* String = cast<StringLiteral>(D.ReadOwnedPtr<Stmt>(C));
- return new ObjCStringLiteral(String,T,L);
-}
-
-//===----------------------------------------------------------------------===//
-// Serialization for Clang Extensions.
-//===----------------------------------------------------------------------===//
-
-void BlockExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(getCaretLocation());
- S.EmitOwnedPtr(Body);
-}
-
-BlockExpr* BlockExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType Q = QualType::ReadVal(D);
- SourceLocation L = SourceLocation::ReadVal(D);
- /*CompoundStmt* BodyStmt = cast<CompoundStmt>(*/D.ReadOwnedPtr<Stmt>(C)/*)*/;
- assert(0 && "Cannot deserialize BlockBlockExpr yet");
- // FIXME: need to handle parameters.
- //return new BlockBlockExpr(L, Q, BodyStmt);
- return 0;
-}
-
-void BlockDeclRefExpr::EmitImpl(Serializer& S) const {
- S.Emit(Loc);
- S.Emit(getType());
- S.EmitBool(false);
- S.EmitPtr(getDecl());
-}
-
-BlockDeclRefExpr* BlockDeclRefExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- assert(0 && "Cannot deserialize BlockDeclRefExpr yet");
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Serialization
-//===----------------------------------------------------------------------===//
-void CXXDefaultArgExpr::EmitImpl(Serializer& S) const {
- S.EmitPtr(Param);
-}
-
-CXXDefaultArgExpr *CXXDefaultArgExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- ParmVarDecl* Param = 0;
- D.ReadPtr(Param, false);
- return new CXXDefaultArgExpr(Param);
-}
-
-void CXXFunctionalCastExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(TyBeginLoc);
- S.Emit(RParenLoc);
- S.EmitOwnedPtr(getSubExpr());
-}
-
-CXXFunctionalCastExpr *
-CXXFunctionalCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType Ty = QualType::ReadVal(D);
- SourceLocation TyBeginLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
- Expr* SubExpr = D.ReadOwnedPtr<Expr>(C);
- return new CXXFunctionalCastExpr(Ty, TyBeginLoc, SubExpr, RParenLoc);
-}
-
-void CXXZeroInitValueExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(TyBeginLoc);
- S.Emit(RParenLoc);
-}
-
-CXXZeroInitValueExpr *
-CXXZeroInitValueExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType Ty = QualType::ReadVal(D);
- SourceLocation TyBeginLoc = SourceLocation::ReadVal(D);
- SourceLocation RParenLoc = SourceLocation::ReadVal(D);
- return new CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc);
-}
diff --git a/clang/lib/AST/StmtViz.cpp b/clang/lib/AST/StmtViz.cpp
deleted file mode 100644
index 6790efbd5682..000000000000
--- a/clang/lib/AST/StmtViz.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//===--- StmtViz.cpp - Graphviz visualization for Stmt ASTs -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Stmt::viewAST, which generates a Graphviz DOT file
-// that depicts the AST and then calls Graphviz/dot+gv on it.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/StmtGraphTraits.h"
-#include "llvm/Support/GraphWriter.h"
-#include <sstream>
-
-using namespace clang;
-
-void Stmt::viewAST() const {
-#ifndef NDEBUG
- llvm::ViewGraph(this,"AST");
-#else
- llvm::cerr << "Stmt::viewAST is only available in debug builds on "
- << "systems with Graphviz or gv!\n";
-#endif
-}
-
-namespace llvm {
-template<>
-struct DOTGraphTraits<const Stmt*> : public DefaultDOTGraphTraits {
- static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph) {
-
-#ifndef NDEBUG
- std::string OutSStr;
- llvm::raw_string_ostream Out(OutSStr);
-
- if (Node)
- Out << Node->getStmtClassName();
- else
- Out << "<NULL>";
-
- std::string OutStr = Out.str();
- if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
-
- // Process string output to make it nicer...
- for (unsigned i = 0; i != OutStr.length(); ++i)
- if (OutStr[i] == '\n') { // Left justify
- OutStr[i] = '\\';
- OutStr.insert(OutStr.begin()+i+1, 'l');
- }
-
- return OutStr;
-#else
- return "";
-#endif
- }
-};
-} // end namespace llvm
diff --git a/clang/lib/AST/TranslationUnit.cpp b/clang/lib/AST/TranslationUnit.cpp
deleted file mode 100644
index 659aa064de14..000000000000
--- a/clang/lib/AST/TranslationUnit.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-//===--- TranslationUnit.cpp - Abstraction for Translation Units ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-// FIXME: This should eventually be moved out of the driver, or replaced
-// with its eventual successor.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/TranslationUnit.h"
-
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/AST/AST.h"
-
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Path.h"
-
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/DenseSet.h"
-
-using namespace clang;
-
-enum { BasicMetadataBlock = 1,
- ASTContextBlock = 2,
- DeclsBlock = 3 };
-
-TranslationUnit::~TranslationUnit() {
- if (OwnsDecls) {
- llvm::DenseSet<Decl*> Killed;
- for (iterator I=begin(), E=end(); I!=E; ++I) {
- if (Killed.count(*I)) continue;
-
- Killed.insert(*I);
-
- // FIXME: This is a horrible hack. Because there is no clear ownership
- // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
- // reference, we need to destroy ObjCPropertyDecls here. This will
- // eventually be fixed when the ownership of ObjCPropertyDecls gets
- // cleaned up.
- if (ObjCInterfaceDecl* IDecl = dyn_cast<ObjCInterfaceDecl>(*I))
- for (ObjCInterfaceDecl::classprop_iterator ID=IDecl->classprop_begin(),
- ED=IDecl->classprop_end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
- // FIXME: This is a horrible hack. Because there is no clear ownership
- // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
- // reference, we need to destroy ObjCPropertyDecls here. This will
- // eventually be fixed when the ownership of ObjCPropertyDecls gets
- // cleaned up.
- if (ObjCProtocolDecl* PDecl = dyn_cast<ObjCProtocolDecl>(*I))
- for (ObjCProtocolDecl::classprop_iterator ID=PDecl->classprop_begin(),
- ED=PDecl->classprop_end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
- // FIXME: There is no clear ownership policy now for ObjCInterfaceDecls
- // referenced by ObjCClassDecls. Some of them can be forward decls that
- // are never later defined (and forward decls can be referenced by
- // multiple ObjCClassDecls) or the ObjCInterfaceDecl later
- // becomes a real definition.
- // Ideally we should have separate objects for forward declarations and
- // definitions, obviating this problem. Because of this situation,
- // referenced ObjCInterfaceDecls are destroyed here.
- if (ObjCClassDecl* CDecl = dyn_cast<ObjCClassDecl>(*I))
- for (ObjCClassDecl::iterator ID=CDecl->begin(),
- ED=CDecl->end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
- // FIXME: There is no clear ownership policy now for ObjCProtocolDecls
- // referenced by ObjCForwardProtocolDecl. Some of them can be forward
- // decls that are never later defined (and forward decls can be
- // referenced by multiple ObjCClassDecls) or the ObjCProtocolDecl
- // later becomes a real definition.
- // Ideally we should have separate objects for forward declarations and
- // definitions, obviating this problem. Because of this situation,
- // referenced ObjCProtocolDecls are destroyed here.
- if (ObjCForwardProtocolDecl* FDec = dyn_cast<ObjCForwardProtocolDecl>(*I))
- for (ObjCForwardProtocolDecl::iterator ID=FDec->begin(),
- ED=FDec->end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
-
- (*I)->Destroy(*Context);
- }
- }
-
- if (OwnsMetaData && Context) {
- // The ASTContext object has the sole references to the IdentifierTable
- // Selectors, and the Target information. Go and delete them, since
- // the TranslationUnit effectively owns them.
-
- delete &(Context->Idents);
- delete &(Context->Selectors);
- delete &(Context->Target);
- delete Context;
- }
-}
-
-bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
- const llvm::sys::Path& Filename) {
-
- return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
-}
-
-bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,
- std::vector<unsigned char>& Buffer) {
-
- return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false;
-}
-
-bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,
- std::ostream& Stream) {
-
- return TU ? EmitASTBitcodeStream(*TU, Stream) : false;
-}
-
-bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,
- std::vector<unsigned char>& Buffer) {
- // Create bitstream.
- llvm::BitstreamWriter Stream(Buffer);
-
- // Emit the preamble.
- Stream.Emit((unsigned)'B', 8);
- Stream.Emit((unsigned)'C', 8);
- Stream.Emit(0xC, 4);
- Stream.Emit(0xF, 4);
- Stream.Emit(0xE, 4);
- Stream.Emit(0x0, 4);
-
- {
- // Create serializer. Placing it in its own scope assures any necessary
- // finalization of bits to the buffer in the serializer's dstor.
- llvm::Serializer Sezr(Stream);
-
- // Emit the translation unit.
- TU.Emit(Sezr);
- }
-
- return true;
-}
-
-bool clang::EmitASTBitcodeStream(const TranslationUnit& TU,
- std::ostream& Stream) {
-
- // Reserve 256K for bitstream buffer.
- std::vector<unsigned char> Buffer;
- Buffer.reserve(256*1024);
-
- EmitASTBitcodeBuffer(TU,Buffer);
-
- // Write the bits to disk.
- Stream.write((char*)&Buffer.front(), Buffer.size());
- return true;
-}
-
-bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
- const llvm::sys::Path& Filename) {
-
- // Reserve 256K for bitstream buffer.
- std::vector<unsigned char> Buffer;
- Buffer.reserve(256*1024);
-
- EmitASTBitcodeBuffer(TU,Buffer);
-
- // Write the bits to disk.
- if (FILE* fp = fopen(Filename.c_str(),"wb")) {
- fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
- fclose(fp);
- return true;
- }
-
- return false;
-}
-
-void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
-
- // ===---------------------------------------------------===/
- // Serialize the top-level decls.
- // ===---------------------------------------------------===/
-
- Sezr.EnterBlock(DeclsBlock);
-
- // Only serialize the head of a decl chain. The ASTConsumer interfaces
- // provides us with each top-level decl, including those nested in
- // a decl chain, so we may be passed decls that are already serialized.
- for (const_iterator I=begin(), E=end(); I!=E; ++I)
- if (!Sezr.isRegistered(*I))
- Sezr.EmitOwnedPtr(*I);
-
- Sezr.ExitBlock();
-
- // ===---------------------------------------------------===/
- // Serialize the "Translation Unit" metadata.
- // ===---------------------------------------------------===/
-
- // Emit ASTContext.
- Sezr.EnterBlock(ASTContextBlock);
- Sezr.EmitOwnedPtr(Context);
- Sezr.ExitBlock();
-
- Sezr.EnterBlock(BasicMetadataBlock);
-
- // Block for SourceManager and Target. Allows easy skipping
- // around to the block for the Selectors during deserialization.
- Sezr.EnterBlock();
-
- // Emit the SourceManager.
- Sezr.Emit(Context->getSourceManager());
-
- // Emit the Target.
- Sezr.EmitPtr(&Context->Target);
- Sezr.EmitCStr(Context->Target.getTargetTriple());
-
- Sezr.ExitBlock(); // exit "BasicMetadataBlock"
-
- // Emit the Selectors.
- Sezr.Emit(Context->Selectors);
-
- // Emit the Identifier Table.
- Sezr.Emit(Context->Idents);
-
- Sezr.ExitBlock(); // exit "ASTContextBlock"
-}
-
-TranslationUnit*
-clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) {
-
- // Check if the file is of the proper length.
- if (MBuffer.getBufferSize() & 0x3) {
- // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
- return NULL;
- }
-
- // Create the bitstream reader.
- unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart();
- llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize());
-
- if (Stream.Read(8) != 'B' ||
- Stream.Read(8) != 'C' ||
- Stream.Read(4) != 0xC ||
- Stream.Read(4) != 0xF ||
- Stream.Read(4) != 0xE ||
- Stream.Read(4) != 0x0) {
- // FIXME: Provide diagnostic.
- return NULL;
- }
-
- // Create the deserializer.
- llvm::Deserializer Dezr(Stream);
-
- return TranslationUnit::Create(Dezr,FMgr);
-}
-
-TranslationUnit*
-clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) {
-
- // Create the memory buffer that contains the contents of the file.
- llvm::OwningPtr<llvm::MemoryBuffer>
- MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str()));
-
- if (!MBuffer) {
- // FIXME: Provide diagnostic.
- return NULL;
- }
-
- return ReadASTBitcodeBuffer(*MBuffer, FMgr);
-}
-
-TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
- FileManager& FMgr) {
-
- // Create the translation unit object.
- TranslationUnit* TU = new TranslationUnit();
-
- // ===---------------------------------------------------===/
- // Deserialize the "Translation Unit" metadata.
- // ===---------------------------------------------------===/
-
- // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
- // (which will appear earlier) and record its location.
-
- bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
- assert (FoundBlock);
-
- llvm::Deserializer::Location ASTContextBlockLoc =
- Dezr.getCurrentBlockLocation();
-
- FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
- assert (FoundBlock);
-
- // Read the SourceManager.
- SourceManager::CreateAndRegister(Dezr,FMgr);
-
- { // Read the TargetInfo.
- llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
- char* triple = Dezr.ReadCStr(NULL,0,true);
- Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple)));
- delete [] triple;
- }
-
- // For Selectors, we must read the identifier table first because the
- // SelectorTable depends on the identifiers being already deserialized.
- llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();
- Dezr.SkipBlock();
-
- // Read the identifier table.
- IdentifierTable::CreateAndRegister(Dezr);
-
- // Now jump back and read the selectors.
- Dezr.JumpTo(SelectorBlkLoc);
- SelectorTable::CreateAndRegister(Dezr);
-
- // Now jump back to ASTContextBlock and read the ASTContext.
- Dezr.JumpTo(ASTContextBlockLoc);
- TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
-
- // "Rewind" the stream. Find the block with the serialized top-level decls.
- Dezr.Rewind();
- FoundBlock = Dezr.SkipToBlock(DeclsBlock);
- assert (FoundBlock);
- llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
-
- while (!Dezr.FinishedBlock(DeclBlockLoc))
- TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>(*TU->Context));
-
- return TU;
-}
-
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
deleted file mode 100644
index 74e52fef88fd..000000000000
--- a/clang/lib/AST/Type.cpp
+++ /dev/null
@@ -1,1049 +0,0 @@
-//===--- Type.cpp - Type representation and manipulation ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements type-related functionality.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "llvm/ADT/StringExtras.h"
-
-using namespace clang;
-
-bool QualType::isConstant(ASTContext& Ctx) const {
- if (isConstQualified())
- return true;
-
- if (getTypePtr()->isArrayType())
- return Ctx.getAsArrayType(*this)->getElementType().isConstant(Ctx);
-
- return false;
-}
-
-void Type::Destroy(ASTContext& C) { delete this; }
-
-void FunctionTypeProto::Destroy(ASTContext& C) {
- // Destroy the object, but don't call delete. These are malloc'd.
- this->~FunctionTypeProto();
- free(this);
-}
-
-void VariableArrayType::Destroy(ASTContext& C) {
- SizeExpr->Destroy(C);
- delete this;
-}
-
-
-/// getArrayElementTypeNoTypeQual - If this is an array type, return the
-/// element type of the array, potentially with type qualifiers missing.
-/// This method should never be used when type qualifiers are meaningful.
-const Type *Type::getArrayElementTypeNoTypeQual() const {
- // If this is directly an array type, return it.
- if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
- return ATy->getElementType().getTypePtr();
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ArrayType>(CanonicalType)) {
- // Look through type qualifiers
- if (ArrayType *AT = dyn_cast<ArrayType>(CanonicalType.getUnqualifiedType()))
- return AT->getElementType().getTypePtr();
- return 0;
- }
-
- // If this is a typedef for an array type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getArrayElementTypeNoTypeQual();
-}
-
-/// getDesugaredType - Return the specified type with any "sugar" removed from
-/// type 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
-/// to getting the canonical type, but it doesn't remove *all* typedefs. For
-/// example, it return "T*" as "T*", (not as "int*"), because the pointer is
-/// concrete.
-QualType Type::getDesugaredType() const {
- if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
- return TDT->LookThroughTypedefs();
- if (const TypeOfExpr *TOE = dyn_cast<TypeOfExpr>(this))
- return TOE->getUnderlyingExpr()->getType();
- if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
- return TOT->getUnderlyingType();
- // FIXME: remove this cast.
- return QualType(const_cast<Type*>(this), 0);
-}
-
-/// isVoidType - Helper method to determine if this is the 'void' type.
-bool Type::isVoidType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Void;
- return false;
-}
-
-bool Type::isObjectType() const {
- if (isa<FunctionType>(CanonicalType))
- return false;
- else if (CanonicalType->isIncompleteType())
- return false;
- else
- return true;
-}
-
-bool Type::isDerivedType() const {
- switch (CanonicalType->getTypeClass()) {
- case Pointer:
- case VariableArray:
- case ConstantArray:
- case IncompleteArray:
- case FunctionProto:
- case FunctionNoProto:
- case Reference:
- return true;
- case Tagged: {
- const TagType *TT = cast<TagType>(CanonicalType);
- return !TT->getDecl()->isEnum();
- }
- default:
- return false;
- }
-}
-
-bool Type::isClassType() const {
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
- if (RT->getDecl()->isClass())
- return true;
- return false;
-}
-bool Type::isStructureType() const {
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
- if (RT->getDecl()->isStruct())
- return true;
- return false;
-}
-bool Type::isUnionType() const {
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
- if (RT->getDecl()->isUnion())
- return true;
- return false;
-}
-
-bool Type::isComplexType() const {
- if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
- return CT->getElementType()->isFloatingType();
- return false;
-}
-
-bool Type::isComplexIntegerType() const {
- // Check for GCC complex integer extension.
- if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
- return CT->getElementType()->isIntegerType();
- return false;
-}
-
-const ComplexType *Type::getAsComplexIntegerType() const {
- // Are we directly a complex type?
- if (const ComplexType *CTy = dyn_cast<ComplexType>(this)) {
- if (CTy->getElementType()->isIntegerType())
- return CTy;
- }
- // If the canonical form of this type isn't the right kind, reject it.
- const ComplexType *CTy = dyn_cast<ComplexType>(CanonicalType);
- if (!CTy || !CTy->getElementType()->isIntegerType())
- return 0;
-
- // If this is a typedef for a complex type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsComplexIntegerType();
-}
-
-const BuiltinType *Type::getAsBuiltinType() const {
- // If this is directly a builtin type, return it.
- if (const BuiltinType *BTy = dyn_cast<BuiltinType>(this))
- return BTy;
-
- // If the canonical form of this type isn't a builtin type, reject it.
- if (!isa<BuiltinType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<BuiltinType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsBuiltinType();
- return 0;
- }
-
- // If this is a typedef for a builtin type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsBuiltinType();
-}
-
-const FunctionType *Type::getAsFunctionType() const {
- // If this is directly a function type, return it.
- if (const FunctionType *FTy = dyn_cast<FunctionType>(this))
- return FTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<FunctionType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<FunctionType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsFunctionType();
- return 0;
- }
-
- // If this is a typedef for a function type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsFunctionType();
-}
-
-const FunctionTypeProto *Type::getAsFunctionTypeProto() const {
- return dyn_cast_or_null<FunctionTypeProto>(getAsFunctionType());
-}
-
-
-const PointerLikeType *Type::getAsPointerLikeType() const {
- // If this is directly a pointer-like type, return it.
- if (const PointerLikeType *PTy = dyn_cast<PointerLikeType>(this))
- return PTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<PointerLikeType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<PointerLikeType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsPointerLikeType();
- return 0;
- }
-
- // If this is a typedef for a pointer type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsPointerLikeType();
-}
-
-const PointerType *Type::getAsPointerType() const {
- // If this is directly a pointer type, return it.
- if (const PointerType *PTy = dyn_cast<PointerType>(this))
- return PTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<PointerType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<PointerType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsPointerType();
- return 0;
- }
-
- // If this is a typedef for a pointer type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsPointerType();
-}
-
-const BlockPointerType *Type::getAsBlockPointerType() const {
- // If this is directly a block pointer type, return it.
- if (const BlockPointerType *PTy = dyn_cast<BlockPointerType>(this))
- return PTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<BlockPointerType>(CanonicalType))
- return 0;
-
- // If this is a typedef for a block pointer type, strip the typedef off
- // without losing all typedef information.
- return getDesugaredType()->getAsBlockPointerType();
-}
-
-const ReferenceType *Type::getAsReferenceType() const {
- // If this is directly a reference type, return it.
- if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
- return RTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ReferenceType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<ReferenceType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsReferenceType();
- return 0;
- }
-
- // If this is a typedef for a reference type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsReferenceType();
-}
-
-/// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length
-/// array types and types that contain variable array types in their
-/// declarator
-bool Type::isVariablyModifiedType() const {
- // A VLA is a variably modified type.
- if (isVariableArrayType())
- return true;
-
- // An array can contain a variably modified type
- if (const Type *T = getArrayElementTypeNoTypeQual())
- return T->isVariablyModifiedType();
-
- // A pointer can point to a variably modified type
- if (const PointerType* PT = getAsPointerType())
- return PT->getPointeeType()->isVariablyModifiedType();
-
- // A function can return a variably modified type
- // This one isn't completely obvious, but it follows from the
- // definition in C99 6.7.5p3. Because of this rule, it's
- // illegal to declare a function returning a variably modified type.
- if (const FunctionType* FT = getAsFunctionType())
- return FT->getResultType()->isVariablyModifiedType();
-
- return false;
-}
-
-const RecordType *Type::getAsRecordType() const {
- // If this is directly a reference type, return it.
- if (const RecordType *RTy = dyn_cast<RecordType>(this))
- return RTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<RecordType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsRecordType();
- return 0;
- }
-
- // If this is a typedef for a record type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsRecordType();
-}
-
-const RecordType *Type::getAsStructureType() const {
- // If this is directly a structure type, return it.
- if (const RecordType *RT = dyn_cast<RecordType>(this)) {
- if (RT->getDecl()->isStruct())
- return RT;
- }
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
- if (!RT->getDecl()->isStruct())
- return 0;
-
- // If this is a typedef for a structure type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsStructureType();
- }
- // Look through type qualifiers
- if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsStructureType();
- return 0;
-}
-
-const RecordType *Type::getAsUnionType() const {
- // If this is directly a union type, return it.
- if (const RecordType *RT = dyn_cast<RecordType>(this)) {
- if (RT->getDecl()->isUnion())
- return RT;
- }
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
- if (!RT->getDecl()->isUnion())
- return 0;
-
- // If this is a typedef for a union type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsUnionType();
- }
-
- // Look through type qualifiers
- if (isa<RecordType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsUnionType();
- return 0;
-}
-
-const EnumType *Type::getAsEnumType() const {
- // Check the canonicalized unqualified type directly; the more complex
- // version is unnecessary because there isn't any typedef information
- // to preserve.
- return dyn_cast<EnumType>(CanonicalType.getUnqualifiedType());
-}
-
-const ComplexType *Type::getAsComplexType() const {
- // Are we directly a complex type?
- if (const ComplexType *CTy = dyn_cast<ComplexType>(this))
- return CTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ComplexType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<ComplexType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsComplexType();
- return 0;
- }
-
- // If this is a typedef for a complex type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsComplexType();
-}
-
-const VectorType *Type::getAsVectorType() const {
- // Are we directly a vector type?
- if (const VectorType *VTy = dyn_cast<VectorType>(this))
- return VTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<VectorType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<VectorType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsVectorType();
- return 0;
- }
-
- // If this is a typedef for a vector type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsVectorType();
-}
-
-const ExtVectorType *Type::getAsExtVectorType() const {
- // Are we directly an OpenCU vector type?
- if (const ExtVectorType *VTy = dyn_cast<ExtVectorType>(this))
- return VTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ExtVectorType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<ExtVectorType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsExtVectorType();
- return 0;
- }
-
- // If this is a typedef for an extended vector type, strip the typedef off
- // without losing all typedef information.
- return getDesugaredType()->getAsExtVectorType();
-}
-
-const ObjCInterfaceType *Type::getAsObjCInterfaceType() const {
- // There is no sugar for ObjCInterfaceType's, just return the canonical
- // type pointer if it is the right class.
- return dyn_cast<ObjCInterfaceType>(CanonicalType);
-}
-
-const ObjCQualifiedInterfaceType *
-Type::getAsObjCQualifiedInterfaceType() const {
- // There is no sugar for ObjCQualifiedInterfaceType's, just return the canonical
- // type pointer if it is the right class.
- return dyn_cast<ObjCQualifiedInterfaceType>(CanonicalType);
-}
-
-const ObjCQualifiedIdType *Type::getAsObjCQualifiedIdType() const {
- // There is no sugar for ObjCQualifiedIdType's, just return the canonical
- // type pointer if it is the right class.
- return dyn_cast<ObjCQualifiedIdType>(CanonicalType);
-}
-
-
-bool Type::isIntegerType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::LongLong;
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
- // Incomplete enum types are not treated as integer types.
- if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
- return true;
- if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
- return VT->getElementType()->isIntegerType();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isIntegerType();
- return false;
-}
-
-bool Type::isIntegralType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::LongLong;
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
- if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
- return true; // Complete enum types are integral.
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isIntegralType();
- return false;
-}
-
-bool Type::isEnumeralType() const {
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
- return TT->getDecl()->isEnum();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isEnumeralType();
- return false;
-}
-
-bool Type::isBooleanType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Bool;
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isBooleanType();
- return false;
-}
-
-bool Type::isCharType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Char_U ||
- BT->getKind() == BuiltinType::UChar ||
- BT->getKind() == BuiltinType::Char_S ||
- BT->getKind() == BuiltinType::SChar;
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isCharType();
- return false;
-}
-
-bool Type::isWideCharType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::WChar;
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isWideCharType();
- return false;
-}
-
-/// isSignedIntegerType - Return true if this is an integer type that is
-/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
-/// an enum decl which has a signed representation, or a vector of signed
-/// integer element type.
-bool Type::isSignedIntegerType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
- return BT->getKind() >= BuiltinType::Char_S &&
- BT->getKind() <= BuiltinType::LongLong;
- }
-
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
- return ET->getDecl()->getIntegerType()->isSignedIntegerType();
-
- if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
- return VT->getElementType()->isSignedIntegerType();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isSignedIntegerType();
- return false;
-}
-
-/// isUnsignedIntegerType - Return true if this is an integer type that is
-/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
-/// decl which has an unsigned representation, or a vector of unsigned integer
-/// element type.
-bool Type::isUnsignedIntegerType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::ULongLong;
- }
-
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
- return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
-
- if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
- return VT->getElementType()->isUnsignedIntegerType();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isUnsignedIntegerType();
- return false;
-}
-
-bool Type::isFloatingType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Float &&
- BT->getKind() <= BuiltinType::LongDouble;
- if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
- return CT->getElementType()->isFloatingType();
- if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
- return VT->getElementType()->isFloatingType();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isFloatingType();
- return false;
-}
-
-bool Type::isRealFloatingType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Float &&
- BT->getKind() <= BuiltinType::LongDouble;
- if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
- return VT->getElementType()->isRealFloatingType();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isRealFloatingType();
- return false;
-}
-
-bool Type::isRealType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::LongDouble;
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
- return TT->getDecl()->isEnum() && TT->getDecl()->isDefinition();
- if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
- return VT->getElementType()->isRealType();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isRealType();
- return false;
-}
-
-bool Type::isArithmeticType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() != BuiltinType::Void;
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
- // GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
- // If a body isn't seen by the time we get here, return false.
- return ET->getDecl()->isDefinition();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isArithmeticType();
- return isa<ComplexType>(CanonicalType) || isa<VectorType>(CanonicalType);
-}
-
-bool Type::isScalarType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() != BuiltinType::Void;
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
- // Enums are scalar types, but only if they are defined. Incomplete enums
- // are not treated as scalar types.
- if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
- return true;
- return false;
- }
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isScalarType();
- return isa<PointerType>(CanonicalType) ||
- isa<BlockPointerType>(CanonicalType) ||
- isa<ComplexType>(CanonicalType) ||
- isa<ObjCQualifiedIdType>(CanonicalType);
-}
-
-bool Type::isAggregateType() const {
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
- if (TT->getDecl()->isStruct())
- return true;
- return false;
- }
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isAggregateType();
- return isa<ArrayType>(CanonicalType);
-}
-
-/// isConstantSizeType - Return true if this is not a variable sized type,
-/// according to the rules of C99 6.7.5p3. It is not legal to call this on
-/// incomplete types.
-bool Type::isConstantSizeType() const {
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isConstantSizeType();
- assert(!isIncompleteType() && "This doesn't make sense for incomplete types");
- // The VAT must have a size, as it is known to be complete.
- return !isa<VariableArrayType>(CanonicalType);
-}
-
-/// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
-/// - a type that can describe objects, but which lacks information needed to
-/// determine its size.
-bool Type::isIncompleteType() const {
- switch (CanonicalType->getTypeClass()) {
- default: return false;
- case ASQual:
- return cast<ASQualType>(CanonicalType)->getBaseType()->isIncompleteType();
- case Builtin:
- // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never
- // be completed.
- return isVoidType();
- case Tagged:
- // A tagged type (struct/union/enum/class) is incomplete if the decl is a
- // forward declaration, but not a full definition (C99 6.2.5p22).
- return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
- case IncompleteArray:
- // An array of unknown size is an incomplete type (C99 6.2.5p22).
- return true;
- }
-}
-
-bool Type::isPromotableIntegerType() const {
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isPromotableIntegerType();
- const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
- if (!BT) return false;
- switch (BT->getKind()) {
- case BuiltinType::Bool:
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- case BuiltinType::Short:
- case BuiltinType::UShort:
- return true;
- default:
- return false;
- }
-}
-
-const char *BuiltinType::getName() const {
- switch (getKind()) {
- default: assert(0 && "Unknown builtin type!");
- case Void: return "void";
- case Bool: return "_Bool";
- case Char_S: return "char";
- case Char_U: return "char";
- case SChar: return "signed char";
- case Short: return "short";
- case Int: return "int";
- case Long: return "long";
- case LongLong: return "long long";
- case UChar: return "unsigned char";
- case UShort: return "unsigned short";
- case UInt: return "unsigned int";
- case ULong: return "unsigned long";
- case ULongLong: return "unsigned long long";
- case Float: return "float";
- case Double: return "double";
- case LongDouble: return "long double";
- case WChar: return "wchar_t";
- }
-}
-
-void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
- arg_type_iterator ArgTys,
- unsigned NumArgs, bool isVariadic) {
- ID.AddPointer(Result.getAsOpaquePtr());
- for (unsigned i = 0; i != NumArgs; ++i)
- ID.AddPointer(ArgTys[i].getAsOpaquePtr());
- ID.AddInteger(isVariadic);
-}
-
-void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
-}
-
-void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
- const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **protocols,
- unsigned NumProtocols) {
- ID.AddPointer(Decl);
- for (unsigned i = 0; i != NumProtocols; i++)
- ID.AddPointer(protocols[i]);
-}
-
-void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
-}
-
-void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID,
- ObjCProtocolDecl **protocols,
- unsigned NumProtocols) {
- for (unsigned i = 0; i != NumProtocols; i++)
- ID.AddPointer(protocols[i]);
-}
-
-void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, &Protocols[0], getNumProtocols());
-}
-
-/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
-/// potentially looking through *all* consequtive typedefs. This returns the
-/// sum of the type qualifiers, so if you have:
-/// typedef const int A;
-/// typedef volatile A B;
-/// looking through the typedefs for B will give you "const volatile A".
-///
-QualType TypedefType::LookThroughTypedefs() const {
- // Usually, there is only a single level of typedefs, be fast in that case.
- QualType FirstType = getDecl()->getUnderlyingType();
- if (!isa<TypedefType>(FirstType))
- return FirstType;
-
- // Otherwise, do the fully general loop.
- unsigned TypeQuals = 0;
- const TypedefType *TDT = this;
- while (1) {
- QualType CurType = TDT->getDecl()->getUnderlyingType();
-
-
- /// FIXME:
- /// FIXME: This is incorrect for ASQuals!
- /// FIXME:
- TypeQuals |= CurType.getCVRQualifiers();
-
- TDT = dyn_cast<TypedefType>(CurType);
- if (TDT == 0)
- return QualType(CurType.getTypePtr(), TypeQuals);
- }
-}
-
-bool RecordType::classof(const TagType *TT) {
- return isa<RecordDecl>(TT->getDecl());
-}
-
-bool CXXRecordType::classof(const TagType *TT) {
- return isa<CXXRecordDecl>(TT->getDecl());
-}
-
-bool EnumType::classof(const TagType *TT) {
- return isa<EnumDecl>(TT->getDecl());
-}
-
-
-//===----------------------------------------------------------------------===//
-// Type Printing
-//===----------------------------------------------------------------------===//
-
-void QualType::dump(const char *msg) const {
- std::string R = "identifier";
- getAsStringInternal(R);
- 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";
- getAsStringInternal(S);
- fprintf(stderr, "%s\n", S.c_str());
-}
-
-
-
-static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
- // Note: funkiness to ensure we get a space only between quals.
- bool NonePrinted = true;
- if (TypeQuals & QualType::Const)
- S += "const", NonePrinted = false;
- if (TypeQuals & QualType::Volatile)
- S += (NonePrinted+" volatile"), NonePrinted = false;
- if (TypeQuals & QualType::Restrict)
- S += (NonePrinted+" restrict"), NonePrinted = false;
-}
-
-void QualType::getAsStringInternal(std::string &S) const {
- if (isNull()) {
- S += "NULL TYPE\n";
- return;
- }
-
- // Print qualifiers as appropriate.
- if (unsigned Tq = getCVRQualifiers()) {
- std::string TQS;
- AppendTypeQualList(TQS, Tq);
- if (!S.empty())
- S = TQS + ' ' + S;
- else
- S = TQS;
- }
-
- getTypePtr()->getAsStringInternal(S);
-}
-
-void BuiltinType::getAsStringInternal(std::string &S) const {
- if (S.empty()) {
- S = getName();
- } else {
- // Prefix the basic type, e.g. 'int X'.
- S = ' ' + S;
- S = getName() + S;
- }
-}
-
-void ComplexType::getAsStringInternal(std::string &S) const {
- ElementType->getAsStringInternal(S);
- S = "_Complex " + S;
-}
-
-void ASQualType::getAsStringInternal(std::string &S) const {
- S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
- BaseType->getAsStringInternal(S);
-}
-
-void PointerType::getAsStringInternal(std::string &S) 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);
-}
-
-void BlockPointerType::getAsStringInternal(std::string &S) const {
- S = '^' + S;
- PointeeType.getAsStringInternal(S);
-}
-
-void ReferenceType::getAsStringInternal(std::string &S) 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);
-}
-
-void ConstantArrayType::getAsStringInternal(std::string &S) const {
- S += '[';
- S += llvm::utostr(getSize().getZExtValue());
- S += ']';
-
- getElementType().getAsStringInternal(S);
-}
-
-void IncompleteArrayType::getAsStringInternal(std::string &S) const {
- S += "[]";
-
- getElementType().getAsStringInternal(S);
-}
-
-void VariableArrayType::getAsStringInternal(std::string &S) const {
- S += '[';
-
- if (getIndexTypeQualifier()) {
- AppendTypeQualList(S, getIndexTypeQualifier());
- 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);
- S += s.str();
- }
- S += ']';
-
- getElementType().getAsStringInternal(S);
-}
-
-void VectorType::getAsStringInternal(std::string &S) 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() + "))))";
-}
-
-void ExtVectorType::getAsStringInternal(std::string &S) const {
- S += " __attribute__((ext_vector_type(";
- S += llvm::utostr_32(NumElements);
- S += ")))";
- ElementType.getAsStringInternal(S);
-}
-
-void TypeOfExpr::getAsStringInternal(std::string &InnerString) 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);
- InnerString = "typeof(" + s.str() + ")" + InnerString;
-}
-
-void TypeOfType::getAsStringInternal(std::string &InnerString) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(t) X'.
- InnerString = ' ' + InnerString;
- std::string Tmp;
- getUnderlyingType().getAsStringInternal(Tmp);
- InnerString = "typeof(" + Tmp + ")" + InnerString;
-}
-
-void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
- // If needed for precedence reasons, wrap the inner part in grouping parens.
- if (!S.empty())
- S = "(" + S + ")";
-
- S += "()";
- getResultType().getAsStringInternal(S);
-}
-
-void FunctionTypeProto::getAsStringInternal(std::string &S) const {
- // If needed for precedence reasons, wrap the inner part in grouping parens.
- if (!S.empty())
- S = "(" + S + ")";
-
- S += "(";
- std::string Tmp;
- for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
- if (i) S += ", ";
- getArgType(i).getAsStringInternal(Tmp);
- S += Tmp;
- Tmp.clear();
- }
-
- if (isVariadic()) {
- if (getNumArgs())
- S += ", ";
- S += "...";
- } else if (getNumArgs() == 0) {
- // Do not emit int() if we have a proto, emit 'int(void)'.
- S += "void";
- }
-
- S += ")";
- getResultType().getAsStringInternal(S);
-}
-
-
-void TypedefType::getAsStringInternal(std::string &InnerString) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
- InnerString = getDecl()->getIdentifier()->getName() + InnerString;
-}
-
-void ObjCInterfaceType::getAsStringInternal(std::string &InnerString) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
- InnerString = getDecl()->getIdentifier()->getName() + InnerString;
-}
-
-void ObjCQualifiedInterfaceType::getAsStringInternal(
- std::string &InnerString) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
- std::string ObjCQIString = getDecl()->getName();
- ObjCQIString += '<';
- bool isFirst = true;
- for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
- if (isFirst)
- isFirst = false;
- else
- ObjCQIString += ',';
- ObjCQIString += (*I)->getName();
- }
- ObjCQIString += '>';
- InnerString = ObjCQIString + InnerString;
-}
-
-void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
- std::string ObjCQIString = "id";
- ObjCQIString += '<';
- int num = getNumProtocols();
- for (int i = 0; i < num; i++) {
- ObjCQIString += getProtocols(i)->getName();
- if (i < num-1)
- ObjCQIString += ',';
- }
- ObjCQIString += '>';
- InnerString = ObjCQIString + InnerString;
-}
-
-void TagType::getAsStringInternal(std::string &InnerString) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
-
- const char *Kind = getDecl()->getKindName();
- const char *ID;
- if (const IdentifierInfo *II = getDecl()->getIdentifier())
- ID = II->getName();
- else
- ID = "<anonymous>";
-
- InnerString = std::string(Kind) + " " + ID + InnerString;
-}
diff --git a/clang/lib/AST/TypeSerialization.cpp b/clang/lib/AST/TypeSerialization.cpp
deleted file mode 100644
index 967472685529..000000000000
--- a/clang/lib/AST/TypeSerialization.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-//===--- TypeSerialization.cpp - Serialization of Decls ---------*- 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 methods that implement bitcode serialization for Types.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Type.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using namespace clang;
-using llvm::Serializer;
-using llvm::Deserializer;
-using llvm::SerializedPtrID;
-
-
-void QualType::Emit(Serializer& S) const {
- S.EmitPtr(getTypePtr());
- S.EmitInt(getCVRQualifiers());
-}
-
-QualType QualType::ReadVal(Deserializer& D) {
- QualType Q;
- D.ReadUIntPtr(Q.ThePtr,false);
- Q.ThePtr |= D.ReadInt();
- return Q;
-}
-
-void QualType::ReadBackpatch(Deserializer& D) {
- D.ReadUIntPtr(ThePtr,true);
- ThePtr |= D.ReadInt();
-}
-
-//===----------------------------------------------------------------------===//
-// Type Serialization: Dispatch code to handle specific types.
-//===----------------------------------------------------------------------===//
-
-void Type::Emit(Serializer& S) const {
- S.EmitInt(getTypeClass());
- S.EmitPtr(this);
-
- if (!isa<BuiltinType>(this))
- EmitImpl(S);
-}
-
-void Type::EmitImpl(Serializer& S) const {
- assert (false && "Serializization for type not supported.");
-}
-
-void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) {
- Type::TypeClass K = static_cast<Type::TypeClass>(D.ReadInt());
- SerializedPtrID PtrID = D.ReadPtrID();
-
- switch (K) {
- default:
- assert (false && "Deserialization for type not supported.");
- break;
-
- case Type::Builtin:
- assert (i < Context.getTypes().size());
- assert (isa<BuiltinType>(Context.getTypes()[i]));
- D.RegisterPtr(PtrID,Context.getTypes()[i]);
- break;
-
- case Type::ASQual:
- D.RegisterPtr(PtrID,ASQualType::CreateImpl(Context,D));
- break;
-
- case Type::Complex:
- D.RegisterPtr(PtrID,ComplexType::CreateImpl(Context,D));
- break;
-
- case Type::ConstantArray:
- D.RegisterPtr(PtrID,ConstantArrayType::CreateImpl(Context,D));
- break;
-
- case Type::FunctionNoProto:
- D.RegisterPtr(PtrID,FunctionTypeNoProto::CreateImpl(Context,D));
- break;
-
- case Type::FunctionProto:
- D.RegisterPtr(PtrID,FunctionTypeProto::CreateImpl(Context,D));
- break;
-
- case Type::IncompleteArray:
- D.RegisterPtr(PtrID,IncompleteArrayType::CreateImpl(Context,D));
- break;
-
- case Type::Pointer:
- D.RegisterPtr(PtrID,PointerType::CreateImpl(Context,D));
- break;
-
- case Type::BlockPointer:
- D.RegisterPtr(PtrID,BlockPointerType::CreateImpl(Context,D));
- break;
-
- case Type::Tagged:
- D.RegisterPtr(PtrID,TagType::CreateImpl(Context,D));
- break;
-
- case Type::TypeName:
- D.RegisterPtr(PtrID,TypedefType::CreateImpl(Context,D));
- break;
-
- case Type::VariableArray:
- D.RegisterPtr(PtrID,VariableArrayType::CreateImpl(Context,D));
- break;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// ASQualType
-//===----------------------------------------------------------------------===//
-
-void ASQualType::EmitImpl(Serializer& S) const {
- S.EmitPtr(getBaseType());
- S.EmitInt(getAddressSpace());
-}
-
-Type* ASQualType::CreateImpl(ASTContext& Context, Deserializer& D) {
- QualType BaseTy = QualType::ReadVal(D);
- unsigned AddressSpace = D.ReadInt();
- return Context.getASQualType(BaseTy, AddressSpace).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// BlockPointerType
-//===----------------------------------------------------------------------===//
-
-void BlockPointerType::EmitImpl(Serializer& S) const {
- S.Emit(getPointeeType());
-}
-
-Type* BlockPointerType::CreateImpl(ASTContext& Context, Deserializer& D) {
- return Context.getBlockPointerType(QualType::ReadVal(D)).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// ComplexType
-//===----------------------------------------------------------------------===//
-
-void ComplexType::EmitImpl(Serializer& S) const {
- S.Emit(getElementType());
-}
-
-Type* ComplexType::CreateImpl(ASTContext& Context, Deserializer& D) {
- return Context.getComplexType(QualType::ReadVal(D)).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// ConstantArray
-//===----------------------------------------------------------------------===//
-
-void ConstantArrayType::EmitImpl(Serializer& S) const {
- S.Emit(getElementType());
- S.EmitInt(getSizeModifier());
- S.EmitInt(getIndexTypeQualifier());
- S.Emit(Size);
-}
-
-Type* ConstantArrayType::CreateImpl(ASTContext& Context, Deserializer& D) {
- QualType ElTy = QualType::ReadVal(D);
- ArraySizeModifier am = static_cast<ArraySizeModifier>(D.ReadInt());
- unsigned ITQ = D.ReadInt();
-
- llvm::APInt Size;
- D.Read(Size);
-
- return Context.getConstantArrayType(ElTy,Size,am,ITQ).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionTypeNoProto
-//===----------------------------------------------------------------------===//
-
-void FunctionTypeNoProto::EmitImpl(Serializer& S) const {
- S.Emit(getResultType());
-}
-
-Type* FunctionTypeNoProto::CreateImpl(ASTContext& Context, Deserializer& D) {
- return Context.getFunctionTypeNoProto(QualType::ReadVal(D)).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionTypeProto
-//===----------------------------------------------------------------------===//
-
-void FunctionTypeProto::EmitImpl(Serializer& S) const {
- S.Emit(getResultType());
- S.EmitBool(isVariadic());
- S.EmitInt(getNumArgs());
-
- for (arg_type_iterator I=arg_type_begin(), E=arg_type_end(); I!=E; ++I)
- S.Emit(*I);
-}
-
-Type* FunctionTypeProto::CreateImpl(ASTContext& Context, Deserializer& D) {
- QualType ResultType = QualType::ReadVal(D);
- bool isVariadic = D.ReadBool();
- unsigned NumArgs = D.ReadInt();
-
- llvm::SmallVector<QualType,15> Args;
-
- for (unsigned j = 0; j < NumArgs; ++j)
- Args.push_back(QualType::ReadVal(D));
-
- return Context.getFunctionType(ResultType,&*Args.begin(),
- NumArgs,isVariadic).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// PointerType
-//===----------------------------------------------------------------------===//
-
-void PointerType::EmitImpl(Serializer& S) const {
- S.Emit(getPointeeType());
-}
-
-Type* PointerType::CreateImpl(ASTContext& Context, Deserializer& D) {
- return Context.getPointerType(QualType::ReadVal(D)).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// TagType
-//===----------------------------------------------------------------------===//
-
-void TagType::EmitImpl(Serializer& S) const {
- S.EmitOwnedPtr(getDecl());
-}
-
-Type* TagType::CreateImpl(ASTContext& Context, Deserializer& D) {
- std::vector<Type*>& Types =
- const_cast<std::vector<Type*>&>(Context.getTypes());
-
- TagType* T = new TagType(NULL,QualType());
- Types.push_back(T);
-
- // Deserialize the decl.
- T->decl = cast<TagDecl>(D.ReadOwnedPtr<Decl>(Context));
-
- return T;
-}
-
-//===----------------------------------------------------------------------===//
-// TypedefType
-//===----------------------------------------------------------------------===//
-
-void TypedefType::EmitImpl(Serializer& S) const {
- S.Emit(getCanonicalTypeInternal());
- S.EmitPtr(Decl);
-}
-
-Type* TypedefType::CreateImpl(ASTContext& Context, Deserializer& D) {
- std::vector<Type*>& Types =
- const_cast<std::vector<Type*>&>(Context.getTypes());
-
- TypedefType* T = new TypedefType(Type::TypeName, NULL, QualType::ReadVal(D));
- Types.push_back(T);
-
- D.ReadPtr(T->Decl); // May be backpatched.
- return T;
-}
-
-//===----------------------------------------------------------------------===//
-// VariableArrayType
-//===----------------------------------------------------------------------===//
-
-void VariableArrayType::EmitImpl(Serializer& S) const {
- S.Emit(getElementType());
- S.EmitInt(getSizeModifier());
- S.EmitInt(getIndexTypeQualifier());
- S.EmitOwnedPtr(SizeExpr);
-}
-
-Type* VariableArrayType::CreateImpl(ASTContext& Context, Deserializer& D) {
- QualType ElTy = QualType::ReadVal(D);
- ArraySizeModifier am = static_cast<ArraySizeModifier>(D.ReadInt());
- unsigned ITQ = D.ReadInt();
- Expr* SizeExpr = D.ReadOwnedPtr<Expr>(Context);
-
- return Context.getVariableArrayType(ElTy,SizeExpr,am,ITQ).getTypePtr();
-}
-
-//===----------------------------------------------------------------------===//
-// IncompleteArrayType
-//===----------------------------------------------------------------------===//
-
-void IncompleteArrayType::EmitImpl(Serializer& S) const {
- S.Emit(getElementType());
- S.EmitInt(getSizeModifier());
- S.EmitInt(getIndexTypeQualifier());
-}
-
-Type* IncompleteArrayType::CreateImpl(ASTContext& Context, Deserializer& D) {
- QualType ElTy = QualType::ReadVal(D);
- ArraySizeModifier am = static_cast<ArraySizeModifier>(D.ReadInt());
- unsigned ITQ = D.ReadInt();
-
- return Context.getIncompleteArrayType(ElTy,am,ITQ).getTypePtr();
-}
diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp
deleted file mode 100644
index 66bf082b136a..000000000000
--- a/clang/lib/Analysis/BasicConstraintManager.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-//== BasicConstraintManager.cpp - Manage basic constraints.------*- 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 BasicConstraintManager, a class that tracks simple
-// equality and inequality constraints on symbolic values of GRState.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/ConstraintManager.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRStateTrait.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-
-namespace {
-
-typedef llvm::ImmutableMap<SymbolID,GRState::IntSetTy> ConstNotEqTy;
-typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
-
-// BasicConstraintManager only tracks equality and inequality constraints of
-// constants and integer variables.
-class VISIBILITY_HIDDEN BasicConstraintManager : public ConstraintManager {
- GRStateManager& StateMgr;
-
-public:
- BasicConstraintManager(GRStateManager& statemgr) : StateMgr(statemgr) {}
-
- virtual const GRState* Assume(const GRState* St, RVal Cond,
- bool Assumption, bool& isFeasible);
-
- const GRState* Assume(const GRState* St, LVal Cond, bool Assumption,
- bool& isFeasible);
-
- const GRState* AssumeAux(const GRState* St, LVal Cond,bool Assumption,
- bool& isFeasible);
-
- const GRState* Assume(const GRState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible);
-
- const GRState* AssumeAux(const GRState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible);
-
- const GRState* AssumeSymInt(const GRState* St, bool Assumption,
- const SymIntConstraint& C, bool& isFeasible);
-
- const GRState* AssumeSymNE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible);
-
- const GRState* AssumeSymEQ(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible);
-
- const GRState* AssumeSymLT(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible);
-
- const GRState* AssumeSymGT(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible);
-
- const GRState* AssumeSymGE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible);
-
- const GRState* AssumeSymLE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible);
-
- const GRState* AddEQ(const GRState* St, SymbolID sym, const llvm::APSInt& V);
-
- const GRState* AddNE(const GRState* St, SymbolID sym, const llvm::APSInt& V);
-
- const llvm::APSInt* getSymVal(const GRState* St, SymbolID sym);
- bool isNotEqual(const GRState* St, SymbolID sym, const llvm::APSInt& V) const;
- bool isEqual(const GRState* St, SymbolID sym, const llvm::APSInt& V) const;
-
- const GRState* RemoveDeadBindings(const GRState* St,
- StoreManager::LiveSymbolsTy& LSymbols,
- StoreManager::DeadSymbolsTy& DSymbols);
-
- void print(const GRState* St, std::ostream& Out,
- const char* nl, const char *sep);
-};
-
-} // end anonymous namespace
-
-ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& StateMgr)
-{
- return new BasicConstraintManager(StateMgr);
-}
-
-const GRState* BasicConstraintManager::Assume(const GRState* St, RVal Cond,
- bool Assumption, bool& isFeasible) {
- if (Cond.isUnknown()) {
- isFeasible = true;
- return St;
- }
-
- if (isa<NonLVal>(Cond))
- return Assume(St, cast<NonLVal>(Cond), Assumption, isFeasible);
- else
- return Assume(St, cast<LVal>(Cond), Assumption, isFeasible);
-}
-
-const GRState* BasicConstraintManager::Assume(const GRState* St, LVal Cond,
- bool Assumption, bool& isFeasible) {
- St = AssumeAux(St, Cond, Assumption, isFeasible);
- // TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
- return St;
-}
-
-const GRState* BasicConstraintManager::AssumeAux(const GRState* St, LVal Cond,
- bool Assumption, bool& isFeasible) {
- BasicValueFactory& BasicVals = StateMgr.getBasicVals();
-
- switch (Cond.getSubKind()) {
- default:
- assert (false && "'Assume' not implemented for this LVal.");
- return St;
-
- case lval::SymbolValKind:
- if (Assumption)
- return AssumeSymNE(St, cast<lval::SymbolVal>(Cond).getSymbol(),
- BasicVals.getZeroWithPtrWidth(), isFeasible);
- else
- return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
- BasicVals.getZeroWithPtrWidth(), isFeasible);
-
- case lval::MemRegionKind:
- case lval::FuncValKind:
- case lval::GotoLabelKind:
- case lval::StringLiteralValKind:
- isFeasible = Assumption;
- return St;
-
- case lval::FieldOffsetKind:
- return AssumeAux(St, cast<lval::FieldOffset>(Cond).getBase(),
- Assumption, isFeasible);
-
- case lval::ArrayOffsetKind:
- return AssumeAux(St, cast<lval::ArrayOffset>(Cond).getBase(),
- Assumption, isFeasible);
-
- case lval::ConcreteIntKind: {
- bool b = cast<lval::ConcreteInt>(Cond).getValue() != 0;
- isFeasible = b ? Assumption : !Assumption;
- return St;
- }
- } // end switch
-}
-
-const GRState*
-BasicConstraintManager::Assume(const GRState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible) {
- St = AssumeAux(St, Cond, Assumption, isFeasible);
- // TF->EvalAssume() does nothing now.
- return St;
-}
-
-const GRState*
-BasicConstraintManager::AssumeAux(const GRState* St,NonLVal Cond,
- bool Assumption, bool& isFeasible) {
- BasicValueFactory& BasicVals = StateMgr.getBasicVals();
- SymbolManager& SymMgr = StateMgr.getSymbolManager();
-
- switch (Cond.getSubKind()) {
- default:
- assert(false && "'Assume' not implemented for this NonLVal");
-
- case nonlval::SymbolValKind: {
- nonlval::SymbolVal& SV = cast<nonlval::SymbolVal>(Cond);
- SymbolID sym = SV.getSymbol();
-
- if (Assumption)
- return AssumeSymNE(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
- isFeasible);
- else
- return AssumeSymEQ(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
- isFeasible);
- }
-
- case nonlval::SymIntConstraintValKind:
- return
- AssumeSymInt(St, Assumption,
- cast<nonlval::SymIntConstraintVal>(Cond).getConstraint(),
- isFeasible);
-
- case nonlval::ConcreteIntKind: {
- bool b = cast<nonlval::ConcreteInt>(Cond).getValue() != 0;
- isFeasible = b ? Assumption : !Assumption;
- return St;
- }
-
- case nonlval::LValAsIntegerKind:
- return AssumeAux(St, cast<nonlval::LValAsInteger>(Cond).getLVal(),
- Assumption, isFeasible);
- } // end switch
-}
-
-const GRState*
-BasicConstraintManager::AssumeSymInt(const GRState* St, bool Assumption,
- const SymIntConstraint& C, bool& isFeasible) {
-
- switch (C.getOpcode()) {
- default:
- // No logic yet for other operators.
- isFeasible = true;
- return St;
-
- case BinaryOperator::EQ:
- if (Assumption)
- return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
- else
- return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
-
- case BinaryOperator::NE:
- if (Assumption)
- return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
- else
- return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
-
- case BinaryOperator::GT:
- if (Assumption)
- return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
- else
- return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
-
- case BinaryOperator::GE:
- if (Assumption)
- return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
- else
- return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
-
- case BinaryOperator::LT:
- if (Assumption)
- return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
- else
- return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
-
- case BinaryOperator::LE:
- if (Assumption)
- return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
- else
- return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
- } // end switch
-}
-
-
-
-const GRState*
-BasicConstraintManager::AssumeSymNE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
- // First, determine if sym == X, where X != V.
- if (const llvm::APSInt* X = getSymVal(St, sym)) {
- isFeasible = (*X != V);
- return St;
- }
-
- // Second, determine if sym != V.
- if (isNotEqual(St, sym, V)) {
- isFeasible = true;
- return St;
- }
-
- // If we reach here, sym is not a constant and we don't know if it is != V.
- // Make that assumption.
- isFeasible = true;
- return AddNE(St, sym, V);
-}
-
-const GRState*
-BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
- // First, determine if sym == X, where X != V.
- if (const llvm::APSInt* X = getSymVal(St, sym)) {
- isFeasible = *X == V;
- return St;
- }
-
- // Second, determine if sym != V.
- if (isNotEqual(St, sym, V)) {
- isFeasible = false;
- return St;
- }
-
- // If we reach here, sym is not a constant and we don't know if it is == V.
- // Make that assumption.
-
- isFeasible = true;
- return AddEQ(St, sym, V);
-}
-
-// These logic will be handled in another ConstraintManager.
-const GRState*
-BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
- // FIXME: For now have assuming x < y be the same as assuming sym != V;
- return AssumeSymNE(St, sym, V, isFeasible);
-}
-
-const GRState*
-BasicConstraintManager::AssumeSymGT(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
- // FIXME: For now have assuming x > y be the same as assuming sym != V;
- return AssumeSymNE(St, sym, V, isFeasible);
-}
-
-const GRState*
-BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
- // Reject a path if the value of sym is a constant X and !(X >= V).
- if (const llvm::APSInt* X = getSymVal(St, sym)) {
- isFeasible = *X >= V;
- return St;
- }
-
- isFeasible = !isNotEqual(St, sym, V) ||
- (V != llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned()));
-
- return St;
-}
-
-const GRState*
-BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
- // FIXME: Primitive logic for now. Only reject a path if the value of
- // sym is a constant X and !(X <= V).
-
- if (const llvm::APSInt* X = getSymVal(St, sym)) {
- isFeasible = *X <= V;
- return St;
- }
-
- isFeasible = !isNotEqual(St, sym, V) ||
- (V != llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned()));
-
- return St;
-}
-
-static int ConstEqTyIndex = 0;
-static int ConstNotEqTyIndex = 0;
-
-namespace clang {
- template<>
- struct GRStateTrait<ConstNotEqTy> : public GRStatePartialTrait<ConstNotEqTy> {
- static inline void* GDMIndex() { return &ConstNotEqTyIndex; }
- };
-
- template<>
- struct GRStateTrait<ConstEqTy> : public GRStatePartialTrait<ConstEqTy> {
- static inline void* GDMIndex() { return &ConstEqTyIndex; }
- };
-}
-
-const GRState* BasicConstraintManager::AddEQ(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) {
- // Create a new state with the old binding replaced.
- GRStateRef state(St, StateMgr);
- return state.set<ConstEqTy>(sym, &V);
-}
-
-const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) {
- GRState::IntSetTy::Factory ISetFactory(StateMgr.getAllocator());
- GRStateRef state(St, StateMgr);
-
- // First, retrieve the NE-set associated with the given symbol.
- ConstNotEqTy::data_type* T = state.get<ConstNotEqTy>(sym);
- GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
-
-
- // Now add V to the NE set.
- S = ISetFactory.Add(S, &V);
-
- // Create a new state with the old binding replaced.
- return state.set<ConstNotEqTy>(sym, S);
-}
-
-const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St,
- SymbolID sym) {
- const ConstEqTy::data_type* T = St->get<ConstEqTy>(sym);
- return T ? *T : NULL;
-}
-
-bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) const {
-
- // Retrieve the NE-set associated with the given symbol.
- const ConstNotEqTy::data_type* T = St->get<ConstNotEqTy>(sym);
-
- // See if V is present in the NE-set.
- return T ? T->contains(&V) : false;
-}
-
-bool BasicConstraintManager::isEqual(const GRState* St, SymbolID sym,
- const llvm::APSInt& V) const {
- // Retrieve the EQ-set associated with the given symbol.
- const ConstEqTy::data_type* T = St->get<ConstEqTy>(sym);
- // See if V is present in the EQ-set.
- return T ? **T == V : false;
-}
-
-const GRState* BasicConstraintManager::RemoveDeadBindings(const GRState* St,
- StoreManager::LiveSymbolsTy& LSymbols,
- StoreManager::DeadSymbolsTy& DSymbols) {
- GRStateRef state(St, StateMgr);
- ConstEqTy CE = state.get<ConstEqTy>();
- ConstEqTy::Factory& CEFactory = state.get_context<ConstEqTy>();
-
- for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
- SymbolID sym = I.getKey();
- if (!LSymbols.count(sym)) {
- DSymbols.insert(sym);
- CE = CEFactory.Remove(CE, sym);
- }
- }
- state = state.set<ConstEqTy>(CE);
-
- ConstNotEqTy CNE = state.get<ConstNotEqTy>();
- ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEqTy>();
-
- for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
- SymbolID sym = I.getKey();
- if (!LSymbols.count(sym)) {
- DSymbols.insert(sym);
- CNE = CNEFactory.Remove(CNE, sym);
- }
- }
-
- return state.set<ConstNotEqTy>(CNE);
-}
-
-void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
- const char* nl, const char *sep) {
- // Print equality constraints.
-
- ConstEqTy CE = St->get<ConstEqTy>();
-
- if (!CE.isEmpty()) {
- Out << nl << sep << "'==' constraints:";
-
- for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
- Out << nl << " $" << I.getKey();
- llvm::raw_os_ostream OS(Out);
- OS << " : " << *I.getData();
- }
- }
-
- // Print != constraints.
-
- ConstNotEqTy CNE = St->get<ConstNotEqTy>();
-
- if (!CNE.isEmpty()) {
- Out << nl << sep << "'!=' constraints:";
-
- for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
- Out << nl << " $" << I.getKey() << " : ";
- bool isFirst = true;
-
- GRState::IntSetTy::iterator J = I.getData().begin(),
- EJ = I.getData().end();
-
- for ( ; J != EJ; ++J) {
- if (isFirst) isFirst = false;
- else Out << ", ";
-
- Out << *J;
- }
- }
- }
-}
diff --git a/clang/lib/Analysis/BasicObjCFoundationChecks.cpp b/clang/lib/Analysis/BasicObjCFoundationChecks.cpp
deleted file mode 100644
index b3f534d1af01..000000000000
--- a/clang/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-//== BasicObjCFoundationChecks.cpp - Simple Apple-Foundation checks -*- 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 BasicObjCFoundationChecks, a class that encapsulates
-// a set of simple checks to run on Objective-C code using Apple's Foundation
-// classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "BasicObjCFoundationChecks.h"
-
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/LocalCheckers.h"
-
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/Support/Compiler.h"
-
-#include <sstream>
-
-using namespace clang;
-
-static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
- Expr* Receiver = ME->getReceiver();
-
- if (!Receiver)
- return NULL;
-
- QualType X = Receiver->getType();
-
- if (X->isPointerType()) {
- Type* TP = X.getTypePtr();
- const PointerType* T = TP->getAsPointerType();
- return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
- }
-
- // FIXME: Support ObjCQualifiedIdType?
- return NULL;
-}
-
-static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
- ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
- return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
- : NULL;
-}
-
-namespace {
-
-class VISIBILITY_HIDDEN APIMisuse : public BugTypeCacheLocation {
-public:
- const char* getCategory() const {
- return "API Misuse (Apple)";
- }
-};
-
-class VISIBILITY_HIDDEN NilArg : public APIMisuse {
-public:
- virtual ~NilArg() {}
-
- virtual const char* getName() const {
- return "nil argument";
- }
-
- class Report : public BugReport {
- std::string Msg;
- const char* s;
- SourceRange R;
- public:
-
- Report(NilArg& Desc, ExplodedNode<GRState>* N,
- ObjCMessageExpr* ME, unsigned Arg)
- : BugReport(Desc, N) {
-
- Expr* E = ME->getArg(Arg);
- R = E->getSourceRange();
-
- std::ostringstream os;
-
- os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
- << ME->getSelector().getName() << "' cannot be nil.";
-
- Msg = os.str();
- s = Msg.c_str();
- }
-
- virtual ~Report() {}
-
- virtual const char* getDescription() const { return s; }
-
- virtual void getRanges(BugReporter& BR,
- const SourceRange*& B, const SourceRange*& E) {
- B = &R;
- E = B+1;
- }
- };
-};
-
-
-class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck {
- NilArg Desc;
- ASTContext &Ctx;
- GRStateManager* VMgr;
-
- typedef std::vector<BugReport*> ErrorsTy;
- ErrorsTy Errors;
-
- RVal GetRVal(const GRState* St, Expr* E) { return VMgr->GetRVal(St, E); }
-
- bool isNSString(ObjCInterfaceType* T, const char* suffix);
- bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
-
- void Warn(NodeTy* N, Expr* E, const std::string& s);
- void WarnNilArg(NodeTy* N, Expr* E);
-
- bool CheckNilArg(NodeTy* N, unsigned Arg);
-
-public:
- BasicObjCFoundationChecks(ASTContext& ctx, GRStateManager* vmgr)
- : Ctx(ctx), VMgr(vmgr) {}
-
- virtual ~BasicObjCFoundationChecks() {
- for (ErrorsTy::iterator I = Errors.begin(), E = Errors.end(); I!=E; ++I)
- delete *I;
- }
-
- virtual bool Audit(ExplodedNode<GRState>* N, GRStateManager&);
-
- virtual void EmitWarnings(BugReporter& BR);
-
-private:
-
- void AddError(BugReport* R) {
- Errors.push_back(R);
- }
-
- void WarnNilArg(NodeTy* N, ObjCMessageExpr* ME, unsigned Arg) {
- AddError(new NilArg::Report(Desc, N, ME, Arg));
- }
-};
-
-} // end anonymous namespace
-
-
-GRSimpleAPICheck*
-clang::CreateBasicObjCFoundationChecks(ASTContext& Ctx,
- GRStateManager* VMgr) {
-
- return new BasicObjCFoundationChecks(Ctx, VMgr);
-}
-
-
-
-bool BasicObjCFoundationChecks::Audit(ExplodedNode<GRState>* N,
- GRStateManager&) {
-
- ObjCMessageExpr* ME =
- cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
-
- ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
-
- if (!ReceiverType)
- return false;
-
- const char* name = ReceiverType->getDecl()->getIdentifier()->getName();
-
- if (!name)
- return false;
-
- if (name[0] != 'N' || name[1] != 'S')
- return false;
-
- name += 2;
-
- // FIXME: Make all of this faster.
-
- if (isNSString(ReceiverType, name))
- return AuditNSString(N, ME);
-
- return false;
-}
-
-static inline bool isNil(RVal X) {
- return isa<lval::ConcreteInt>(X);
-}
-
-//===----------------------------------------------------------------------===//
-// Error reporting.
-//===----------------------------------------------------------------------===//
-
-
-void BasicObjCFoundationChecks::EmitWarnings(BugReporter& BR) {
-
- for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I)
- BR.EmitWarning(**I);
-}
-
-bool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) {
- ObjCMessageExpr* ME =
- cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
-
- Expr * E = ME->getArg(Arg);
-
- if (isNil(GetRVal(N->getState(), E))) {
- WarnNilArg(N, ME, Arg);
- return true;
- }
-
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-// NSString checking.
-//===----------------------------------------------------------------------===//
-
-bool BasicObjCFoundationChecks::isNSString(ObjCInterfaceType* T,
- const char* suffix) {
-
- return !strcmp("String", suffix) || !strcmp("MutableString", suffix);
-}
-
-bool BasicObjCFoundationChecks::AuditNSString(NodeTy* N,
- ObjCMessageExpr* ME) {
-
- Selector S = ME->getSelector();
-
- if (S.isUnarySelector())
- return false;
-
- // FIXME: This is going to be really slow doing these checks with
- // lexical comparisons.
-
- std::string name = S.getName();
- assert (!name.empty());
- const char* cstr = &name[0];
- unsigned len = name.size();
-
- switch (len) {
- default:
- break;
- case 8:
- if (!strcmp(cstr, "compare:"))
- return CheckNilArg(N, 0);
-
- break;
-
- case 15:
- // FIXME: Checking for initWithFormat: will not work in most cases
- // yet because [NSString alloc] returns id, not NSString*. We will
- // need support for tracking expected-type information in the analyzer
- // to find these errors.
- if (!strcmp(cstr, "initWithFormat:"))
- return CheckNilArg(N, 0);
-
- break;
-
- case 16:
- if (!strcmp(cstr, "compare:options:"))
- return CheckNilArg(N, 0);
-
- break;
-
- case 22:
- if (!strcmp(cstr, "compare:options:range:"))
- return CheckNilArg(N, 0);
-
- break;
-
- case 23:
-
- if (!strcmp(cstr, "caseInsensitiveCompare:"))
- return CheckNilArg(N, 0);
-
- break;
-
- case 29:
- if (!strcmp(cstr, "compare:options:range:locale:"))
- return CheckNilArg(N, 0);
-
- break;
-
- case 37:
- if (!strcmp(cstr, "componentsSeparatedByCharactersInSet:"))
- return CheckNilArg(N, 0);
-
- break;
- }
-
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Error reporting.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN BadCFNumberCreate : public APIMisuse{
-public:
- typedef std::vector<BugReport*> AllErrorsTy;
- AllErrorsTy AllErrors;
-
- virtual const char* getName() const {
- return "Bad use of CFNumberCreate";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- // FIXME: Refactor this method.
- for (AllErrorsTy::iterator I=AllErrors.begin(), E=AllErrors.end(); I!=E;++I)
- BR.EmitWarning(**I);
- }
-};
-
- // FIXME: This entire class should be refactored into the common
- // BugReporter classes.
-class VISIBILITY_HIDDEN StrBugReport : public RangedBugReport {
- std::string str;
- const char* cstr;
-public:
- StrBugReport(BugType& D, ExplodedNode<GRState>* N, std::string s)
- : RangedBugReport(D, N), str(s) {
- cstr = str.c_str();
- }
-
- virtual const char* getDescription() const { return cstr; }
-};
-
-
-class VISIBILITY_HIDDEN AuditCFNumberCreate : public GRSimpleAPICheck {
- // FIXME: Who should own this?
- BadCFNumberCreate Desc;
-
- // FIXME: Either this should be refactored into GRSimpleAPICheck, or
- // it should always be passed with a call to Audit. The latter
- // approach makes this class more stateless.
- ASTContext& Ctx;
- IdentifierInfo* II;
- GRStateManager* VMgr;
-
- RVal GetRVal(const GRState* St, Expr* E) { return VMgr->GetRVal(St, E); }
-
-public:
-
- AuditCFNumberCreate(ASTContext& ctx, GRStateManager* vmgr)
- : Ctx(ctx), II(&Ctx.Idents.get("CFNumberCreate")), VMgr(vmgr) {}
-
- virtual ~AuditCFNumberCreate() {}
-
- virtual bool Audit(ExplodedNode<GRState>* N, GRStateManager&);
-
- virtual void EmitWarnings(BugReporter& BR) {
- Desc.EmitWarnings(BR);
- }
-
-private:
-
- void AddError(TypedRegion* R, Expr* Ex, ExplodedNode<GRState> *N,
- uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
-};
-} // end anonymous namespace
-
-enum CFNumberType {
- kCFNumberSInt8Type = 1,
- kCFNumberSInt16Type = 2,
- kCFNumberSInt32Type = 3,
- kCFNumberSInt64Type = 4,
- kCFNumberFloat32Type = 5,
- kCFNumberFloat64Type = 6,
- kCFNumberCharType = 7,
- kCFNumberShortType = 8,
- kCFNumberIntType = 9,
- kCFNumberLongType = 10,
- kCFNumberLongLongType = 11,
- kCFNumberFloatType = 12,
- kCFNumberDoubleType = 13,
- kCFNumberCFIndexType = 14,
- kCFNumberNSIntegerType = 15,
- kCFNumberCGFloatType = 16
-};
-
-namespace {
- template<typename T>
- class Optional {
- bool IsKnown;
- T Val;
- public:
- Optional() : IsKnown(false), Val(0) {}
- Optional(const T& val) : IsKnown(true), Val(val) {}
-
- bool isKnown() const { return IsKnown; }
-
- const T& getValue() const {
- assert (isKnown());
- return Val;
- }
-
- operator const T&() const {
- return getValue();
- }
- };
-}
-
-static Optional<uint64_t> GetCFNumberSize(ASTContext& Ctx, uint64_t i) {
- static unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };
-
- if (i < kCFNumberCharType)
- return FixedSize[i-1];
-
- QualType T;
-
- switch (i) {
- case kCFNumberCharType: T = Ctx.CharTy; break;
- case kCFNumberShortType: T = Ctx.ShortTy; break;
- case kCFNumberIntType: T = Ctx.IntTy; break;
- case kCFNumberLongType: T = Ctx.LongTy; break;
- case kCFNumberLongLongType: T = Ctx.LongLongTy; break;
- case kCFNumberFloatType: T = Ctx.FloatTy; break;
- case kCFNumberDoubleType: T = Ctx.DoubleTy; break;
- case kCFNumberCFIndexType:
- case kCFNumberNSIntegerType:
- case kCFNumberCGFloatType:
- // FIXME: We need a way to map from names to Type*.
- default:
- return Optional<uint64_t>();
- }
-
- return Ctx.getTypeSize(T);
-}
-
-#if 0
-static const char* GetCFNumberTypeStr(uint64_t i) {
- static const char* Names[] = {
- "kCFNumberSInt8Type",
- "kCFNumberSInt16Type",
- "kCFNumberSInt32Type",
- "kCFNumberSInt64Type",
- "kCFNumberFloat32Type",
- "kCFNumberFloat64Type",
- "kCFNumberCharType",
- "kCFNumberShortType",
- "kCFNumberIntType",
- "kCFNumberLongType",
- "kCFNumberLongLongType",
- "kCFNumberFloatType",
- "kCFNumberDoubleType",
- "kCFNumberCFIndexType",
- "kCFNumberNSIntegerType",
- "kCFNumberCGFloatType"
- };
-
- return i <= kCFNumberCGFloatType ? Names[i-1] : "Invalid CFNumberType";
-}
-#endif
-
-bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
- CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
- Expr* Callee = CE->getCallee();
- RVal CallV = GetRVal(N->getState(), Callee);
- lval::FuncVal* FuncV = dyn_cast<lval::FuncVal>(&CallV);
-
- if (!FuncV || FuncV->getDecl()->getIdentifier() != II || CE->getNumArgs()!=3)
- return false;
-
- // Get the value of the "theType" argument.
- RVal TheTypeVal = GetRVal(N->getState(), CE->getArg(1));
-
- // FIXME: We really should allow ranges of valid theType values, and
- // bifurcate the state appropriately.
- nonlval::ConcreteInt* V = dyn_cast<nonlval::ConcreteInt>(&TheTypeVal);
-
- if (!V)
- return false;
-
- uint64_t NumberKind = V->getValue().getLimitedValue();
- Optional<uint64_t> TargetSize = GetCFNumberSize(Ctx, NumberKind);
-
- // FIXME: In some cases we can emit an error.
- if (!TargetSize.isKnown())
- return false;
-
- // Look at the value of the integer being passed by reference. Essentially
- // we want to catch cases where the value passed in is not equal to the
- // size of the type being created.
- RVal TheValueExpr = GetRVal(N->getState(), CE->getArg(2));
-
- // FIXME: Eventually we should handle arbitrary locations. We can do this
- // by having an enhanced memory model that does low-level typing.
- lval::MemRegionVal* LV = dyn_cast<lval::MemRegionVal>(&TheValueExpr);
-
- if (!LV)
- return false;
-
- TypedRegion* R = dyn_cast<TypedRegion>(LV->getRegion());
- if (!R)
- return false;
-
-
- QualType T = Ctx.getCanonicalType(R->getType());
-
- // FIXME: If the pointee isn't an integer type, should we flag a warning?
- // People can do weird stuff with pointers.
-
- if (!T->isIntegerType())
- return false;
-
- uint64_t SourceSize = Ctx.getTypeSize(T);
-
- // CHECK: is SourceSize == TargetSize
-
- if (SourceSize == TargetSize)
- return false;
-
- AddError(R, CE->getArg(2), N, SourceSize, TargetSize, NumberKind);
-
- // FIXME: We can actually create an abstract "CFNumber" object that has
- // the bits initialized to the provided values.
- return SourceSize < TargetSize;
-}
-
-void AuditCFNumberCreate::AddError(TypedRegion* R, Expr* Ex,
- ExplodedNode<GRState> *N,
- uint64_t SourceSize, uint64_t TargetSize,
- uint64_t NumberKind) {
-
- std::ostringstream os;
-
- os << (SourceSize == 8 ? "An " : "A ")
- << SourceSize << " bit integer is used to initialize a CFNumber "
- "object that represents "
- << (TargetSize == 8 ? "an " : "a ")
- << TargetSize << " bit integer. ";
-
- if (SourceSize < TargetSize)
- os << (TargetSize - SourceSize)
- << " bits of the CFNumber value will be garbage." ;
- else
- os << (SourceSize - TargetSize)
- << " bits of the input integer will be lost.";
-
- StrBugReport* B = new StrBugReport(Desc, N, os.str());
- B->addRange(Ex->getSourceRange());
- Desc.AllErrors.push_back(B);
-}
-
-GRSimpleAPICheck*
-clang::CreateAuditCFNumberCreate(ASTContext& Ctx,
- GRStateManager* VMgr) {
-
- return new AuditCFNumberCreate(Ctx, VMgr);
-}
-
-//===----------------------------------------------------------------------===//
-// Check registration.
-
-void clang::RegisterAppleChecks(GRExprEngine& Eng) {
- ASTContext& Ctx = Eng.getContext();
- GRStateManager* VMgr = &Eng.getStateManager();
-
- Eng.AddCheck(CreateBasicObjCFoundationChecks(Ctx, VMgr),
- Stmt::ObjCMessageExprClass);
-
- Eng.AddCheck(CreateAuditCFNumberCreate(Ctx, VMgr),
- Stmt::CallExprClass);
-
- Eng.Register(CreateNSErrorCheck());
-}
diff --git a/clang/lib/Analysis/BasicObjCFoundationChecks.h b/clang/lib/Analysis/BasicObjCFoundationChecks.h
deleted file mode 100644
index 3ad2ca57aa33..000000000000
--- a/clang/lib/Analysis/BasicObjCFoundationChecks.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//== BasicObjCFoundationChecks.h - Simple Apple-Foundation checks -*- 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 BasicObjCFoundationChecks, a class that encapsulates
-// a set of simple checks to run on Objective-C code using Apple's Foundation
-// classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/Support/Compiler.h"
-
-#ifndef LLVM_CLANG_ANALYSIS_BASICOBJCFOUNDATIONCHECKS
-#define LLVM_CLANG_ANALYSIS_BASICOBJCFOUNDATIONCHECKS
-
-namespace clang {
-
-class GRSimpleAPICheck;
-class ASTContext;
-class GRStateManager;
-class BugType;
-
-GRSimpleAPICheck* CreateBasicObjCFoundationChecks(ASTContext& Ctx,
- GRStateManager* VMgr);
-
-GRSimpleAPICheck* CreateAuditCFNumberCreate(ASTContext& Ctx,
- GRStateManager* VMgr);
-
-BugType* CreateNSErrorCheck();
-
-} // end clang namespace
-
-#endif
diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp
deleted file mode 100644
index 47e2905e02b2..000000000000
--- a/clang/lib/Analysis/BasicStore.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-//== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the BasicStore and BasicStoreManager classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Streams.h"
-
-using namespace clang;
-
-typedef llvm::ImmutableMap<const VarDecl*,RVal> VarBindingsTy;
-
-namespace {
-
-class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
- VarBindingsTy::Factory VBFactory;
- GRStateManager& StateMgr;
- MemRegionManager MRMgr;
-
-public:
- BasicStoreManager(GRStateManager& mgr)
- : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {}
-
- virtual ~BasicStoreManager() {}
-
- virtual RVal GetRVal(Store St, LVal LV, QualType T);
- virtual Store SetRVal(Store St, LVal LV, RVal V);
- virtual Store Remove(Store St, LVal LV);
-
- virtual Store getInitialStore();
-
- virtual MemRegionManager& getRegionManager() { return MRMgr; }
-
- virtual LVal getLVal(const VarDecl* VD) {
- return lval::MemRegionVal(MRMgr.getVarRegion(VD));
- }
-
- virtual Store
- RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
- LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols);
-
- virtual void iterBindings(Store store, BindingsHandler& f);
-
- virtual Store AddDecl(Store store,
- const VarDecl* VD, Expr* Ex,
- RVal InitVal = UndefinedVal(), unsigned Count = 0);
-
- static inline VarBindingsTy GetVarBindings(Store store) {
- return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
- }
-
- virtual void print(Store store, std::ostream& Out,
- const char* nl, const char *sep);
-
-};
-
-} // end anonymous namespace
-
-
-StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
- return new BasicStoreManager(StMgr);
-}
-
-RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
-
- if (isa<UnknownVal>(LV))
- return UnknownVal();
-
- assert (!isa<UndefinedVal>(LV));
-
- switch (LV.getSubKind()) {
-
- case lval::MemRegionKind: {
- VarRegion* R =
- dyn_cast<VarRegion>(cast<lval::MemRegionVal>(LV).getRegion());
-
- if (!R)
- return UnknownVal();
-
- VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
- VarBindingsTy::data_type* T = B.lookup(R->getDecl());
- return T ? *T : UnknownVal();
- }
-
- case lval::SymbolValKind:
- return UnknownVal();
-
- case lval::ConcreteIntKind:
- // Some clients may call GetRVal with such an option simply because
- // they are doing a quick scan through their LVals (potentially to
- // invalidate their bindings). Just return Undefined.
- return UndefinedVal();
-
- case lval::ArrayOffsetKind:
- case lval::FieldOffsetKind:
- return UnknownVal();
-
- case lval::FuncValKind:
- return LV;
-
- case lval::StringLiteralValKind:
- // FIXME: Implement better support for fetching characters from strings.
- return UnknownVal();
-
- default:
- assert (false && "Invalid LVal.");
- break;
- }
-
- return UnknownVal();
-}
-
-Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
- switch (LV.getSubKind()) {
- case lval::MemRegionKind: {
- VarRegion* R =
- dyn_cast<VarRegion>(cast<lval::MemRegionVal>(LV).getRegion());
-
- if (!R)
- return store;
-
- VarBindingsTy B = GetVarBindings(store);
- return V.isUnknown()
- ? VBFactory.Remove(B, R->getDecl()).getRoot()
- : VBFactory.Add(B, R->getDecl(), V).getRoot();
- }
- default:
- assert ("SetRVal for given LVal type not yet implemented.");
- return store;
- }
-}
-
-Store BasicStoreManager::Remove(Store store, LVal LV) {
- switch (LV.getSubKind()) {
- case lval::MemRegionKind: {
- VarRegion* R =
- dyn_cast<VarRegion>(cast<lval::MemRegionVal>(LV).getRegion());
-
- if (!R)
- return store;
-
- VarBindingsTy B = GetVarBindings(store);
- return VBFactory.Remove(B,R->getDecl()).getRoot();
- }
- default:
- assert ("Remove for given LVal type not yet implemented.");
- return store;
- }
-}
-
-Store
-BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
- const LiveVariables& Liveness,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
- LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) {
-
- VarBindingsTy B = GetVarBindings(store);
- typedef RVal::symbol_iterator symbol_iterator;
-
- // Iterate over the variable bindings.
- for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
- if (Liveness.isLive(Loc, I.getKey())) {
- RegionRoots.push_back(MRMgr.getVarRegion(I.getKey()));
- RVal X = I.getData();
-
- for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
- LSymbols.insert(*SI);
- }
-
- // Scan for live variables and live symbols.
- llvm::SmallPtrSet<const VarRegion*, 10> Marked;
-
- while (!RegionRoots.empty()) {
- const VarRegion* R = cast<VarRegion>(RegionRoots.back());
- RegionRoots.pop_back();
-
- if (Marked.count(R))
- continue;
-
- Marked.insert(R);
- // FIXME: Do we need the QualType here, since regions are partially
- // typed?
- RVal X = GetRVal(store, lval::MemRegionVal(R), QualType());
-
- for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
- LSymbols.insert(*SI);
-
- if (!isa<lval::MemRegionVal>(X))
- continue;
-
- const lval::MemRegionVal& LVD = cast<lval::MemRegionVal>(X);
- RegionRoots.push_back(cast<VarRegion>(LVD.getRegion()));
- }
-
- // Remove dead variable bindings.
- for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
- const VarRegion* R = cast<VarRegion>(MRMgr.getVarRegion(I.getKey()));
-
- if (!Marked.count(R)) {
- store = Remove(store, lval::MemRegionVal(R));
- RVal X = I.getData();
-
- for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
- if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
- }
- }
-
- return store;
-}
-
-Store BasicStoreManager::getInitialStore() {
- // The LiveVariables information already has a compilation of all VarDecls
- // used in the function. Iterate through this set, and "symbolicate"
- // any VarDecl whose value originally comes from outside the function.
-
- typedef LiveVariables::AnalysisDataTy LVDataTy;
- LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
-
- Store St = VBFactory.GetEmptyMap().getRoot();
-
- for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
- ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
-
- if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
- // Punt on static variables for now.
- if (VD->getStorageClass() == VarDecl::Static)
- continue;
-
- // Only handle pointers and integers for now.
- QualType T = VD->getType();
- if (LVal::IsLValType(T) || T->isIntegerType()) {
- // Initialize globals and parameters to symbolic values.
- // Initialize local variables to undefined.
- RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
- isa<ImplicitParamDecl>(VD))
- ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
- : UndefinedVal();
-
- St = SetRVal(St, lval::MemRegionVal(MRMgr.getVarRegion(VD)), X);
- }
- }
- }
- return St;
-}
-
-Store BasicStoreManager::AddDecl(Store store,
- const VarDecl* VD, Expr* Ex,
- RVal InitVal, unsigned Count) {
-
- BasicValueFactory& BasicVals = StateMgr.getBasicVals();
- SymbolManager& SymMgr = StateMgr.getSymbolManager();
-
- // BasicStore does not model arrays and structs.
- if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
- return store;
-
- if (VD->hasGlobalStorage()) {
- // Handle variables with global storage: extern, static, PrivateExtern.
-
- // FIXME:: static variables may have an initializer, but the second time a
- // function is called those values may not be current. Currently, a function
- // will not be called more than once.
-
- // Static global variables should not be visited here.
- assert(!(VD->getStorageClass() == VarDecl::Static &&
- VD->isFileVarDecl()));
-
- // Process static variables.
- if (VD->getStorageClass() == VarDecl::Static) {
- // C99: 6.7.8 Initialization
- // If an object that has static storage duration is not initialized
- // explicitly, then:
- // —if it has pointer type, it is initialized to a null pointer;
- // —if it has arithmetic type, it is initialized to (positive or
- // unsigned) zero;
- if (!Ex) {
- QualType T = VD->getType();
- if (LVal::IsLValType(T))
- store = SetRVal(store, getLVal(VD),
- lval::ConcreteInt(BasicVals.getValue(0, T)));
- else if (T->isIntegerType())
- store = SetRVal(store, getLVal(VD),
- nonlval::ConcreteInt(BasicVals.getValue(0, T)));
- else {
- // assert(0 && "ignore other types of variables");
- }
- } else {
- store = SetRVal(store, getLVal(VD), InitVal);
- }
- }
- } else {
- // Process local scalar variables.
- QualType T = VD->getType();
- if (LVal::IsLValType(T) || T->isIntegerType()) {
- RVal V = Ex ? InitVal : UndefinedVal();
-
- if (Ex && InitVal.isUnknown()) {
- // EXPERIMENTAL: "Conjured" symbols.
- SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
-
- V = LVal::IsLValType(Ex->getType())
- ? cast<RVal>(lval::SymbolVal(Sym))
- : cast<RVal>(nonlval::SymbolVal(Sym));
- }
-
- store = SetRVal(store, getLVal(VD), V);
- }
- }
-
- return store;
-}
-
-void BasicStoreManager::print(Store store, std::ostream& Out,
- const char* nl, const char *sep) {
-
- VarBindingsTy B = GetVarBindings(store);
- Out << "Variables:" << nl;
-
- bool isFirst = true;
-
- for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
- if (isFirst) isFirst = false;
- else Out << nl;
-
- Out << ' ' << I.getKey()->getName() << " : ";
- I.getData().print(Out);
- }
-}
-
-
-void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
- VarBindingsTy B = GetVarBindings(store);
-
- for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
-
- f.HandleBinding(*this, store, MRMgr.getVarRegion(I.getKey()),I.getData());
- }
-}
-
-StoreManager::BindingsHandler::~BindingsHandler() {}
diff --git a/clang/lib/Analysis/BasicValueFactory.cpp b/clang/lib/Analysis/BasicValueFactory.cpp
deleted file mode 100644
index a9bb2cec4bda..000000000000
--- a/clang/lib/Analysis/BasicValueFactory.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
-// of APSInt objects and symbolic constraints used by GRExprEngine
-// and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
-#include "clang/Analysis/PathSensitive/RValues.h"
-
-using namespace clang;
-
-typedef std::pair<RVal, uintptr_t> RValData;
-typedef std::pair<RVal, RVal> RValPair;
-
-
-namespace llvm {
-template<> struct FoldingSetTrait<RValData> {
- static inline void Profile(const RValData& X, llvm::FoldingSetNodeID& ID) {
- X.first.Profile(ID);
- ID.AddPointer( (void*) X.second);
- }
-};
-
-template<> struct FoldingSetTrait<RValPair> {
- static inline void Profile(const RValPair& X, llvm::FoldingSetNodeID& ID) {
- X.first.Profile(ID);
- X.second.Profile(ID);
- }
-};
-}
-
-typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<RValData> >
- PersistentRValsTy;
-
-typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<RValPair> >
- PersistentRValPairsTy;
-
-BasicValueFactory::~BasicValueFactory() {
- // Note that the dstor for the contents of APSIntSet will never be called,
- // so we iterate over the set and invoke the dstor for each APSInt. This
- // frees an aux. memory allocated to represent very large constants.
- for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
- I->getValue().~APSInt();
-
- delete (PersistentRValsTy*) PersistentRVals;
- delete (PersistentRValPairsTy*) PersistentRValPairs;
-}
-
-const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
- llvm::FoldingSetNodeID ID;
- void* InsertPos;
- typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
-
- X.Profile(ID);
- FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
-
- if (!P) {
- P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
- new (P) FoldNodeTy(X);
- APSIntSet.InsertNode(P, InsertPos);
- }
-
- return *P;
-}
-
-const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
- bool isUnsigned) {
- llvm::APSInt V(BitWidth, isUnsigned);
- V = X;
- return getValue(V);
-}
-
-const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
-
- unsigned bits = Ctx.getTypeSize(T);
- llvm::APSInt V(bits, T->isUnsignedIntegerType());
- V = X;
- return getValue(V);
-}
-
-const SymIntConstraint&
-BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
- const llvm::APSInt& V) {
-
- llvm::FoldingSetNodeID ID;
- SymIntConstraint::Profile(ID, sym, Op, V);
- void* InsertPos;
-
- SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
-
- if (!C) {
- C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
- new (C) SymIntConstraint(sym, Op, V);
- SymIntCSet.InsertNode(C, InsertPos);
- }
-
- return *C;
-}
-
-const llvm::APSInt*
-BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1, const llvm::APSInt& V2) {
-
- switch (Op) {
- default:
- assert (false && "Invalid Opcode.");
-
- case BinaryOperator::Mul:
- return &getValue( V1 * V2 );
-
- case BinaryOperator::Div:
- return &getValue( V1 / V2 );
-
- case BinaryOperator::Rem:
- return &getValue( V1 % V2 );
-
- case BinaryOperator::Add:
- return &getValue( V1 + V2 );
-
- case BinaryOperator::Sub:
- return &getValue( V1 - V2 );
-
- case BinaryOperator::Shl: {
-
- // FIXME: This logic should probably go higher up, where we can
- // test these conditions symbolically.
-
- // FIXME: Expand these checks to include all undefined behavior.
-
- if (V2.isSigned() && V2.isNegative())
- return NULL;
-
- uint64_t Amt = V2.getZExtValue();
-
- if (Amt > V1.getBitWidth())
- return NULL;
-
- return &getValue( V1.operator<<( (unsigned) Amt ));
- }
-
- case BinaryOperator::Shr: {
-
- // FIXME: This logic should probably go higher up, where we can
- // test these conditions symbolically.
-
- // FIXME: Expand these checks to include all undefined behavior.
-
- if (V2.isSigned() && V2.isNegative())
- return NULL;
-
- uint64_t Amt = V2.getZExtValue();
-
- if (Amt > V1.getBitWidth())
- return NULL;
-
- return &getValue( V1.operator>>( (unsigned) Amt ));
- }
-
- case BinaryOperator::LT:
- return &getTruthValue( V1 < V2 );
-
- case BinaryOperator::GT:
- return &getTruthValue( V1 > V2 );
-
- case BinaryOperator::LE:
- return &getTruthValue( V1 <= V2 );
-
- case BinaryOperator::GE:
- return &getTruthValue( V1 >= V2 );
-
- case BinaryOperator::EQ:
- return &getTruthValue( V1 == V2 );
-
- case BinaryOperator::NE:
- return &getTruthValue( V1 != V2 );
-
- // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
-
- case BinaryOperator::And:
- return &getValue( V1 & V2 );
-
- case BinaryOperator::Or:
- return &getValue( V1 | V2 );
-
- case BinaryOperator::Xor:
- return &getValue( V1 ^ V2 );
- }
-}
-
-
-const std::pair<RVal, uintptr_t>&
-BasicValueFactory::getPersistentRValWithData(const RVal& V, uintptr_t Data) {
-
- // Lazily create the folding set.
- if (!PersistentRVals) PersistentRVals = new PersistentRValsTy();
-
- llvm::FoldingSetNodeID ID;
- void* InsertPos;
- V.Profile(ID);
- ID.AddPointer((void*) Data);
-
- PersistentRValsTy& Map = *((PersistentRValsTy*) PersistentRVals);
-
- typedef llvm::FoldingSetNodeWrapper<RValData> FoldNodeTy;
- FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
-
- if (!P) {
- P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
- new (P) FoldNodeTy(std::make_pair(V, Data));
- Map.InsertNode(P, InsertPos);
- }
-
- return P->getValue();
-}
-
-const std::pair<RVal, RVal>&
-BasicValueFactory::getPersistentRValPair(const RVal& V1, const RVal& V2) {
-
- // Lazily create the folding set.
- if (!PersistentRValPairs) PersistentRValPairs = new PersistentRValPairsTy();
-
- llvm::FoldingSetNodeID ID;
- void* InsertPos;
- V1.Profile(ID);
- V2.Profile(ID);
-
- PersistentRValPairsTy& Map = *((PersistentRValPairsTy*) PersistentRValPairs);
-
- typedef llvm::FoldingSetNodeWrapper<RValPair> FoldNodeTy;
- FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
-
- if (!P) {
- P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
- new (P) FoldNodeTy(std::make_pair(V1, V2));
- Map.InsertNode(P, InsertPos);
- }
-
- return P->getValue();
-}
-
-const RVal* BasicValueFactory::getPersistentRVal(RVal X) {
- return &getPersistentRValWithData(X, 0).first;
-}
-
-
diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp
deleted file mode 100644
index 834567136f46..000000000000
--- a/clang/lib/Analysis/BugReporter.cpp
+++ /dev/null
@@ -1,816 +0,0 @@
-// BugReporter.cpp - Generate PathDiagnostics for Bugs ------------*- 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 BugReporter, a utility class for generating
-// PathDiagnostics for analyses based on GRSimpleVals.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/CFG.h"
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/DenseMap.h"
-#include <sstream>
-
-using namespace clang;
-
-BugReporter::~BugReporter() {}
-GRBugReporter::~GRBugReporter() {}
-BugReporterData::~BugReporterData() {}
-BugType::~BugType() {}
-BugReport::~BugReport() {}
-RangedBugReport::~RangedBugReport() {}
-
-ExplodedGraph<GRState>& GRBugReporter::getGraph() {
- return Eng.getGraph();
-}
-
-GRStateManager& GRBugReporter::getStateManager() {
- return Eng.getStateManager();
-}
-
-static inline Stmt* GetStmt(const ProgramPoint& P) {
- if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
- return PS->getStmt();
- }
- else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
- return BE->getSrc()->getTerminator();
- }
- else if (const BlockEntrance* BE = dyn_cast<BlockEntrance>(&P)) {
- return BE->getFirstStmt();
- }
-
- assert (false && "Unsupported ProgramPoint.");
- return NULL;
-}
-
-static inline Stmt* GetStmt(const CFGBlock* B) {
- if (B->empty())
- return const_cast<Stmt*>(B->getTerminator());
- else
- return (*B)[0];
-}
-
-static inline ExplodedNode<GRState>*
-GetNextNode(ExplodedNode<GRState>* N) {
- return N->pred_empty() ? NULL : *(N->pred_begin());
-}
-
-static Stmt* GetLastStmt(ExplodedNode<GRState>* N) {
- assert (isa<BlockEntrance>(N->getLocation()));
-
- for (N = GetNextNode(N); N; N = GetNextNode(N)) {
-
- ProgramPoint P = N->getLocation();
-
- if (PostStmt* PS = dyn_cast<PostStmt>(&P))
- return PS->getStmt();
- }
-
- return NULL;
-}
-
-static void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr,
- Stmt* S) {
-
- if (!S)
- return;
-
- // Slow, but probably doesn't matter.
- if (os.str().empty())
- os << ' ';
-
- os << "Execution continues on line "
- << SMgr.getLogicalLineNumber(S->getLocStart()) << '.';
-}
-
-
-static inline void ExecutionContinues(std::ostringstream& os,
- SourceManager& SMgr,
- ExplodedNode<GRState>* N) {
-
- ExecutionContinues(os, SMgr, GetStmt(N->getLocation()));
-}
-
-static inline void ExecutionContinues(std::ostringstream& os,
- SourceManager& SMgr,
- const CFGBlock* B) {
-
- ExecutionContinues(os, SMgr, GetStmt(B));
-}
-
-
-Stmt* BugReport::getStmt(BugReporter& BR) const {
-
- ProgramPoint ProgP = EndNode->getLocation();
- Stmt *S = NULL;
-
- if (BlockEntrance* BE = dyn_cast<BlockEntrance>(&ProgP))
- if (BE->getBlock() == &BR.getCFG()->getExit())
- S = GetLastStmt(EndNode);
- if (!S)
- S = GetStmt(ProgP);
-
- return S;
-}
-
-PathDiagnosticPiece*
-BugReport::getEndPath(BugReporter& BR,
- ExplodedNode<GRState>* EndPathNode) {
-
- Stmt* S = getStmt(BR);
-
- if (!S)
- return NULL;
-
- FullSourceLoc L(S->getLocStart(), BR.getContext().getSourceManager());
- PathDiagnosticPiece* P = new PathDiagnosticPiece(L, getDescription());
-
- const SourceRange *Beg, *End;
- getRanges(BR, Beg, End);
-
- for (; Beg != End; ++Beg)
- P->addRange(*Beg);
-
- return P;
-}
-
-void BugReport::getRanges(BugReporter& BR, const SourceRange*& beg,
- const SourceRange*& end) {
-
- if (Expr* E = dyn_cast_or_null<Expr>(getStmt(BR))) {
- R = E->getSourceRange();
- beg = &R;
- end = beg+1;
- }
- else
- beg = end = 0;
-}
-
-FullSourceLoc BugReport::getLocation(SourceManager& Mgr) {
-
- if (!EndNode)
- return FullSourceLoc();
-
- Stmt* S = GetStmt(EndNode->getLocation());
-
- if (!S)
- return FullSourceLoc();
-
- return FullSourceLoc(S->getLocStart(), Mgr);
-}
-
-PathDiagnosticPiece* BugReport::VisitNode(ExplodedNode<GRState>* N,
- ExplodedNode<GRState>* PrevN,
- ExplodedGraph<GRState>& G,
- BugReporter& BR) {
- return NULL;
-}
-
-static std::pair<ExplodedGraph<GRState>*, ExplodedNode<GRState>*>
-MakeReportGraph(ExplodedGraph<GRState>* G, ExplodedNode<GRState>* N) {
-
- llvm::OwningPtr<ExplodedGraph<GRState> > GTrim(G->Trim(&N, &N+1));
-
- // Find the error node in the trimmed graph.
-
- ExplodedNode<GRState>* NOld = N;
- N = 0;
-
- for (ExplodedGraph<GRState>::node_iterator
- I = GTrim->nodes_begin(), E = GTrim->nodes_end(); I != E; ++I) {
-
- if (I->getState() == NOld->getState() &&
- I->getLocation() == NOld->getLocation()) {
- N = &*I;
- break;
- }
- }
-
- assert(N);
-
- // Create a new graph with a single path.
-
- G = new ExplodedGraph<GRState>(GTrim->getCFG(), GTrim->getCodeDecl(),
- GTrim->getContext());
-
- // Sometimes TrimGraph can contain a cycle. Perform a reverse DFS
- // to the root node, and then construct a new graph that contains only
- // a single path.
- llvm::DenseMap<void*,unsigned> Visited;
- llvm::SmallVector<ExplodedNode<GRState>*, 10> WS;
- WS.push_back(N);
- unsigned cnt = 0;
- ExplodedNode<GRState>* Root = 0;
-
- while (!WS.empty()) {
- ExplodedNode<GRState>* Node = WS.back();
- WS.pop_back();
-
- if (Visited.find(Node) != Visited.end())
- continue;
-
- Visited[Node] = cnt++;
-
- if (Node->pred_empty()) {
- Root = Node;
- break;
- }
-
- for (ExplodedNode<GRState>::pred_iterator I=Node->pred_begin(),
- E=Node->pred_end(); I!=E; ++I)
- WS.push_back(*I);
- }
-
- assert (Root);
-
- // Now walk from the root down the DFS path, always taking the successor
- // with the lowest number.
- ExplodedNode<GRState> *Last = 0, *First = 0;
-
- for ( N = Root ;;) {
-
- // Lookup the number associated with the current node.
- llvm::DenseMap<void*,unsigned>::iterator I=Visited.find(N);
- assert (I != Visited.end());
-
- // Create the equivalent node in the new graph with the same state
- // and location.
- ExplodedNode<GRState>* NewN =
- G->getNode(N->getLocation(), N->getState());
-
- // Link up the new node with the previous node.
- if (Last)
- NewN->addPredecessor(Last);
-
- Last = NewN;
-
- // Are we at the final node?
- if (I->second == 0) {
- First = NewN;
- break;
- }
-
- // Find the next successor node. We choose the node that is marked
- // with the lowest DFS number.
- ExplodedNode<GRState>::succ_iterator SI = N->succ_begin();
- ExplodedNode<GRState>::succ_iterator SE = N->succ_end();
- N = 0;
-
- for (unsigned MinVal = 0; SI != SE; ++SI) {
-
- I = Visited.find(*SI);
-
- if (I == Visited.end())
- continue;
-
- if (!N || I->second < MinVal) {
- N = *SI;
- MinVal = I->second;
- }
- }
-
- assert (N);
- }
-
- assert (First);
- return std::make_pair(G, First);
-}
-
-static VarDecl* GetMostRecentVarDeclBinding(ExplodedNode<GRState>* N,
- GRStateManager& VMgr,
- RVal X) {
-
- for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
-
- ProgramPoint P = N->getLocation();
-
- if (!isa<PostStmt>(P))
- continue;
-
- DeclRefExpr* DR = dyn_cast<DeclRefExpr>(cast<PostStmt>(P).getStmt());
-
- if (!DR)
- continue;
-
- RVal Y = VMgr.GetRVal(N->getState(), DR);
-
- if (X != Y)
- continue;
-
- VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl());
-
- if (!VD)
- continue;
-
- return VD;
- }
-
- return 0;
-}
-
-namespace {
-class VISIBILITY_HIDDEN NotableSymbolHandler
- : public StoreManager::BindingsHandler {
-
- SymbolID Sym;
- const GRState* PrevSt;
- Stmt* S;
- GRStateManager& VMgr;
- ExplodedNode<GRState>* Pred;
- PathDiagnostic& PD;
- BugReporter& BR;
-
-public:
-
- NotableSymbolHandler(SymbolID sym, const GRState* prevst, Stmt* s,
- GRStateManager& vmgr, ExplodedNode<GRState>* pred,
- PathDiagnostic& pd, BugReporter& br)
- : Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
-
- bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, RVal V) {
-
- SymbolID ScanSym;
-
- if (lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&V))
- ScanSym = SV->getSymbol();
- else if (nonlval::SymbolVal* SV = dyn_cast<nonlval::SymbolVal>(&V))
- ScanSym = SV->getSymbol();
- else
- return true;
-
- if (ScanSym != Sym)
- return true;
-
- // Check if the previous state has this binding.
- RVal X = VMgr.GetRVal(PrevSt, lval::MemRegionVal(R));
-
- if (X == V) // Same binding?
- return true;
-
- // Different binding. Only handle assignments for now. We don't pull
- // this check out of the loop because we will eventually handle other
- // cases.
-
- VarDecl *VD = 0;
-
- if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
- if (!B->isAssignmentOp())
- return true;
-
- // What variable did we assign to?
- DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenCasts());
-
- if (!DR)
- return true;
-
- VD = dyn_cast<VarDecl>(DR->getDecl());
- }
- else if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
- // FIXME: Eventually CFGs won't have DeclStmts. Right now we
- // assume that each DeclStmt has a single Decl. This invariant
- // holds by contruction in the CFG.
- VD = dyn_cast<VarDecl>(*DS->decl_begin());
- }
-
- if (!VD)
- return true;
-
- // What is the most recently referenced variable with this binding?
- VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V);
-
- if (!MostRecent)
- return true;
-
- // Create the diagnostic.
-
- FullSourceLoc L(S->getLocStart(), BR.getSourceManager());
-
- if (VD->getType()->isPointerLikeType()) {
- std::string msg = "'" + std::string(VD->getName()) +
- "' now aliases '" + MostRecent->getName() + "'";
-
- PD.push_front(new PathDiagnosticPiece(L, msg));
- }
-
- return true;
- }
-};
-}
-
-static void HandleNotableSymbol(ExplodedNode<GRState>* N, Stmt* S,
- SymbolID Sym, BugReporter& BR,
- PathDiagnostic& PD) {
-
- ExplodedNode<GRState>* Pred = N->pred_empty() ? 0 : *N->pred_begin();
- const GRState* PrevSt = Pred ? Pred->getState() : 0;
-
- if (!PrevSt)
- return;
-
- // Look at the region bindings of the current state that map to the
- // specified symbol. Are any of them not in the previous state?
- GRStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
- NotableSymbolHandler H(Sym, PrevSt, S, VMgr, Pred, PD, BR);
- cast<GRBugReporter>(BR).getStateManager().iterBindings(N->getState(), H);
-}
-
-namespace {
-class VISIBILITY_HIDDEN ScanNotableSymbols
- : public StoreManager::BindingsHandler {
-
- llvm::SmallSet<SymbolID, 10> AlreadyProcessed;
- ExplodedNode<GRState>* N;
- Stmt* S;
- GRBugReporter& BR;
- PathDiagnostic& PD;
-
-public:
- ScanNotableSymbols(ExplodedNode<GRState>* n, Stmt* s, GRBugReporter& br,
- PathDiagnostic& pd)
- : N(n), S(s), BR(br), PD(pd) {}
-
- bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, RVal V) {
- SymbolID ScanSym;
-
- if (lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&V))
- ScanSym = SV->getSymbol();
- else if (nonlval::SymbolVal* SV = dyn_cast<nonlval::SymbolVal>(&V))
- ScanSym = SV->getSymbol();
- else
- return true;
-
- assert (ScanSym.isInitialized());
-
- if (!BR.isNotable(ScanSym))
- return true;
-
- if (AlreadyProcessed.count(ScanSym))
- return true;
-
- AlreadyProcessed.insert(ScanSym);
-
- HandleNotableSymbol(N, S, ScanSym, BR, PD);
- return true;
- }
-};
-} // end anonymous namespace
-
-void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
- BugReport& R) {
-
- ExplodedNode<GRState>* N = R.getEndNode();
-
- if (!N) return;
-
- // Construct a new graph that contains only a single path from the error
- // node to a root.
-
- const std::pair<ExplodedGraph<GRState>*,ExplodedNode<GRState>*>
- GPair = MakeReportGraph(&getGraph(), N);
-
- llvm::OwningPtr<ExplodedGraph<GRState> > ReportGraph(GPair.first);
- assert(GPair.second->getLocation() == N->getLocation());
- N = GPair.second;
-
- // Start building the path diagnostic...
-
- if (PathDiagnosticPiece* Piece = R.getEndPath(*this, N))
- PD.push_back(Piece);
- else
- return;
-
- ExplodedNode<GRState>* NextNode = N->pred_empty()
- ? NULL : *(N->pred_begin());
-
- ASTContext& Ctx = getContext();
- SourceManager& SMgr = Ctx.getSourceManager();
-
- while (NextNode) {
-
- ExplodedNode<GRState>* LastNode = N;
- N = NextNode;
- NextNode = GetNextNode(N);
-
- ProgramPoint P = N->getLocation();
-
- if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
-
- CFGBlock* Src = BE->getSrc();
- CFGBlock* Dst = BE->getDst();
-
- Stmt* T = Src->getTerminator();
-
- if (!T)
- continue;
-
- FullSourceLoc L(T->getLocStart(), SMgr);
-
- switch (T->getStmtClass()) {
- default:
- break;
-
- case Stmt::GotoStmtClass:
- case Stmt::IndirectGotoStmtClass: {
-
- Stmt* S = GetStmt(LastNode->getLocation());
-
- if (!S)
- continue;
-
- std::ostringstream os;
-
- os << "Control jumps to line "
- << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
-
- PD.push_front(new PathDiagnosticPiece(L, os.str()));
- break;
- }
-
- case Stmt::SwitchStmtClass: {
-
- // Figure out what case arm we took.
-
- std::ostringstream os;
-
- if (Stmt* S = Dst->getLabel())
- switch (S->getStmtClass()) {
-
- default:
- assert(false && "Not a valid switch label.");
- continue;
-
- case Stmt::DefaultStmtClass: {
-
- os << "Control jumps to the 'default' case at line "
- << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
-
- break;
- }
-
- case Stmt::CaseStmtClass: {
-
- os << "Control jumps to 'case ";
-
- CaseStmt* Case = cast<CaseStmt>(S);
- Expr* LHS = Case->getLHS()->IgnoreParenCasts();
-
- // Determine if it is an enum.
-
- bool GetRawInt = true;
-
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
-
- // FIXME: Maybe this should be an assertion. Are there cases
- // were it is not an EnumConstantDecl?
-
- EnumConstantDecl* D = dyn_cast<EnumConstantDecl>(DR->getDecl());
-
- if (D) {
- GetRawInt = false;
- os << D->getName();
- }
- }
-
- if (GetRawInt) {
-
- // Not an enum.
- Expr* CondE = cast<SwitchStmt>(T)->getCond();
- unsigned bits = Ctx.getTypeSize(CondE->getType());
- llvm::APSInt V(bits, false);
-
- if (!LHS->isIntegerConstantExpr(V, Ctx, 0, true)) {
- assert (false && "Case condition must be constant.");
- continue;
- }
-
- llvm::raw_os_ostream OS(os);
- OS << V;
- }
-
- os << ":' at line "
- << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n";
-
- break;
-
- }
- }
- else {
- os << "'Default' branch taken. ";
- ExecutionContinues(os, SMgr, LastNode);
- }
-
- PD.push_front(new PathDiagnosticPiece(L, os.str()));
- break;
- }
-
- case Stmt::BreakStmtClass:
- case Stmt::ContinueStmtClass: {
- std::ostringstream os;
- ExecutionContinues(os, SMgr, LastNode);
- PD.push_front(new PathDiagnosticPiece(L, os.str()));
- break;
- }
-
- case Stmt::ConditionalOperatorClass: {
-
- std::ostringstream os;
- os << "'?' condition evaluates to ";
-
- if (*(Src->succ_begin()+1) == Dst)
- os << "false.";
- else
- os << "true.";
-
- PD.push_front(new PathDiagnosticPiece(L, os.str()));
-
- break;
- }
-
- case Stmt::DoStmtClass: {
-
- if (*(Src->succ_begin()) == Dst) {
-
- std::ostringstream os;
-
- os << "Loop condition is true. ";
- ExecutionContinues(os, SMgr, Dst);
-
- PD.push_front(new PathDiagnosticPiece(L, os.str()));
- }
- else
- PD.push_front(new PathDiagnosticPiece(L,
- "Loop condition is false. Exiting loop."));
-
- break;
- }
-
- case Stmt::WhileStmtClass:
- case Stmt::ForStmtClass: {
-
- if (*(Src->succ_begin()+1) == Dst) {
-
- std::ostringstream os;
-
- os << "Loop condition is false. ";
- ExecutionContinues(os, SMgr, Dst);
-
- PD.push_front(new PathDiagnosticPiece(L, os.str()));
- }
- else
- PD.push_front(new PathDiagnosticPiece(L,
- "Loop condition is true. Entering loop body."));
-
- break;
- }
-
- case Stmt::IfStmtClass: {
-
- if (*(Src->succ_begin()+1) == Dst)
- PD.push_front(new PathDiagnosticPiece(L, "Taking false branch."));
- else
- PD.push_front(new PathDiagnosticPiece(L, "Taking true branch."));
-
- break;
- }
- }
- }
-
- if (PathDiagnosticPiece* p = R.VisitNode(N, NextNode, *ReportGraph, *this))
- PD.push_front(p);
-
- if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
- // Scan the region bindings, and see if a "notable" symbol has a new
- // lval binding.
- ScanNotableSymbols SNS(N, PS->getStmt(), *this, PD);
- getStateManager().iterBindings(N->getState(), SNS);
- }
- }
-}
-
-
-bool BugTypeCacheLocation::isCached(BugReport& R) {
-
- ExplodedNode<GRState>* N = R.getEndNode();
-
- if (!N)
- return false;
-
- // Cache the location of the error. Don't emit the same
- // warning for the same error type that occurs at the same program
- // location but along a different path.
-
- return isCached(N->getLocation());
-}
-
-bool BugTypeCacheLocation::isCached(ProgramPoint P) {
- if (CachedErrors.count(P))
- return true;
-
- CachedErrors.insert(P);
- return false;
-}
-
-void BugReporter::EmitWarning(BugReport& R) {
-
- if (R.getBugType().isCached(R))
- return;
-
- llvm::OwningPtr<PathDiagnostic> D(new PathDiagnostic(R.getName(),
- R.getCategory()));
- GeneratePathDiagnostic(*D.get(), R);
-
- // Get the meta data.
-
- std::pair<const char**, const char**> Meta = R.getExtraDescriptiveText();
-
- for (const char** s = Meta.first; s != Meta.second; ++s)
- D->addMeta(*s);
-
- // Emit a full diagnostic for the path if we have a PathDiagnosticClient.
-
- PathDiagnosticClient* PD = getPathDiagnosticClient();
-
- if (PD && !D->empty()) {
- PD->HandlePathDiagnostic(D.take());
- return;
- }
-
- // We don't have a PathDiagnosticClient, but we can still emit a single
- // line diagnostic. Determine the location.
-
- FullSourceLoc L = D->empty() ? R.getLocation(getSourceManager())
- : D->back()->getLocation();
-
-
- // Determine the range.
-
- const SourceRange *Beg, *End;
-
- if (!D->empty()) {
- Beg = D->back()->ranges_begin();
- End = D->back()->ranges_end();
- }
- else
- R.getRanges(*this, Beg, End);
-
- if (PD) {
- PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription());
-
- for ( ; Beg != End; ++Beg)
- piece->addRange(*Beg);
-
- D->push_back(piece);
- PD->HandlePathDiagnostic(D.take());
- }
- else {
- std::ostringstream os;
-
- if (D->empty())
- os << R.getDescription();
- else
- os << D->back()->getString();
-
-
- Diagnostic& Diag = getDiagnostic();
- unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning,
- os.str().c_str());
-
- Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg);
- }
-}
-
-void BugReporter::EmitBasicReport(const char* name, const char* str,
- SourceLocation Loc,
- SourceRange* RBeg, unsigned NumRanges) {
- EmitBasicReport(name, "", str, Loc, RBeg, NumRanges);
-}
-
-void BugReporter::EmitBasicReport(const char* name, const char* category,
- const char* str, SourceLocation Loc,
- SourceRange* RBeg, unsigned NumRanges) {
-
- SimpleBugType BT(name, category, 0);
- DiagCollector C(BT);
- Diagnostic& Diag = getDiagnostic();
- Diag.Report(&C, getContext().getFullLoc(Loc),
- Diag.getCustomDiagID(Diagnostic::Warning, str),
- 0, 0, RBeg, NumRanges);
-
- for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I)
- EmitWarning(*I);
-}
-
diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
deleted file mode 100644
index c63529aa0559..000000000000
--- a/clang/lib/Analysis/CFRefCount.cpp
+++ /dev/null
@@ -1,2533 +0,0 @@
-// CFRefCount.cpp - Transfer functions for tracking simple values -*- 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 methods for CFRefCount, which implements
-// a reference count checker for Core Foundation (Mac OS X).
-//
-//===----------------------------------------------------------------------===//
-
-#include "GRSimpleVals.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRStateTrait.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/ADT/STLExtras.h"
-#include <ostream>
-#include <sstream>
-#include <stdarg.h>
-
-using namespace clang;
-using llvm::CStrInCStrNoCase;
-
-//===----------------------------------------------------------------------===//
-// Selector creation functions.
-//===----------------------------------------------------------------------===//
-
-static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
- IdentifierInfo* II = &Ctx.Idents.get(name);
- return Ctx.Selectors.getSelector(0, &II);
-}
-
-static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
- IdentifierInfo* II = &Ctx.Idents.get(name);
- return Ctx.Selectors.getSelector(1, &II);
-}
-
-//===----------------------------------------------------------------------===//
-// Type querying functions.
-//===----------------------------------------------------------------------===//
-
-static bool isCFRefType(QualType T) {
-
- if (!T->isPointerType())
- return false;
-
- // Check the typedef for the name "CF" and the substring "Ref".
- TypedefType* TD = dyn_cast<TypedefType>(T.getTypePtr());
-
- if (!TD)
- return false;
-
- const char* TDName = TD->getDecl()->getIdentifier()->getName();
- assert (TDName);
-
- if (TDName[0] != 'C' || TDName[1] != 'F')
- return false;
-
- if (strstr(TDName, "Ref") == 0)
- return false;
-
- return true;
-}
-
-static bool isCGRefType(QualType T) {
-
- if (!T->isPointerType())
- return false;
-
- // Check the typedef for the name "CG" and the substring "Ref".
- TypedefType* TD = dyn_cast<TypedefType>(T.getTypePtr());
-
- if (!TD)
- return false;
-
- const char* TDName = TD->getDecl()->getIdentifier()->getName();
- assert (TDName);
-
- if (TDName[0] != 'C' || TDName[1] != 'G')
- return false;
-
- if (strstr(TDName, "Ref") == 0)
- return false;
-
- return true;
-}
-
-static bool isNSType(QualType T) {
-
- if (!T->isPointerType())
- return false;
-
- ObjCInterfaceType* OT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
-
- if (!OT)
- return false;
-
- const char* ClsName = OT->getDecl()->getIdentifier()->getName();
- assert (ClsName);
-
- if (ClsName[0] != 'N' || ClsName[1] != 'S')
- return false;
-
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Primitives used for constructing summaries for function/method calls.
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// ArgEffect is used to summarize a function/method call's effect on a
-/// particular argument.
-enum ArgEffect { IncRef, DecRef, DoNothing, DoNothingByRef,
- StopTracking, MayEscape, SelfOwn, Autorelease };
-
-/// ArgEffects summarizes the effects of a function/method call on all of
-/// its arguments.
-typedef std::vector<std::pair<unsigned,ArgEffect> > ArgEffects;
-}
-
-namespace llvm {
-template <> struct FoldingSetTrait<ArgEffects> {
- static void Profile(const ArgEffects& X, FoldingSetNodeID& ID) {
- for (ArgEffects::const_iterator I = X.begin(), E = X.end(); I!= E; ++I) {
- ID.AddInteger(I->first);
- ID.AddInteger((unsigned) I->second);
- }
- }
-};
-} // end llvm namespace
-
-namespace {
-
-/// RetEffect is used to summarize a function/method call's behavior with
-/// respect to its return value.
-class VISIBILITY_HIDDEN RetEffect {
-public:
- enum Kind { NoRet, Alias, OwnedSymbol, OwnedAllocatedSymbol,
- NotOwnedSymbol, ReceiverAlias };
-
-private:
- unsigned Data;
- RetEffect(Kind k, unsigned D = 0) { Data = (D << 3) | (unsigned) k; }
-
-public:
-
- Kind getKind() const { return (Kind) (Data & 0x7); }
-
- unsigned getIndex() const {
- assert(getKind() == Alias);
- return Data >> 3;
- }
-
- static RetEffect MakeAlias(unsigned Idx) {
- return RetEffect(Alias, Idx);
- }
- static RetEffect MakeReceiverAlias() {
- return RetEffect(ReceiverAlias);
- }
- static RetEffect MakeOwned(bool isAllocated = false) {
- return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol);
- }
- static RetEffect MakeNotOwned() {
- return RetEffect(NotOwnedSymbol);
- }
- static RetEffect MakeNoRet() {
- return RetEffect(NoRet);
- }
-
- operator Kind() const {
- return getKind();
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger(Data);
- }
-};
-
-
-class VISIBILITY_HIDDEN RetainSummary : public llvm::FoldingSetNode {
- /// Args - an ordered vector of (index, ArgEffect) pairs, where index
- /// specifies the argument (starting from 0). This can be sparsely
- /// populated; arguments with no entry in Args use 'DefaultArgEffect'.
- ArgEffects* Args;
-
- /// DefaultArgEffect - The default ArgEffect to apply to arguments that
- /// do not have an entry in Args.
- ArgEffect DefaultArgEffect;
-
- /// Receiver - If this summary applies to an Objective-C message expression,
- /// this is the effect applied to the state of the receiver.
- ArgEffect Receiver;
-
- /// Ret - The effect on the return value. Used to indicate if the
- /// function/method call returns a new tracked symbol, returns an
- /// alias of one of the arguments in the call, and so on.
- RetEffect Ret;
-
- /// EndPath - Indicates that execution of this method/function should
- /// terminate the simulation of a path.
- bool EndPath;
-
-public:
-
- RetainSummary(ArgEffects* A, RetEffect R, ArgEffect defaultEff,
- ArgEffect ReceiverEff, bool endpath = false)
- : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R),
- EndPath(endpath) {}
-
- /// getArg - Return the argument effect on the argument specified by
- /// idx (starting from 0).
- ArgEffect getArg(unsigned idx) const {
-
- if (!Args)
- return DefaultArgEffect;
-
- // If Args is present, it is likely to contain only 1 element.
- // Just do a linear search. Do it from the back because functions with
- // large numbers of arguments will be tail heavy with respect to which
- // argument they actually modify with respect to the reference count.
- for (ArgEffects::reverse_iterator I=Args->rbegin(), E=Args->rend();
- I!=E; ++I) {
-
- if (idx > I->first)
- return DefaultArgEffect;
-
- if (idx == I->first)
- return I->second;
- }
-
- return DefaultArgEffect;
- }
-
- /// getRetEffect - Returns the effect on the return value of the call.
- RetEffect getRetEffect() const {
- return Ret;
- }
-
- /// isEndPath - Returns true if executing the given method/function should
- /// terminate the path.
- bool isEndPath() const { return EndPath; }
-
- /// getReceiverEffect - Returns the effect on the receiver of the call.
- /// This is only meaningful if the summary applies to an ObjCMessageExpr*.
- ArgEffect getReceiverEffect() const {
- return Receiver;
- }
-
- typedef ArgEffects::const_iterator ExprIterator;
-
- ExprIterator begin_args() const { return Args->begin(); }
- ExprIterator end_args() const { return Args->end(); }
-
- static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects* A,
- RetEffect RetEff, ArgEffect DefaultEff,
- ArgEffect ReceiverEff, bool EndPath) {
- ID.AddPointer(A);
- ID.Add(RetEff);
- ID.AddInteger((unsigned) DefaultEff);
- ID.AddInteger((unsigned) ReceiverEff);
- ID.AddInteger((unsigned) EndPath);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, Args, Ret, DefaultArgEffect, Receiver, EndPath);
- }
-};
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Data structures for constructing summaries.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN ObjCSummaryKey {
- IdentifierInfo* II;
- Selector S;
-public:
- ObjCSummaryKey(IdentifierInfo* ii, Selector s)
- : II(ii), S(s) {}
-
- ObjCSummaryKey(ObjCInterfaceDecl* d, Selector s)
- : II(d ? d->getIdentifier() : 0), S(s) {}
-
- ObjCSummaryKey(Selector s)
- : II(0), S(s) {}
-
- IdentifierInfo* getIdentifier() const { return II; }
- Selector getSelector() const { return S; }
-};
-}
-
-namespace llvm {
-template <> struct DenseMapInfo<ObjCSummaryKey> {
- static inline ObjCSummaryKey getEmptyKey() {
- return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
- DenseMapInfo<Selector>::getEmptyKey());
- }
-
- static inline ObjCSummaryKey getTombstoneKey() {
- return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
- DenseMapInfo<Selector>::getTombstoneKey());
- }
-
- static unsigned getHashValue(const ObjCSummaryKey &V) {
- return (DenseMapInfo<IdentifierInfo*>::getHashValue(V.getIdentifier())
- & 0x88888888)
- | (DenseMapInfo<Selector>::getHashValue(V.getSelector())
- & 0x55555555);
- }
-
- static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
- return DenseMapInfo<IdentifierInfo*>::isEqual(LHS.getIdentifier(),
- RHS.getIdentifier()) &&
- DenseMapInfo<Selector>::isEqual(LHS.getSelector(),
- RHS.getSelector());
- }
-
- static bool isPod() {
- return DenseMapInfo<ObjCInterfaceDecl*>::isPod() &&
- DenseMapInfo<Selector>::isPod();
- }
-};
-} // end llvm namespace
-
-namespace {
-class VISIBILITY_HIDDEN ObjCSummaryCache {
- typedef llvm::DenseMap<ObjCSummaryKey, RetainSummary*> MapTy;
- MapTy M;
-public:
- ObjCSummaryCache() {}
-
- typedef MapTy::iterator iterator;
-
- iterator find(ObjCInterfaceDecl* D, Selector S) {
-
- // Do a lookup with the (D,S) pair. If we find a match return
- // the iterator.
- ObjCSummaryKey K(D, S);
- MapTy::iterator I = M.find(K);
-
- if (I != M.end() || !D)
- return I;
-
- // Walk the super chain. If we find a hit with a parent, we'll end
- // up returning that summary. We actually allow that key (null,S), as
- // we cache summaries for the null ObjCInterfaceDecl* to allow us to
- // generate initial summaries without having to worry about NSObject
- // being declared.
- // FIXME: We may change this at some point.
- for (ObjCInterfaceDecl* C=D->getSuperClass() ;; C=C->getSuperClass()) {
- if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
- break;
-
- if (!C)
- return I;
- }
-
- // Cache the summary with original key to make the next lookup faster
- // and return the iterator.
- M[K] = I->second;
- return I;
- }
-
-
- iterator find(Expr* Receiver, Selector S) {
- return find(getReceiverDecl(Receiver), S);
- }
-
- iterator find(IdentifierInfo* II, Selector S) {
- // FIXME: Class method lookup. Right now we dont' have a good way
- // of going between IdentifierInfo* and the class hierarchy.
- iterator I = M.find(ObjCSummaryKey(II, S));
- return I == M.end() ? M.find(ObjCSummaryKey(S)) : I;
- }
-
- ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
-
- const PointerType* PT = E->getType()->getAsPointerType();
- if (!PT) return 0;
-
- ObjCInterfaceType* OI = dyn_cast<ObjCInterfaceType>(PT->getPointeeType());
- if (!OI) return 0;
-
- return OI ? OI->getDecl() : 0;
- }
-
- iterator end() { return M.end(); }
-
- RetainSummary*& operator[](ObjCMessageExpr* ME) {
-
- Selector S = ME->getSelector();
-
- if (Expr* Receiver = ME->getReceiver()) {
- ObjCInterfaceDecl* OD = getReceiverDecl(Receiver);
- return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
- }
-
- return M[ObjCSummaryKey(ME->getClassName(), S)];
- }
-
- RetainSummary*& operator[](ObjCSummaryKey K) {
- return M[K];
- }
-
- RetainSummary*& operator[](Selector S) {
- return M[ ObjCSummaryKey(S) ];
- }
-};
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Data structures for managing collections of summaries.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN RetainSummaryManager {
-
- //==-----------------------------------------------------------------==//
- // Typedefs.
- //==-----------------------------------------------------------------==//
-
- typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<ArgEffects> >
- ArgEffectsSetTy;
-
- typedef llvm::FoldingSet<RetainSummary>
- SummarySetTy;
-
- typedef llvm::DenseMap<FunctionDecl*, RetainSummary*>
- FuncSummariesTy;
-
- typedef ObjCSummaryCache ObjCMethodSummariesTy;
-
- //==-----------------------------------------------------------------==//
- // Data.
- //==-----------------------------------------------------------------==//
-
- /// Ctx - The ASTContext object for the analyzed ASTs.
- ASTContext& Ctx;
-
- /// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
- /// "CFDictionaryCreate".
- IdentifierInfo* CFDictionaryCreateII;
-
- /// GCEnabled - Records whether or not the analyzed code runs in GC mode.
- const bool GCEnabled;
-
- /// SummarySet - A FoldingSet of uniqued summaries.
- SummarySetTy SummarySet;
-
- /// FuncSummaries - A map from FunctionDecls to summaries.
- FuncSummariesTy FuncSummaries;
-
- /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
- /// to summaries.
- ObjCMethodSummariesTy ObjCClassMethodSummaries;
-
- /// ObjCMethodSummaries - A map from selectors to summaries.
- ObjCMethodSummariesTy ObjCMethodSummaries;
-
- /// ArgEffectsSet - A FoldingSet of uniqued ArgEffects.
- ArgEffectsSetTy ArgEffectsSet;
-
- /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
- /// and all other data used by the checker.
- llvm::BumpPtrAllocator BPAlloc;
-
- /// ScratchArgs - A holding buffer for construct ArgEffects.
- ArgEffects ScratchArgs;
-
- RetainSummary* StopSummary;
-
- //==-----------------------------------------------------------------==//
- // Methods.
- //==-----------------------------------------------------------------==//
-
- /// getArgEffects - Returns a persistent ArgEffects object based on the
- /// data in ScratchArgs.
- ArgEffects* getArgEffects();
-
- enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };
- RetainSummary* getUnarySummary(FunctionDecl* FD, UnaryFuncKind func);
-
- RetainSummary* getNSSummary(FunctionDecl* FD, const char* FName);
- RetainSummary* getCFSummary(FunctionDecl* FD, const char* FName);
- RetainSummary* getCGSummary(FunctionDecl* FD, const char* FName);
-
- RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
- RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
- RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, const char* FName);
-
- RetainSummary* getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = MayEscape,
- bool isEndPath = false);
-
- RetainSummary* getPersistentSummary(RetEffect RE,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = MayEscape) {
- return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
- }
-
- RetainSummary* getPersistentStopSummary() {
- if (StopSummary)
- return StopSummary;
-
- StopSummary = getPersistentSummary(RetEffect::MakeNoRet(),
- StopTracking, StopTracking);
-
- return StopSummary;
- }
-
- RetainSummary* getInitMethodSummary(ObjCMessageExpr* ME);
-
- void InitializeClassMethodSummaries();
- void InitializeMethodSummaries();
-
- void addClsMethSummary(IdentifierInfo* ClsII, Selector S,
- RetainSummary* Summ) {
- ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
- }
-
- void addNSObjectClsMethSummary(Selector S, RetainSummary *Summ) {
- ObjCClassMethodSummaries[S] = Summ;
- }
-
- void addNSObjectMethSummary(Selector S, RetainSummary *Summ) {
- ObjCMethodSummaries[S] = Summ;
- }
-
- void addInstMethSummary(const char* Cls, RetainSummary* Summ, va_list argp) {
-
- IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
- llvm::SmallVector<IdentifierInfo*, 10> II;
-
- while (const char* s = va_arg(argp, const char*))
- II.push_back(&Ctx.Idents.get(s));
-
- Selector S = Ctx.Selectors.getSelector(II.size(), &II[0]);
- ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
- }
-
- void addInstMethSummary(const char* Cls, RetainSummary* Summ, ...) {
- va_list argp;
- va_start(argp, Summ);
- addInstMethSummary(Cls, Summ, argp);
- va_end(argp);
- }
-
- void addPanicSummary(const char* Cls, ...) {
- RetainSummary* Summ = getPersistentSummary(0, RetEffect::MakeNoRet(),
- DoNothing, DoNothing, true);
- va_list argp;
- va_start (argp, Cls);
- addInstMethSummary(Cls, Summ, argp);
- va_end(argp);
- }
-
-public:
-
- RetainSummaryManager(ASTContext& ctx, bool gcenabled)
- : Ctx(ctx),
- CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
- GCEnabled(gcenabled), StopSummary(0) {
-
- InitializeClassMethodSummaries();
- InitializeMethodSummaries();
- }
-
- ~RetainSummaryManager();
-
- RetainSummary* getSummary(FunctionDecl* FD);
- RetainSummary* getMethodSummary(ObjCMessageExpr* ME, ObjCInterfaceDecl* ID);
- RetainSummary* getClassMethodSummary(IdentifierInfo* ClsName, Selector S);
-
- bool isGCEnabled() const { return GCEnabled; }
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Implementation of checker data structures.
-//===----------------------------------------------------------------------===//
-
-RetainSummaryManager::~RetainSummaryManager() {
-
- // FIXME: The ArgEffects could eventually be allocated from BPAlloc,
- // mitigating the need to do explicit cleanup of the
- // Argument-Effect summaries.
-
- for (ArgEffectsSetTy::iterator I = ArgEffectsSet.begin(),
- E = ArgEffectsSet.end(); I!=E; ++I)
- I->getValue().~ArgEffects();
-}
-
-ArgEffects* RetainSummaryManager::getArgEffects() {
-
- if (ScratchArgs.empty())
- return NULL;
-
- // Compute a profile for a non-empty ScratchArgs.
- llvm::FoldingSetNodeID profile;
- profile.Add(ScratchArgs);
- void* InsertPos;
-
- // Look up the uniqued copy, or create a new one.
- llvm::FoldingSetNodeWrapper<ArgEffects>* E =
- ArgEffectsSet.FindNodeOrInsertPos(profile, InsertPos);
-
- if (E) {
- ScratchArgs.clear();
- return &E->getValue();
- }
-
- E = (llvm::FoldingSetNodeWrapper<ArgEffects>*)
- BPAlloc.Allocate<llvm::FoldingSetNodeWrapper<ArgEffects> >();
-
- new (E) llvm::FoldingSetNodeWrapper<ArgEffects>(ScratchArgs);
- ArgEffectsSet.InsertNode(E, InsertPos);
-
- ScratchArgs.clear();
- return &E->getValue();
-}
-
-RetainSummary*
-RetainSummaryManager::getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
- ArgEffect ReceiverEff,
- ArgEffect DefaultEff,
- bool isEndPath) {
-
- // Generate a profile for the summary.
- llvm::FoldingSetNodeID profile;
- RetainSummary::Profile(profile, AE, RetEff, DefaultEff, ReceiverEff,
- isEndPath);
-
- // Look up the uniqued summary, or create one if it doesn't exist.
- void* InsertPos;
- RetainSummary* Summ = SummarySet.FindNodeOrInsertPos(profile, InsertPos);
-
- if (Summ)
- return Summ;
-
- // Create the summary and return it.
- Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
- new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff, isEndPath);
- SummarySet.InsertNode(Summ, InsertPos);
-
- return Summ;
-}
-
-//===----------------------------------------------------------------------===//
-// Summary creation for functions (largely uses of Core Foundation).
-//===----------------------------------------------------------------------===//
-
-RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
-
- SourceLocation Loc = FD->getLocation();
-
- if (!Loc.isFileID())
- return NULL;
-
- // Look up a summary in our cache of FunctionDecls -> Summaries.
- FuncSummariesTy::iterator I = FuncSummaries.find(FD);
-
- if (I != FuncSummaries.end())
- return I->second;
-
- // No summary. Generate one.
- const char* FName = FD->getIdentifier()->getName();
-
- RetainSummary *S = 0;
-
- FunctionType* FT = dyn_cast<FunctionType>(FD->getType());
-
- do {
- if (FT) {
-
- QualType T = FT->getResultType();
-
- if (isCFRefType(T)) {
- S = getCFSummary(FD, FName);
- break;
- }
-
- if (isCGRefType(T)) {
- S = getCGSummary(FD, FName );
- break;
- }
- }
-
- if (FName[0] == 'C' && FName[1] == 'F')
- S = getCFSummary(FD, FName);
- else if (FName[0] == 'N' && FName[1] == 'S')
- S = getNSSummary(FD, FName);
- }
- while (0);
-
- FuncSummaries[FD] = S;
- return S;
-}
-
-RetainSummary* RetainSummaryManager::getNSSummary(FunctionDecl* FD,
- const char* FName) {
- FName += 2;
-
- if (strcmp(FName, "MakeCollectable") == 0)
- return getUnarySummary(FD, cfmakecollectable);
-
- return 0;
-}
-
-static bool isRetain(FunctionDecl* FD, const char* FName) {
- const char* loc = strstr(FName, "Retain");
- return loc && loc[sizeof("Retain")-1] == '\0';
-}
-
-static bool isRelease(FunctionDecl* FD, const char* FName) {
- const char* loc = strstr(FName, "Release");
- return loc && loc[sizeof("Release")-1] == '\0';
-}
-
-RetainSummary* RetainSummaryManager::getCFSummary(FunctionDecl* FD,
- const char* FName) {
-
- if (FName[0] == 'C' && FName[1] == 'F')
- FName += 2;
-
- if (isRetain(FD, FName))
- return getUnarySummary(FD, cfretain);
-
- if (isRelease(FD, FName))
- return getUnarySummary(FD, cfrelease);
-
- if (strcmp(FName, "MakeCollectable") == 0)
- return getUnarySummary(FD, cfmakecollectable);
-
- return getCFCreateGetRuleSummary(FD, FName);
-}
-
-RetainSummary* RetainSummaryManager::getCGSummary(FunctionDecl* FD,
- const char* FName) {
-
- if (FName[0] == 'C' && FName[1] == 'G')
- FName += 2;
-
- if (isRelease(FD, FName))
- return getUnarySummary(FD, cfrelease);
-
- if (isRetain(FD, FName))
- return getUnarySummary(FD, cfretain);
-
- return getCFCreateGetRuleSummary(FD, FName);
-}
-
-RetainSummary*
-RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
- const char* FName) {
-
- if (strstr(FName, "Create") || strstr(FName, "Copy"))
- return getCFSummaryCreateRule(FD);
-
- if (strstr(FName, "Get"))
- return getCFSummaryGetRule(FD);
-
- return 0;
-}
-
-RetainSummary*
-RetainSummaryManager::getUnarySummary(FunctionDecl* FD, UnaryFuncKind func) {
-
- FunctionTypeProto* FT =
- dyn_cast<FunctionTypeProto>(FD->getType().getTypePtr());
-
- if (FT) {
-
- if (FT->getNumArgs() != 1)
- return 0;
-
- TypedefType* ArgT = dyn_cast<TypedefType>(FT->getArgType(0).getTypePtr());
-
- if (!ArgT)
- return 0;
-
- if (!ArgT->isPointerType())
- return NULL;
- }
-
- assert (ScratchArgs.empty());
-
- switch (func) {
- case cfretain: {
- ScratchArgs.push_back(std::make_pair(0, IncRef));
- return getPersistentSummary(RetEffect::MakeAlias(0),
- DoNothing, DoNothing);
- }
-
- case cfrelease: {
- ScratchArgs.push_back(std::make_pair(0, DecRef));
- return getPersistentSummary(RetEffect::MakeNoRet(),
- DoNothing, DoNothing);
- }
-
- case cfmakecollectable: {
- if (GCEnabled)
- ScratchArgs.push_back(std::make_pair(0, DecRef));
-
- return getPersistentSummary(RetEffect::MakeAlias(0),
- DoNothing, DoNothing);
- }
-
- default:
- assert (false && "Not a supported unary function.");
- return 0;
- }
-}
-
-RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
-
- FunctionType* FT =
- dyn_cast<FunctionType>(FD->getType().getTypePtr());
-
- if (FT && !isCFRefType(FT->getResultType()))
- return getPersistentSummary(RetEffect::MakeNoRet());
-
- assert (ScratchArgs.empty());
-
- if (FD->getIdentifier() == CFDictionaryCreateII) {
- ScratchArgs.push_back(std::make_pair(1, DoNothingByRef));
- ScratchArgs.push_back(std::make_pair(2, DoNothingByRef));
- }
-
- return getPersistentSummary(RetEffect::MakeOwned(true));
-}
-
-RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
-
- FunctionType* FT =
- dyn_cast<FunctionType>(FD->getType().getTypePtr());
-
- if (FT) {
- QualType RetTy = FT->getResultType();
-
- // FIXME: For now we assume that all pointer types returned are referenced
- // counted. Since this is the "Get" rule, we assume non-ownership, which
- // works fine for things that are not reference counted. We do this because
- // some generic data structures return "void*". We need something better
- // in the future.
-
- if (!isCFRefType(RetTy) && !RetTy->isPointerType())
- return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
- }
-
- // FIXME: Add special-cases for functions that retain/release. For now
- // just handle the default case.
-
- assert (ScratchArgs.empty());
- return getPersistentSummary(RetEffect::MakeNotOwned(), DoNothing, DoNothing);
-}
-
-//===----------------------------------------------------------------------===//
-// Summary creation for Selectors.
-//===----------------------------------------------------------------------===//
-
-RetainSummary*
-RetainSummaryManager::getInitMethodSummary(ObjCMessageExpr* ME) {
- assert(ScratchArgs.empty());
-
- RetainSummary* Summ =
- getPersistentSummary(RetEffect::MakeReceiverAlias());
-
- ObjCMethodSummaries[ME] = Summ;
- return Summ;
-}
-
-
-RetainSummary*
-RetainSummaryManager::getMethodSummary(ObjCMessageExpr* ME,
- ObjCInterfaceDecl* ID) {
-
- Selector S = ME->getSelector();
-
- // Look up a summary in our summary cache.
- ObjCMethodSummariesTy::iterator I = ObjCMethodSummaries.find(ID, S);
-
- if (I != ObjCMethodSummaries.end())
- return I->second;
-
- if (!ME->getType()->isPointerType())
- return 0;
-
- // "initXXX": pass-through for receiver.
-
- const char* s = S.getIdentifierInfoForSlot(0)->getName();
- assert (ScratchArgs.empty());
-
- if (strncmp(s, "init", 4) == 0 || strncmp(s, "_init", 5) == 0)
- return getInitMethodSummary(ME);
-
- // "copyXXX", "createXXX", "newXXX": allocators.
-
- if (!isNSType(ME->getReceiver()->getType()))
- return 0;
-
- if (CStrInCStrNoCase(s, "create") || CStrInCStrNoCase(s, "copy") ||
- CStrInCStrNoCase(s, "new")) {
-
- RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
- : RetEffect::MakeOwned(true);
-
- RetainSummary* Summ = getPersistentSummary(E);
- ObjCMethodSummaries[ME] = Summ;
- return Summ;
- }
-
- return 0;
-}
-
-RetainSummary*
-RetainSummaryManager::getClassMethodSummary(IdentifierInfo* ClsName,
- Selector S) {
-
- // FIXME: Eventually we should properly do class method summaries, but
- // it requires us being able to walk the type hierarchy. Unfortunately,
- // we cannot do this with just an IdentifierInfo* for the class name.
-
- // Look up a summary in our cache of Selectors -> Summaries.
- ObjCMethodSummariesTy::iterator I = ObjCClassMethodSummaries.find(ClsName, S);
-
- if (I != ObjCClassMethodSummaries.end())
- return I->second;
-
- return 0;
-}
-
-void RetainSummaryManager::InitializeClassMethodSummaries() {
-
- assert (ScratchArgs.empty());
-
- RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
- : RetEffect::MakeOwned(true);
-
- RetainSummary* Summ = getPersistentSummary(E);
-
- // Create the summaries for "alloc", "new", and "allocWithZone:" for
- // NSObject and its derivatives.
- addNSObjectClsMethSummary(GetNullarySelector("alloc", Ctx), Summ);
- addNSObjectClsMethSummary(GetNullarySelector("new", Ctx), Summ);
- addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
-
- // Create the [NSAssertionHandler currentHander] summary.
- addClsMethSummary(&Ctx.Idents.get("NSAssertionHandler"),
- GetNullarySelector("currentHandler", Ctx),
- getPersistentSummary(RetEffect::MakeNotOwned()));
-}
-
-void RetainSummaryManager::InitializeMethodSummaries() {
-
- assert (ScratchArgs.empty());
-
- // Create the "init" selector. It just acts as a pass-through for the
- // receiver.
- RetainSummary* InitSumm = getPersistentSummary(RetEffect::MakeReceiverAlias());
- addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
-
- // The next methods are allocators.
- RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
- : RetEffect::MakeOwned(true);
-
- RetainSummary* Summ = getPersistentSummary(E);
-
- // Create the "copy" selector.
- addNSObjectMethSummary(GetNullarySelector("copy", Ctx), Summ);
-
- // Create the "mutableCopy" selector.
- addNSObjectMethSummary(GetNullarySelector("mutableCopy", Ctx), Summ);
-
- // Create the "retain" selector.
- E = RetEffect::MakeReceiverAlias();
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : IncRef);
- addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
-
- // Create the "release" selector.
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
- addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
-
- // Create the "drain" selector.
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
- addNSObjectMethSummary(GetNullarySelector("drain", Ctx), Summ);
-
- // Create the "autorelease" selector.
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : Autorelease);
- addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
-
- // For NSWindow, allocated objects are (initially) self-owned.
- RetainSummary *NSWindowSumm =
- getPersistentSummary(RetEffect::MakeReceiverAlias(), SelfOwn);
-
- addInstMethSummary("NSWindow", NSWindowSumm, "initWithContentRect",
- "styleMask", "backing", "defer", NULL);
-
- addInstMethSummary("NSWindow", NSWindowSumm, "initWithContentRect",
- "styleMask", "backing", "defer", "screen", NULL);
-
- // For NSPanel (which subclasses NSWindow), allocated objects are not
- // self-owned.
- addInstMethSummary("NSPanel", InitSumm, "initWithContentRect",
- "styleMask", "backing", "defer", NULL);
-
- addInstMethSummary("NSPanel", InitSumm, "initWithContentRect",
- "styleMask", "backing", "defer", "screen", NULL);
-
- // Create NSAssertionHandler summaries.
- addPanicSummary("NSAssertionHandler", "handleFailureInFunction", "file",
- "lineNumber", "description", NULL);
-
- addPanicSummary("NSAssertionHandler", "handleFailureInMethod", "object",
- "file", "lineNumber", "description", NULL);
-}
-
-//===----------------------------------------------------------------------===//
-// Reference-counting logic (typestate + counts).
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN RefVal {
-public:
-
- enum Kind {
- Owned = 0, // Owning reference.
- NotOwned, // Reference is not owned by still valid (not freed).
- Released, // Object has been released.
- ReturnedOwned, // Returned object passes ownership to caller.
- ReturnedNotOwned, // Return object does not pass ownership to caller.
- ErrorUseAfterRelease, // Object used after released.
- ErrorReleaseNotOwned, // Release of an object that was not owned.
- ErrorLeak // A memory leak due to excessive reference counts.
- };
-
-private:
-
- Kind kind;
- unsigned Cnt;
- QualType T;
-
- RefVal(Kind k, unsigned cnt, QualType t) : kind(k), Cnt(cnt), T(t) {}
- RefVal(Kind k, unsigned cnt = 0) : kind(k), Cnt(cnt) {}
-
-public:
-
- Kind getKind() const { return kind; }
-
- unsigned getCount() const { return Cnt; }
- QualType getType() const { return T; }
-
- // Useful predicates.
-
- static bool isError(Kind k) { return k >= ErrorUseAfterRelease; }
-
- static bool isLeak(Kind k) { return k == ErrorLeak; }
-
- bool isOwned() const {
- return getKind() == Owned;
- }
-
- bool isNotOwned() const {
- return getKind() == NotOwned;
- }
-
- bool isReturnedOwned() const {
- return getKind() == ReturnedOwned;
- }
-
- bool isReturnedNotOwned() const {
- return getKind() == ReturnedNotOwned;
- }
-
- bool isNonLeakError() const {
- Kind k = getKind();
- return isError(k) && !isLeak(k);
- }
-
- // State creation: normal state.
-
- static RefVal makeOwned(QualType t, unsigned Count = 1) {
- return RefVal(Owned, Count, t);
- }
-
- static RefVal makeNotOwned(QualType t, unsigned Count = 0) {
- return RefVal(NotOwned, Count, t);
- }
-
- static RefVal makeReturnedOwned(unsigned Count) {
- return RefVal(ReturnedOwned, Count);
- }
-
- static RefVal makeReturnedNotOwned() {
- return RefVal(ReturnedNotOwned);
- }
-
- // Comparison, profiling, and pretty-printing.
-
- bool operator==(const RefVal& X) const {
- return kind == X.kind && Cnt == X.Cnt && T == X.T;
- }
-
- RefVal operator-(size_t i) const {
- return RefVal(getKind(), getCount() - i, getType());
- }
-
- RefVal operator+(size_t i) const {
- return RefVal(getKind(), getCount() + i, getType());
- }
-
- RefVal operator^(Kind k) const {
- return RefVal(k, getCount(), getType());
- }
-
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned) kind);
- ID.AddInteger(Cnt);
- ID.Add(T);
- }
-
- void print(std::ostream& Out) const;
-};
-
-void RefVal::print(std::ostream& Out) const {
- if (!T.isNull())
- Out << "Tracked Type:" << T.getAsString() << '\n';
-
- switch (getKind()) {
- default: assert(false);
- case Owned: {
- Out << "Owned";
- unsigned cnt = getCount();
- if (cnt) Out << " (+ " << cnt << ")";
- break;
- }
-
- case NotOwned: {
- Out << "NotOwned";
- unsigned cnt = getCount();
- if (cnt) Out << " (+ " << cnt << ")";
- break;
- }
-
- case ReturnedOwned: {
- Out << "ReturnedOwned";
- unsigned cnt = getCount();
- if (cnt) Out << " (+ " << cnt << ")";
- break;
- }
-
- case ReturnedNotOwned: {
- Out << "ReturnedNotOwned";
- unsigned cnt = getCount();
- if (cnt) Out << " (+ " << cnt << ")";
- break;
- }
-
- case Released:
- Out << "Released";
- break;
-
- case ErrorLeak:
- Out << "Leaked";
- break;
-
- case ErrorUseAfterRelease:
- Out << "Use-After-Release [ERROR]";
- break;
-
- case ErrorReleaseNotOwned:
- Out << "Release of Not-Owned [ERROR]";
- break;
- }
-}
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// RefBindings - State used to track object reference counts.
-//===----------------------------------------------------------------------===//
-
-typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings;
-static int RefBIndex = 0;
-
-namespace clang {
- template<>
- struct GRStateTrait<RefBindings> : public GRStatePartialTrait<RefBindings> {
- static inline void* GDMIndex() { return &RefBIndex; }
- };
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals {
-public:
- // Type definitions.
- typedef llvm::DenseMap<GRExprEngine::NodeTy*,std::pair<Expr*, SymbolID> >
- ReleasesNotOwnedTy;
-
- typedef ReleasesNotOwnedTy UseAfterReleasesTy;
-
- typedef llvm::DenseMap<GRExprEngine::NodeTy*, std::vector<SymbolID>*>
- LeaksTy;
-
- class BindingsPrinter : public GRState::Printer {
- public:
- virtual void Print(std::ostream& Out, const GRState* state,
- const char* nl, const char* sep);
- };
-
-private:
- RetainSummaryManager Summaries;
- const LangOptions& LOpts;
-
- UseAfterReleasesTy UseAfterReleases;
- ReleasesNotOwnedTy ReleasesNotOwned;
- LeaksTy Leaks;
-
- RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E,
- RefVal::Kind& hasErr, RefBindings::Factory& RefBFactory);
-
- RefVal::Kind& Update(GRStateRef& state, SymbolID sym, RefVal V,
- ArgEffect E, RefVal::Kind& hasErr) {
-
- state = state.set<RefBindings>(Update(state.get<RefBindings>(), sym, V,
- E, hasErr,
- state.get_context<RefBindings>()));
- return hasErr;
- }
-
- void ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* NodeExpr, Expr* ErrorExpr,
- ExplodedNode<GRState>* Pred,
- const GRState* St,
- RefVal::Kind hasErr, SymbolID Sym);
-
- const GRState* HandleSymbolDeath(GRStateManager& VMgr,
- const GRState* St,
- SymbolID sid, RefVal V, bool& hasLeak);
-
-public:
-
- CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
- : Summaries(Ctx, gcenabled),
- LOpts(lopts) {}
-
- virtual ~CFRefCount() {
- for (LeaksTy::iterator I = Leaks.begin(), E = Leaks.end(); I!=E; ++I)
- delete I->second;
- }
-
- virtual void RegisterChecks(GRExprEngine& Eng);
-
- virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {
- Printers.push_back(new BindingsPrinter());
- }
-
- bool isGCEnabled() const { return Summaries.isGCEnabled(); }
- const LangOptions& getLangOptions() const { return LOpts; }
-
- // Calls.
-
- void EvalSummary(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* Ex,
- Expr* Receiver,
- RetainSummary* Summ,
- ExprIterator arg_beg, ExprIterator arg_end,
- ExplodedNode<GRState>* Pred);
-
- virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<GRState>* Pred);
-
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<GRState>* Pred);
-
- bool EvalObjCMessageExprAux(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<GRState>* Pred);
-
- // Stores.
-
- virtual void EvalStore(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* E, ExplodedNode<GRState>* Pred,
- const GRState* St, RVal TargetLV, RVal Val);
- // End-of-path.
-
- virtual void EvalEndPath(GRExprEngine& Engine,
- GREndPathNodeBuilder<GRState>& Builder);
-
- virtual void EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ExplodedNode<GRState>* Pred,
- Stmt* S,
- const GRState* St,
- const GRStateManager::DeadSymbolsTy& Dead);
- // Return statements.
-
- virtual void EvalReturn(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ReturnStmt* S,
- ExplodedNode<GRState>* Pred);
-
- // Assumptions.
-
- virtual const GRState* EvalAssume(GRStateManager& VMgr,
- const GRState* St, RVal Cond,
- bool Assumption, bool& isFeasible);
-
- // Error iterators.
-
- typedef UseAfterReleasesTy::iterator use_after_iterator;
- typedef ReleasesNotOwnedTy::iterator bad_release_iterator;
- typedef LeaksTy::iterator leaks_iterator;
-
- use_after_iterator use_after_begin() { return UseAfterReleases.begin(); }
- use_after_iterator use_after_end() { return UseAfterReleases.end(); }
-
- bad_release_iterator bad_release_begin() { return ReleasesNotOwned.begin(); }
- bad_release_iterator bad_release_end() { return ReleasesNotOwned.end(); }
-
- leaks_iterator leaks_begin() { return Leaks.begin(); }
- leaks_iterator leaks_end() { return Leaks.end(); }
-};
-
-} // end anonymous namespace
-
-
-
-
-void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state,
- const char* nl, const char* sep) {
-
- RefBindings B = state->get<RefBindings>();
-
- if (!B.isEmpty())
- Out << sep << nl;
-
- for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
- Out << (*I).first << " : ";
- (*I).second.print(Out);
- Out << nl;
- }
-}
-
-static inline ArgEffect GetArgE(RetainSummary* Summ, unsigned idx) {
- return Summ ? Summ->getArg(idx) : MayEscape;
-}
-
-static inline RetEffect GetRetEffect(RetainSummary* Summ) {
- return Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
-}
-
-static inline ArgEffect GetReceiverE(RetainSummary* Summ) {
- return Summ ? Summ->getReceiverEffect() : DoNothing;
-}
-
-static inline bool IsEndPath(RetainSummary* Summ) {
- return Summ ? Summ->isEndPath() : false;
-}
-
-void CFRefCount::ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* NodeExpr, Expr* ErrorExpr,
- ExplodedNode<GRState>* Pred,
- const GRState* St,
- RefVal::Kind hasErr, SymbolID Sym) {
- Builder.BuildSinks = true;
- GRExprEngine::NodeTy* N = Builder.MakeNode(Dst, NodeExpr, Pred, St);
-
- if (!N) return;
-
- switch (hasErr) {
- default: assert(false);
- case RefVal::ErrorUseAfterRelease:
- UseAfterReleases[N] = std::make_pair(ErrorExpr, Sym);
- break;
-
- case RefVal::ErrorReleaseNotOwned:
- ReleasesNotOwned[N] = std::make_pair(ErrorExpr, Sym);
- break;
- }
-}
-
-/// GetReturnType - Used to get the return type of a message expression or
-/// function call with the intention of affixing that type to a tracked symbol.
-/// While the the return type can be queried directly from RetEx, when
-/// invoking class methods we augment to the return type to be that of
-/// a pointer to the class (as opposed it just being id).
-static QualType GetReturnType(Expr* RetE, ASTContext& Ctx) {
-
- QualType RetTy = RetE->getType();
-
- // FIXME: We aren't handling id<...>.
- const PointerType* PT = RetTy->getAsPointerType();
- if (!PT)
- return RetTy;
-
- // If RetEx is not a message expression just return its type.
- // If RetEx is a message expression, return its types if it is something
- /// more specific than id.
-
- ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(RetE);
-
- if (!ME || !Ctx.isObjCIdType(PT->getPointeeType()))
- return RetTy;
-
- ObjCInterfaceDecl* D = ME->getClassInfo().first;
-
- // At this point we know the return type of the message expression is id.
- // If we have an ObjCInterceDecl, we know this is a call to a class method
- // whose type we can resolve. In such cases, promote the return type to
- // Class*.
- return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
-}
-
-
-void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* Ex,
- Expr* Receiver,
- RetainSummary* Summ,
- ExprIterator arg_beg, ExprIterator arg_end,
- ExplodedNode<GRState>* Pred) {
-
- // Get the state.
- GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
-
- // Evaluate the effect of the arguments.
- RefVal::Kind hasErr = (RefVal::Kind) 0;
- unsigned idx = 0;
- Expr* ErrorExpr = NULL;
- SymbolID ErrorSym = 0;
-
- for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
- RVal V = state.GetRVal(*I);
-
- if (isa<lval::SymbolVal>(V)) {
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
- if (RefBindings::data_type* T = state.get<RefBindings>(Sym))
- if (Update(state, Sym, *T, GetArgE(Summ, idx), hasErr)) {
- ErrorExpr = *I;
- ErrorSym = Sym;
- break;
- }
- }
- else if (isa<LVal>(V)) {
-#if 0
- // Nuke all arguments passed by reference.
- StateMgr.Unbind(StVals, cast<LVal>(V));
-#else
- if (lval::MemRegionVal* MR = dyn_cast<lval::MemRegionVal>(&V)) {
-
- if (GetArgE(Summ, idx) == DoNothingByRef)
- continue;
-
- // Invalidate the value of the variable passed by reference.
-
- // FIXME: Either this logic should also be replicated in GRSimpleVals
- // or should be pulled into a separate "constraint engine."
-
- // FIXME: We can have collisions on the conjured symbol if the
- // expression *I also creates conjured symbols. We probably want
- // to identify conjured symbols by an expression pair: the enclosing
- // expression (the context) and the expression itself. This should
- // disambiguate conjured symbols.
-
- // Is the invalidated variable something that we were tracking?
- RVal X = state.GetRVal(*MR);
-
- if (isa<lval::SymbolVal>(X)) {
- SymbolID Sym = cast<lval::SymbolVal>(X).getSymbol();
- state = state.remove<RefBindings>(Sym);
- }
-
- TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());
- if (R) {
- // Set the value of the variable to be a conjured symbol.
- unsigned Count = Builder.getCurrentBlockCount();
- QualType T = R->getType();
- SymbolID NewSym =
- Eng.getSymbolManager().getConjuredSymbol(*I, T, Count);
-
- state = state.SetRVal(*MR,
- LVal::IsLValType(T)
- ? cast<RVal>(lval::SymbolVal(NewSym))
- : cast<RVal>(nonlval::SymbolVal(NewSym)));
- }
- else
- state = state.SetRVal(*MR, UnknownVal());
- }
- else {
- // Nuke all other arguments passed by reference.
- state = state.Unbind(cast<LVal>(V));
- }
-#endif
- }
- else if (isa<nonlval::LValAsInteger>(V))
- state = state.Unbind(cast<nonlval::LValAsInteger>(V).getLVal());
- }
-
- // Evaluate the effect on the message receiver.
- if (!ErrorExpr && Receiver) {
- RVal V = state.GetRVal(Receiver);
- if (isa<lval::SymbolVal>(V)) {
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
- if (const RefVal* T = state.get<RefBindings>(Sym))
- if (Update(state, Sym, *T, GetReceiverE(Summ), hasErr)) {
- ErrorExpr = Receiver;
- ErrorSym = Sym;
- }
- }
- }
-
- // Process any errors.
- if (hasErr) {
- ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, state,
- hasErr, ErrorSym);
- return;
- }
-
- // Consult the summary for the return value.
- RetEffect RE = GetRetEffect(Summ);
-
- switch (RE.getKind()) {
- default:
- assert (false && "Unhandled RetEffect."); break;
-
- case RetEffect::NoRet:
-
- // Make up a symbol for the return value (not reference counted).
- // FIXME: This is basically copy-and-paste from GRSimpleVals. We
- // should compose behavior, not copy it.
-
- if (Ex->getType() != Eng.getContext().VoidTy) {
- unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
-
- RVal X = LVal::IsLValType(Ex->getType())
- ? cast<RVal>(lval::SymbolVal(Sym))
- : cast<RVal>(nonlval::SymbolVal(Sym));
-
- state = state.SetRVal(Ex, X, false);
- }
-
- break;
-
- case RetEffect::Alias: {
- unsigned idx = RE.getIndex();
- assert (arg_end >= arg_beg);
- assert (idx < (unsigned) (arg_end - arg_beg));
- RVal V = state.GetRVal(*(arg_beg+idx));
- state = state.SetRVal(Ex, V, false);
- break;
- }
-
- case RetEffect::ReceiverAlias: {
- assert (Receiver);
- RVal V = state.GetRVal(Receiver);
- state = state.SetRVal(Ex, V, false);
- break;
- }
-
- case RetEffect::OwnedAllocatedSymbol:
- case RetEffect::OwnedSymbol: {
- unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
- QualType RetT = GetReturnType(Ex, Eng.getContext());
-
- state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT));
- state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
-
-#if 0
- RefBindings B = GetRefBindings(StImpl);
- SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(RetT)));
-#endif
-
- // FIXME: Add a flag to the checker where allocations are allowed to fail.
- if (RE.getKind() == RetEffect::OwnedAllocatedSymbol)
- state = state.AddNE(Sym, Eng.getBasicVals().getZeroWithPtrWidth());
-
- break;
- }
-
- case RetEffect::NotOwnedSymbol: {
- unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
- QualType RetT = GetReturnType(Ex, Eng.getContext());
-
- state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT));
- state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
- break;
- }
- }
-
- // Is this a sink?
- if (IsEndPath(Summ))
- Builder.MakeSinkNode(Dst, Ex, Pred, state);
- else
- Builder.MakeNode(Dst, Ex, Pred, state);
-}
-
-
-void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<GRState>* Pred) {
-
- RetainSummary* Summ = !isa<lval::FuncVal>(L) ? 0
- : Summaries.getSummary(cast<lval::FuncVal>(L).getDecl());
-
- EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
- CE->arg_begin(), CE->arg_end(), Pred);
-}
-
-void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<GRState>* Pred) {
- RetainSummary* Summ;
-
- if (Expr* Receiver = ME->getReceiver()) {
- // We need the type-information of the tracked receiver object
- // Retrieve it from the state.
- ObjCInterfaceDecl* ID = 0;
-
- // FIXME: Wouldn't it be great if this code could be reduced? It's just
- // a chain of lookups.
- const GRState* St = Builder.GetState(Pred);
- RVal V = Eng.getStateManager().GetRVal(St, Receiver );
-
- if (isa<lval::SymbolVal>(V)) {
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
-
- if (const RefVal* T = St->get<RefBindings>(Sym)) {
- QualType Ty = T->getType();
-
- if (const PointerType* PT = Ty->getAsPointerType()) {
- QualType PointeeTy = PT->getPointeeType();
-
- if (ObjCInterfaceType* IT = dyn_cast<ObjCInterfaceType>(PointeeTy))
- ID = IT->getDecl();
- }
- }
- }
-
- Summ = Summaries.getMethodSummary(ME, ID);
- }
- else
- Summ = Summaries.getClassMethodSummary(ME->getClassName(),
- ME->getSelector());
-
- EvalSummary(Dst, Eng, Builder, ME, ME->getReceiver(), Summ,
- ME->arg_begin(), ME->arg_end(), Pred);
-}
-
-// Stores.
-
-void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* E, ExplodedNode<GRState>* Pred,
- const GRState* St, RVal TargetLV, RVal Val) {
-
- // Check if we have a binding for "Val" and if we are storing it to something
- // we don't understand or otherwise the value "escapes" the function.
-
- if (!isa<lval::SymbolVal>(Val))
- return;
-
- // Are we storing to something that causes the value to "escape"?
-
- bool escapes = false;
-
- if (!isa<lval::MemRegionVal>(TargetLV))
- escapes = true;
- else {
- MemRegion* R = cast<lval::MemRegionVal>(TargetLV).getRegion();
- escapes = !Eng.getStateManager().hasStackStorage(R);
- }
-
- if (!escapes)
- return;
-
- SymbolID Sym = cast<lval::SymbolVal>(Val).getSymbol();
-
- GRStateRef state(St, Eng.getStateManager());
-
- if (!state.get<RefBindings>(Sym))
- return;
-
- // Nuke the binding.
- state = state.remove<RefBindings>(Sym);
-
- // Hand of the remaining logic to the parent implementation.
- GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, state, TargetLV, Val);
-}
-
-// End-of-path.
-
-const GRState* CFRefCount::HandleSymbolDeath(GRStateManager& VMgr,
- const GRState* St, SymbolID sid,
- RefVal V, bool& hasLeak) {
-
- hasLeak = V.isOwned() ||
- ((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
-
- GRStateRef state(St, VMgr);
-
- if (!hasLeak)
- return state.remove<RefBindings>(sid);
-
- return state.set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
-}
-
-void CFRefCount::EvalEndPath(GRExprEngine& Eng,
- GREndPathNodeBuilder<GRState>& Builder) {
-
- const GRState* St = Builder.getState();
- RefBindings B = St->get<RefBindings>();
-
- llvm::SmallVector<SymbolID, 10> Leaked;
-
- for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
- bool hasLeak = false;
-
- St = HandleSymbolDeath(Eng.getStateManager(), St,
- (*I).first, (*I).second, hasLeak);
-
- if (hasLeak) Leaked.push_back((*I).first);
- }
-
- if (Leaked.empty())
- return;
-
- ExplodedNode<GRState>* N = Builder.MakeNode(St);
-
- if (!N)
- return;
-
- std::vector<SymbolID>*& LeaksAtNode = Leaks[N];
- assert (!LeaksAtNode);
- LeaksAtNode = new std::vector<SymbolID>();
-
- for (llvm::SmallVector<SymbolID, 10>::iterator I=Leaked.begin(),
- E = Leaked.end(); I != E; ++I)
- (*LeaksAtNode).push_back(*I);
-}
-
-// Dead symbols.
-
-void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- ExplodedNode<GRState>* Pred,
- Stmt* S,
- const GRState* St,
- const GRStateManager::DeadSymbolsTy& Dead) {
-
- // FIXME: a lot of copy-and-paste from EvalEndPath. Refactor.
-
- RefBindings B = St->get<RefBindings>();
- llvm::SmallVector<SymbolID, 10> Leaked;
-
- for (GRStateManager::DeadSymbolsTy::const_iterator
- I=Dead.begin(), E=Dead.end(); I!=E; ++I) {
-
- const RefVal* T = B.lookup(*I);
-
- if (!T)
- continue;
-
- bool hasLeak = false;
-
- St = HandleSymbolDeath(Eng.getStateManager(), St, *I, *T, hasLeak);
-
- if (hasLeak)
- Leaked.push_back(*I);
- }
-
- if (Leaked.empty())
- return;
-
- ExplodedNode<GRState>* N = Builder.MakeNode(Dst, S, Pred, St);
-
- if (!N)
- return;
-
- std::vector<SymbolID>*& LeaksAtNode = Leaks[N];
- assert (!LeaksAtNode);
- LeaksAtNode = new std::vector<SymbolID>();
-
- for (llvm::SmallVector<SymbolID, 10>::iterator I=Leaked.begin(),
- E = Leaked.end(); I != E; ++I)
- (*LeaksAtNode).push_back(*I);
-}
-
- // Return statements.
-
-void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- ReturnStmt* S,
- ExplodedNode<GRState>* Pred) {
-
- Expr* RetE = S->getRetValue();
- if (!RetE) return;
-
- GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
- RVal V = state.GetRVal(RetE);
-
- if (!isa<lval::SymbolVal>(V))
- return;
-
- // Get the reference count binding (if any).
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
- const RefVal* T = state.get<RefBindings>(Sym);
-
- if (!T)
- return;
-
- // Change the reference count.
- RefVal X = *T;
-
- switch (X.getKind()) {
- case RefVal::Owned: {
- unsigned cnt = X.getCount();
- assert (cnt > 0);
- X = RefVal::makeReturnedOwned(cnt - 1);
- break;
- }
-
- case RefVal::NotOwned: {
- unsigned cnt = X.getCount();
- X = cnt ? RefVal::makeReturnedOwned(cnt - 1)
- : RefVal::makeReturnedNotOwned();
- break;
- }
-
- default:
- return;
- }
-
- // Update the binding.
- state = state.set<RefBindings>(Sym, X);
- Builder.MakeNode(Dst, S, Pred, state);
-}
-
-// Assumptions.
-
-const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
- const GRState* St,
- RVal Cond, bool Assumption,
- bool& isFeasible) {
-
- // FIXME: We may add to the interface of EvalAssume the list of symbols
- // whose assumptions have changed. For now we just iterate through the
- // bindings and check if any of the tracked symbols are NULL. This isn't
- // too bad since the number of symbols we will track in practice are
- // probably small and EvalAssume is only called at branches and a few
- // other places.
- RefBindings B = St->get<RefBindings>();
-
- if (B.isEmpty())
- return St;
-
- bool changed = false;
-
- GRStateRef state(St, VMgr);
- RefBindings::Factory& RefBFactory = state.get_context<RefBindings>();
-
- for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
- // Check if the symbol is null (or equal to any constant).
- // If this is the case, stop tracking the symbol.
- if (VMgr.getSymVal(St, I.getKey())) {
- changed = true;
- B = RefBFactory.Remove(B, I.getKey());
- }
- }
-
- if (changed)
- state = state.set<RefBindings>(B);
-
- return state;
-}
-
-RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
- RefVal V, ArgEffect E,
- RefVal::Kind& hasErr,
- RefBindings::Factory& RefBFactory) {
-
- // FIXME: This dispatch can potentially be sped up by unifiying it into
- // a single switch statement. Opt for simplicity for now.
-
- switch (E) {
- default:
- assert (false && "Unhandled CFRef transition.");
-
- case MayEscape:
- if (V.getKind() == RefVal::Owned) {
- V = V ^ RefVal::NotOwned;
- break;
- }
- // Fall-through.
- case DoNothingByRef:
- case DoNothing:
- if (!isGCEnabled() && V.getKind() == RefVal::Released) {
- V = V ^ RefVal::ErrorUseAfterRelease;
- hasErr = V.getKind();
- break;
- }
- return B;
-
- case Autorelease:
- case StopTracking:
- return RefBFactory.Remove(B, sym);
-
- case IncRef:
- switch (V.getKind()) {
- default:
- assert(false);
-
- case RefVal::Owned:
- case RefVal::NotOwned:
- V = V + 1;
- break;
- case RefVal::Released:
- if (isGCEnabled())
- V = V ^ RefVal::Owned;
- else {
- V = V ^ RefVal::ErrorUseAfterRelease;
- hasErr = V.getKind();
- }
- break;
- }
- break;
-
- case SelfOwn:
- V = V ^ RefVal::NotOwned;
- // Fall-through.
- case DecRef:
- switch (V.getKind()) {
- default:
- assert (false);
-
- case RefVal::Owned:
- V = V.getCount() > 1 ? V - 1 : V ^ RefVal::Released;
- break;
-
- case RefVal::NotOwned:
- if (V.getCount() > 0)
- V = V - 1;
- else {
- V = V ^ RefVal::ErrorReleaseNotOwned;
- hasErr = V.getKind();
- }
- break;
-
- case RefVal::Released:
- V = V ^ RefVal::ErrorUseAfterRelease;
- hasErr = V.getKind();
- break;
- }
- break;
- }
- return RefBFactory.Add(B, sym, V);
-}
-
-//===----------------------------------------------------------------------===//
-// Error reporting.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
- //===-------------===//
- // Bug Descriptions. //
- //===-------------===//
-
- class VISIBILITY_HIDDEN CFRefBug : public BugTypeCacheLocation {
- protected:
- CFRefCount& TF;
-
- public:
- CFRefBug(CFRefCount& tf) : TF(tf) {}
-
- CFRefCount& getTF() { return TF; }
- const CFRefCount& getTF() const { return TF; }
-
- virtual bool isLeak() const { return false; }
-
- const char* getCategory() const {
- return "Memory (Core Foundation/Objective-C)";
- }
- };
-
- class VISIBILITY_HIDDEN UseAfterRelease : public CFRefBug {
- public:
- UseAfterRelease(CFRefCount& tf) : CFRefBug(tf) {}
-
- virtual const char* getName() const {
- return "use-after-release";
- }
- virtual const char* getDescription() const {
- return "Reference-counted object is used after it is released.";
- }
-
- virtual void EmitWarnings(BugReporter& BR);
- };
-
- class VISIBILITY_HIDDEN BadRelease : public CFRefBug {
- public:
- BadRelease(CFRefCount& tf) : CFRefBug(tf) {}
-
- virtual const char* getName() const {
- return "bad release";
- }
- virtual const char* getDescription() const {
- return "Incorrect decrement of the reference count of a "
- "CoreFoundation object: "
- "The object is not owned at this point by the caller.";
- }
-
- virtual void EmitWarnings(BugReporter& BR);
- };
-
- class VISIBILITY_HIDDEN Leak : public CFRefBug {
- public:
- Leak(CFRefCount& tf) : CFRefBug(tf) {}
-
- virtual const char* getName() const {
-
- if (getTF().isGCEnabled())
- return "leak (GC)";
-
- if (getTF().getLangOptions().getGCMode() == LangOptions::HybridGC)
- return "leak (hybrid MM, non-GC)";
-
- assert (getTF().getLangOptions().getGCMode() == LangOptions::NonGC);
- return "leak";
- }
-
- virtual const char* getDescription() const {
- return "Object leaked";
- }
-
- virtual void EmitWarnings(BugReporter& BR);
- virtual void GetErrorNodes(std::vector<ExplodedNode<GRState>*>& Nodes);
- virtual bool isLeak() const { return true; }
- virtual bool isCached(BugReport& R);
- };
-
- //===---------===//
- // Bug Reports. //
- //===---------===//
-
- class VISIBILITY_HIDDEN CFRefReport : public RangedBugReport {
- SymbolID Sym;
- public:
- CFRefReport(CFRefBug& D, ExplodedNode<GRState> *n, SymbolID sym)
- : RangedBugReport(D, n), Sym(sym) {}
-
- virtual ~CFRefReport() {}
-
- CFRefBug& getBugType() {
- return (CFRefBug&) RangedBugReport::getBugType();
- }
- const CFRefBug& getBugType() const {
- return (const CFRefBug&) RangedBugReport::getBugType();
- }
-
- virtual void getRanges(BugReporter& BR, const SourceRange*& beg,
- const SourceRange*& end) {
-
- if (!getBugType().isLeak())
- RangedBugReport::getRanges(BR, beg, end);
- else
- beg = end = 0;
- }
-
- SymbolID getSymbol() const { return Sym; }
-
- virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
- ExplodedNode<GRState>* N);
-
- virtual std::pair<const char**,const char**> getExtraDescriptiveText();
-
- virtual PathDiagnosticPiece* VisitNode(ExplodedNode<GRState>* N,
- ExplodedNode<GRState>* PrevN,
- ExplodedGraph<GRState>& G,
- BugReporter& BR);
- };
-
-
-} // end anonymous namespace
-
-void CFRefCount::RegisterChecks(GRExprEngine& Eng) {
- Eng.Register(new UseAfterRelease(*this));
- Eng.Register(new BadRelease(*this));
- Eng.Register(new Leak(*this));
-}
-
-
-static const char* Msgs[] = {
- "Code is compiled in garbage collection only mode" // GC only
- " (the bug occurs with garbage collection enabled).",
-
- "Code is compiled without garbage collection.", // No GC.
-
- "Code is compiled for use with and without garbage collection (GC)."
- " The bug occurs with GC enabled.", // Hybrid, with GC.
-
- "Code is compiled for use with and without garbage collection (GC)."
- " The bug occurs in non-GC mode." // Hyrbird, without GC/
-};
-
-std::pair<const char**,const char**> CFRefReport::getExtraDescriptiveText() {
- CFRefCount& TF = static_cast<CFRefBug&>(getBugType()).getTF();
-
- switch (TF.getLangOptions().getGCMode()) {
- default:
- assert(false);
-
- case LangOptions::GCOnly:
- assert (TF.isGCEnabled());
- return std::make_pair(&Msgs[0], &Msgs[0]+1);
-
- case LangOptions::NonGC:
- assert (!TF.isGCEnabled());
- return std::make_pair(&Msgs[1], &Msgs[1]+1);
-
- case LangOptions::HybridGC:
- if (TF.isGCEnabled())
- return std::make_pair(&Msgs[2], &Msgs[2]+1);
- else
- return std::make_pair(&Msgs[3], &Msgs[3]+1);
- }
-}
-
-PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode<GRState>* N,
- ExplodedNode<GRState>* PrevN,
- ExplodedGraph<GRState>& G,
- BugReporter& BR) {
-
- // Check if the type state has changed.
-
- const GRState* PrevSt = PrevN->getState();
- const GRState* CurrSt = N->getState();
-
- RefBindings PrevB = PrevSt->get<RefBindings>();
- RefBindings CurrB = CurrSt->get<RefBindings>();
-
- const RefVal* PrevT = PrevB.lookup(Sym);
- const RefVal* CurrT = CurrB.lookup(Sym);
-
- if (!CurrT)
- return NULL;
-
- const char* Msg = NULL;
- const RefVal& CurrV = *CurrB.lookup(Sym);
-
- if (!PrevT) {
-
- Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
-
- if (CurrV.isOwned()) {
-
- if (isa<CallExpr>(S))
- Msg = "Function call returns an object with a +1 retain count"
- " (owning reference).";
- else {
- assert (isa<ObjCMessageExpr>(S));
- Msg = "Method returns an object with a +1 retain count"
- " (owning reference).";
- }
- }
- else {
- assert (CurrV.isNotOwned());
-
- if (isa<CallExpr>(S))
- Msg = "Function call returns an object with a +0 retain count"
- " (non-owning reference).";
- else {
- assert (isa<ObjCMessageExpr>(S));
- Msg = "Method returns an object with a +0 retain count"
- " (non-owning reference).";
- }
- }
-
- FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager());
- PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, Msg);
-
- if (Expr* Exp = dyn_cast<Expr>(S))
- P->addRange(Exp->getSourceRange());
-
- return P;
- }
-
- // Determine if the typestate has changed.
- RefVal PrevV = *PrevB.lookup(Sym);
-
- if (PrevV == CurrV)
- return NULL;
-
- // The typestate has changed.
-
- std::ostringstream os;
- std::string s;
-
- switch (CurrV.getKind()) {
- case RefVal::Owned:
- case RefVal::NotOwned:
-
- if (PrevV.getCount() == CurrV.getCount())
- return 0;
-
- if (PrevV.getCount() > CurrV.getCount())
- os << "Reference count decremented.";
- else
- os << "Reference count incremented.";
-
- if (unsigned Count = CurrV.getCount()) {
-
- os << " Object has +" << Count;
-
- if (Count > 1)
- os << " retain counts.";
- else
- os << " retain count.";
- }
-
- s = os.str();
- Msg = s.c_str();
-
- break;
-
- case RefVal::Released:
- Msg = "Object released.";
- break;
-
- case RefVal::ReturnedOwned:
- Msg = "Object returned to caller as owning reference (single retain count"
- " transferred to caller).";
- break;
-
- case RefVal::ReturnedNotOwned:
- Msg = "Object returned to caller with a +0 (non-owning) retain count.";
- break;
-
- default:
- return NULL;
- }
-
- Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
- FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager());
- PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, Msg);
-
- // Add the range by scanning the children of the statement for any bindings
- // to Sym.
-
- GRStateManager& VSM = cast<GRBugReporter>(BR).getStateManager();
-
- for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
- if (Expr* Exp = dyn_cast_or_null<Expr>(*I)) {
- RVal X = VSM.GetRVal(CurrSt, Exp);
-
- if (lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&X))
- if (SV->getSymbol() == Sym) {
- P->addRange(Exp->getSourceRange()); break;
- }
- }
-
- return P;
-}
-
-namespace {
-class VISIBILITY_HIDDEN FindUniqueBinding :
- public StoreManager::BindingsHandler {
- SymbolID Sym;
- MemRegion* Binding;
- bool First;
-
- public:
- FindUniqueBinding(SymbolID sym) : Sym(sym), Binding(0), First(true) {}
-
- bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, RVal val) {
- if (const lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&val)) {
- if (SV->getSymbol() != Sym)
- return true;
- }
- else if (const nonlval::SymbolVal* SV=dyn_cast<nonlval::SymbolVal>(&val)) {
- if (SV->getSymbol() != Sym)
- return true;
- }
- else
- return true;
-
- if (Binding) {
- First = false;
- return false;
- }
- else
- Binding = R;
-
- return true;
- }
-
- operator bool() { return First && Binding; }
- MemRegion* getRegion() { return Binding; }
-};
-}
-
-static std::pair<ExplodedNode<GRState>*,MemRegion*>
-GetAllocationSite(GRStateManager* StateMgr, ExplodedNode<GRState>* N,
- SymbolID Sym) {
-
- // Find both first node that referred to the tracked symbol and the
- // memory location that value was store to.
- ExplodedNode<GRState>* Last = N;
- MemRegion* FirstBinding = 0;
-
- while (N) {
- const GRState* St = N->getState();
- RefBindings B = St->get<RefBindings>();
-
- if (!B.lookup(Sym))
- break;
-
- if (StateMgr) {
- FindUniqueBinding FB(Sym);
- StateMgr->iterBindings(St, FB);
- if (FB) FirstBinding = FB.getRegion();
- }
-
- Last = N;
- N = N->pred_empty() ? NULL : *(N->pred_begin());
- }
-
- return std::make_pair(Last, FirstBinding);
-}
-
-PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br,
- ExplodedNode<GRState>* EndN) {
-
- GRBugReporter& BR = cast<GRBugReporter>(br);
-
- // Tell the BugReporter to report cases when the tracked symbol is
- // assigned to different variables, etc.
- cast<GRBugReporter>(BR).addNotableSymbol(Sym);
-
- if (!getBugType().isLeak())
- return RangedBugReport::getEndPath(BR, EndN);
-
- // Get the retain count.
- unsigned long RetCount = EndN->getState()->get<RefBindings>(Sym)->getCount();
-
- // We are a leak. Walk up the graph to get to the first node where the
- // symbol appeared, and also get the first VarDecl that tracked object
- // is stored to.
- ExplodedNode<GRState>* AllocNode = 0;
- MemRegion* FirstBinding = 0;
-
- llvm::tie(AllocNode, FirstBinding) =
- GetAllocationSite(&BR.getStateManager(), EndN, Sym);
-
- // Get the allocate site.
- assert (AllocNode);
- Stmt* FirstStmt = cast<PostStmt>(AllocNode->getLocation()).getStmt();
-
- SourceManager& SMgr = BR.getContext().getSourceManager();
- unsigned AllocLine = SMgr.getLogicalLineNumber(FirstStmt->getLocStart());
-
- // Get the leak site. We may have multiple ExplodedNodes (one with the
- // leak) that occur on the same line number; if the node with the leak
- // has any immediate predecessor nodes with the same line number, find
- // any transitive-successors that have a different statement and use that
- // line number instead. This avoids emiting a diagnostic like:
- //
- // // 'y' is leaked.
- // int x = foo(y);
- //
- // instead we want:
- //
- // int x = foo(y);
- // // 'y' is leaked.
-
- Stmt* S = getStmt(BR); // This is the statement where the leak occured.
- assert (S);
- unsigned EndLine = SMgr.getLogicalLineNumber(S->getLocStart());
-
- // Look in the *trimmed* graph at the immediate predecessor of EndN. Does
- // it occur on the same line?
- PathDiagnosticPiece::DisplayHint Hint = PathDiagnosticPiece::Above;
-
- assert (!EndN->pred_empty()); // Not possible to have 0 predecessors.
- ExplodedNode<GRState> *Pred = *(EndN->pred_begin());
- ProgramPoint PredPos = Pred->getLocation();
-
- if (PostStmt* PredPS = dyn_cast<PostStmt>(&PredPos)) {
-
- Stmt* SPred = PredPS->getStmt();
-
- // Predecessor at same line?
- if (SMgr.getLogicalLineNumber(SPred->getLocStart()) != EndLine) {
- Hint = PathDiagnosticPiece::Below;
- S = SPred;
- }
- }
-
- // Generate the diagnostic.
- FullSourceLoc L( S->getLocStart(), SMgr);
- std::ostringstream os;
-
- os << "Object allocated on line " << AllocLine;
-
- if (FirstBinding)
- os << " and stored into '" << FirstBinding->getString() << '\'';
-
- os << " is no longer referenced after this point and has a retain count of +"
- << RetCount << " (object leaked).";
-
- return new PathDiagnosticPiece(L, os.str(), Hint);
-}
-
-void UseAfterRelease::EmitWarnings(BugReporter& BR) {
-
- for (CFRefCount::use_after_iterator I = TF.use_after_begin(),
- E = TF.use_after_end(); I != E; ++I) {
-
- CFRefReport report(*this, I->first, I->second.second);
- report.addRange(I->second.first->getSourceRange());
- BR.EmitWarning(report);
- }
-}
-
-void BadRelease::EmitWarnings(BugReporter& BR) {
-
- for (CFRefCount::bad_release_iterator I = TF.bad_release_begin(),
- E = TF.bad_release_end(); I != E; ++I) {
-
- CFRefReport report(*this, I->first, I->second.second);
- report.addRange(I->second.first->getSourceRange());
- BR.EmitWarning(report);
- }
-}
-
-void Leak::EmitWarnings(BugReporter& BR) {
-
- for (CFRefCount::leaks_iterator I = TF.leaks_begin(),
- E = TF.leaks_end(); I != E; ++I) {
-
- std::vector<SymbolID>& SymV = *(I->second);
- unsigned n = SymV.size();
-
- for (unsigned i = 0; i < n; ++i) {
- CFRefReport report(*this, I->first, SymV[i]);
- BR.EmitWarning(report);
- }
- }
-}
-
-void Leak::GetErrorNodes(std::vector<ExplodedNode<GRState>*>& Nodes) {
- for (CFRefCount::leaks_iterator I=TF.leaks_begin(), E=TF.leaks_end();
- I!=E; ++I)
- Nodes.push_back(I->first);
-}
-
-bool Leak::isCached(BugReport& R) {
-
- // Most bug reports are cached at the location where they occured.
- // With leaks, we want to unique them by the location where they were
- // allocated, and only report only a single path.
-
- SymbolID Sym = static_cast<CFRefReport&>(R).getSymbol();
-
- ExplodedNode<GRState>* AllocNode =
- GetAllocationSite(0, R.getEndNode(), Sym).first;
-
- if (!AllocNode)
- return false;
-
- return BugTypeCacheLocation::isCached(AllocNode->getLocation());
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function creation for external clients.
-//===----------------------------------------------------------------------===//
-
-GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
- const LangOptions& lopts) {
- return new CFRefCount(Ctx, GCEnabled, lopts);
-}
diff --git a/clang/lib/Analysis/CheckDeadStores.cpp b/clang/lib/Analysis/CheckDeadStores.cpp
deleted file mode 100644
index d87bfb1964ec..000000000000
--- a/clang/lib/Analysis/CheckDeadStores.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-//==- DeadStores.cpp - Check for stores to dead variables --------*- 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 a DeadStores, a flow-sensitive checker that looks for
-// stores to variables that are no longer live.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ParentMap.h"
-#include "llvm/Support/Compiler.h"
-
-using namespace clang;
-
-namespace {
-
-class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
- ASTContext &Ctx;
- BugReporter& BR;
- ParentMap& Parents;
-
- enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
-
-public:
- DeadStoreObs(ASTContext &ctx, BugReporter& br, ParentMap& parents)
- : Ctx(ctx), BR(br), Parents(parents) {}
-
- virtual ~DeadStoreObs() {}
-
- void Report(VarDecl* V, DeadStoreKind dsk, SourceLocation L, SourceRange R) {
-
- std::string name(V->getName());
-
- const char* BugType = 0;
- std::string msg;
-
- switch (dsk) {
- default:
- assert(false && "Impossible dead store type.");
-
- case DeadInit:
- BugType = "dead initialization";
- msg = "Value stored to '" + name +
- "' during its initialization is never read";
- break;
-
- case DeadIncrement:
- BugType = "dead increment";
- case Standard:
- if (!BugType) BugType = "dead assignment";
- msg = "Value stored to '" + name + "' is never read";
- break;
-
- case Enclosing:
- BugType = "dead nested assignment";
- msg = "Although the value stored to '" + name +
- "' is used in the enclosing expression, the value is never actually"
- " read from '" + name + "'";
- break;
- }
-
- BR.EmitBasicReport(BugType, "Dead Store", msg.c_str(), L, R);
- }
-
- void CheckVarDecl(VarDecl* VD, Expr* Ex, Expr* Val,
- DeadStoreKind dsk,
- const LiveVariables::AnalysisDataTy& AD,
- const LiveVariables::ValTy& Live) {
-
- if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())
- Report(VD, dsk, Ex->getSourceRange().getBegin(),
- Val->getSourceRange());
- }
-
- void CheckDeclRef(DeclRefExpr* DR, Expr* Val, DeadStoreKind dsk,
- const LiveVariables::AnalysisDataTy& AD,
- const LiveVariables::ValTy& Live) {
-
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
- CheckVarDecl(VD, DR, Val, dsk, AD, Live);
- }
-
- bool isIncrement(VarDecl* VD, BinaryOperator* B) {
- if (B->isCompoundAssignmentOp())
- return true;
-
- Expr* RHS = B->getRHS()->IgnoreParenCasts();
- BinaryOperator* BRHS = dyn_cast<BinaryOperator>(RHS);
-
- if (!BRHS)
- return false;
-
- DeclRefExpr *DR;
-
- if ((DR = dyn_cast<DeclRefExpr>(BRHS->getLHS()->IgnoreParenCasts())))
- if (DR->getDecl() == VD)
- return true;
-
- if ((DR = dyn_cast<DeclRefExpr>(BRHS->getRHS()->IgnoreParenCasts())))
- if (DR->getDecl() == VD)
- return true;
-
- return false;
- }
-
- virtual void ObserveStmt(Stmt* S,
- const LiveVariables::AnalysisDataTy& AD,
- const LiveVariables::ValTy& Live) {
-
- // Skip statements in macros.
- if (S->getLocStart().isMacroID())
- return;
-
- if (BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
- if (!B->isAssignmentOp()) return; // Skip non-assignments.
-
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
- if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
- // Special case: check for assigning null to a pointer.
- // This is a common form of defensive programming.
- if (VD->getType()->isPointerType()) {
- if (IntegerLiteral* L =
- dyn_cast<IntegerLiteral>(B->getRHS()->IgnoreParenCasts()))
- // FIXME: Probably should have an Expr::isNullPointerConstant.
- if (L->getValue() == 0)
- return;
- }
-
- DeadStoreKind dsk =
- Parents.isSubExpr(B)
- ? Enclosing
- : (isIncrement(VD,B) ? DeadIncrement : Standard);
-
- CheckVarDecl(VD, DR, B->getRHS(), dsk, AD, Live);
- }
- }
- else if (UnaryOperator* U = dyn_cast<UnaryOperator>(S)) {
- if (!U->isIncrementOp())
- return;
-
- Expr *Ex = U->getSubExpr()->IgnoreParenCasts();
-
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex))
- CheckDeclRef(DR, U, DeadIncrement, AD, Live);
- }
- else if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
- // Iterate through the decls. Warn if any initializers are complex
- // expressions that are not live (never used).
- for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
- DI != DE; ++DI) {
-
- VarDecl* V = dyn_cast<VarDecl>(*DI);
-
- if (!V)
- continue;
-
- if (V->hasLocalStorage())
- if (Expr* E = V->getInit()) {
- // A dead initialization is a variable that is dead after it
- // is initialized. We don't flag warnings for those variables
- // marked 'unused'.
- if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {
- // Special case: check for initializations with constants.
- //
- // e.g. : int x = 0;
- //
- // If x is EVER assigned a new value later, don't issue
- // a warning. This is because such initialization can be
- // due to defensive programming.
- if (!E->isConstantExpr(Ctx,NULL))
- Report(V, DeadInit, V->getLocation(), E->getSourceRange());
- }
- }
- }
- }
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Driver function to invoke the Dead-Stores checker on a CFG.
-//===----------------------------------------------------------------------===//
-
-void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) {
- DeadStoreObs A(BR.getContext(), BR, BR.getParentMap());
- L.runOnAllBlocks(*BR.getCFG(), &A);
-}
diff --git a/clang/lib/Analysis/CheckNSError.cpp b/clang/lib/Analysis/CheckNSError.cpp
deleted file mode 100644
index 03c9af3a729c..000000000000
--- a/clang/lib/Analysis/CheckNSError.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-//=- CheckNSError.cpp - Coding conventions for uses of NSError ---*- 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 a CheckNSError, a flow-insenstive check
-// that determines if an Objective-C class interface correctly returns
-// a non-void return type.
-//
-// File under feature request PR 2600.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "BasicObjCFoundationChecks.h"
-#include "llvm/Support/Compiler.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Decl.h"
-#include "llvm/ADT/SmallVector.h"
-
-using namespace clang;
-
-namespace {
-class VISIBILITY_HIDDEN NSErrorCheck : public BugTypeCacheLocation {
-
- void EmitGRWarnings(GRBugReporter& BR);
-
- void CheckSignature(ObjCMethodDecl& MD, QualType& ResultTy,
- llvm::SmallVectorImpl<VarDecl*>& NSErrorParams,
- llvm::SmallVectorImpl<VarDecl*>& CFErrorParams,
- IdentifierInfo* NSErrorII,
- IdentifierInfo* CFErrorII);
-
- void CheckSignature(FunctionDecl& MD, QualType& ResultTy,
- llvm::SmallVectorImpl<VarDecl*>& NSErrorParams,
- llvm::SmallVectorImpl<VarDecl*>& CFErrorParams,
- IdentifierInfo* NSErrorII,
- IdentifierInfo* CFErrorII);
-
- bool CheckNSErrorArgument(QualType ArgTy, IdentifierInfo* NSErrorII);
- bool CheckCFErrorArgument(QualType ArgTy, IdentifierInfo* CFErrorII);
-
- void CheckParamDeref(VarDecl* V, GRStateRef state, GRExprEngine& Eng,
- GRBugReporter& BR, bool isNErrorWarning);
-
- void EmitRetTyWarning(BugReporter& BR, Decl& CodeDecl, bool isNSErrorWarning);
-
- const char* desc;
- const char* name;
-public:
- NSErrorCheck() : desc(0) {}
-
- void EmitWarnings(BugReporter& BR) { EmitGRWarnings(cast<GRBugReporter>(BR));}
- const char* getName() const { return name; }
- const char* getDescription() const { return desc; }
- const char* getCategory() const { return "Coding Conventions (Apple)"; }
-};
-
-} // end anonymous namespace
-
-BugType* clang::CreateNSErrorCheck() {
- return new NSErrorCheck();
-}
-
-void NSErrorCheck::EmitGRWarnings(GRBugReporter& BR) {
- // Get the analysis engine and the exploded analysis graph.
- GRExprEngine& Eng = BR.getEngine();
- GRExprEngine::GraphTy& G = Eng.getGraph();
-
- // Get the declaration of the method/function that was analyzed.
- Decl& CodeDecl = G.getCodeDecl();
-
- // Get the ASTContext, which is useful for querying type information.
- ASTContext &Ctx = BR.getContext();
-
- QualType ResultTy;
- llvm::SmallVector<VarDecl*, 5> NSErrorParams;
- llvm::SmallVector<VarDecl*, 5> CFErrorParams;
-
- if (ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CodeDecl))
- CheckSignature(*MD, ResultTy, NSErrorParams, CFErrorParams,
- &Ctx.Idents.get("NSError"), &Ctx.Idents.get("CFErrorRef"));
- else if (FunctionDecl* FD = dyn_cast<FunctionDecl>(&CodeDecl))
- CheckSignature(*FD, ResultTy, NSErrorParams, CFErrorParams,
- &Ctx.Idents.get("NSError"), &Ctx.Idents.get("CFErrorRef"));
- else
- return;
-
- if (NSErrorParams.empty() && CFErrorParams.empty())
- return;
-
- if (ResultTy == Ctx.VoidTy) {
- if (!NSErrorParams.empty())
- EmitRetTyWarning(BR, CodeDecl, true);
- if (!CFErrorParams.empty())
- EmitRetTyWarning(BR, CodeDecl, false);
- }
-
- for (GRExprEngine::GraphTy::roots_iterator RI=G.roots_begin(),
- RE=G.roots_end(); RI!=RE; ++RI) {
-
- // Scan the NSError** parameters for an implicit null dereference.
- for (llvm::SmallVectorImpl<VarDecl*>::iterator I=NSErrorParams.begin(),
- E=NSErrorParams.end(); I!=E; ++I)
- CheckParamDeref(*I, GRStateRef((*RI)->getState(), Eng.getStateManager()),
- Eng, BR, true);
-
- // Scan the CFErrorRef* parameters for an implicit null dereference.
- for (llvm::SmallVectorImpl<VarDecl*>::iterator I=CFErrorParams.begin(),
- E=CFErrorParams.end(); I!=E; ++I)
- CheckParamDeref(*I, GRStateRef((*RI)->getState(), Eng.getStateManager()),
- Eng, BR, false);
- }
-}
-
-void NSErrorCheck::EmitRetTyWarning(BugReporter& BR, Decl& CodeDecl,
- bool isNSErrorWarning) {
-
- std::string msg;
- llvm::raw_string_ostream os(msg);
-
- if (isa<ObjCMethodDecl>(CodeDecl))
- os << "Method";
- else
- os << "Function";
-
- os << " accepting ";
- os << (isNSErrorWarning ? "NSError**" : "CFErrorRef*");
- os << " should have a non-void return value to indicate whether or not an "
- "error occured.";
-
- BR.EmitBasicReport(isNSErrorWarning
- ? "Bad return type when passing NSError**"
- : "Bad return type when passing CFError*",
- getCategory(), os.str().c_str(), CodeDecl.getLocation());
-}
-
-void
-NSErrorCheck::CheckSignature(ObjCMethodDecl& M, QualType& ResultTy,
- llvm::SmallVectorImpl<VarDecl*>& NSErrorParams,
- llvm::SmallVectorImpl<VarDecl*>& CFErrorParams,
- IdentifierInfo* NSErrorII,
- IdentifierInfo* CFErrorII) {
-
- ResultTy = M.getResultType();
-
- for (ObjCMethodDecl::param_iterator I=M.param_begin(),
- E=M.param_end(); I!=E; ++I) {
-
- QualType T = (*I)->getType();
-
- if (CheckNSErrorArgument(T, NSErrorII))
- NSErrorParams.push_back(*I);
- else if (CheckCFErrorArgument(T, CFErrorII))
- CFErrorParams.push_back(*I);
- }
-}
-
-void
-NSErrorCheck::CheckSignature(FunctionDecl& F, QualType& ResultTy,
- llvm::SmallVectorImpl<VarDecl*>& NSErrorParams,
- llvm::SmallVectorImpl<VarDecl*>& CFErrorParams,
- IdentifierInfo* NSErrorII,
- IdentifierInfo* CFErrorII) {
-
- ResultTy = F.getResultType();
-
- for (FunctionDecl::param_iterator I=F.param_begin(),
- E=F.param_end(); I!=E; ++I) {
-
- QualType T = (*I)->getType();
-
- if (CheckNSErrorArgument(T, NSErrorII))
- NSErrorParams.push_back(*I);
- else if (CheckCFErrorArgument(T, CFErrorII))
- CFErrorParams.push_back(*I);
- }
-}
-
-
-bool NSErrorCheck::CheckNSErrorArgument(QualType ArgTy,
- IdentifierInfo* NSErrorII) {
-
- const PointerType* PPT = ArgTy->getAsPointerType();
- if (!PPT) return false;
-
- const PointerType* PT = PPT->getPointeeType()->getAsPointerType();
- if (!PT) return false;
-
- const ObjCInterfaceType *IT =
- PT->getPointeeType()->getAsObjCInterfaceType();
-
- if (!IT) return false;
- return IT->getDecl()->getIdentifier() == NSErrorII;
-}
-
-bool NSErrorCheck::CheckCFErrorArgument(QualType ArgTy,
- IdentifierInfo* CFErrorII) {
-
- const PointerType* PPT = ArgTy->getAsPointerType();
- if (!PPT) return false;
-
- const TypedefType* TT = PPT->getPointeeType()->getAsTypedefType();
- if (!TT) return false;
-
- return TT->getDecl()->getIdentifier() == CFErrorII;
-}
-
-void NSErrorCheck::CheckParamDeref(VarDecl* Param, GRStateRef rootState,
- GRExprEngine& Eng, GRBugReporter& BR,
- bool isNSErrorWarning) {
-
- RVal ParamRVal = rootState.GetRVal(Eng.getLVal(Param));
-
- // FIXME: For now assume that ParamRVal is symbolic. We need to generalize
- // this later.
- lval::SymbolVal* SV = dyn_cast<lval::SymbolVal>(&ParamRVal);
- if (!SV) return;
-
- // Iterate over the implicit-null dereferences.
- for (GRExprEngine::null_deref_iterator I=Eng.implicit_null_derefs_begin(),
- E=Eng.implicit_null_derefs_end(); I!=E; ++I) {
-
- GRStateRef state = GRStateRef((*I)->getState(), Eng.getStateManager());
- const RVal* X = state.get<GRState::NullDerefTag>();
- const lval::SymbolVal* SVX = dyn_cast_or_null<lval::SymbolVal>(X);
- if (!SVX || SVX->getSymbol() != SV->getSymbol()) continue;
-
- // Emit an error.
- BugReport R(*this, *I);
-
- name = isNSErrorWarning ? "NSError** null dereference"
- : "CFErrorRef* null dereference";
-
- std::string msg;
- llvm::raw_string_ostream os(msg);
- os << "Potential null dereference. According to coding standards ";
-
- if (isNSErrorWarning)
- os << "in 'Creating and Returning NSError Objects' the parameter '";
- else
- os << "documented in CoreFoundation/CFError.h the parameter '";
-
- os << Param->getName() << "' may be null.";
- desc = os.str().c_str();
-
- BR.addNotableSymbol(SV->getSymbol());
- BR.EmitWarning(R);
- }
-}
diff --git a/clang/lib/Analysis/CheckObjCDealloc.cpp b/clang/lib/Analysis/CheckObjCDealloc.cpp
deleted file mode 100644
index f6a3fd0112de..000000000000
--- a/clang/lib/Analysis/CheckObjCDealloc.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-//==- CheckObjCDealloc.cpp - Check ObjC -dealloc implementation --*- 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 a CheckObjCDealloc, a checker that
-// analyzes an Objective-C class's implementation to determine if it
-// correctly implements -dealloc.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/LangOptions.h"
-#include <sstream>
-
-using namespace clang;
-
-static bool scan_dealloc(Stmt* S, Selector Dealloc) {
-
- if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
- if (ME->getSelector() == Dealloc)
- if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
- if (PredefinedExpr* E = dyn_cast<PredefinedExpr>(Receiver))
- if (E->getIdentType() == PredefinedExpr::ObjCSuper)
- return true;
-
- // Recurse to children.
-
- for (Stmt::child_iterator I = S->child_begin(), E= S->child_end(); I!=E; ++I)
- if (*I && scan_dealloc(*I, Dealloc))
- return true;
-
- return false;
-}
-
-void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
- const LangOptions& LOpts, BugReporter& BR) {
-
- assert (LOpts.getGCMode() != LangOptions::GCOnly);
-
- ASTContext& Ctx = BR.getContext();
- ObjCInterfaceDecl* ID = D->getClassInterface();
-
- // Does the class contain any ivars that are pointers (or id<...>)?
- // If not, skip the check entirely.
- // NOTE: This is motivated by PR 2517:
- // http://llvm.org/bugs/show_bug.cgi?id=2517
-
- bool containsPointerIvar = false;
-
- for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
- I!=E; ++I) {
-
- ObjCIvarDecl* ID = *I;
- QualType T = ID->getType();
-
- if (!Ctx.isObjCObjectPointerType(T) ||
- ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
- continue;
-
- containsPointerIvar = true;
- break;
- }
-
- if (!containsPointerIvar)
- return;
-
- // Determine if the class subclasses NSObject.
- IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");
-
- for ( ; ID ; ID = ID->getSuperClass())
- if (ID->getIdentifier() == NSObjectII)
- break;
-
- if (!ID)
- return;
-
- // Get the "dealloc" selector.
- IdentifierInfo* II = &Ctx.Idents.get("dealloc");
- Selector S = Ctx.Selectors.getSelector(0, &II);
- ObjCMethodDecl* MD = 0;
-
- // Scan the instance methods for "dealloc".
- for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
- E = D->instmeth_end(); I!=E; ++I) {
-
- if ((*I)->getSelector() == S) {
- MD = *I;
- break;
- }
- }
-
- if (!MD) { // No dealloc found.
-
- const char* name = LOpts.getGCMode() == LangOptions::NonGC
- ? "missing -dealloc"
- : "missing -dealloc (Hybrid MM, non-GC)";
-
- std::ostringstream os;
- os << "Objective-C class '" << D->getName()
- << "' lacks a 'dealloc' instance method";
-
- BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart());
- return;
- }
-
- // dealloc found. Scan for missing [super dealloc].
- if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {
-
- const char* name = LOpts.getGCMode() == LangOptions::NonGC
- ? "missing [super dealloc]"
- : "missing [super dealloc] (Hybrid MM, non-GC)";
-
- std::ostringstream os;
- os << "The 'dealloc' instance method in Objective-C class '" << D->getName()
- << "' does not send a 'dealloc' message to its super class"
- " (missing [super dealloc])";
-
- BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart());
- return;
- }
-}
-
diff --git a/clang/lib/Analysis/CheckObjCInstMethSignature.cpp b/clang/lib/Analysis/CheckObjCInstMethSignature.cpp
deleted file mode 100644
index ffaef42b2359..000000000000
--- a/clang/lib/Analysis/CheckObjCInstMethSignature.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//=- CheckObjCInstMethodRetTy.cpp - Check ObjC method signatures -*- 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 a CheckObjCInstMethSignature, a flow-insenstive check
-// that determines if an Objective-C class interface incorrectly redefines
-// the method signature in a subclass.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/ASTContext.h"
-
-#include "llvm/ADT/DenseMap.h"
-#include <sstream>
-
-using namespace clang;
-
-static bool AreTypesCompatible(QualType Derived, QualType Ancestor,
- ASTContext& C) {
-
- // Right now don't compare the compatibility of pointers. That involves
- // looking at subtyping relationships. FIXME: Future patch.
- if ((Derived->isPointerType() || Derived->isObjCQualifiedIdType()) &&
- (Ancestor->isPointerType() || Ancestor->isObjCQualifiedIdType()))
- return true;
-
- return C.typesAreCompatible(Derived, Ancestor);
-}
-
-static void CompareReturnTypes(ObjCMethodDecl* MethDerived,
- ObjCMethodDecl* MethAncestor,
- BugReporter& BR, ASTContext& Ctx,
- ObjCImplementationDecl* ID) {
-
- QualType ResDerived = MethDerived->getResultType();
- QualType ResAncestor = MethAncestor->getResultType();
-
- if (!AreTypesCompatible(ResDerived, ResAncestor, Ctx)) {
- std::ostringstream os;
-
- os << "The Objective-C class '"
- << MethDerived->getClassInterface()->getName()
- << "', which is derived from class '"
- << MethAncestor->getClassInterface()->getName()
- << "', defines the instance method '"
- << MethDerived->getSelector().getName()
- << "' whose return type is '"
- << ResDerived.getAsString()
- << "'. A method with the same name (same selector) is also defined in "
- "class '"
- << MethAncestor->getClassInterface()->getName()
- << "' and has a return type of '"
- << ResAncestor.getAsString()
- << "'. These two types are incompatible, and may result in undefined "
- "behavior for clients of these classes.";
-
- BR.EmitBasicReport("incompatible instance method return type",
- os.str().c_str(), MethDerived->getLocStart());
- }
-}
-
-void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
- BugReporter& BR) {
-
- ObjCInterfaceDecl* D = ID->getClassInterface();
- ObjCInterfaceDecl* C = D->getSuperClass();
-
- if (!C)
- return;
-
- // Build a DenseMap of the methods for quick querying.
- typedef llvm::DenseMap<Selector,ObjCMethodDecl*> MapTy;
- MapTy IMeths;
- unsigned NumMethods = 0;
-
- for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
- E=ID->instmeth_end(); I!=E; ++I) {
-
- ObjCMethodDecl* M = *I;
- IMeths[M->getSelector()] = M;
- ++NumMethods;
- }
-
- // Now recurse the class hierarchy chain looking for methods with the
- // same signatures.
- ASTContext& Ctx = BR.getContext();
-
- while (C && NumMethods) {
- for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(),
- E=C->instmeth_end(); I!=E; ++I) {
-
- ObjCMethodDecl* M = *I;
- Selector S = M->getSelector();
-
- MapTy::iterator MI = IMeths.find(S);
-
- if (MI == IMeths.end() || MI->second == 0)
- continue;
-
- --NumMethods;
- ObjCMethodDecl* MethDerived = MI->second;
- MI->second = 0;
-
- CompareReturnTypes(MethDerived, M, BR, Ctx, ID);
- }
-
- C = C->getSuperClass();
- }
-}
diff --git a/clang/lib/Analysis/CheckObjCUnusedIVars.cpp b/clang/lib/Analysis/CheckObjCUnusedIVars.cpp
deleted file mode 100644
index c2deeeff8fe4..000000000000
--- a/clang/lib/Analysis/CheckObjCUnusedIVars.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//==- CheckObjCUnusedIVars.cpp - Check for unused ivars ----------*- 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 a CheckObjCUnusedIvars, a checker that
-// analyzes an Objective-C class's interface/implementation to determine if it
-// has any ivars that are never accessed.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/LangOptions.h"
-#include <sstream>
-
-using namespace clang;
-
-enum IVarState { Unused, Used };
-typedef llvm::DenseMap<ObjCIvarDecl*,IVarState> IvarUsageMap;
-
-static void Scan(IvarUsageMap& M, Stmt* S) {
- if (!S)
- return;
-
- if (ObjCIvarRefExpr* Ex = dyn_cast<ObjCIvarRefExpr>(S)) {
- ObjCIvarDecl* D = Ex->getDecl();
- IvarUsageMap::iterator I = M.find(D);
- if (I != M.end()) I->second = Used;
- return;
- }
-
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E;++I)
- Scan(M, *I);
-}
-
-static void Scan(IvarUsageMap& M, ObjCPropertyImplDecl* D) {
- if (!D)
- return;
-
- ObjCIvarDecl* ID = D->getPropertyIvarDecl();
-
- if (!ID)
- return;
-
- IvarUsageMap::iterator I = M.find(ID);
- if (I != M.end()) I->second = Used;
-}
-
-void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
-
- ObjCInterfaceDecl* ID = D->getClassInterface();
- IvarUsageMap M;
-
-
-
- // Iterate over the ivars.
- for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
- I!=E; ++I) {
-
- ObjCIvarDecl* ID = *I;
-
- // Ignore ivars that aren't private.
- if (ID->getAccessControl() != ObjCIvarDecl::Private)
- continue;
-
- // Skip IB Outlets.
- if (ID->getAttr<IBOutletAttr>())
- continue;
-
- M[ID] = Unused;
- }
-
- if (M.empty())
- return;
-
- // Now scan the methods for accesses.
- for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
- E = D->instmeth_end(); I!=E; ++I)
- Scan(M, (*I)->getBody());
-
- // Scan for @synthesized property methods that act as setters/getters
- // to an ivar.
- for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
- E = D->propimpl_end(); I!=E; ++I)
- Scan(M, *I);
-
- // Find ivars that are unused.
- for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
- if (I->second == Unused) {
-
- std::ostringstream os;
- os << "Instance variable '" << I->first->getName()
- << "' in class '" << ID->getName()
- << "' is never used by the methods in its @implementation "
- "(although it may be used by category methods).";
-
- BR.EmitBasicReport("unused ivar", "Optimization",
- os.str().c_str(), I->first->getLocation());
- }
-}
-
diff --git a/clang/lib/Analysis/Environment.cpp b/clang/lib/Analysis/Environment.cpp
deleted file mode 100644
index f86c4fea7165..000000000000
--- a/clang/lib/Analysis/Environment.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-//== Environment.cpp - Map from Expr* to Locations/Values -------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the Environment and EnvironmentManager classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/Environment.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/Support/Streams.h"
-
-using namespace clang;
-
-RVal Environment::GetRVal(Expr* E, BasicValueFactory& BasicVals) const {
-
- for (;;) {
-
- switch (E->getStmtClass()) {
-
- case Stmt::AddrLabelExprClass:
- return LVal::MakeVal(cast<AddrLabelExpr>(E));
-
- // ParenExprs are no-ops.
-
- case Stmt::ParenExprClass:
- E = cast<ParenExpr>(E)->getSubExpr();
- continue;
-
- case Stmt::CharacterLiteralClass: {
- CharacterLiteral* C = cast<CharacterLiteral>(E);
- return NonLVal::MakeVal(BasicVals, C->getValue(), C->getType());
- }
-
- case Stmt::IntegerLiteralClass: {
- return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
- }
-
- case Stmt::StringLiteralClass:
- return LVal::MakeVal(cast<StringLiteral>(E));
-
- // Casts where the source and target type are the same
- // are no-ops. We blast through these to get the descendant
- // subexpression that has a value.
-
- case Stmt::ImplicitCastExprClass:
- case Stmt::ExplicitCastExprClass: {
- CastExpr* C = cast<CastExpr>(E);
- QualType CT = C->getType();
- QualType ST = C->getSubExpr()->getType();
-
- if (CT->isVoidType())
- return UnknownVal();
-
- break;
- }
-
- // Handle all other Expr* using a lookup.
-
- default:
- break;
- };
-
- break;
- }
-
- return LookupExpr(E);
-}
-
-RVal Environment::GetBlkExprRVal(Expr* E, BasicValueFactory& BasicVals) const {
-
- E = E->IgnoreParens();
-
- switch (E->getStmtClass()) {
- case Stmt::CharacterLiteralClass: {
- CharacterLiteral* C = cast<CharacterLiteral>(E);
- return NonLVal::MakeVal(BasicVals, C->getValue(), C->getType());
- }
-
- case Stmt::IntegerLiteralClass: {
- return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
- }
-
- default:
- return LookupBlkExpr(E);
- }
-}
-
-Environment EnvironmentManager::SetRVal(const Environment& Env, Expr* E, RVal V,
- bool isBlkExpr, bool Invalidate) {
- assert (E);
-
- if (V.isUnknown()) {
- if (Invalidate)
- return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
- else
- return Env;
- }
-
- return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
-}
-
-Environment
-EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
- const LiveVariables& Liveness,
- llvm::SmallVectorImpl<const MemRegion*>& DRoots,
- StoreManager::LiveSymbolsTy& LSymbols) {
-
- // Drop bindings for subexpressions.
- Env = RemoveSubExprBindings(Env);
-
- // Iterate over the block-expr bindings.
- for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
- I != E; ++I) {
- Expr* BlkExpr = I.getKey();
-
- if (Liveness.isLive(Loc, BlkExpr)) {
- RVal X = I.getData();
-
- // If the block expr's value is a memory region, then mark that region.
- if (isa<lval::MemRegionVal>(X))
- DRoots.push_back(cast<lval::MemRegionVal>(X).getRegion());
-
-
- // Mark all symbols in the block expr's value.
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI) {
- LSymbols.insert(*SI);
- }
- } else {
- // The block expr is dead.
- RVal X = I.getData();
-
- // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
- // beginning of itself, but we need its UndefinedVal to determine its
- // RVal.
-
- if (X.isUndef() && cast<UndefinedVal>(X).getData())
- continue;
-
- Env = RemoveBlkExpr(Env, BlkExpr);
- }
- }
-
- return Env;
-}
diff --git a/clang/lib/Analysis/ExplodedGraph.cpp b/clang/lib/Analysis/ExplodedGraph.cpp
deleted file mode 100644
index 945416b1b56e..000000000000
--- a/clang/lib/Analysis/ExplodedGraph.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-//=-- ExplodedGraph.cpp - Local, Path-Sens. "Exploded Graph" -*- 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 template classes ExplodedNode and ExplodedGraph,
-// which represent a path-sensitive, intra-procedural "exploded graph."
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/AST/Stmt.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include <vector>
-#include <list>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Node auditing.
-//===----------------------------------------------------------------------===//
-
-// An out of line virtual method to provide a home for the class vtable.
-ExplodedNodeImpl::Auditor::~Auditor() {}
-
-#ifndef NDEBUG
-static ExplodedNodeImpl::Auditor* NodeAuditor = 0;
-#endif
-
-void ExplodedNodeImpl::SetAuditor(ExplodedNodeImpl::Auditor* A) {
-#ifndef NDEBUG
- NodeAuditor = A;
-#endif
-}
-
-//===----------------------------------------------------------------------===//
-// ExplodedNodeImpl.
-//===----------------------------------------------------------------------===//
-
-static inline std::vector<ExplodedNodeImpl*>& getVector(void* P) {
- return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P);
-}
-
-void ExplodedNodeImpl::addPredecessor(ExplodedNodeImpl* V) {
- assert (!V->isSink());
- Preds.addNode(V);
- V->Succs.addNode(this);
-#ifndef NDEBUG
- if (NodeAuditor) NodeAuditor->AddEdge(V, this);
-#endif
-}
-
-void ExplodedNodeImpl::NodeGroup::addNode(ExplodedNodeImpl* N) {
-
- assert ((reinterpret_cast<uintptr_t>(N) & Mask) == 0x0);
- assert (!getFlag());
-
- if (getKind() == Size1) {
- if (ExplodedNodeImpl* NOld = getNode()) {
- std::vector<ExplodedNodeImpl*>* V = new std::vector<ExplodedNodeImpl*>();
- assert ((reinterpret_cast<uintptr_t>(V) & Mask) == 0x0);
- V->push_back(NOld);
- V->push_back(N);
- P = reinterpret_cast<uintptr_t>(V) | SizeOther;
- assert (getPtr() == (void*) V);
- assert (getKind() == SizeOther);
- }
- else {
- P = reinterpret_cast<uintptr_t>(N);
- assert (getKind() == Size1);
- }
- }
- else {
- assert (getKind() == SizeOther);
- getVector(getPtr()).push_back(N);
- }
-}
-
-
-unsigned ExplodedNodeImpl::NodeGroup::size() const {
- if (getFlag())
- return 0;
-
- if (getKind() == Size1)
- return getNode() ? 1 : 0;
- else
- return getVector(getPtr()).size();
-}
-
-ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::begin() const {
- if (getFlag())
- return NULL;
-
- if (getKind() == Size1)
- return (ExplodedNodeImpl**) (getPtr() ? &P : NULL);
- else
- return const_cast<ExplodedNodeImpl**>(&*(getVector(getPtr()).begin()));
-}
-
-ExplodedNodeImpl** ExplodedNodeImpl::NodeGroup::end() const {
- if (getFlag())
- return NULL;
-
- if (getKind() == Size1)
- return (ExplodedNodeImpl**) (getPtr() ? &P+1 : NULL);
- else {
- // Dereferencing end() is undefined behaviour. The vector is not empty, so
- // we can dereference the last elem and then add 1 to the result.
- return const_cast<ExplodedNodeImpl**>(&getVector(getPtr()).back()) + 1;
- }
-}
-
-ExplodedNodeImpl::NodeGroup::~NodeGroup() {
- if (getKind() == SizeOther) delete &getVector(getPtr());
-}
-
-ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources,
- ExplodedNodeImpl** EndSources) const{
-
- typedef llvm::DenseMap<ExplodedNodeImpl*, ExplodedNodeImpl*> Pass1Ty;
- typedef llvm::DenseMap<ExplodedNodeImpl*, ExplodedNodeImpl*> Pass2Ty;
-
- Pass1Ty Pass1;
- Pass2Ty Pass2;
-
- llvm::SmallVector<ExplodedNodeImpl*, 10> WL2;
-
- { // ===- Pass 1 (reverse BFS) -===
-
- // Enqueue the source nodes to the first worklist.
-
- std::list<std::pair<ExplodedNodeImpl*, ExplodedNodeImpl*> > WL1;
- std::list<std::pair<ExplodedNodeImpl*, ExplodedNodeImpl*> > WL1_Loops;
-
- for (ExplodedNodeImpl** I = BeginSources; I != EndSources; ++I)
- WL1.push_back(std::make_pair(*I, *I));
-
- // Process the worklist.
-
- while (! (WL1.empty() && WL1_Loops.empty())) {
-
- ExplodedNodeImpl *N, *Src;
-
- // Only dequeue from the "loops" worklist if WL1 has no items.
- // Thus we prioritize for paths that don't span loop boundaries.
-
- if (WL1.empty()) {
- N = WL1_Loops.back().first;
- Src = WL1_Loops.back().second;
- WL1_Loops.pop_back();
- }
- else {
- N = WL1.back().first;
- Src = WL1.back().second;
- WL1.pop_back();
- }
-
- if (Pass1.find(N) != Pass1.end())
- continue;
-
- bool PredHasSameSource = false;
- bool VisitPreds = true;
-
- for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end();
- I!=E; ++I) {
-
- Pass1Ty::iterator pi = Pass1.find(*I);
-
- if (pi == Pass1.end())
- continue;
-
- VisitPreds = false;
-
- if (pi->second == Src) {
- PredHasSameSource = true;
- break;
- }
- }
-
- if (VisitPreds || !PredHasSameSource) {
-
- Pass1[N] = Src;
-
- if (N->Preds.empty()) {
- WL2.push_back(N);
- continue;
- }
- }
- else
- Pass1[N] = NULL;
-
- if (VisitPreds)
- for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end();
- I!=E; ++I) {
-
- ProgramPoint P = Src->getLocation();
-
- if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
- if (Stmt* T = BE->getSrc()->getTerminator())
- switch (T->getStmtClass()) {
- default: break;
- case Stmt::ForStmtClass:
- case Stmt::WhileStmtClass:
- case Stmt::DoStmtClass:
- WL1_Loops.push_front(std::make_pair(*I, Src));
- continue;
-
- }
-
- WL1.push_front(std::make_pair(*I, Src));
- }
- }
- }
-
- if (WL2.empty())
- return NULL;
-
- ExplodedGraphImpl* G = MakeEmptyGraph();
-
- // ===- Pass 2 (forward DFS to construct the new graph) -===
-
- while (!WL2.empty()) {
-
- ExplodedNodeImpl* N = WL2.back();
- WL2.pop_back();
-
- // Skip this node if we have already processed it.
-
- if (Pass2.find(N) != Pass2.end())
- continue;
-
- // Create the corresponding node in the new graph.
-
- ExplodedNodeImpl* NewN = G->getNodeImpl(N->getLocation(), N->State, NULL);
- Pass2[N] = NewN;
-
- if (N->Preds.empty())
- G->addRoot(NewN);
-
- // In the case that some of the intended predecessors of NewN have already
- // been created, we should hook them up as predecessors.
-
- for (ExplodedNodeImpl **I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I) {
-
- Pass2Ty::iterator PI = Pass2.find(*I);
-
- if (PI == Pass2.end())
- continue;
-
- NewN->addPredecessor(PI->second);
- }
-
- // In the case that some of the intended successors of NewN have already
- // been created, we should hook them up as successors. Otherwise, enqueue
- // the new nodes from the original graph that should have nodes created
- // in the new graph.
-
- for (ExplodedNodeImpl **I=N->Succs.begin(), **E=N->Succs.end(); I!=E; ++I) {
-
- Pass2Ty::iterator PI = Pass2.find(*I);
-
- if (PI != Pass2.end()) {
- PI->second->addPredecessor(NewN);
- continue;
- }
-
- // Enqueue nodes to the worklist that were marked during pass 1.
-
- Pass1Ty::iterator pi = Pass1.find(*I);
-
- if (pi == Pass1.end() || pi->second == NULL)
- continue;
-
- WL2.push_back(*I);
- }
-
- if (N->isSink())
- NewN->markAsSink();
- }
-
- return G;
-}
diff --git a/clang/lib/Analysis/GRBlockCounter.cpp b/clang/lib/Analysis/GRBlockCounter.cpp
deleted file mode 100644
index f69a16da401c..000000000000
--- a/clang/lib/Analysis/GRBlockCounter.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//==- GRBlockCounter.h - ADT for counting block visits -------------*- 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 GRBlockCounter, an abstract data type used to count
-// the number of times a given block has been visited along a path
-// analyzed by GRCoreEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
-#include "llvm/ADT/ImmutableMap.h"
-
-using namespace clang;
-
-typedef llvm::ImmutableMap<unsigned,unsigned> CountMap;
-
-static inline CountMap GetMap(void* D) {
- return CountMap(static_cast<CountMap::TreeTy*>(D));
-}
-
-static inline CountMap::Factory& GetFactory(void* F) {
- return *static_cast<CountMap::Factory*>(F);
-}
-
-unsigned GRBlockCounter::getNumVisited(unsigned BlockID) const {
- CountMap M = GetMap(Data);
- CountMap::data_type* T = M.lookup(BlockID);
- return T ? *T : 0;
-}
-
-GRBlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
- F = new CountMap::Factory(Alloc);
-}
-
-GRBlockCounter::Factory::~Factory() {
- delete static_cast<CountMap::Factory*>(F);
-}
-
-GRBlockCounter
-GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC, unsigned BlockID) {
- return GRBlockCounter(GetFactory(F).Add(GetMap(BC.Data), BlockID,
- BC.getNumVisited(BlockID)+1).getRoot());
-}
-
-GRBlockCounter
-GRBlockCounter::Factory::GetEmptyCounter() {
- return GRBlockCounter(GetFactory(F).GetEmptyMap().getRoot());
-}
diff --git a/clang/lib/Analysis/GRCoreEngine.cpp b/clang/lib/Analysis/GRCoreEngine.cpp
deleted file mode 100644
index 84a8d5522deb..000000000000
--- a/clang/lib/Analysis/GRCoreEngine.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-//==- GRCoreEngine.cpp - Path-Sensitive Dataflow Engine ----------------*- 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 a generic engine for intraprocedural, path-sensitive,
-// dataflow analysis via graph reachability engine.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/AST/Expr.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/ADT/DenseMap.h"
-#include <vector>
-
-using llvm::cast;
-using llvm::isa;
-using namespace clang;
-
-namespace {
- class VISIBILITY_HIDDEN DFS : public GRWorkList {
- llvm::SmallVector<GRWorkListUnit,20> Stack;
-public:
- virtual bool hasWork() const {
- return !Stack.empty();
- }
-
- virtual void Enqueue(const GRWorkListUnit& U) {
- Stack.push_back(U);
- }
-
- virtual GRWorkListUnit Dequeue() {
- assert (!Stack.empty());
- const GRWorkListUnit& U = Stack.back();
- Stack.pop_back(); // This technically "invalidates" U, but we are fine.
- return U;
- }
-};
-} // end anonymous namespace
-
-// Place the dstor for GRWorkList here because it contains virtual member
-// functions, and we the code for the dstor generated in one compilation unit.
-GRWorkList::~GRWorkList() {}
-
-GRWorkList* GRWorkList::MakeDFS() { return new DFS(); }
-
-/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
-bool GRCoreEngineImpl::ExecuteWorkList(unsigned Steps) {
-
- if (G->num_roots() == 0) { // Initialize the analysis by constructing
- // the root if none exists.
-
- CFGBlock* Entry = &getCFG().getEntry();
-
- assert (Entry->empty() &&
- "Entry block must be empty.");
-
- assert (Entry->succ_size() == 1 &&
- "Entry block must have 1 successor.");
-
- // Get the solitary successor.
- CFGBlock* Succ = *(Entry->succ_begin());
-
- // Construct an edge representing the
- // starting location in the function.
- BlockEdge StartLoc(Entry, Succ);
-
- // Set the current block counter to being empty.
- WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
-
- // Generate the root.
- GenerateNode(StartLoc, getInitialState(), 0);
- }
-
- while (Steps && WList->hasWork()) {
- --Steps;
- const GRWorkListUnit& WU = WList->Dequeue();
-
- // Set the current block counter.
- WList->setBlockCounter(WU.getBlockCounter());
-
- // Retrieve the node.
- ExplodedNodeImpl* Node = WU.getNode();
-
- // Dispatch on the location type.
- switch (Node->getLocation().getKind()) {
- default:
- assert (isa<BlockEdge>(Node->getLocation()));
- HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
- break;
-
- case ProgramPoint::BlockEntranceKind:
- HandleBlockEntrance(cast<BlockEntrance>(Node->getLocation()), Node);
- break;
-
- case ProgramPoint::BlockExitKind:
- assert (false && "BlockExit location never occur in forward analysis.");
- break;
-
- case ProgramPoint::PostLoadKind:
- case ProgramPoint::PostStmtKind:
- HandlePostStmt(cast<PostStmt>(Node->getLocation()), WU.getBlock(),
- WU.getIndex(), Node);
- break;
- }
- }
-
- return WList->hasWork();
-}
-
-void GRCoreEngineImpl::HandleBlockEdge(const BlockEdge& L,
- ExplodedNodeImpl* Pred) {
-
- CFGBlock* Blk = L.getDst();
-
- // Check if we are entering the EXIT block.
- if (Blk == &getCFG().getExit()) {
-
- assert (getCFG().getExit().size() == 0
- && "EXIT block cannot contain Stmts.");
-
- // Process the final state transition.
- GREndPathNodeBuilderImpl Builder(Blk, Pred, this);
- ProcessEndPath(Builder);
-
- // This path is done. Don't enqueue any more nodes.
- return;
- }
-
- // FIXME: Should we allow ProcessBlockEntrance to also manipulate state?
-
- if (ProcessBlockEntrance(Blk, Pred->State, WList->getBlockCounter()))
- GenerateNode(BlockEntrance(Blk), Pred->State, Pred);
-}
-
-void GRCoreEngineImpl::HandleBlockEntrance(const BlockEntrance& L,
- ExplodedNodeImpl* Pred) {
-
- // Increment the block counter.
- GRBlockCounter Counter = WList->getBlockCounter();
- Counter = BCounterFactory.IncrementCount(Counter, L.getBlock()->getBlockID());
- WList->setBlockCounter(Counter);
-
- // Process the entrance of the block.
- if (Stmt* S = L.getFirstStmt()) {
- GRStmtNodeBuilderImpl Builder(L.getBlock(), 0, Pred, this);
- ProcessStmt(S, Builder);
- }
- else
- HandleBlockExit(L.getBlock(), Pred);
-}
-
-GRCoreEngineImpl::~GRCoreEngineImpl() {
- delete WList;
-}
-
-void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) {
-
- if (Stmt* Term = B->getTerminator()) {
- switch (Term->getStmtClass()) {
- default:
- assert(false && "Analysis for this terminator not implemented.");
- break;
-
- case Stmt::BinaryOperatorClass: // '&&' and '||'
- HandleBranch(cast<BinaryOperator>(Term)->getLHS(), Term, B, Pred);
- return;
-
- case Stmt::ConditionalOperatorClass:
- HandleBranch(cast<ConditionalOperator>(Term)->getCond(), Term, B, Pred);
- return;
-
- // FIXME: Use constant-folding in CFG construction to simplify this
- // case.
-
- case Stmt::ChooseExprClass:
- HandleBranch(cast<ChooseExpr>(Term)->getCond(), Term, B, Pred);
- return;
-
- case Stmt::DoStmtClass:
- HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
- return;
-
- case Stmt::ForStmtClass:
- HandleBranch(cast<ForStmt>(Term)->getCond(), Term, B, Pred);
- return;
-
- case Stmt::ContinueStmtClass:
- case Stmt::BreakStmtClass:
- case Stmt::GotoStmtClass:
- break;
-
- case Stmt::IfStmtClass:
- HandleBranch(cast<IfStmt>(Term)->getCond(), Term, B, Pred);
- return;
-
- case Stmt::IndirectGotoStmtClass: {
- // Only 1 successor: the indirect goto dispatch block.
- assert (B->succ_size() == 1);
-
- GRIndirectGotoNodeBuilderImpl
- builder(Pred, B, cast<IndirectGotoStmt>(Term)->getTarget(),
- *(B->succ_begin()), this);
-
- ProcessIndirectGoto(builder);
- return;
- }
-
- case Stmt::SwitchStmtClass: {
- GRSwitchNodeBuilderImpl builder(Pred, B,
- cast<SwitchStmt>(Term)->getCond(),
- this);
-
- ProcessSwitch(builder);
- return;
- }
-
- case Stmt::WhileStmtClass:
- HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
- return;
- }
- }
-
- assert (B->succ_size() == 1 &&
- "Blocks with no terminator should have at most 1 successor.");
-
- GenerateNode(BlockEdge(B, *(B->succ_begin())), Pred->State, Pred);
-}
-
-void GRCoreEngineImpl::HandleBranch(Expr* Cond, Stmt* Term, CFGBlock * B,
- ExplodedNodeImpl* Pred) {
- assert (B->succ_size() == 2);
-
- GRBranchNodeBuilderImpl Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
- Pred, this);
-
- ProcessBranch(Cond, Term, Builder);
-}
-
-void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
- unsigned StmtIdx, ExplodedNodeImpl* Pred) {
-
- assert (!B->empty());
-
- if (StmtIdx == B->size())
- HandleBlockExit(B, Pred);
- else {
- GRStmtNodeBuilderImpl Builder(B, StmtIdx, Pred, this);
- ProcessStmt((*B)[StmtIdx], Builder);
- }
-}
-
-/// GenerateNode - Utility method to generate nodes, hook up successors,
-/// and add nodes to the worklist.
-void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State,
- ExplodedNodeImpl* Pred) {
-
- bool IsNew;
- ExplodedNodeImpl* Node = G->getNodeImpl(Loc, State, &IsNew);
-
- if (Pred)
- Node->addPredecessor(Pred); // Link 'Node' with its predecessor.
- else {
- assert (IsNew);
- G->addRoot(Node); // 'Node' has no predecessor. Make it a root.
- }
-
- // Only add 'Node' to the worklist if it was freshly generated.
- if (IsNew) WList->Enqueue(Node);
-}
-
-GRStmtNodeBuilderImpl::GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
- ExplodedNodeImpl* N, GRCoreEngineImpl* e)
- : Eng(*e), B(*b), Idx(idx), Pred(N), LastNode(N) {
- Deferred.insert(N);
-}
-
-GRStmtNodeBuilderImpl::~GRStmtNodeBuilderImpl() {
- for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
- if (!(*I)->isSink())
- GenerateAutoTransition(*I);
-}
-
-void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNodeImpl* N) {
- assert (!N->isSink());
-
- PostStmt Loc(getStmt());
-
- if (Loc == N->getLocation()) {
- // Note: 'N' should be a fresh node because otherwise it shouldn't be
- // a member of Deferred.
- Eng.WList->Enqueue(N, B, Idx+1);
- return;
- }
-
- bool IsNew;
- ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(Loc, N->State, &IsNew);
- Succ->addPredecessor(N);
-
- if (IsNew)
- Eng.WList->Enqueue(Succ, B, Idx+1);
-}
-
-static inline ProgramPoint GetPostLoc(Stmt* S, ProgramPoint::Kind K) {
- switch (K) {
- default:
- assert(false && "Invalid PostXXXKind.");
-
- case ProgramPoint::PostStmtKind:
- return PostStmt(S);
-
- case ProgramPoint::PostLoadKind:
- return PostLoad(S);
-
- case ProgramPoint::PostPurgeDeadSymbolsKind:
- return PostPurgeDeadSymbols(S);
- }
-}
-
-ExplodedNodeImpl*
-GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, const void* State,
- ExplodedNodeImpl* Pred,
- ProgramPoint::Kind K) {
-
- bool IsNew;
- ProgramPoint Loc = GetPostLoc(S, K);
-
- ExplodedNodeImpl* N = Eng.G->getNodeImpl(Loc, State, &IsNew);
- N->addPredecessor(Pred);
- Deferred.erase(Pred);
-
- if (IsNew) {
- Deferred.insert(N);
- LastNode = N;
- return N;
- }
-
- LastNode = NULL;
- return NULL;
-}
-
-ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
- bool branch) {
- bool IsNew;
-
- ExplodedNodeImpl* Succ =
- Eng.G->getNodeImpl(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew);
-
- Succ->addPredecessor(Pred);
-
- if (branch) GeneratedTrue = true;
- else GeneratedFalse = true;
-
- if (IsNew) {
- Deferred.push_back(Succ);
- return Succ;
- }
-
- return NULL;
-}
-
-GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
- if (!GeneratedTrue) generateNodeImpl(Pred->State, true);
- if (!GeneratedFalse) generateNodeImpl(Pred->State, false);
-
- for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
- if (!(*I)->isSink()) Eng.WList->Enqueue(*I);
-}
-
-
-ExplodedNodeImpl*
-GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
- const void* St,
- bool isSink) {
- bool IsNew;
-
- ExplodedNodeImpl* Succ =
- Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()), St, &IsNew);
-
- Succ->addPredecessor(Pred);
-
- if (IsNew) {
-
- if (isSink)
- Succ->markAsSink();
- else
- Eng.WList->Enqueue(Succ);
-
- return Succ;
- }
-
- return NULL;
-}
-
-
-ExplodedNodeImpl*
-GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
- const void* St) {
-
- bool IsNew;
-
- ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()),
- St, &IsNew);
- Succ->addPredecessor(Pred);
-
- if (IsNew) {
- Eng.WList->Enqueue(Succ);
- return Succ;
- }
-
- return NULL;
-}
-
-
-ExplodedNodeImpl*
-GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
- bool isSink) {
-
- // Get the block for the default case.
- assert (Src->succ_rbegin() != Src->succ_rend());
- CFGBlock* DefaultBlock = *Src->succ_rbegin();
-
- bool IsNew;
-
- ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
- St, &IsNew);
- Succ->addPredecessor(Pred);
-
- if (IsNew) {
- if (isSink)
- Succ->markAsSink();
- else
- Eng.WList->Enqueue(Succ);
-
- return Succ;
- }
-
- return NULL;
-}
-
-GREndPathNodeBuilderImpl::~GREndPathNodeBuilderImpl() {
- // Auto-generate an EOP node if one has not been generated.
- if (!HasGeneratedNode) generateNodeImpl(Pred->State);
-}
-
-ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(const void* State){
- HasGeneratedNode = true;
-
- bool IsNew;
-
- ExplodedNodeImpl* Node =
- Eng.G->getNodeImpl(BlockEntrance(&B), State, &IsNew);
-
-
- Node->addPredecessor(Pred);
-
- if (IsNew) {
- Node->markAsSink();
- Eng.G->addEndOfPath(Node);
- return Node;
- }
-
- return NULL;
-}
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp
deleted file mode 100644
index 1c3a170a5686..000000000000
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ /dev/null
@@ -1,2430 +0,0 @@
-//=-- GRExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- 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 a meta-engine for path-sensitive dataflow analysis that
-// is built on GREngine, but provides the boilerplate to execute transfer
-// functions and build the ExplodedGraph at the expression level.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/ADT/ImmutableList.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-
-#ifndef NDEBUG
-#include "llvm/Support/GraphWriter.h"
-#include <sstream>
-#endif
-
-using namespace clang;
-using llvm::dyn_cast;
-using llvm::cast;
-using llvm::APSInt;
-
-//===----------------------------------------------------------------------===//
-// Engine construction and deletion.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN MappedBatchAuditor : public GRSimpleAPICheck {
- typedef llvm::ImmutableList<GRSimpleAPICheck*> Checks;
- typedef llvm::DenseMap<void*,Checks> MapTy;
-
- MapTy M;
- Checks::Factory F;
-
-public:
- MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) : F(Alloc) {}
-
- virtual ~MappedBatchAuditor() {
- llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
-
- for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
- for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
-
- GRSimpleAPICheck* check = *I;
-
- if (AlreadyVisited.count(check))
- continue;
-
- AlreadyVisited.insert(check);
- delete check;
- }
- }
-
- void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
- assert (A && "Check cannot be null.");
- void* key = reinterpret_cast<void*>((uintptr_t) C);
- MapTy::iterator I = M.find(key);
- M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second);
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- llvm::DenseSet<GRSimpleAPICheck*> AlreadyVisited;
-
- for (MapTy::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
- for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E;++I){
-
- GRSimpleAPICheck* check = *I;
-
- if (AlreadyVisited.count(check))
- continue;
-
- check->EmitWarnings(BR);
- }
- }
-
- virtual bool Audit(NodeTy* N, GRStateManager& VMgr) {
- Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
- void* key = reinterpret_cast<void*>((uintptr_t) S->getStmtClass());
- MapTy::iterator MI = M.find(key);
-
- if (MI == M.end())
- return false;
-
- bool isSink = false;
-
- for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
- isSink |= (*I)->Audit(N, VMgr);
-
- return isSink;
- }
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Engine construction and deletion.
-//===----------------------------------------------------------------------===//
-
-static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
- IdentifierInfo* II = &Ctx.Idents.get(name);
- return Ctx.Selectors.getSelector(0, &II);
-}
-
-
-GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
- LiveVariables& L)
- : CoreEngine(cfg, CD, Ctx, *this),
- G(CoreEngine.getGraph()),
- Liveness(L),
- Builder(NULL),
- StateMgr(G.getContext(), CreateBasicStoreManager,
- CreateBasicConstraintManager, G.getAllocator(), G.getCFG(), L),
- SymMgr(StateMgr.getSymbolManager()),
- CurrentStmt(NULL),
- NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
- RaiseSel(GetNullarySelector("raise", G.getContext())) {}
-
-GRExprEngine::~GRExprEngine() {
- for (BugTypeSet::iterator I = BugTypes.begin(), E = BugTypes.end(); I!=E; ++I)
- delete *I;
-
-
- delete [] NSExceptionInstanceRaiseSelectors;
-}
-
-//===----------------------------------------------------------------------===//
-// Utility methods.
-//===----------------------------------------------------------------------===//
-
-// SaveAndRestore - A utility class that uses RIIA to save and restore
-// the value of a variable.
-template<typename T>
-struct VISIBILITY_HIDDEN SaveAndRestore {
- SaveAndRestore(T& x) : X(x), old_value(x) {}
- ~SaveAndRestore() { X = old_value; }
- T get() { return old_value; }
-
- T& X;
- T old_value;
-};
-
-// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
-// value of a variable is saved, and during the dstor the old value is
-// or'ed with the new value.
-struct VISIBILITY_HIDDEN SaveOr {
- SaveOr(bool& x) : X(x), old_value(x) { x = false; }
- ~SaveOr() { X |= old_value; }
-
- bool& X;
- bool old_value;
-};
-
-
-void GRExprEngine::EmitWarnings(BugReporterData& BRData) {
- for (bug_type_iterator I = bug_types_begin(), E = bug_types_end(); I!=E; ++I){
- GRBugReporter BR(BRData, *this);
- (*I)->EmitWarnings(BR);
- }
-
- if (BatchAuditor) {
- GRBugReporter BR(BRData, *this);
- BatchAuditor->EmitWarnings(BR);
- }
-}
-
-void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
- StateMgr.TF = tf;
- tf->RegisterChecks(*this);
- tf->RegisterPrinters(getStateManager().Printers);
-}
-
-void GRExprEngine::AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
- if (!BatchAuditor)
- BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
-
- ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
-}
-
-const GRState* GRExprEngine::getInitialState() {
- return StateMgr.getInitialState();
-}
-
-//===----------------------------------------------------------------------===//
-// Top-level transfer function logic (Dispatcher).
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
-
- Builder = &builder;
- EntryNode = builder.getLastNode();
-
- // FIXME: Consolidate.
- CurrentStmt = S;
- StateMgr.CurrentStmt = S;
-
- // Set up our simple checks.
- if (BatchAuditor)
- Builder->setAuditor(BatchAuditor.get());
-
- // Create the cleaned state.
- CleanedState = StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt,
- Liveness, DeadSymbols);
-
- // Process any special transfer function for dead symbols.
- NodeSet Tmp;
-
- if (DeadSymbols.empty())
- Tmp.Add(EntryNode);
- else {
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
- SaveOr OldHasGen(Builder->HasGeneratedNode);
-
- SaveAndRestore<bool> OldPurgeDeadSymbols(Builder->PurgingDeadSymbols);
- Builder->PurgingDeadSymbols = true;
-
- getTF().EvalDeadSymbols(Tmp, *this, *Builder, EntryNode, S,
- CleanedState, DeadSymbols);
-
- if (!Builder->BuildSinks && !Builder->HasGeneratedNode)
- Tmp.Add(EntryNode);
- }
-
- bool HasAutoGenerated = false;
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
- NodeSet Dst;
-
- // Set the cleaned state.
- Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
-
- // Visit the statement.
- Visit(S, *I, Dst);
-
- // Do we need to auto-generate a node? We only need to do this to generate
- // a node with a "cleaned" state; GRCoreEngine will actually handle
- // auto-transitions for other cases.
- if (Dst.size() == 1 && *Dst.begin() == EntryNode
- && !Builder->HasGeneratedNode && !HasAutoGenerated) {
- HasAutoGenerated = true;
- builder.generateNode(S, GetState(EntryNode), *I);
- }
- }
-
- // NULL out these variables to cleanup.
- CleanedState = NULL;
- EntryNode = NULL;
-
- // FIXME: Consolidate.
- StateMgr.CurrentStmt = 0;
- CurrentStmt = 0;
-
- Builder = NULL;
-}
-
-void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) {
-
- // FIXME: add metadata to the CFG so that we can disable
- // this check when we KNOW that there is no block-level subexpression.
- // The motivation is that this check requires a hashtable lookup.
-
- if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
- Dst.Add(Pred);
- return;
- }
-
- switch (S->getStmtClass()) {
-
- default:
- // Cases we intentionally have "default" handle:
- // AddrLabelExpr, IntegerLiteral, CharacterLiteral
-
- Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
- break;
-
- case Stmt::ArraySubscriptExprClass:
- VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst, false);
- break;
-
- case Stmt::AsmStmtClass:
- VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
- break;
-
- case Stmt::BinaryOperatorClass: {
- BinaryOperator* B = cast<BinaryOperator>(S);
-
- if (B->isLogicalOp()) {
- VisitLogicalExpr(B, Pred, Dst);
- break;
- }
- else if (B->getOpcode() == BinaryOperator::Comma) {
- const GRState* St = GetState(Pred);
- MakeNode(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS())));
- break;
- }
-
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
- break;
- }
-
- case Stmt::CallExprClass: {
- CallExpr* C = cast<CallExpr>(S);
- VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst);
- break;
- }
-
- // FIXME: ChooseExpr is really a constant. We need to fix
- // the CFG do not model them as explicit control-flow.
-
- case Stmt::ChooseExprClass: { // __builtin_choose_expr
- ChooseExpr* C = cast<ChooseExpr>(S);
- VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
- break;
- }
-
- case Stmt::CompoundAssignOperatorClass:
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
- break;
-
- case Stmt::ConditionalOperatorClass: { // '?' operator
- ConditionalOperator* C = cast<ConditionalOperator>(S);
- VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
- break;
- }
-
- case Stmt::DeclRefExprClass:
- VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
- break;
-
- case Stmt::DeclStmtClass:
- VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
- break;
-
- case Stmt::ImplicitCastExprClass:
- case Stmt::ExplicitCastExprClass: {
- CastExpr* C = cast<CastExpr>(S);
- VisitCast(C, C->getSubExpr(), Pred, Dst);
- break;
- }
-
- case Stmt::MemberExprClass: {
- VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
- break;
- }
-
- case Stmt::ObjCMessageExprClass: {
- VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst);
- break;
- }
-
- case Stmt::ParenExprClass:
- Visit(cast<ParenExpr>(S)->getSubExpr()->IgnoreParens(), Pred, Dst);
- break;
-
- case Stmt::ReturnStmtClass:
- VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
- break;
-
- case Stmt::SizeOfAlignOfTypeExprClass:
- VisitSizeOfAlignOfTypeExpr(cast<SizeOfAlignOfTypeExpr>(S), Pred, Dst);
- break;
-
- case Stmt::StmtExprClass: {
- StmtExpr* SE = cast<StmtExpr>(S);
-
- const GRState* St = GetState(Pred);
-
- // FIXME: Not certain if we can have empty StmtExprs. If so, we should
- // probably just remove these from the CFG.
- assert (!SE->getSubStmt()->body_empty());
-
- if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin()))
- MakeNode(Dst, SE, Pred, SetRVal(St, SE, GetRVal(St, LastExpr)));
- else
- Dst.Add(Pred);
-
- break;
- }
-
- case Stmt::UnaryOperatorClass:
- VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst, false);
- break;
- }
-}
-
-void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
-
- Ex = Ex->IgnoreParens();
-
- if (Ex != CurrentStmt && getCFG().isBlkExpr(Ex)) {
- Dst.Add(Pred);
- return;
- }
-
- switch (Ex->getStmtClass()) {
- default:
- Visit(Ex, Pred, Dst);
- return;
-
- case Stmt::ArraySubscriptExprClass:
- VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
- return;
-
- case Stmt::DeclRefExprClass:
- VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
- return;
-
- case Stmt::UnaryOperatorClass:
- VisitUnaryOperator(cast<UnaryOperator>(Ex), Pred, Dst, true);
- return;
-
- case Stmt::MemberExprClass:
- VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true);
- return;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Block entrance. (Update counters).
-//===----------------------------------------------------------------------===//
-
-bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const GRState*,
- GRBlockCounter BC) {
-
- return BC.getNumVisited(B->getBlockID()) < 3;
-}
-
-//===----------------------------------------------------------------------===//
-// Branch processing.
-//===----------------------------------------------------------------------===//
-
-const GRState* GRExprEngine::MarkBranch(const GRState* St,
- Stmt* Terminator,
- bool branchTaken) {
-
- switch (Terminator->getStmtClass()) {
- default:
- return St;
-
- case Stmt::BinaryOperatorClass: { // '&&' and '||'
-
- BinaryOperator* B = cast<BinaryOperator>(Terminator);
- BinaryOperator::Opcode Op = B->getOpcode();
-
- assert (Op == BinaryOperator::LAnd || Op == BinaryOperator::LOr);
-
- // For &&, if we take the true branch, then the value of the whole
- // expression is that of the RHS expression.
- //
- // For ||, if we take the false branch, then the value of the whole
- // expression is that of the RHS expression.
-
- Expr* Ex = (Op == BinaryOperator::LAnd && branchTaken) ||
- (Op == BinaryOperator::LOr && !branchTaken)
- ? B->getRHS() : B->getLHS();
-
- return SetBlkExprRVal(St, B, UndefinedVal(Ex));
- }
-
- case Stmt::ConditionalOperatorClass: { // ?:
-
- ConditionalOperator* C = cast<ConditionalOperator>(Terminator);
-
- // For ?, if branchTaken == true then the value is either the LHS or
- // the condition itself. (GNU extension).
-
- Expr* Ex;
-
- if (branchTaken)
- Ex = C->getLHS() ? C->getLHS() : C->getCond();
- else
- Ex = C->getRHS();
-
- return SetBlkExprRVal(St, C, UndefinedVal(Ex));
- }
-
- case Stmt::ChooseExprClass: { // ?:
-
- ChooseExpr* C = cast<ChooseExpr>(Terminator);
-
- Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();
- return SetBlkExprRVal(St, C, UndefinedVal(Ex));
- }
- }
-}
-
-void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term,
- BranchNodeBuilder& builder) {
-
- // Remove old bindings for subexpressions.
- const GRState* PrevState =
- StateMgr.RemoveSubExprBindings(builder.getState());
-
- // Check for NULL conditions; e.g. "for(;;)"
- if (!Condition) {
- builder.markInfeasible(false);
- return;
- }
-
- RVal V = GetRVal(PrevState, Condition);
-
- switch (V.getBaseKind()) {
- default:
- break;
-
- case RVal::UnknownKind:
- builder.generateNode(MarkBranch(PrevState, Term, true), true);
- builder.generateNode(MarkBranch(PrevState, Term, false), false);
- return;
-
- case RVal::UndefinedKind: {
- NodeTy* N = builder.generateNode(PrevState, true);
-
- if (N) {
- N->markAsSink();
- UndefBranches.insert(N);
- }
-
- builder.markInfeasible(false);
- return;
- }
- }
-
- // Process the true branch.
-
- bool isFeasible = false;
- const GRState* St = Assume(PrevState, V, true, isFeasible);
-
- if (isFeasible)
- builder.generateNode(MarkBranch(St, Term, true), true);
- else
- builder.markInfeasible(true);
-
- // Process the false branch.
-
- isFeasible = false;
- St = Assume(PrevState, V, false, isFeasible);
-
- if (isFeasible)
- builder.generateNode(MarkBranch(St, Term, false), false);
- else
- builder.markInfeasible(false);
-}
-
-/// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
-/// nodes by processing the 'effects' of a computed goto jump.
-void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
-
- const GRState* St = builder.getState();
- RVal V = GetRVal(St, builder.getTarget());
-
- // Three possibilities:
- //
- // (1) We know the computed label.
- // (2) The label is NULL (or some other constant), or Undefined.
- // (3) We have no clue about the label. Dispatch to all targets.
- //
-
- typedef IndirectGotoNodeBuilder::iterator iterator;
-
- if (isa<lval::GotoLabel>(V)) {
- LabelStmt* L = cast<lval::GotoLabel>(V).getLabel();
-
- for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
- if (I.getLabel() == L) {
- builder.generateNode(I, St);
- return;
- }
- }
-
- assert (false && "No block with label.");
- return;
- }
-
- if (isa<lval::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
- // Dispatch to the first target and mark it as a sink.
- NodeTy* N = builder.generateNode(builder.begin(), St, true);
- UndefBranches.insert(N);
- return;
- }
-
- // This is really a catch-all. We don't support symbolics yet.
-
- assert (V.isUnknown());
-
- for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
- builder.generateNode(I, St);
-}
-
-
-void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
- NodeTy* Pred, NodeSet& Dst) {
-
- assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex));
-
- const GRState* St = GetState(Pred);
- RVal X = GetBlkExprRVal(St, Ex);
-
- assert (X.isUndef());
-
- Expr* SE = (Expr*) cast<UndefinedVal>(X).getData();
-
- assert (SE);
-
- X = GetBlkExprRVal(St, SE);
-
- // Make sure that we invalidate the previous binding.
- MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, X, true, true));
-}
-
-/// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
-/// nodes by processing the 'effects' of a switch statement.
-void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
-
- typedef SwitchNodeBuilder::iterator iterator;
-
- const GRState* St = builder.getState();
- Expr* CondE = builder.getCondition();
- RVal CondV = GetRVal(St, CondE);
-
- if (CondV.isUndef()) {
- NodeTy* N = builder.generateDefaultCaseNode(St, true);
- UndefBranches.insert(N);
- return;
- }
-
- const GRState* DefaultSt = St;
-
- // While most of this can be assumed (such as the signedness), having it
- // just computed makes sure everything makes the same assumptions end-to-end.
-
- unsigned bits = getContext().getTypeSize(CondE->getType());
-
- APSInt V1(bits, false);
- APSInt V2 = V1;
- bool DefaultFeasible = false;
-
- for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
-
- CaseStmt* Case = cast<CaseStmt>(I.getCase());
-
- // Evaluate the case.
- if (!Case->getLHS()->isIntegerConstantExpr(V1, getContext(), 0, true)) {
- assert (false && "Case condition must evaluate to an integer constant.");
- return;
- }
-
- // Get the RHS of the case, if it exists.
-
- if (Expr* E = Case->getRHS()) {
- if (!E->isIntegerConstantExpr(V2, getContext(), 0, true)) {
- assert (false &&
- "Case condition (RHS) must evaluate to an integer constant.");
- return ;
- }
-
- assert (V1 <= V2);
- }
- else
- V2 = V1;
-
- // FIXME: Eventually we should replace the logic below with a range
- // comparison, rather than concretize the values within the range.
- // This should be easy once we have "ranges" for NonLVals.
-
- do {
- nonlval::ConcreteInt CaseVal(getBasicVals().getValue(V1));
-
- RVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
-
- // Now "assume" that the case matches.
-
- bool isFeasible = false;
- const GRState* StNew = Assume(St, Res, true, isFeasible);
-
- if (isFeasible) {
- builder.generateCaseStmtNode(I, StNew);
-
- // If CondV evaluates to a constant, then we know that this
- // is the *only* case that we can take, so stop evaluating the
- // others.
- if (isa<nonlval::ConcreteInt>(CondV))
- return;
- }
-
- // Now "assume" that the case doesn't match. Add this state
- // to the default state (if it is feasible).
-
- isFeasible = false;
- StNew = Assume(DefaultSt, Res, false, isFeasible);
-
- if (isFeasible) {
- DefaultFeasible = true;
- DefaultSt = StNew;
- }
-
- // Concretize the next value in the range.
- if (V1 == V2)
- break;
-
- ++V1;
- assert (V1 <= V2);
-
- } while (true);
- }
-
- // If we reach here, than we know that the default branch is
- // possible.
- if (DefaultFeasible) builder.generateDefaultCaseNode(DefaultSt);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions: logical operations ('&&', '||').
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
- NodeSet& Dst) {
-
- assert (B->getOpcode() == BinaryOperator::LAnd ||
- B->getOpcode() == BinaryOperator::LOr);
-
- assert (B == CurrentStmt && getCFG().isBlkExpr(B));
-
- const GRState* St = GetState(Pred);
- RVal X = GetBlkExprRVal(St, B);
-
- assert (X.isUndef());
-
- Expr* Ex = (Expr*) cast<UndefinedVal>(X).getData();
-
- assert (Ex);
-
- if (Ex == B->getRHS()) {
-
- X = GetBlkExprRVal(St, Ex);
-
- // Handle undefined values.
-
- if (X.isUndef()) {
- MakeNode(Dst, B, Pred, SetBlkExprRVal(St, B, X));
- return;
- }
-
- // We took the RHS. Because the value of the '&&' or '||' expression must
- // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
- // or 1. Alternatively, we could take a lazy approach, and calculate this
- // value later when necessary. We don't have the machinery in place for
- // this right now, and since most logical expressions are used for branches,
- // the payoff is not likely to be large. Instead, we do eager evaluation.
-
- bool isFeasible = false;
- const GRState* NewState = Assume(St, X, true, isFeasible);
-
- if (isFeasible)
- MakeNode(Dst, B, Pred,
- SetBlkExprRVal(NewState, B, MakeConstantVal(1U, B)));
-
- isFeasible = false;
- NewState = Assume(St, X, false, isFeasible);
-
- if (isFeasible)
- MakeNode(Dst, B, Pred,
- SetBlkExprRVal(NewState, B, MakeConstantVal(0U, B)));
- }
- else {
- // We took the LHS expression. Depending on whether we are '&&' or
- // '||' we know what the value of the expression is via properties of
- // the short-circuiting.
-
- X = MakeConstantVal( B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, B);
- MakeNode(Dst, B, Pred, SetBlkExprRVal(St, B, X));
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions: Loads and stores.
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst,
- bool asLVal) {
-
- const GRState* St = GetState(Pred);
- RVal X = RVal::MakeVal(getStateManager(), D);
-
- if (asLVal)
- MakeNode(Dst, D, Pred, SetRVal(St, D, cast<LVal>(X)));
- else {
- RVal V = isa<lval::MemRegionVal>(X) ? GetRVal(St, cast<LVal>(X)) : X;
- MakeNode(Dst, D, Pred, SetRVal(St, D, V));
- }
-}
-
-/// VisitArraySubscriptExpr - Transfer function for array accesses
-void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred,
- NodeSet& Dst, bool asLVal) {
-
- Expr* Base = A->getBase()->IgnoreParens();
- Expr* Idx = A->getIdx()->IgnoreParens();
-
- // Always visit the base as an LVal expression. This computes the
- // abstract address of the base object.
- NodeSet Tmp;
-
- if (LVal::IsLValType(Base->getType())) // Base always is an LVal.
- Visit(Base, Pred, Tmp);
- else
- VisitLVal(Base, Pred, Tmp);
-
- for (NodeSet::iterator I1=Tmp.begin(), E1=Tmp.end(); I1!=E1; ++I1) {
-
- // Evaluate the index.
-
- NodeSet Tmp2;
- Visit(Idx, *I1, Tmp2);
-
- for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) {
-
- const GRState* St = GetState(*I2);
- RVal BaseV = GetRVal(St, Base);
- RVal IdxV = GetRVal(St, Idx);
-
- // If IdxV is 0, return just BaseV.
-
- bool useBase = false;
-
- if (nonlval::ConcreteInt* IdxInt = dyn_cast<nonlval::ConcreteInt>(&IdxV))
- useBase = IdxInt->getValue() == 0;
-
- RVal V = useBase ? BaseV : lval::ArrayOffset::Make(getBasicVals(), BaseV,IdxV);
-
- if (asLVal)
- MakeNode(Dst, A, *I2, SetRVal(St, A, V));
- else
- EvalLoad(Dst, A, *I2, St, V);
- }
- }
-}
-
-/// VisitMemberExpr - Transfer function for member expressions.
-void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred,
- NodeSet& Dst, bool asLVal) {
-
- Expr* Base = M->getBase()->IgnoreParens();
-
- // Always visit the base as an LVal expression. This computes the
- // abstract address of the base object.
- NodeSet Tmp;
-
- if (asLVal) {
-
- if (LVal::IsLValType(Base->getType())) // Base always is an LVal.
- Visit(Base, Pred, Tmp);
- else
- VisitLVal(Base, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- const GRState* St = GetState(*I);
- RVal BaseV = GetRVal(St, Base);
-
- RVal V = lval::FieldOffset::Make(getBasicVals(), GetRVal(St, Base),
- M->getMemberDecl());
-
- MakeNode(Dst, M, *I, SetRVal(St, M, V));
- }
-
- return;
- }
-
- // Evaluate the base. Can be an LVal or NonLVal (depends on whether
- // or not isArrow() is true).
- Visit(Base, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
- const GRState* St = GetState(*I);
- RVal BaseV = GetRVal(St, Base);
-
- if (LVal::IsLValType(Base->getType())) {
-
- assert (M->isArrow());
-
- RVal V = lval::FieldOffset::Make(getBasicVals(), GetRVal(St, Base),
- M->getMemberDecl());
-
- EvalLoad(Dst, M, *I, St, V);
- }
- else {
-
- assert (!M->isArrow());
-
- if (BaseV.isUnknownOrUndef()) {
- MakeNode(Dst, M, *I, SetRVal(St, M, BaseV));
- continue;
- }
-
- // FIXME: Implement nonlval objects representing struct temporaries.
- assert (isa<NonLVal>(BaseV));
- MakeNode(Dst, M, *I, SetRVal(St, M, UnknownVal()));
- }
- }
-}
-
-void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
- const GRState* St, RVal location, RVal Val) {
-
- assert (Builder && "GRStmtNodeBuilder must be defined.");
-
- // Evaluate the location (checks for bad dereferences).
- St = EvalLocation(Ex, Pred, St, location);
-
- if (!St)
- return;
-
- // Proceed with the store.
-
- unsigned size = Dst.size();
-
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
- SaveAndRestore<ProgramPoint::Kind> OldSPointKind(Builder->PointKind);
- SaveOr OldHasGen(Builder->HasGeneratedNode);
-
- assert (!location.isUndef());
- Builder->PointKind = ProgramPoint::PostStoreKind;
-
- getTF().EvalStore(Dst, *this, *Builder, Ex, Pred, St, location, Val);
-
- // Handle the case where no nodes where generated. Auto-generate that
- // contains the updated state if we aren't generating sinks.
-
- if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
- getTF().GRTransferFuncs::EvalStore(Dst, *this, *Builder, Ex, Pred, St,
- location, Val);
-}
-
-void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
- const GRState* St, RVal location,
- bool CheckOnly) {
-
- // Evaluate the location (checks for bad dereferences).
-
- St = EvalLocation(Ex, Pred, St, location, true);
-
- if (!St)
- return;
-
- // Proceed with the load.
- ProgramPoint::Kind K = ProgramPoint::PostLoadKind;
-
- // FIXME: Currently symbolic analysis "generates" new symbols
- // for the contents of values. We need a better approach.
-
- // FIXME: The "CheckOnly" option exists only because Array and Field
- // loads aren't fully implemented. Eventually this option will go away.
-
- if (CheckOnly)
- MakeNode(Dst, Ex, Pred, St, K);
- else if (location.isUnknown()) {
- // This is important. We must nuke the old binding.
- MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, UnknownVal()), K);
- }
- else
- MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, GetRVal(St, cast<LVal>(location),
- Ex->getType())), K);
-}
-
-void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, Expr* StoreE, NodeTy* Pred,
- const GRState* St, RVal location, RVal Val) {
-
- NodeSet TmpDst;
- EvalStore(TmpDst, StoreE, Pred, St, location, Val);
-
- for (NodeSet::iterator I=TmpDst.begin(), E=TmpDst.end(); I!=E; ++I)
- MakeNode(Dst, Ex, *I, (*I)->getState());
-}
-
-const GRState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
- const GRState* St,
- RVal location, bool isLoad) {
-
- // Check for loads/stores from/to undefined values.
- if (location.isUndef()) {
- ProgramPoint::Kind K =
- isLoad ? ProgramPoint::PostLoadKind : ProgramPoint::PostStmtKind;
-
- if (NodeTy* Succ = Builder->generateNode(Ex, St, Pred, K)) {
- Succ->markAsSink();
- UndefDeref.insert(Succ);
- }
-
- return NULL;
- }
-
- // Check for loads/stores from/to unknown locations. Treat as No-Ops.
- if (location.isUnknown())
- return St;
-
- // During a load, one of two possible situations arise:
- // (1) A crash, because the location (pointer) was NULL.
- // (2) The location (pointer) is not NULL, and the dereference works.
- //
- // We add these assumptions.
-
- LVal LV = cast<LVal>(location);
-
- // "Assume" that the pointer is not NULL.
-
- bool isFeasibleNotNull = false;
- const GRState* StNotNull = Assume(St, LV, true, isFeasibleNotNull);
-
- // "Assume" that the pointer is NULL.
-
- bool isFeasibleNull = false;
- GRStateRef StNull = GRStateRef(Assume(St, LV, false, isFeasibleNull),
- getStateManager());
-
- if (isFeasibleNull) {
-
- // Use the Generic Data Map to mark in the state what lval was null.
- const RVal* PersistentLV = getBasicVals().getPersistentRVal(LV);
- StNull = StNull.set<GRState::NullDerefTag>(PersistentLV);
-
- // We don't use "MakeNode" here because the node will be a sink
- // and we have no intention of processing it later.
-
- ProgramPoint::Kind K =
- isLoad ? ProgramPoint::PostLoadKind : ProgramPoint::PostStmtKind;
-
- NodeTy* NullNode = Builder->generateNode(Ex, StNull, Pred, K);
-
- if (NullNode) {
-
- NullNode->markAsSink();
-
- if (isFeasibleNotNull) ImplicitNullDeref.insert(NullNode);
- else ExplicitNullDeref.insert(NullNode);
- }
- }
-
- return isFeasibleNotNull ? StNotNull : NULL;
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function: Function calls.
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
- CallExpr::arg_iterator AI,
- CallExpr::arg_iterator AE,
- NodeSet& Dst) {
-
- // Process the arguments.
-
- if (AI != AE) {
-
- NodeSet DstTmp;
- Visit(*AI, Pred, DstTmp);
- ++AI;
-
- for (NodeSet::iterator DI=DstTmp.begin(), DE=DstTmp.end(); DI != DE; ++DI)
- VisitCall(CE, *DI, AI, AE, Dst);
-
- return;
- }
-
- // If we reach here we have processed all of the arguments. Evaluate
- // the callee expression.
-
- NodeSet DstTmp;
- Expr* Callee = CE->getCallee()->IgnoreParens();
-
- VisitLVal(Callee, Pred, DstTmp);
-
- // Finally, evaluate the function call.
- for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
-
- const GRState* St = GetState(*DI);
- RVal L = GetRVal(St, Callee);
-
- // FIXME: Add support for symbolic function calls (calls involving
- // function pointer values that are symbolic).
-
- // Check for undefined control-flow or calls to NULL.
-
- if (L.isUndef() || isa<lval::ConcreteInt>(L)) {
- NodeTy* N = Builder->generateNode(CE, St, *DI);
-
- if (N) {
- N->markAsSink();
- BadCalls.insert(N);
- }
-
- continue;
- }
-
- // Check for the "noreturn" attribute.
-
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
-
- if (isa<lval::FuncVal>(L)) {
-
- FunctionDecl* FD = cast<lval::FuncVal>(L).getDecl();
-
- if (FD->getAttr<NoReturnAttr>())
- Builder->BuildSinks = true;
- else {
- // HACK: Some functions are not marked noreturn, and don't return.
- // Here are a few hardwired ones. If this takes too long, we can
- // potentially cache these results.
- const char* s = FD->getIdentifier()->getName();
- unsigned n = strlen(s);
-
- switch (n) {
- default:
- break;
-
- case 4:
- if (!memcmp(s, "exit", 4)) Builder->BuildSinks = true;
- break;
-
- case 5:
- if (!memcmp(s, "panic", 5)) Builder->BuildSinks = true;
- break;
-
- case 6:
- if (!memcmp(s, "Assert", 6)) {
- Builder->BuildSinks = true;
- break;
- }
-
- // FIXME: This is just a wrapper around throwing an exception.
- // Eventually inter-procedural analysis should handle this easily.
- if (!memcmp(s, "ziperr", 6)) Builder->BuildSinks = true;
-
- break;
-
- case 7:
- if (!memcmp(s, "assfail", 7)) Builder->BuildSinks = true;
- break;
-
- case 8:
- if (!memcmp(s ,"db_error", 8)) Builder->BuildSinks = true;
- break;
-
- case 12:
- if (!memcmp(s, "__assert_rtn", 12)) Builder->BuildSinks = true;
- break;
-
- case 13:
- if (!memcmp(s, "__assert_fail", 13)) Builder->BuildSinks = true;
- break;
-
- case 14:
- if (!memcmp(s, "dtrace_assfail", 14)) Builder->BuildSinks = true;
- break;
-
- case 26:
- if (!memcmp(s, "_XCAssertionFailureHandler", 26) ||
- !memcmp(s, "_DTAssertionFailureHandler", 26))
- Builder->BuildSinks = true;
-
- break;
- }
-
- }
- }
-
- // Evaluate the call.
-
- if (isa<lval::FuncVal>(L)) {
-
- IdentifierInfo* Info = cast<lval::FuncVal>(L).getDecl()->getIdentifier();
-
- if (unsigned id = Info->getBuiltinID())
- switch (id) {
- case Builtin::BI__builtin_expect: {
- // For __builtin_expect, just return the value of the subexpression.
- assert (CE->arg_begin() != CE->arg_end());
- RVal X = GetRVal(St, *(CE->arg_begin()));
- MakeNode(Dst, CE, *DI, SetRVal(St, CE, X));
- continue;
- }
-
- default:
- break;
- }
- }
-
- // Check any arguments passed-by-value against being undefined.
-
- bool badArg = false;
-
- for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
- I != E; ++I) {
-
- if (GetRVal(GetState(*DI), *I).isUndef()) {
- NodeTy* N = Builder->generateNode(CE, GetState(*DI), *DI);
-
- if (N) {
- N->markAsSink();
- UndefArgs[N] = *I;
- }
-
- badArg = true;
- break;
- }
- }
-
- if (badArg)
- continue;
-
- // Dispatch to the plug-in transfer function.
-
- unsigned size = Dst.size();
- SaveOr OldHasGen(Builder->HasGeneratedNode);
- EvalCall(Dst, CE, L, *DI);
-
- // Handle the case where no nodes where generated. Auto-generate that
- // contains the updated state if we aren't generating sinks.
-
- if (!Builder->BuildSinks && Dst.size() == size &&
- !Builder->HasGeneratedNode)
- MakeNode(Dst, CE, *DI, St);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function: Objective-C message expressions.
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, NodeTy* Pred,
- NodeSet& Dst){
-
- VisitObjCMessageExprArgHelper(ME, ME->arg_begin(), ME->arg_end(),
- Pred, Dst);
-}
-
-void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
- ObjCMessageExpr::arg_iterator AI,
- ObjCMessageExpr::arg_iterator AE,
- NodeTy* Pred, NodeSet& Dst) {
- if (AI == AE) {
-
- // Process the receiver.
-
- if (Expr* Receiver = ME->getReceiver()) {
- NodeSet Tmp;
- Visit(Receiver, Pred, Tmp);
-
- for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
- VisitObjCMessageExprDispatchHelper(ME, *NI, Dst);
-
- return;
- }
-
- VisitObjCMessageExprDispatchHelper(ME, Pred, Dst);
- return;
- }
-
- NodeSet Tmp;
- Visit(*AI, Pred, Tmp);
-
- ++AI;
-
- for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
- VisitObjCMessageExprArgHelper(ME, AI, AE, *NI, Dst);
-}
-
-void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
- NodeTy* Pred,
- NodeSet& Dst) {
-
- // FIXME: More logic for the processing the method call.
-
- const GRState* St = GetState(Pred);
- bool RaisesException = false;
-
-
- if (Expr* Receiver = ME->getReceiver()) {
-
- RVal L = GetRVal(St, Receiver);
-
- // Check for undefined control-flow or calls to NULL.
-
- if (L.isUndef()) {
- NodeTy* N = Builder->generateNode(ME, St, Pred);
-
- if (N) {
- N->markAsSink();
- UndefReceivers.insert(N);
- }
-
- return;
- }
-
- // Check if the "raise" message was sent.
- if (ME->getSelector() == RaiseSel)
- RaisesException = true;
- }
- else {
-
- IdentifierInfo* ClsName = ME->getClassName();
- Selector S = ME->getSelector();
-
- // Check for special instance methods.
-
- if (!NSExceptionII) {
- ASTContext& Ctx = getContext();
-
- NSExceptionII = &Ctx.Idents.get("NSException");
- }
-
- if (ClsName == NSExceptionII) {
-
- enum { NUM_RAISE_SELECTORS = 2 };
-
- // Lazily create a cache of the selectors.
-
- if (!NSExceptionInstanceRaiseSelectors) {
-
- ASTContext& Ctx = getContext();
-
- NSExceptionInstanceRaiseSelectors = new Selector[NUM_RAISE_SELECTORS];
-
- llvm::SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
- unsigned idx = 0;
-
- // raise:format:
- II.push_back(&Ctx.Idents.get("raise"));
- II.push_back(&Ctx.Idents.get("format"));
- NSExceptionInstanceRaiseSelectors[idx++] =
- Ctx.Selectors.getSelector(II.size(), &II[0]);
-
- // raise:format::arguments:
- II.push_back(&Ctx.Idents.get("arguments"));
- NSExceptionInstanceRaiseSelectors[idx++] =
- Ctx.Selectors.getSelector(II.size(), &II[0]);
- }
-
- for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i)
- if (S == NSExceptionInstanceRaiseSelectors[i]) {
- RaisesException = true; break;
- }
- }
- }
-
- // Check for any arguments that are uninitialized/undefined.
-
- for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
- I != E; ++I) {
-
- if (GetRVal(St, *I).isUndef()) {
-
- // Generate an error node for passing an uninitialized/undefined value
- // as an argument to a message expression. This node is a sink.
- NodeTy* N = Builder->generateNode(ME, St, Pred);
-
- if (N) {
- N->markAsSink();
- MsgExprUndefArgs[N] = *I;
- }
-
- return;
- }
- }
-
- // Check if we raise an exception. For now treat these as sinks. Eventually
- // we will want to handle exceptions properly.
-
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
-
- if (RaisesException)
- Builder->BuildSinks = true;
-
- // Dispatch to plug-in transfer function.
-
- unsigned size = Dst.size();
- SaveOr OldHasGen(Builder->HasGeneratedNode);
-
- EvalObjCMessageExpr(Dst, ME, Pred);
-
- // Handle the case where no nodes where generated. Auto-generate that
- // contains the updated state if we aren't generating sinks.
-
- if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
- MakeNode(Dst, ME, Pred, St);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions: Miscellaneous statements.
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
-
- NodeSet S1;
- QualType T = CastE->getType();
-
- if (T->isReferenceType())
- VisitLVal(Ex, Pred, S1);
- else
- Visit(Ex, Pred, S1);
-
- // Check for casting to "void".
- if (T->isVoidType()) {
-
- for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1)
- Dst.Add(*I1);
-
- return;
- }
-
- // FIXME: The rest of this should probably just go into EvalCall, and
- // let the transfer function object be responsible for constructing
- // nodes.
-
- QualType ExTy = Ex->getType();
-
- for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) {
- NodeTy* N = *I1;
- const GRState* St = GetState(N);
- RVal V = GetRVal(St, Ex);
-
- // Unknown?
-
- if (V.isUnknown()) {
- Dst.Add(N);
- continue;
- }
-
- // Undefined?
-
- if (V.isUndef()) {
- MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
- continue;
- }
-
- // For const casts, just propagate the value.
- ASTContext& C = getContext();
-
- if (C.getCanonicalType(T).getUnqualifiedType() ==
- C.getCanonicalType(ExTy).getUnqualifiedType()) {
- MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
- continue;
- }
-
- // Check for casts from pointers to integers.
- if (T->isIntegerType() && LVal::IsLValType(ExTy)) {
- unsigned bits = getContext().getTypeSize(ExTy);
-
- // FIXME: Determine if the number of bits of the target type is
- // equal or exceeds the number of bits to store the pointer value.
- // If not, flag an error.
-
- V = nonlval::LValAsInteger::Make(getBasicVals(), cast<LVal>(V), bits);
- MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
- continue;
- }
-
- // Check for casts from integers to pointers.
- if (LVal::IsLValType(T) && ExTy->isIntegerType())
- if (nonlval::LValAsInteger *LV = dyn_cast<nonlval::LValAsInteger>(&V)) {
- // Just unpackage the lval and return it.
- V = LV->getLVal();
- MakeNode(Dst, CastE, N, SetRVal(St, CastE, V));
- continue;
- }
-
- // All other cases.
-
- MakeNode(Dst, CastE, N, SetRVal(St, CastE, EvalCast(V, CastE->getType())));
- }
-}
-
-void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) {
-
- // The CFG has one DeclStmt per Decl.
- ScopedDecl* D = *DS->decl_begin();
-
- if (!D || !isa<VarDecl>(D))
- return;
-
- const VarDecl* VD = dyn_cast<VarDecl>(D);
-
- // FIXME: Add support for local arrays.
- if (VD->getType()->isArrayType()) {
- return;
- }
-
- Expr* Ex = const_cast<Expr*>(VD->getInit());
-
- // FIXME: static variables may have an initializer, but the second
- // time a function is called those values may not be current.
- NodeSet Tmp;
-
- if (Ex)
- Visit(Ex, Pred, Tmp);
-
- if (Tmp.empty())
- Tmp.Add(Pred);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- const GRState* St = GetState(*I);
- St = StateMgr.AddDecl(St, VD, Ex, Builder->getCurrentBlockCount());
- MakeNode(Dst, DS, *I, St);
- }
-}
-
-
-/// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type).
-void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
- NodeTy* Pred,
- NodeSet& Dst) {
- QualType T = Ex->getArgumentType();
- uint64_t amt;
-
- if (Ex->isSizeOf()) {
-
- // FIXME: Add support for VLAs.
- if (!T.getTypePtr()->isConstantSizeType())
- return;
-
- // Some code tries to take the sizeof an ObjCInterfaceType, relying that
- // the compiler has laid out its representation. Just report Unknown
- // for these.
- if (T->isObjCInterfaceType())
- return;
-
- amt = 1; // Handle sizeof(void)
-
- if (T != getContext().VoidTy)
- amt = getContext().getTypeSize(T) / 8;
-
- }
- else // Get alignment of the type.
- amt = getContext().getTypeAlign(T) / 8;
-
- MakeNode(Dst, Ex, Pred,
- SetRVal(GetState(Pred), Ex,
- NonLVal::MakeVal(getBasicVals(), amt, Ex->getType())));
-}
-
-
-void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
- NodeSet& Dst, bool asLVal) {
-
- switch (U->getOpcode()) {
-
- default:
- break;
-
- case UnaryOperator::Deref: {
-
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- NodeSet Tmp;
- Visit(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
- const GRState* St = GetState(*I);
- RVal location = GetRVal(St, Ex);
-
- if (asLVal)
- MakeNode(Dst, U, *I, SetRVal(St, U, location));
- else
- EvalLoad(Dst, U, *I, St, location);
- }
-
- return;
- }
-
- case UnaryOperator::Real: {
-
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- NodeSet Tmp;
- Visit(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
- // FIXME: We don't have complex RValues yet.
- if (Ex->getType()->isAnyComplexType()) {
- // Just report "Unknown."
- Dst.Add(*I);
- continue;
- }
-
- // For all other types, UnaryOperator::Real is an identity operation.
- assert (U->getType() == Ex->getType());
- const GRState* St = GetState(*I);
- MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
- }
-
- return;
- }
-
- case UnaryOperator::Imag: {
-
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- NodeSet Tmp;
- Visit(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- // FIXME: We don't have complex RValues yet.
- if (Ex->getType()->isAnyComplexType()) {
- // Just report "Unknown."
- Dst.Add(*I);
- continue;
- }
-
- // For all other types, UnaryOperator::Float returns 0.
- assert (Ex->getType()->isIntegerType());
- const GRState* St = GetState(*I);
- RVal X = NonLVal::MakeVal(getBasicVals(), 0, Ex->getType());
- MakeNode(Dst, U, *I, SetRVal(St, U, X));
- }
-
- return;
- }
-
- // FIXME: Just report "Unknown" for OffsetOf.
- case UnaryOperator::OffsetOf:
- Dst.Add(Pred);
- return;
-
- case UnaryOperator::Plus: assert (!asLVal); // FALL-THROUGH.
- case UnaryOperator::Extension: {
-
- // Unary "+" is a no-op, similar to a parentheses. We still have places
- // where it may be a block-level expression, so we need to
- // generate an extra node that just propagates the value of the
- // subexpression.
-
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- NodeSet Tmp;
- Visit(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- const GRState* St = GetState(*I);
- MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
- }
-
- return;
- }
-
- case UnaryOperator::AddrOf: {
-
- assert (!asLVal);
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- NodeSet Tmp;
- VisitLVal(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- const GRState* St = GetState(*I);
- RVal V = GetRVal(St, Ex);
- St = SetRVal(St, U, V);
- MakeNode(Dst, U, *I, St);
- }
-
- return;
- }
-
- case UnaryOperator::LNot:
- case UnaryOperator::Minus:
- case UnaryOperator::Not: {
-
- assert (!asLVal);
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- NodeSet Tmp;
- Visit(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- const GRState* St = GetState(*I);
-
- // Get the value of the subexpression.
- RVal V = GetRVal(St, Ex);
-
- // Perform promotions.
- // FIXME: This is the right thing to do, but it currently breaks
- // a bunch of tests.
- // V = EvalCast(V, U->getType());
-
- if (V.isUnknownOrUndef()) {
- MakeNode(Dst, U, *I, SetRVal(St, U, V));
- continue;
- }
-
- switch (U->getOpcode()) {
- default:
- assert(false && "Invalid Opcode.");
- break;
-
- case UnaryOperator::Not:
- // FIXME: Do we need to handle promotions?
- St = SetRVal(St, U, EvalComplement(cast<NonLVal>(V)));
- break;
-
- case UnaryOperator::Minus:
- // FIXME: Do we need to handle promotions?
- St = SetRVal(St, U, EvalMinus(U, cast<NonLVal>(V)));
- break;
-
- case UnaryOperator::LNot:
-
- // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
- //
- // Note: technically we do "E == 0", but this is the same in the
- // transfer functions as "0 == E".
-
- if (isa<LVal>(V)) {
- lval::ConcreteInt X(getBasicVals().getZeroWithPtrWidth());
- RVal Result = EvalBinOp(BinaryOperator::EQ, cast<LVal>(V), X);
- St = SetRVal(St, U, Result);
- }
- else {
- nonlval::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
-#if 0
- RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
- St = SetRVal(St, U, Result);
-#else
- EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLVal>(V), X, *I);
- continue;
-#endif
- }
-
- break;
- }
-
- MakeNode(Dst, U, *I, St);
- }
-
- return;
- }
-
- case UnaryOperator::SizeOf: {
-
- QualType T = U->getSubExpr()->getType();
-
- // FIXME: Add support for VLAs.
-
- if (!T.getTypePtr()->isConstantSizeType())
- return;
-
- uint64_t size = getContext().getTypeSize(T) / 8;
- const GRState* St = GetState(Pred);
- St = SetRVal(St, U, NonLVal::MakeVal(getBasicVals(), size, U->getType()));
-
- MakeNode(Dst, U, Pred, St);
- return;
- }
- }
-
- // Handle ++ and -- (both pre- and post-increment).
-
- assert (U->isIncrementDecrementOp());
- NodeSet Tmp;
- Expr* Ex = U->getSubExpr()->IgnoreParens();
- VisitLVal(Ex, Pred, Tmp);
-
- for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
-
- const GRState* St = GetState(*I);
- RVal V1 = GetRVal(St, Ex);
-
- // Perform a load.
- NodeSet Tmp2;
- EvalLoad(Tmp2, Ex, *I, St, V1);
-
- for (NodeSet::iterator I2 = Tmp2.begin(), E2 = Tmp2.end(); I2!=E2; ++I2) {
-
- St = GetState(*I2);
- RVal V2 = GetRVal(St, Ex);
-
- // Propagate unknown and undefined values.
- if (V2.isUnknownOrUndef()) {
- MakeNode(Dst, U, *I2, SetRVal(St, U, V2));
- continue;
- }
-
- // Handle all other values.
-
- BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
- : BinaryOperator::Sub;
-
- RVal Result = EvalBinOp(Op, V2, MakeConstantVal(1U, U));
- St = SetRVal(St, U, U->isPostfix() ? V2 : Result);
-
- // Perform the store.
- EvalStore(Dst, U, *I2, St, V1, Result);
- }
- }
-}
-
-void GRExprEngine::VisitAsmStmt(AsmStmt* A, NodeTy* Pred, NodeSet& Dst) {
- VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
-}
-
-void GRExprEngine::VisitAsmStmtHelperOutputs(AsmStmt* A,
- AsmStmt::outputs_iterator I,
- AsmStmt::outputs_iterator E,
- NodeTy* Pred, NodeSet& Dst) {
- if (I == E) {
- VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
- return;
- }
-
- NodeSet Tmp;
- VisitLVal(*I, Pred, Tmp);
-
- ++I;
-
- for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
- VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
-}
-
-void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A,
- AsmStmt::inputs_iterator I,
- AsmStmt::inputs_iterator E,
- NodeTy* Pred, NodeSet& Dst) {
- if (I == E) {
-
- // We have processed both the inputs and the outputs. All of the outputs
- // should evaluate to LVals. Nuke all of their values.
-
- // FIXME: Some day in the future it would be nice to allow a "plug-in"
- // which interprets the inline asm and stores proper results in the
- // outputs.
-
- const GRState* St = GetState(Pred);
-
- for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
- OE = A->end_outputs(); OI != OE; ++OI) {
-
- RVal X = GetRVal(St, *OI);
- assert (!isa<NonLVal>(X)); // Should be an Lval, or unknown, undef.
-
- if (isa<LVal>(X))
- St = SetRVal(St, cast<LVal>(X), UnknownVal());
- }
-
- MakeNode(Dst, A, Pred, St);
- return;
- }
-
- NodeSet Tmp;
- Visit(*I, Pred, Tmp);
-
- ++I;
-
- for (NodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI)
- VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
-}
-
-void GRExprEngine::EvalReturn(NodeSet& Dst, ReturnStmt* S, NodeTy* Pred) {
- assert (Builder && "GRStmtNodeBuilder must be defined.");
-
- unsigned size = Dst.size();
-
- SaveAndRestore<bool> OldSink(Builder->BuildSinks);
- SaveOr OldHasGen(Builder->HasGeneratedNode);
-
- getTF().EvalReturn(Dst, *this, *Builder, S, Pred);
-
- // Handle the case where no nodes where generated.
-
- if (!Builder->BuildSinks && Dst.size() == size && !Builder->HasGeneratedNode)
- MakeNode(Dst, S, Pred, GetState(Pred));
-}
-
-void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) {
-
- Expr* R = S->getRetValue();
-
- if (!R) {
- EvalReturn(Dst, S, Pred);
- return;
- }
-
- NodeSet DstRet;
- QualType T = R->getType();
-
- if (T->isPointerLikeType()) {
-
- // Check if any of the return values return the address of a stack variable.
-
- NodeSet Tmp;
- Visit(R, Pred, Tmp);
-
- for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- RVal X = GetRVal((*I)->getState(), R);
-
- if (isa<lval::MemRegionVal>(X)) {
-
- // Determine if the value is on the stack.
- const MemRegion* R = cast<lval::MemRegionVal>(&X)->getRegion();
-
- if (R && getStateManager().hasStackStorage(R)) {
-
- // Create a special node representing the v
-
- NodeTy* RetStackNode = Builder->generateNode(S, GetState(*I), *I);
-
- if (RetStackNode) {
- RetStackNode->markAsSink();
- RetsStackAddr.insert(RetStackNode);
- }
-
- continue;
- }
- }
-
- DstRet.Add(*I);
- }
- }
- else
- Visit(R, Pred, DstRet);
-
- for (NodeSet::iterator I=DstRet.begin(), E=DstRet.end(); I!=E; ++I)
- EvalReturn(Dst, S, *I);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions: Binary operators.
-//===----------------------------------------------------------------------===//
-
-bool GRExprEngine::CheckDivideZero(Expr* Ex, const GRState* St,
- NodeTy* Pred, RVal Denom) {
-
- // Divide by undefined? (potentially zero)
-
- if (Denom.isUndef()) {
- NodeTy* DivUndef = Builder->generateNode(Ex, St, Pred);
-
- if (DivUndef) {
- DivUndef->markAsSink();
- ExplicitBadDivides.insert(DivUndef);
- }
-
- return true;
- }
-
- // Check for divide/remainder-by-zero.
- // First, "assume" that the denominator is 0 or undefined.
-
- bool isFeasibleZero = false;
- const GRState* ZeroSt = Assume(St, Denom, false, isFeasibleZero);
-
- // Second, "assume" that the denominator cannot be 0.
-
- bool isFeasibleNotZero = false;
- St = Assume(St, Denom, true, isFeasibleNotZero);
-
- // Create the node for the divide-by-zero (if it occurred).
-
- if (isFeasibleZero)
- if (NodeTy* DivZeroNode = Builder->generateNode(Ex, ZeroSt, Pred)) {
- DivZeroNode->markAsSink();
-
- if (isFeasibleNotZero)
- ImplicitBadDivides.insert(DivZeroNode);
- else
- ExplicitBadDivides.insert(DivZeroNode);
-
- }
-
- return !isFeasibleNotZero;
-}
-
-void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
- GRExprEngine::NodeTy* Pred,
- GRExprEngine::NodeSet& Dst) {
-
- NodeSet Tmp1;
- Expr* LHS = B->getLHS()->IgnoreParens();
- Expr* RHS = B->getRHS()->IgnoreParens();
-
- if (B->isAssignmentOp())
- VisitLVal(LHS, Pred, Tmp1);
- else
- Visit(LHS, Pred, Tmp1);
-
- for (NodeSet::iterator I1=Tmp1.begin(), E1=Tmp1.end(); I1 != E1; ++I1) {
-
- RVal LeftV = GetRVal((*I1)->getState(), LHS);
-
- // Process the RHS.
-
- NodeSet Tmp2;
- Visit(RHS, *I1, Tmp2);
-
- // With both the LHS and RHS evaluated, process the operation itself.
-
- for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
-
- const GRState* St = GetState(*I2);
- RVal RightV = GetRVal(St, RHS);
- BinaryOperator::Opcode Op = B->getOpcode();
-
- switch (Op) {
-
- case BinaryOperator::Assign: {
-
- // EXPERIMENTAL: "Conjured" symbols.
-
- if (RightV.isUnknown()) {
- unsigned Count = Builder->getCurrentBlockCount();
- SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), Count);
-
- RightV = LVal::IsLValType(B->getRHS()->getType())
- ? cast<RVal>(lval::SymbolVal(Sym))
- : cast<RVal>(nonlval::SymbolVal(Sym));
- }
-
- // Simulate the effects of a "store": bind the value of the RHS
- // to the L-Value represented by the LHS.
-
- EvalStore(Dst, B, LHS, *I2, SetRVal(St, B, RightV), LeftV, RightV);
- continue;
- }
-
- case BinaryOperator::Div:
- case BinaryOperator::Rem:
-
- // Special checking for integer denominators.
-
- if (RHS->getType()->isIntegerType()
- && CheckDivideZero(B, St, *I2, RightV))
- continue;
-
- // FALL-THROUGH.
-
- default: {
-
- if (B->isAssignmentOp())
- break;
-
- // Process non-assignements except commas or short-circuited
- // logical expressions (LAnd and LOr).
-
- RVal Result = EvalBinOp(Op, LeftV, RightV);
-
- if (Result.isUnknown()) {
- Dst.Add(*I2);
- continue;
- }
-
- if (Result.isUndef() && !LeftV.isUndef() && !RightV.isUndef()) {
-
- // The operands were *not* undefined, but the result is undefined.
- // This is a special node that should be flagged as an error.
-
- if (NodeTy* UndefNode = Builder->generateNode(B, St, *I2)) {
- UndefNode->markAsSink();
- UndefResults.insert(UndefNode);
- }
-
- continue;
- }
-
- // Otherwise, create a new node.
-
- MakeNode(Dst, B, *I2, SetRVal(St, B, Result));
- continue;
- }
- }
-
- assert (B->isCompoundAssignmentOp());
-
- if (Op >= BinaryOperator::AndAssign)
- ((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
- else
- ((int&) Op) -= BinaryOperator::MulAssign;
-
- // Perform a load (the LHS). This performs the checks for
- // null dereferences, and so on.
- NodeSet Tmp3;
- RVal location = GetRVal(St, LHS);
- EvalLoad(Tmp3, LHS, *I2, St, location);
-
- for (NodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3; ++I3) {
-
- St = GetState(*I3);
- RVal V = GetRVal(St, LHS);
-
- // Propagate undefined values (left-side).
- if (V.isUndef()) {
- EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, V), location, V);
- continue;
- }
-
- // Propagate unknown values (left and right-side).
- if (RightV.isUnknown() || V.isUnknown()) {
- EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, UnknownVal()), location,
- UnknownVal());
- continue;
- }
-
- // At this point:
- //
- // The LHS is not Undef/Unknown.
- // The RHS is not Unknown.
-
- // Get the computation type.
- QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
-
- // Perform promotions.
- V = EvalCast(V, CTy);
- RightV = EvalCast(RightV, CTy);
-
- // Evaluate operands and promote to result type.
-
- if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
- && RHS->getType()->isIntegerType()) {
-
- if (CheckDivideZero(B, St, *I3, RightV))
- continue;
- }
- else if (RightV.isUndef()) {
- // Propagate undefined values (right-side).
- EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, RightV), location, RightV);
- continue;
- }
-
- // Compute the result of the operation.
-
- RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
-
- if (Result.isUndef()) {
-
- // The operands were not undefined, but the result is undefined.
-
- if (NodeTy* UndefNode = Builder->generateNode(B, St, *I3)) {
- UndefNode->markAsSink();
- UndefResults.insert(UndefNode);
- }
-
- continue;
- }
-
- EvalStore(Dst, B, LHS, *I3, SetRVal(St, B, Result), location, Result);
- }
- }
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer-function Helpers.
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
- BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R,
- ExplodedNode<GRState>* Pred) {
-
- GRStateSet OStates;
- EvalBinOp(OStates, GetState(Pred), Ex, Op, L, R);
-
- for (GRStateSet::iterator I=OStates.begin(), E=OStates.end(); I!=E; ++I)
- MakeNode(Dst, Ex, Pred, *I);
-}
-
-void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* St,
- Expr* Ex, BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R) {
-
- GRStateSet::AutoPopulate AP(OStates, St);
- if (R.isValid()) getTF().EvalBinOpNN(OStates, StateMgr, St, Ex, Op, L, R);
-}
-
-//===----------------------------------------------------------------------===//
-// Visualization.
-//===----------------------------------------------------------------------===//
-
-#ifndef NDEBUG
-static GRExprEngine* GraphPrintCheckerState;
-static SourceManager* GraphPrintSourceManager;
-
-namespace llvm {
-template<>
-struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
- public DefaultDOTGraphTraits {
-
- static std::string getNodeAttributes(const GRExprEngine::NodeTy* N, void*) {
-
- if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
- GraphPrintCheckerState->isExplicitNullDeref(N) ||
- GraphPrintCheckerState->isUndefDeref(N) ||
- GraphPrintCheckerState->isUndefStore(N) ||
- GraphPrintCheckerState->isUndefControlFlow(N) ||
- GraphPrintCheckerState->isExplicitBadDivide(N) ||
- GraphPrintCheckerState->isImplicitBadDivide(N) ||
- GraphPrintCheckerState->isUndefResult(N) ||
- GraphPrintCheckerState->isBadCall(N) ||
- GraphPrintCheckerState->isUndefArg(N))
- return "color=\"red\",style=\"filled\"";
-
- if (GraphPrintCheckerState->isNoReturnCall(N))
- return "color=\"blue\",style=\"filled\"";
-
- return "";
- }
-
- static std::string getNodeLabel(const GRExprEngine::NodeTy* N, void*) {
- std::ostringstream Out;
-
- // Program Location.
- ProgramPoint Loc = N->getLocation();
-
- switch (Loc.getKind()) {
- case ProgramPoint::BlockEntranceKind:
- Out << "Block Entrance: B"
- << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
- break;
-
- case ProgramPoint::BlockExitKind:
- assert (false);
- break;
-
- case ProgramPoint::PostLoadKind:
- case ProgramPoint::PostPurgeDeadSymbolsKind:
- case ProgramPoint::PostStmtKind: {
- const PostStmt& L = cast<PostStmt>(Loc);
- Stmt* S = L.getStmt();
- SourceLocation SLoc = S->getLocStart();
-
- Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
- llvm::raw_os_ostream OutS(Out);
- S->printPretty(OutS);
- OutS.flush();
-
- if (SLoc.isFileID()) {
- Out << "\\lline="
- << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
- << GraphPrintSourceManager->getColumnNumber(SLoc) << "\\l";
- }
-
- if (GraphPrintCheckerState->isImplicitNullDeref(N))
- Out << "\\|Implicit-Null Dereference.\\l";
- else if (GraphPrintCheckerState->isExplicitNullDeref(N))
- Out << "\\|Explicit-Null Dereference.\\l";
- else if (GraphPrintCheckerState->isUndefDeref(N))
- Out << "\\|Dereference of undefialied value.\\l";
- else if (GraphPrintCheckerState->isUndefStore(N))
- Out << "\\|Store to Undefined LVal.";
- else if (GraphPrintCheckerState->isExplicitBadDivide(N))
- Out << "\\|Explicit divide-by zero or undefined value.";
- else if (GraphPrintCheckerState->isImplicitBadDivide(N))
- Out << "\\|Implicit divide-by zero or undefined value.";
- else if (GraphPrintCheckerState->isUndefResult(N))
- Out << "\\|Result of operation is undefined.";
- else if (GraphPrintCheckerState->isNoReturnCall(N))
- Out << "\\|Call to function marked \"noreturn\".";
- else if (GraphPrintCheckerState->isBadCall(N))
- Out << "\\|Call to NULL/Undefined.";
- else if (GraphPrintCheckerState->isUndefArg(N))
- Out << "\\|Argument in call is undefined";
-
- break;
- }
-
- default: {
- const BlockEdge& E = cast<BlockEdge>(Loc);
- Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
- << E.getDst()->getBlockID() << ')';
-
- if (Stmt* T = E.getSrc()->getTerminator()) {
-
- SourceLocation SLoc = T->getLocStart();
-
- Out << "\\|Terminator: ";
-
- llvm::raw_os_ostream OutS(Out);
- E.getSrc()->printTerminator(OutS);
- OutS.flush();
-
- if (SLoc.isFileID()) {
- Out << "\\lline="
- << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
- << GraphPrintSourceManager->getColumnNumber(SLoc);
- }
-
- if (isa<SwitchStmt>(T)) {
- Stmt* Label = E.getDst()->getLabel();
-
- if (Label) {
- if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
- Out << "\\lcase ";
- llvm::raw_os_ostream OutS(Out);
- C->getLHS()->printPretty(OutS);
- OutS.flush();
-
- if (Stmt* RHS = C->getRHS()) {
- Out << " .. ";
- RHS->printPretty(OutS);
- OutS.flush();
- }
-
- Out << ":";
- }
- else {
- assert (isa<DefaultStmt>(Label));
- Out << "\\ldefault:";
- }
- }
- else
- Out << "\\l(implicit) default:";
- }
- else if (isa<IndirectGotoStmt>(T)) {
- // FIXME
- }
- else {
- Out << "\\lCondition: ";
- if (*E.getSrc()->succ_begin() == E.getDst())
- Out << "true";
- else
- Out << "false";
- }
-
- Out << "\\l";
- }
-
- if (GraphPrintCheckerState->isUndefControlFlow(N)) {
- Out << "\\|Control-flow based on\\lUndefined value.\\l";
- }
- }
- }
-
- Out << "\\|StateID: " << (void*) N->getState() << "\\|";
-
- GRStateRef state(N->getState(), GraphPrintCheckerState->getStateManager());
- state.printDOT(Out);
-
- Out << "\\l";
- return Out.str();
- }
-};
-} // end llvm namespace
-#endif
-
-#ifndef NDEBUG
-
-template <typename ITERATOR>
-GRExprEngine::NodeTy* GetGraphNode(ITERATOR I) { return *I; }
-
-template <>
-GRExprEngine::NodeTy*
-GetGraphNode<llvm::DenseMap<GRExprEngine::NodeTy*, Expr*>::iterator>
- (llvm::DenseMap<GRExprEngine::NodeTy*, Expr*>::iterator I) {
- return I->first;
-}
-
-template <typename ITERATOR>
-static void AddSources(std::vector<GRExprEngine::NodeTy*>& Sources,
- ITERATOR I, ITERATOR E) {
-
- llvm::SmallSet<ProgramPoint,10> CachedSources;
-
- for ( ; I != E; ++I ) {
- GRExprEngine::NodeTy* N = GetGraphNode(I);
- ProgramPoint P = N->getLocation();
-
- if (CachedSources.count(P))
- continue;
-
- CachedSources.insert(P);
- Sources.push_back(N);
- }
-}
-#endif
-
-void GRExprEngine::ViewGraph(bool trim) {
-#ifndef NDEBUG
- if (trim) {
- std::vector<NodeTy*> Src;
-
- // Fixme: Migrate over to the new way of adding nodes.
- AddSources(Src, null_derefs_begin(), null_derefs_end());
- AddSources(Src, undef_derefs_begin(), undef_derefs_end());
- AddSources(Src, explicit_bad_divides_begin(), explicit_bad_divides_end());
- AddSources(Src, undef_results_begin(), undef_results_end());
- AddSources(Src, bad_calls_begin(), bad_calls_end());
- AddSources(Src, undef_arg_begin(), undef_arg_end());
- AddSources(Src, undef_branches_begin(), undef_branches_end());
-
- // The new way.
- for (BugTypeSet::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
- (*I)->GetErrorNodes(Src);
-
-
- ViewGraph(&Src[0], &Src[0]+Src.size());
- }
- else {
- GraphPrintCheckerState = this;
- GraphPrintSourceManager = &getContext().getSourceManager();
-
- llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
-
- GraphPrintCheckerState = NULL;
- GraphPrintSourceManager = NULL;
- }
-#endif
-}
-
-void GRExprEngine::ViewGraph(NodeTy** Beg, NodeTy** End) {
-#ifndef NDEBUG
- GraphPrintCheckerState = this;
- GraphPrintSourceManager = &getContext().getSourceManager();
-
- GRExprEngine::GraphTy* TrimmedG = G.Trim(Beg, End);
-
- if (!TrimmedG)
- llvm::cerr << "warning: Trimmed ExplodedGraph is empty.\n";
- else {
- llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedGRExprEngine");
- delete TrimmedG;
- }
-
- GraphPrintCheckerState = NULL;
- GraphPrintSourceManager = NULL;
-#endif
-}
diff --git a/clang/lib/Analysis/GRExprEngineInternalChecks.cpp b/clang/lib/Analysis/GRExprEngineInternalChecks.cpp
deleted file mode 100644
index d61998c5a410..000000000000
--- a/clang/lib/Analysis/GRExprEngineInternalChecks.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- 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 BugType classes used by GRExprEngine to report
-// bugs derived from builtin checks in the path-sensitive engine.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "llvm/Support/Compiler.h"
-#include <sstream>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Utility functions.
-//===----------------------------------------------------------------------===//
-
-template <typename ITERATOR> inline
-ExplodedNode<GRState>* GetNode(ITERATOR I) {
- return *I;
-}
-
-template <> inline
-ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) {
- return I->first;
-}
-
-//===----------------------------------------------------------------------===//
-// Bug Descriptions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation {
- const char* name;
- const char* desc;
-public:
- BuiltinBug(const char* n, const char* d = 0) : name(n), desc(d) {}
- virtual const char* getName() const { return name; }
- virtual const char* getDescription() const {
- return desc ? desc : name;
- }
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0;
- virtual void EmitWarnings(BugReporter& BR) {
- EmitBuiltinWarnings(BR, cast<GRBugReporter>(BR).getEngine());
- }
-
- template <typename ITER>
- void Emit(BugReporter& BR, ITER I, ITER E) {
- for (; I != E; ++I) {
- BugReport R(*this, GetNode(I));
- BR.EmitWarning(R);
- }
- }
-
- virtual const char* getCategory() const { return "Logic Errors"; }
-};
-
-class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
-public:
- NullDeref() : BuiltinBug("null dereference",
- "Dereference of null pointer.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
- }
-};
-
-class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
-public:
- UndefinedDeref() : BuiltinBug("uninitialized pointer dereference",
- "Dereference of undefined value.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
- }
-};
-
-class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
-public:
- DivZero() : BuiltinBug("divide-by-zero",
- "Division by zero/undefined value.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
- }
-};
-
-class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
-public:
- UndefResult() : BuiltinBug("undefined result",
- "Result of operation is undefined.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
- }
-};
-
-class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
-public:
- BadCall()
- : BuiltinBug("invalid function call",
- "Called function is a NULL or undefined function pointer value.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
- }
-};
-
-class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
-public:
- BadArg() : BuiltinBug("uninitialized argument",
- "Pass-by-value argument in function is undefined.") {}
-
- BadArg(const char* d) : BuiltinBug("uninitialized argument", d) {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
- E = Eng.undef_arg_end(); I!=E; ++I) {
-
- // Generate a report for this bug.
- RangedBugReport report(*this, I->first);
- report.addRange(I->second->getSourceRange());
-
- // Emit the warning.
- BR.EmitWarning(report);
- }
- }
-};
-
-class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
-public:
- BadMsgExprArg()
- : BadArg("Pass-by-value argument in message expression is undefined.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
- E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
-
- // Generate a report for this bug.
- RangedBugReport report(*this, I->first);
- report.addRange(I->second->getSourceRange());
-
- // Emit the warning.
- BR.EmitWarning(report);
- }
- }
-};
-
-class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
-public:
- BadReceiver()
- : BuiltinBug("uninitialized receiver",
- "Receiver in message expression is an uninitialized value.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
- End = Eng.undef_receivers_end(); I!=End; ++I) {
-
- // Generate a report for this bug.
- RangedBugReport report(*this, *I);
-
- ExplodedNode<GRState>* N = *I;
- Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
- Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
- assert (E && "Receiver cannot be NULL");
- report.addRange(E->getSourceRange());
-
- // Emit the warning.
- BR.EmitWarning(report);
- }
- }
-};
-
-class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
-public:
- RetStack() : BuiltinBug("return of stack address") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
- End = Eng.ret_stackaddr_end(); I!=End; ++I) {
-
- ExplodedNode<GRState>* N = *I;
- Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
- Expr* E = cast<ReturnStmt>(S)->getRetValue();
- assert (E && "Return expression cannot be NULL");
-
- // Get the value associated with E.
- lval::MemRegionVal V =
- cast<lval::MemRegionVal>(Eng.getStateManager().GetRVal(N->getState(),
- E));
-
- // Generate a report for this bug.
- std::ostringstream os;
- os << "Address of stack memory associated with local variable '"
- << V.getRegion()->getString() << "' returned.";
-
- std::string s = os.str();
-
- RangedBugReport report(*this, N, s.c_str());
- report.addRange(E->getSourceRange());
-
- // Emit the warning.
- BR.EmitWarning(report);
- }
- }
-};
-
-
-class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
- struct VISIBILITY_HIDDEN FindUndefExpr {
- GRStateManager& VM;
- const GRState* St;
-
- FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
-
- Expr* FindExpr(Expr* Ex) {
- if (!MatchesCriteria(Ex))
- return 0;
-
- for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
- if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
- Expr* E2 = FindExpr(ExI);
- if (E2) return E2;
- }
-
- return Ex;
- }
-
- bool MatchesCriteria(Expr* Ex) { return VM.GetRVal(St, Ex).isUndef(); }
- };
-
-public:
- UndefBranch()
- : BuiltinBug("uninitialized value",
- "Branch condition evaluates to an uninitialized value.") {}
-
- virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
- for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
- E=Eng.undef_branches_end(); I!=E; ++I) {
-
- // What's going on here: we want to highlight the subexpression of the
- // condition that is the most likely source of the "uninitialized
- // branch condition." We do a recursive walk of the condition's
- // subexpressions and roughly look for the most nested subexpression
- // that binds to Undefined. We then highlight that expression's range.
-
- BlockEdge B = cast<BlockEdge>((*I)->getLocation());
- Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
- assert (Ex && "Block must have a terminator.");
-
- // Get the predecessor node and check if is a PostStmt with the Stmt
- // being the terminator condition. We want to inspect the state
- // of that node instead because it will contain main information about
- // the subexpressions.
-
- assert (!(*I)->pred_empty());
-
- // Note: any predecessor will do. They should have identical state,
- // since all the BlockEdge did was act as an error sink since the value
- // had to already be undefined.
- ExplodedNode<GRState> *N = *(*I)->pred_begin();
- ProgramPoint P = N->getLocation();
-
- const GRState* St = (*I)->getState();
-
- if (PostStmt* PS = dyn_cast<PostStmt>(&P))
- if (PS->getStmt() == Ex)
- St = N->getState();
-
- FindUndefExpr FindIt(Eng.getStateManager(), St);
- Ex = FindIt.FindExpr(Ex);
-
- RangedBugReport R(*this, *I);
- R.addRange(Ex->getSourceRange());
-
- BR.EmitWarning(R);
- }
- }
-};
-
-//===----------------------------------------------------------------------===//
-// __attribute__(nonnull) checking
-
-class VISIBILITY_HIDDEN CheckAttrNonNull : public GRSimpleAPICheck {
- SimpleBugType BT;
- std::list<RangedBugReport> Reports;
-
-public:
- CheckAttrNonNull() :
- BT("'nonnull' argument passed null", "API",
- "Null pointer passed as an argument to a 'nonnull' parameter") {}
-
- virtual bool Audit(ExplodedNode<GRState>* N, GRStateManager& VMgr) {
- CallExpr* CE = cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
- const GRState* state = N->getState();
-
- RVal X = VMgr.GetRVal(state, CE->getCallee());
-
- if (!isa<lval::FuncVal>(X))
- return false;
-
- FunctionDecl* FD = dyn_cast<FunctionDecl>(cast<lval::FuncVal>(X).getDecl());
- const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
-
- if (!Att)
- return false;
-
- // Iterate through the arguments of CE and check them for null.
-
- unsigned idx = 0;
- bool hasError = false;
-
- for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
- ++I, ++idx) {
-
- if (!VMgr.isEqual(state, *I, 0) || !Att->isNonNull(idx))
- continue;
-
- RangedBugReport R(BT, N);
- R.addRange((*I)->getSourceRange());
- Reports.push_back(R);
- hasError = true;
- }
-
- return hasError;
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- for (std::list<RangedBugReport>::iterator I=Reports.begin(),
- E=Reports.end(); I!=E; ++I)
- BR.EmitWarning(*I);
- }
-};
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Check registration.
-
-void GRExprEngine::RegisterInternalChecks() {
- Register(new NullDeref());
- Register(new UndefinedDeref());
- Register(new UndefBranch());
- Register(new DivZero());
- Register(new UndefResult());
- Register(new BadCall());
- Register(new RetStack());
- Register(new BadArg());
- Register(new BadMsgExprArg());
- Register(new BadReceiver());
- AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass);
-}
diff --git a/clang/lib/Analysis/GRSimpleVals.cpp b/clang/lib/Analysis/GRSimpleVals.cpp
deleted file mode 100644
index 44703163e06f..000000000000
--- a/clang/lib/Analysis/GRSimpleVals.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- 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 GRSimpleVals, a sub-class of GRTransferFuncs that
-// provides transfer functions for performing simple value tracking with
-// limited support for symbolics.
-//
-//===----------------------------------------------------------------------===//
-
-#include "GRSimpleVals.h"
-#include "BasicObjCFoundationChecks.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "llvm/Support/Compiler.h"
-#include <sstream>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Transfer Function creation for External clients.
-//===----------------------------------------------------------------------===//
-
-GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); }
-
-//===----------------------------------------------------------------------===//
-// Transfer function for Casts.
-//===----------------------------------------------------------------------===//
-
-RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
-
- if (!isa<nonlval::ConcreteInt>(X))
- return UnknownVal();
-
- bool isLValType = LVal::IsLValType(T);
-
- // Only handle casts from integers to integers.
- if (!isLValType && !T->isIntegerType())
- return UnknownVal();
-
- BasicValueFactory& BasicVals = Eng.getBasicVals();
-
- llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
- V.setIsUnsigned(T->isUnsignedIntegerType() || LVal::IsLValType(T));
- V.extOrTrunc(Eng.getContext().getTypeSize(T));
-
- if (isLValType)
- return lval::ConcreteInt(BasicVals.getValue(V));
- else
- return nonlval::ConcreteInt(BasicVals.getValue(V));
-}
-
-// Casts.
-
-RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
-
- // Casts from pointers -> pointers, just return the lval.
- //
- // Casts from pointers -> references, just return the lval. These
- // can be introduced by the frontend for corner cases, e.g
- // casting from va_list* to __builtin_va_list&.
- //
- if (LVal::IsLValType(T) || T->isReferenceType())
- return X;
-
- assert (T->isIntegerType());
-
- if (!isa<lval::ConcreteInt>(X))
- return UnknownVal();
-
- BasicValueFactory& BasicVals = Eng.getBasicVals();
-
- llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
- V.setIsUnsigned(T->isUnsignedIntegerType() || LVal::IsLValType(T));
- V.extOrTrunc(Eng.getContext().getTypeSize(T));
-
- return nonlval::ConcreteInt(BasicVals.getValue(V));
-}
-
-// Unary operators.
-
-RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
-
- switch (X.getSubKind()) {
-
- case nonlval::ConcreteIntKind:
- return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
-
- default:
- return UnknownVal();
- }
-}
-
-RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
-
- switch (X.getSubKind()) {
-
- case nonlval::ConcreteIntKind:
- return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
-
- default:
- return UnknownVal();
- }
-}
-
-// Binary operators.
-
-static unsigned char LNotOpMap[] = {
- (unsigned char) BinaryOperator::GE, /* LT => GE */
- (unsigned char) BinaryOperator::LE, /* GT => LE */
- (unsigned char) BinaryOperator::GT, /* LE => GT */
- (unsigned char) BinaryOperator::LT, /* GE => LT */
- (unsigned char) BinaryOperator::NE, /* EQ => NE */
- (unsigned char) BinaryOperator::EQ /* NE => EQ */
-};
-
-RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
- BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R) {
-
- BasicValueFactory& BasicVals = StateMgr.getBasicVals();
- unsigned subkind = L.getSubKind();
-
- while (1) {
-
- switch (subkind) {
- default:
- return UnknownVal();
-
- case nonlval::SymIntConstraintValKind: {
-
- // Logical not?
- if (!(Op == BinaryOperator::EQ && R.isZeroConstant()))
- return UnknownVal();
-
- const SymIntConstraint& C =
- cast<nonlval::SymIntConstraintVal>(L).getConstraint();
-
- BinaryOperator::Opcode Opc = C.getOpcode();
-
- if (Opc < BinaryOperator::LT || Opc > BinaryOperator::NE)
- return UnknownVal();
-
- // For comparison operators, translate the constraint by
- // changing the opcode.
-
- int idx = (unsigned) Opc - (unsigned) BinaryOperator::LT;
-
- assert (idx >= 0 &&
- (unsigned) idx < sizeof(LNotOpMap)/sizeof(unsigned char));
-
- Opc = (BinaryOperator::Opcode) LNotOpMap[idx];
-
- const SymIntConstraint& CNew =
- BasicVals.getConstraint(C.getSymbol(), Opc, C.getInt());
-
- return nonlval::SymIntConstraintVal(CNew);
- }
-
- case nonlval::ConcreteIntKind:
-
- if (isa<nonlval::ConcreteInt>(R)) {
- const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
- const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
- return L_CI.EvalBinOp(BasicVals, Op, R_CI);
- }
- else {
- subkind = R.getSubKind();
- NonLVal tmp = R;
- R = L;
- L = tmp;
-
- // Swap the operators.
- switch (Op) {
- case BinaryOperator::LT: Op = BinaryOperator::GT; break;
- case BinaryOperator::GT: Op = BinaryOperator::LT; break;
- case BinaryOperator::LE: Op = BinaryOperator::GE; break;
- case BinaryOperator::GE: Op = BinaryOperator::LE; break;
- default: break;
- }
-
- continue;
- }
-
- case nonlval::SymbolValKind:
- if (isa<nonlval::ConcreteInt>(R)) {
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
- cast<nonlval::ConcreteInt>(R).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
- else
- return UnknownVal();
- }
- }
-}
-
-
-// Binary Operators (except assignments and comma).
-
-RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
- LVal L, LVal R) {
-
- switch (Op) {
-
- default:
- return UnknownVal();
-
- case BinaryOperator::EQ:
- return EvalEQ(Eng, L, R);
-
- case BinaryOperator::NE:
- return EvalNE(Eng, L, R);
- }
-}
-
-// Pointer arithmetic.
-
-RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
- LVal L, NonLVal R) {
- return UnknownVal();
-}
-
-// Equality operators for LVals.
-
-RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
-
- BasicValueFactory& BasicVals = Eng.getBasicVals();
-
- switch (L.getSubKind()) {
-
- default:
- assert(false && "EQ not implemented for this LVal.");
- return UnknownVal();
-
- case lval::ConcreteIntKind:
-
- if (isa<lval::ConcreteInt>(R)) {
- bool b = cast<lval::ConcreteInt>(L).getValue() ==
- cast<lval::ConcreteInt>(R).getValue();
-
- return NonLVal::MakeIntTruthVal(BasicVals, b);
- }
- else if (isa<lval::SymbolVal>(R)) {
-
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
- BinaryOperator::EQ,
- cast<lval::ConcreteInt>(L).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- break;
-
- case lval::SymbolValKind: {
-
- if (isa<lval::ConcreteInt>(R)) {
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
- BinaryOperator::EQ,
- cast<lval::ConcreteInt>(R).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- // FIXME: Implement == for lval Symbols. This is mainly useful
- // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
- // Since this is not useful for many checkers we'll punt on this for
- // now.
-
- return UnknownVal();
- }
-
- // FIXME: Different offsets can map to the same memory cell.
- case lval::ArrayOffsetKind:
- case lval::FieldOffsetKind:
- // Fall-through.
-
- case lval::MemRegionKind:
- case lval::FuncValKind:
- case lval::GotoLabelKind:
- case lval::StringLiteralValKind:
- return NonLVal::MakeIntTruthVal(BasicVals, L == R);
- }
-
- return NonLVal::MakeIntTruthVal(BasicVals, false);
-}
-
-RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
-
- BasicValueFactory& BasicVals = Eng.getBasicVals();
-
- switch (L.getSubKind()) {
-
- default:
- assert(false && "NE not implemented for this LVal.");
- return UnknownVal();
-
- case lval::ConcreteIntKind:
-
- if (isa<lval::ConcreteInt>(R)) {
- bool b = cast<lval::ConcreteInt>(L).getValue() !=
- cast<lval::ConcreteInt>(R).getValue();
-
- return NonLVal::MakeIntTruthVal(BasicVals, b);
- }
- else if (isa<lval::SymbolVal>(R)) {
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
- BinaryOperator::NE,
- cast<lval::ConcreteInt>(L).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- break;
-
- case lval::SymbolValKind: {
- if (isa<lval::ConcreteInt>(R)) {
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
- BinaryOperator::NE,
- cast<lval::ConcreteInt>(R).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- // FIXME: Implement != for lval Symbols. This is mainly useful
- // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
- // Since this is not useful for many checkers we'll punt on this for
- // now.
-
- return UnknownVal();
-
- break;
- }
-
- // FIXME: Different offsets can map to the same memory cell.
- case lval::ArrayOffsetKind:
- case lval::FieldOffsetKind:
- // Fall-through.
-
- case lval::MemRegionKind:
- case lval::FuncValKind:
- case lval::GotoLabelKind:
- case lval::StringLiteralValKind:
- return NonLVal::MakeIntTruthVal(BasicVals, L != R);
- }
-
- return NonLVal::MakeIntTruthVal(BasicVals, true);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function for function calls.
-//===----------------------------------------------------------------------===//
-
-void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<GRState>* Pred) {
-
- GRStateManager& StateMgr = Eng.getStateManager();
- const GRState* St = Builder.GetState(Pred);
-
- // Invalidate all arguments passed in by reference (LVals).
-
- for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
- I != E; ++I) {
-
- RVal V = StateMgr.GetRVal(St, *I);
-
- if (isa<LVal>(V))
- St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
- else if (isa<nonlval::LValAsInteger>(V))
- St = StateMgr.SetRVal(St, cast<nonlval::LValAsInteger>(V).getLVal(),
- UnknownVal());
-
- }
-
- // Make up a symbol for the return value of this function.
-
- if (CE->getType() != Eng.getContext().VoidTy) {
- unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
-
- RVal X = LVal::IsLValType(CE->getType())
- ? cast<RVal>(lval::SymbolVal(Sym))
- : cast<RVal>(nonlval::SymbolVal(Sym));
-
- St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
- }
-
- Builder.MakeNode(Dst, CE, Pred, St);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function for Objective-C message expressions.
-//===----------------------------------------------------------------------===//
-
-void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<GRState>* Pred) {
-
-
- // The basic transfer function logic for message expressions does nothing.
- // We just invalidate all arguments passed in by references.
-
- GRStateManager& StateMgr = Eng.getStateManager();
- const GRState* St = Builder.GetState(Pred);
-
- for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
- I != E; ++I) {
-
- RVal V = StateMgr.GetRVal(St, *I);
-
- if (isa<LVal>(V))
- St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
- }
-
- Builder.MakeNode(Dst, ME, Pred, St);
-}
diff --git a/clang/lib/Analysis/GRSimpleVals.h b/clang/lib/Analysis/GRSimpleVals.h
deleted file mode 100644
index 720ccc1f2039..000000000000
--- a/clang/lib/Analysis/GRSimpleVals.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// GRSimpleVals.h - Transfer functions for tracking simple values -*- 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 GRSimpleVals, a sub-class of GRTransferFuncs that
-// provides transfer functions for performing simple value tracking with
-// limited support for symbolics.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRSIMPLEVALS
-#define LLVM_CLANG_ANALYSIS_GRSIMPLEVALS
-
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-
-namespace clang {
-
-class PathDiagnostic;
-class ASTContext;
-
-class GRSimpleVals : public GRTransferFuncs {
-protected:
-
- virtual RVal DetermEvalBinOpNN(GRStateManager& StateMgr,
- BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R);
-
-public:
- GRSimpleVals() {}
- virtual ~GRSimpleVals() {}
-
- // Casts.
-
- virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT);
- virtual RVal EvalCast(GRExprEngine& Engine, LVal V, QualType CastT);
-
- // Unary Operators.
-
- virtual RVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLVal X);
-
- virtual RVal EvalComplement(GRExprEngine& Engine, NonLVal X);
-
- // Binary Operators.
-
- virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
- LVal L, LVal R);
-
- // Pointer arithmetic.
-
- virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
- LVal L, NonLVal R);
-
- // Calls.
-
- virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<GRState>* Pred);
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<GRState>* Pred);
-
-
-
- static void GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
- ExplodedNode<GRState>* N);
-
-protected:
-
- // Equality operators for LVals.
-
- RVal EvalEQ(GRExprEngine& Engine, LVal L, LVal R);
- RVal EvalNE(GRExprEngine& Engine, LVal L, LVal R);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/clang/lib/Analysis/GRState.cpp b/clang/lib/Analysis/GRState.cpp
deleted file mode 100644
index 0b519fc6a031..000000000000
--- a/clang/lib/Analysis/GRState.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-//= GRState*cpp - Path-Sens. "State" for tracking valuues -----*- 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 SymbolID, ExprBindKey, and GRState*
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRStateTrait.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-
-// Give the vtable for ConstraintManager somewhere to live.
-ConstraintManager::~ConstraintManager() {}
-
-GRStateManager::~GRStateManager() {
- for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
- E=Printers.end(); I!=E; ++I)
- delete *I;
-
- for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
- I!=E; ++I)
- I->second.second(I->second.first);
-}
-
-const GRState*
-GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
- const LiveVariables& Liveness,
- DeadSymbolsTy& DSymbols) {
-
- // This code essentially performs a "mark-and-sweep" of the VariableBindings.
- // The roots are any Block-level exprs and Decls that our liveness algorithm
- // tells us are live. We then see what Decls they may reference, and keep
- // those around. This code more than likely can be made faster, and the
- // frequency of which this method is called should be experimented with
- // for optimum performance.
- llvm::SmallVector<const MemRegion*, 10> RegionRoots;
- StoreManager::LiveSymbolsTy LSymbols;
- GRState NewSt = *St;
-
- NewSt.Env =
- EnvMgr.RemoveDeadBindings(NewSt.Env, Loc, Liveness, RegionRoots, LSymbols);
-
- // Clean up the store.
- DSymbols.clear();
- NewSt.St = StMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness,
- RegionRoots, LSymbols, DSymbols);
-
- return ConstraintMgr->RemoveDeadBindings(getPersistentState(NewSt),
- LSymbols, DSymbols);
-}
-
-const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
- RVal V) {
-
- Store OldStore = St->getStore();
- Store NewStore = StMgr->SetRVal(OldStore, LV, V);
-
- if (NewStore == OldStore)
- return St;
-
- GRState NewSt = *St;
- NewSt.St = NewStore;
- return getPersistentState(NewSt);
-}
-
-const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
- Expr* Ex, unsigned Count) {
- Store OldStore = St->getStore();
- Store NewStore;
-
- if (Ex)
- NewStore = StMgr->AddDecl(OldStore, VD, Ex,
- GetRVal(St, Ex), Count);
- else
- NewStore = StMgr->AddDecl(OldStore, VD, Ex);
-
- if (NewStore == OldStore)
- return St;
-
- GRState NewSt = *St;
- NewSt.St = NewStore;
- return getPersistentState(NewSt);
-}
-
-const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
- Store OldStore = St->getStore();
- Store NewStore = StMgr->Remove(OldStore, LV);
-
- if (NewStore == OldStore)
- return St;
-
- GRState NewSt = *St;
- NewSt.St = NewStore;
- return getPersistentState(NewSt);
-}
-
-const GRState* GRStateManager::getInitialState() {
-
- GRState StateImpl(EnvMgr.getInitialEnvironment(),
- StMgr->getInitialStore(),
- GDMFactory.GetEmptyMap());
-
- return getPersistentState(StateImpl);
-}
-
-const GRState* GRStateManager::getPersistentState(GRState& State) {
-
- llvm::FoldingSetNodeID ID;
- State.Profile(ID);
- void* InsertPos;
-
- if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
- return I;
-
- GRState* I = (GRState*) Alloc.Allocate<GRState>();
- new (I) GRState(State);
- StateSet.InsertNode(I, InsertPos);
- return I;
-}
-
-
-//===----------------------------------------------------------------------===//
-// State pretty-printing.
-//===----------------------------------------------------------------------===//
-
-void GRState::print(std::ostream& Out, StoreManager& StoreMgr,
- ConstraintManager& ConstraintMgr,
- Printer** Beg, Printer** End,
- const char* nl, const char* sep) const {
-
- // Print the store.
- StoreMgr.print(getStore(), Out, nl, sep);
-
- // Print Subexpression bindings.
- bool isFirst = true;
-
- for (seb_iterator I = seb_begin(), E = seb_end(); I != E; ++I) {
-
- if (isFirst) {
- Out << nl << nl << "Sub-Expressions:" << nl;
- isFirst = false;
- }
- else { Out << nl; }
-
- Out << " (" << (void*) I.getKey() << ") ";
- llvm::raw_os_ostream OutS(Out);
- I.getKey()->printPretty(OutS);
- OutS.flush();
- Out << " : ";
- I.getData().print(Out);
- }
-
- // Print block-expression bindings.
- isFirst = true;
-
- for (beb_iterator I = beb_begin(), E = beb_end(); I != E; ++I) {
-
- if (isFirst) {
- Out << nl << nl << "Block-level Expressions:" << nl;
- isFirst = false;
- }
- else { Out << nl; }
-
- Out << " (" << (void*) I.getKey() << ") ";
- llvm::raw_os_ostream OutS(Out);
- I.getKey()->printPretty(OutS);
- OutS.flush();
- Out << " : ";
- I.getData().print(Out);
- }
-
- ConstraintMgr.print(this, Out, nl, sep);
-
- // Print checker-specific data.
- for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
-}
-
-void GRStateRef::printDOT(std::ostream& Out) const {
- print(Out, "\\l", "\\|");
-}
-
-void GRStateRef::printStdErr() const {
- print(*llvm::cerr);
-}
-
-void GRStateRef::print(std::ostream& Out, const char* nl, const char* sep)const{
- GRState::Printer **beg = Mgr->Printers.empty() ? 0 : &Mgr->Printers[0];
- GRState::Printer **end = !beg ? 0 : beg + Mgr->Printers.size();
- St->print(Out, *Mgr->StMgr, *Mgr->ConstraintMgr, beg, end, nl, sep);
-}
-
-//===----------------------------------------------------------------------===//
-// Generic Data Map.
-//===----------------------------------------------------------------------===//
-
-void* const* GRState::FindGDM(void* K) const {
- return GDM.lookup(K);
-}
-
-void*
-GRStateManager::FindGDMContext(void* K,
- void* (*CreateContext)(llvm::BumpPtrAllocator&),
- void (*DeleteContext)(void*)) {
-
- std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
- if (!p.first) {
- p.first = CreateContext(Alloc);
- p.second = DeleteContext;
- }
-
- return p.first;
-}
-
-const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
- GRState::GenericDataMap M1 = St->getGDM();
- GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
-
- if (M1 == M2)
- return St;
-
- GRState NewSt = *St;
- NewSt.GDM = M2;
- return getPersistentState(NewSt);
-}
-
-//===----------------------------------------------------------------------===//
-// Queries.
-//===----------------------------------------------------------------------===//
-
-bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
- const llvm::APSInt& Y) {
-
- RVal V = GetRVal(state, Ex);
-
- if (lval::ConcreteInt* X = dyn_cast<lval::ConcreteInt>(&V))
- return X->getValue() == Y;
-
- if (nonlval::ConcreteInt* X = dyn_cast<nonlval::ConcreteInt>(&V))
- return X->getValue() == Y;
-
- if (nonlval::SymbolVal* X = dyn_cast<nonlval::SymbolVal>(&V))
- return ConstraintMgr->isEqual(state, X->getSymbol(), Y);
-
- if (lval::SymbolVal* X = dyn_cast<lval::SymbolVal>(&V))
- return ConstraintMgr->isEqual(state, X->getSymbol(), Y);
-
- return false;
-}
-
-bool GRStateManager::isEqual(const GRState* state, Expr* Ex, uint64_t x) {
- return isEqual(state, Ex, BasicVals.getValue(x, Ex->getType()));
-}
-
-//===----------------------------------------------------------------------===//
-// Persistent values for indexing into the Generic Data Map.
-
-int GRState::NullDerefTag::TagInt = 0;
-
diff --git a/clang/lib/Analysis/GRTransferFuncs.cpp b/clang/lib/Analysis/GRTransferFuncs.cpp
deleted file mode 100644
index 03292d1c49b3..000000000000
--- a/clang/lib/Analysis/GRTransferFuncs.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//== GRTransferFuncs.cpp - Path-Sens. Transfer Functions Interface -*- 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 GRTransferFuncs, which provides a base-class that
-// defines an interface for transfer functions used by GRExprEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-
-using namespace clang;
-
-void GRTransferFuncs::RegisterChecks(GRExprEngine& Eng) {}
-
-void GRTransferFuncs::EvalStore(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* E, ExplodedNode<GRState>* Pred,
- const GRState* St, RVal TargetLV, RVal Val) {
-
- // This code basically matches the "safety-net" logic of GRExprEngine:
- // bind Val to TargetLV, and create a new node. We replicate it here
- // because subclasses of GRTransferFuncs may wish to call it.
-
- assert (!TargetLV.isUndef());
-
- if (TargetLV.isUnknown())
- Builder.MakeNode(Dst, E, Pred, St);
- else
- Builder.MakeNode(Dst, E, Pred,
- Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));
-}
-
-void GRTransferFuncs::EvalBinOpNN(GRStateSet& OStates,
- GRStateManager& StateMgr,
- const GRState *St, Expr* Ex,
- BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R) {
-
- OStates.Add(StateMgr.SetRVal(St, Ex, DetermEvalBinOpNN(StateMgr, Op, L, R)));
-}
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp
deleted file mode 100644
index 58affbfcda51..000000000000
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-//=- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-// details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Live Variables analysis for source-level CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/CFG.h"
-#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
-#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
-
-#include <string.h>
-#include <stdio.h>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Useful constants.
-//===----------------------------------------------------------------------===//
-
-static const bool Alive = true;
-static const bool Dead = false;
-
-//===----------------------------------------------------------------------===//
-// Dataflow initialization logic.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN RegisterDecls
- : public CFGRecStmtDeclVisitor<RegisterDecls> {
-
- LiveVariables::AnalysisDataTy& AD;
-
- typedef llvm::SmallVector<VarDecl*, 20> AlwaysLiveTy;
- AlwaysLiveTy AlwaysLive;
-
-
-public:
- RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
-
- ~RegisterDecls() {
-
- AD.AlwaysLive.resetValues(AD);
-
- for (AlwaysLiveTy::iterator I = AlwaysLive.begin(), E = AlwaysLive.end();
- I != E; ++ I)
- AD.AlwaysLive(*I, AD) = Alive;
- }
-
- void VisitImplicitParamDecl(ImplicitParamDecl* IPD) {
- // Register the VarDecl for tracking.
- AD.Register(IPD);
- }
-
- void VisitVarDecl(VarDecl* VD) {
- // Register the VarDecl for tracking.
- AD.Register(VD);
-
- // Does the variable have global storage? If so, it is always live.
- if (VD->hasGlobalStorage())
- AlwaysLive.push_back(VD);
- }
-
- void VisitUnaryOperator(UnaryOperator* U) {
- // Check for '&'. Any VarDecl whose value has its address-taken we
- // treat as always being live (flow-insensitive).
-
- Expr* E = U->getSubExpr()->IgnoreParenCasts();
-
- if (U->getOpcode() == UnaryOperator::AddrOf)
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
- AD.Register(VD);
- AlwaysLive.push_back(VD);
- return;
- }
-
- Visit(E);
- }
-
- CFG& getCFG() { return AD.getCFG(); }
-};
-} // end anonymous namespace
-
-
-LiveVariables::LiveVariables(CFG& cfg) {
- // Register all referenced VarDecls.
- getAnalysisData().setCFG(&cfg);
- RegisterDecls R(getAnalysisData());
- cfg.VisitBlockStmts(R);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN TransferFuncs : public CFGRecStmtVisitor<TransferFuncs>{
- LiveVariables::AnalysisDataTy& AD;
- LiveVariables::ValTy LiveState;
-public:
- TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
-
- LiveVariables::ValTy& getVal() { return LiveState; }
- CFG& getCFG() { return AD.getCFG(); }
-
- void VisitDeclRefExpr(DeclRefExpr* DR);
- void VisitBinaryOperator(BinaryOperator* B);
- void VisitAssign(BinaryOperator* B);
- void VisitDeclStmt(DeclStmt* DS);
- void VisitUnaryOperator(UnaryOperator* U);
- void Visit(Stmt *S);
- void VisitTerminator(CFGBlock* B);
-
- void SetTopValue(LiveVariables::ValTy& V) {
- V = AD.AlwaysLive;
- }
-
-};
-
-void TransferFuncs::Visit(Stmt *S) {
-
- if (S == getCurrentBlkStmt()) {
-
- if (AD.Observer)
- AD.Observer->ObserveStmt(S,AD,LiveState);
-
- if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
- StmtVisitor<TransferFuncs,void>::Visit(S);
- }
- else if (!getCFG().isBlkExpr(S)) {
-
- if (AD.Observer)
- AD.Observer->ObserveStmt(S,AD,LiveState);
-
- StmtVisitor<TransferFuncs,void>::Visit(S);
-
- }
- else
- // For block-level expressions, mark that they are live.
- LiveState(S,AD) = Alive;
-}
-
-void TransferFuncs::VisitTerminator(CFGBlock* B) {
-
- const Expr* E = B->getTerminatorCondition();
-
- if (!E)
- return;
-
- assert (getCFG().isBlkExpr(E));
- LiveState(E, AD) = Alive;
-}
-
-void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
- if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
- LiveState(V,AD) = Alive;
-}
-
-void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
- if (B->isAssignmentOp()) VisitAssign(B);
- else VisitStmt(B);
-}
-
-void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
- Expr *E = U->getSubExpr();
-
- switch (U->getOpcode()) {
- case UnaryOperator::SizeOf: return;
- case UnaryOperator::PostInc:
- case UnaryOperator::PostDec:
- case UnaryOperator::PreInc:
- case UnaryOperator::PreDec:
- // Walk through the subexpressions, blasting through ParenExprs
- // until we either find a DeclRefExpr or some non-DeclRefExpr
- // expression.
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParens()))
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
- // Treat the --/++ operator as a kill.
- if (AD.Observer) { AD.Observer->ObserverKill(DR); }
- LiveState(VD, AD) = Alive;
- return VisitDeclRefExpr(DR);
- }
-
- // Fall-through.
-
- default:
- return Visit(E);
- }
-}
-
-void TransferFuncs::VisitAssign(BinaryOperator* B) {
- Expr* LHS = B->getLHS();
-
- // Assigning to a variable?
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
-
- // Update liveness inforamtion.
- unsigned bit = AD.getIdx(DR->getDecl());
- LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
-
- if (AD.Observer) { AD.Observer->ObserverKill(DR); }
-
- // Handle things like +=, etc., which also generate "uses"
- // of a variable. Do this just by visiting the subexpression.
- if (B->getOpcode() != BinaryOperator::Assign)
- VisitDeclRefExpr(DR);
- }
- else // Not assigning to a variable. Process LHS as usual.
- Visit(LHS);
-
- Visit(B->getRHS());
-}
-
-void TransferFuncs::VisitDeclStmt(DeclStmt* DS) {
- // Declarations effectively "kill" a variable since they cannot
- // possibly be live before they are declared.
- for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE = DS->decl_end();
- DI != DE; ++DI)
- if (VarDecl* VD = dyn_cast<VarDecl>(*DI)) {
- // The initializer is evaluated after the variable comes into scope.
- // Since this is a reverse dataflow analysis, we must evaluate the
- // transfer function for this expression first.
- if (Expr* Init = VD->getInit())
- Visit(Init);
-
- // Update liveness information by killing the VarDecl.
- unsigned bit = AD.getIdx(VD);
- LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
- }
-}
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Merge operator: if something is live on any successor block, it is live
-// in the current block (a set union).
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-struct Merge {
- typedef ExprDeclBitVector_Types::ValTy ValTy;
-
- void operator()(ValTy& Dst, const ValTy& Src) {
- Dst.OrDeclBits(Src);
- Dst.AndExprBits(Src);
- }
-};
-
-typedef DataflowSolver<LiveVariables, TransferFuncs, Merge> Solver;
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// External interface to run Liveness analysis.
-//===----------------------------------------------------------------------===//
-
-void LiveVariables::runOnCFG(CFG& cfg) {
- Solver S(*this);
- S.runOnCFG(cfg);
-}
-
-void LiveVariables::runOnAllBlocks(const CFG& cfg,
- LiveVariables::ObserverTy* Obs,
- bool recordStmtValues) {
- Solver S(*this);
- ObserverTy* OldObserver = getAnalysisData().Observer;
- getAnalysisData().Observer = Obs;
- S.runOnAllBlocks(cfg, recordStmtValues);
- getAnalysisData().Observer = OldObserver;
-}
-
-//===----------------------------------------------------------------------===//
-// liveness queries
-//
-
-bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
- DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
- return i.isValid() ? getBlockData(B).getBit(i) : false;
-}
-
-bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const {
- DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
- return i.isValid() ? Live.getBit(i) : false;
-}
-
-bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {
- return getStmtData(Loc)(StmtVal,getAnalysisData());
-}
-
-bool LiveVariables::isLive(const Stmt* Loc, const VarDecl* D) const {
- return getStmtData(Loc)(D,getAnalysisData());
-}
-
-//===----------------------------------------------------------------------===//
-// printing liveness state for debugging
-//
-
-void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const {
- const AnalysisDataTy& AD = getAnalysisData();
-
- for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
- E = AD.end_decl(); I!=E; ++I)
- if (V.getDeclBit(I->second)) {
- SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
-
- fprintf(stderr, " %s <%s:%u:%u>\n",
- I->first->getIdentifier()->getName(),
- SM.getSourceName(PhysLoc),
- SM.getLineNumber(PhysLoc),
- SM.getColumnNumber(PhysLoc));
- }
-}
-
-void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
- for (BlockDataMapTy::iterator I = getBlockDataMap().begin(),
- E = getBlockDataMap().end(); I!=E; ++I) {
- fprintf(stderr, "\n[ B%d (live variables at block exit) ]\n",
- I->first->getBlockID());
-
- dumpLiveness(I->second,M);
- }
-
- fprintf(stderr,"\n");
-}
diff --git a/clang/lib/Analysis/Makefile b/clang/lib/Analysis/Makefile
deleted file mode 100644
index b1d917818236..000000000000
--- a/clang/lib/Analysis/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- clang/lib/Analysis/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements analyses built on top of source-level CFGs.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangAnalysis
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp
deleted file mode 100644
index 49c58f649626..000000000000
--- a/clang/lib/Analysis/MemRegion.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a
-// partially-typed abstraction of memory useful for path-sensitive dataflow
-// analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/raw_ostream.h"
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-
-using namespace clang;
-
-
-MemRegion::~MemRegion() {}
-
-void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned)getKind());
-}
-
-void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
- const MemRegion* superRegion) {
- ID.AddInteger((unsigned) AnonTypedRegionKind);
- ID.Add(T);
- ID.AddPointer(superRegion);
-}
-
-void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- AnonTypedRegion::ProfileRegion(ID, T, superRegion);
-}
-
-void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
- const MemRegion* superRegion, Kind k) {
- ID.AddInteger((unsigned) k);
- ID.AddPointer(D);
- ID.AddPointer(superRegion);
-}
-
-void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
-}
-
-//===----------------------------------------------------------------------===//
-// Region pretty-printing.
-//===----------------------------------------------------------------------===//
-
-std::string MemRegion::getString() const {
- std::string s;
- llvm::raw_string_ostream os(s);
- print(os);
- return os.str();
-}
-
-void MemRegion::print(llvm::raw_ostream& os) const {
- os << "<Unknown Region>";
-}
-
-void VarRegion::print(llvm::raw_ostream& os) const {
- os << cast<VarDecl>(D)->getName();
-}
-
-//===----------------------------------------------------------------------===//
-// MemRegionManager methods.
-//===----------------------------------------------------------------------===//
-
-MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
-
- if (!region) {
- region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
- new (region) MemSpaceRegion();
- }
-
- return region;
-}
-
-MemSpaceRegion* MemRegionManager::getStackRegion() {
- return LazyAllocate(stack);
-}
-
-MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
- return LazyAllocate(globals);
-}
-
-MemSpaceRegion* MemRegionManager::getHeapRegion() {
- return LazyAllocate(heap);
-}
-
-VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
- MemRegion* superRegion) {
- llvm::FoldingSetNodeID ID;
- DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
-
- void* InsertPos;
- MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
- VarRegion* R = cast_or_null<VarRegion>(data);
-
- if (!R) {
- R = (VarRegion*) A.Allocate<VarRegion>();
- new (R) VarRegion(d, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
- MemRegion* superRegion) {
- llvm::FoldingSetNodeID ID;
- DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
-
- void* InsertPos;
- MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
- FieldRegion* R = cast_or_null<FieldRegion>(data);
-
- if (!R) {
- R = (FieldRegion*) A.Allocate<FieldRegion>();
- new (R) FieldRegion(d, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-ObjCIvarRegion* MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
- MemRegion* superRegion) {
- llvm::FoldingSetNodeID ID;
- DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
-
- void* InsertPos;
- MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
- ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
-
- if (!R) {
- R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
- new (R) ObjCIvarRegion(d, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-bool MemRegionManager::hasStackStorage(const MemRegion* R) {
- MemSpaceRegion* S = getStackRegion();
-
- while (R) {
- if (R == S) return true;
- R = R->getSuperRegion();
- }
-
- return false;
-}
diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp
deleted file mode 100644
index 4c34953b17c8..000000000000
--- a/clang/lib/Analysis/PathDiagnostic.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//===--- PathDiagnostic.cpp - Path-Specific Diagnostic Handling -*- 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 PathDiagnostic-related interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathDiagnostic.h"
-#include <sstream>
-
-using namespace clang;
-
-PathDiagnostic::~PathDiagnostic() {
- for (iterator I = begin(), E = end(); I != E; ++I) delete &*I;
-}
-
-void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level DiagLevel,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges) {
-
- // Create a PathDiagnostic with a single piece.
-
- PathDiagnostic* D = new PathDiagnostic();
-
- std::ostringstream os;
-
- switch (DiagLevel) {
- default: assert(0 && "Unknown diagnostic type!");
- case Diagnostic::Note: os << "note: "; break;
- case Diagnostic::Warning: os << "warning: "; break;
- case Diagnostic::Error: os << "error: "; break;
- case Diagnostic::Fatal: os << "fatal error: "; break;
- break;
- }
-
- std::string Msg = FormatDiagnostic(Diags, DiagLevel, ID, Strs, NumStrs);
-
- os << Msg;
-
- PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str());
-
- while (NumRanges) {
- P->addRange(*Ranges);
- --NumRanges;
- ++Ranges;
- }
-
- D->push_front(P);
-
- HandlePathDiagnostic(D);
-}
diff --git a/clang/lib/Analysis/RValues.cpp b/clang/lib/Analysis/RValues.cpp
deleted file mode 100644
index 337d47925555..000000000000
--- a/clang/lib/Analysis/RValues.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- 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 RVal, LVal, and NonLVal, classes that represent
-// abstract r-values for use with path-sensitive value tracking.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/Support/Streams.h"
-
-using namespace clang;
-using llvm::dyn_cast;
-using llvm::cast;
-using llvm::APSInt;
-
-//===----------------------------------------------------------------------===//
-// Symbol Iteration.
-//===----------------------------------------------------------------------===//
-
-RVal::symbol_iterator RVal::symbol_begin() const {
-
- // FIXME: This is a rat's nest. Cleanup.
-
- if (isa<lval::SymbolVal>(this))
- return (symbol_iterator) (&Data);
- else if (isa<nonlval::SymbolVal>(this))
- return (symbol_iterator) (&Data);
- else if (isa<nonlval::SymIntConstraintVal>(this)) {
- const SymIntConstraint& C =
- cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
-
- return (symbol_iterator) &C.getSymbol();
- }
- else if (isa<nonlval::LValAsInteger>(this)) {
- const nonlval::LValAsInteger& V = cast<nonlval::LValAsInteger>(*this);
- return V.getPersistentLVal().symbol_begin();
- }
- else if (isa<lval::FieldOffset>(this)) {
- const lval::FieldOffset& V = cast<lval::FieldOffset>(*this);
- return V.getPersistentBase().symbol_begin();
- }
- return NULL;
-}
-
-RVal::symbol_iterator RVal::symbol_end() const {
- symbol_iterator X = symbol_begin();
- return X ? X+1 : NULL;
-}
-
-//===----------------------------------------------------------------------===//
-// Useful predicates.
-//===----------------------------------------------------------------------===//
-
-bool RVal::isZeroConstant() const {
- if (isa<lval::ConcreteInt>(*this))
- return cast<lval::ConcreteInt>(*this).getValue() == 0;
- else if (isa<nonlval::ConcreteInt>(*this))
- return cast<nonlval::ConcreteInt>(*this).getValue() == 0;
- else
- return false;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Transfer function dispatch for Non-LVals.
-//===----------------------------------------------------------------------===//
-
-RVal nonlval::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
- BinaryOperator::Opcode Op,
- const nonlval::ConcreteInt& R) const {
-
- const llvm::APSInt* X =
- BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
-
- if (X)
- return nonlval::ConcreteInt(*X);
- else
- return UndefinedVal();
-}
-
- // Bitwise-Complement.
-
-nonlval::ConcreteInt
-nonlval::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
- return BasicVals.getValue(~getValue());
-}
-
- // Unary Minus.
-
-nonlval::ConcreteInt
-nonlval::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
- assert (U->getType() == U->getSubExpr()->getType());
- assert (U->getType()->isIntegerType());
- return BasicVals.getValue(-getValue());
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function dispatch for LVals.
-//===----------------------------------------------------------------------===//
-
-RVal
-lval::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
- const lval::ConcreteInt& R) const {
-
- assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
- (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
-
- const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());
-
- if (X)
- return lval::ConcreteInt(*X);
- else
- return UndefinedVal();
-}
-
-NonLVal LVal::EQ(BasicValueFactory& BasicVals, const LVal& R) const {
-
- switch (getSubKind()) {
- default:
- assert(false && "EQ not implemented for this LVal.");
- break;
-
- case lval::ConcreteIntKind:
- if (isa<lval::ConcreteInt>(R)) {
- bool b = cast<lval::ConcreteInt>(this)->getValue() ==
- cast<lval::ConcreteInt>(R).getValue();
-
- return NonLVal::MakeIntTruthVal(BasicVals, b);
- }
- else if (isa<lval::SymbolVal>(R)) {
-
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
- BinaryOperator::EQ,
- cast<lval::ConcreteInt>(this)->getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- break;
-
- case lval::SymbolValKind: {
- if (isa<lval::ConcreteInt>(R)) {
-
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
- BinaryOperator::EQ,
- cast<lval::ConcreteInt>(R).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement unification.");
-
- break;
- }
-
- case lval::MemRegionKind:
- if (isa<lval::MemRegionVal>(R)) {
- bool b = cast<lval::MemRegionVal>(*this) == cast<lval::MemRegionVal>(R);
- return NonLVal::MakeIntTruthVal(BasicVals, b);
- }
-
- break;
- }
-
- return NonLVal::MakeIntTruthVal(BasicVals, false);
-}
-
-NonLVal LVal::NE(BasicValueFactory& BasicVals, const LVal& R) const {
- switch (getSubKind()) {
- default:
- assert(false && "NE not implemented for this LVal.");
- break;
-
- case lval::ConcreteIntKind:
- if (isa<lval::ConcreteInt>(R)) {
- bool b = cast<lval::ConcreteInt>(this)->getValue() !=
- cast<lval::ConcreteInt>(R).getValue();
-
- return NonLVal::MakeIntTruthVal(BasicVals, b);
- }
- else if (isa<lval::SymbolVal>(R)) {
-
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
- BinaryOperator::NE,
- cast<lval::ConcreteInt>(this)->getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- break;
-
- case lval::SymbolValKind: {
- if (isa<lval::ConcreteInt>(R)) {
-
- const SymIntConstraint& C =
- BasicVals.getConstraint(cast<lval::SymbolVal>(this)->getSymbol(),
- BinaryOperator::NE,
- cast<lval::ConcreteInt>(R).getValue());
-
- return nonlval::SymIntConstraintVal(C);
- }
-
- assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement sym !=.");
-
- break;
- }
-
- case lval::MemRegionKind:
- if (isa<lval::MemRegionVal>(R)) {
- bool b = cast<lval::MemRegionVal>(*this)==cast<lval::MemRegionVal>(R);
- return NonLVal::MakeIntTruthVal(BasicVals, b);
- }
-
- break;
- }
-
- return NonLVal::MakeIntTruthVal(BasicVals, true);
-}
-
-//===----------------------------------------------------------------------===//
-// Utility methods for constructing Non-LVals.
-//===----------------------------------------------------------------------===//
-
-NonLVal NonLVal::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
- return nonlval::ConcreteInt(BasicVals.getValue(X, T));
-}
-
-NonLVal NonLVal::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {
-
- return nonlval::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
- I->getType()->isUnsignedIntegerType())));
-}
-
-NonLVal NonLVal::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
- return nonlval::ConcreteInt(BasicVals.getTruthValue(b));
-}
-
-RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
-
- QualType T = D->getType();
-
- if (LVal::IsLValType(T))
- return lval::SymbolVal(SymMgr.getSymbol(D));
-
- return nonlval::SymbolVal(SymMgr.getSymbol(D));
-}
-
-//===----------------------------------------------------------------------===//
-// Utility methods for constructing LVals.
-//===----------------------------------------------------------------------===//
-
-LVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); }
-
-LVal LVal::MakeVal(StringLiteral* S) {
- return lval::StringLiteralVal(S);
-}
-
-//===----------------------------------------------------------------------===//
-// Utility methods for constructing RVals (both NonLVals and LVals).
-//===----------------------------------------------------------------------===//
-
-RVal RVal::MakeVal(GRStateManager& SMgr, DeclRefExpr* E) {
-
- ValueDecl* D = cast<DeclRefExpr>(E)->getDecl();
-
- if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
- return SMgr.getLVal(VD);
- }
- else if (EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
-
- // FIXME: Do we need to cache a copy of this enum, since it
- // already has persistent storage? We do this because we
- // are comparing states using pointer equality. Perhaps there is
- // a better way, since APInts are fairly lightweight.
- BasicValueFactory& BasicVals = SMgr.getBasicVals();
- return nonlval::ConcreteInt(BasicVals.getValue(ED->getInitVal()));
- }
- else if (FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
- return lval::FuncVal(FD);
- }
-
- assert (false &&
- "ValueDecl support for this ValueDecl not implemented.");
-
- return UnknownVal();
-}
-
-//===----------------------------------------------------------------------===//
-// Pretty-Printing.
-//===----------------------------------------------------------------------===//
-
-void RVal::printStdErr() const { print(*llvm::cerr.stream()); }
-
-void RVal::print(std::ostream& Out) const {
-
- switch (getBaseKind()) {
-
- case UnknownKind:
- Out << "Invalid"; break;
-
- case NonLValKind:
- cast<NonLVal>(this)->print(Out); break;
-
- case LValKind:
- cast<LVal>(this)->print(Out); break;
-
- case UndefinedKind:
- Out << "Undefined"; break;
-
- default:
- assert (false && "Invalid RVal.");
- }
-}
-
-static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) {
-
- switch (Op) {
- case BinaryOperator::Mul: Out << '*' ; break;
- case BinaryOperator::Div: Out << '/' ; break;
- case BinaryOperator::Rem: Out << '%' ; break;
- case BinaryOperator::Add: Out << '+' ; break;
- case BinaryOperator::Sub: Out << '-' ; break;
- case BinaryOperator::Shl: Out << "<<" ; break;
- case BinaryOperator::Shr: Out << ">>" ; break;
- case BinaryOperator::LT: Out << "<" ; break;
- case BinaryOperator::GT: Out << '>' ; break;
- case BinaryOperator::LE: Out << "<=" ; break;
- case BinaryOperator::GE: Out << ">=" ; break;
- case BinaryOperator::EQ: Out << "==" ; break;
- case BinaryOperator::NE: Out << "!=" ; break;
- case BinaryOperator::And: Out << '&' ; break;
- case BinaryOperator::Xor: Out << '^' ; break;
- case BinaryOperator::Or: Out << '|' ; break;
-
- default: assert(false && "Not yet implemented.");
- }
-}
-
-void NonLVal::print(std::ostream& Out) const {
-
- switch (getSubKind()) {
-
- case nonlval::ConcreteIntKind:
- Out << cast<nonlval::ConcreteInt>(this)->getValue().getZExtValue();
-
- if (cast<nonlval::ConcreteInt>(this)->getValue().isUnsigned())
- Out << 'U';
-
- break;
-
- case nonlval::SymbolValKind:
- Out << '$' << cast<nonlval::SymbolVal>(this)->getSymbol();
- break;
-
- case nonlval::SymIntConstraintValKind: {
- const nonlval::SymIntConstraintVal& C =
- *cast<nonlval::SymIntConstraintVal>(this);
-
- Out << '$' << C.getConstraint().getSymbol() << ' ';
- printOpcode(Out, C.getConstraint().getOpcode());
- Out << ' ' << C.getConstraint().getInt().getZExtValue();
-
- if (C.getConstraint().getInt().isUnsigned())
- Out << 'U';
-
- break;
- }
-
- case nonlval::LValAsIntegerKind: {
- const nonlval::LValAsInteger& C = *cast<nonlval::LValAsInteger>(this);
- C.getLVal().print(Out);
- Out << " [as " << C.getNumBits() << " bit integer]";
- break;
- }
-
- default:
- assert (false && "Pretty-printed not implemented for this NonLVal.");
- break;
- }
-}
-
-void LVal::print(std::ostream& Out) const {
-
- switch (getSubKind()) {
-
- case lval::ConcreteIntKind:
- Out << cast<lval::ConcreteInt>(this)->getValue().getZExtValue()
- << " (LVal)";
- break;
-
- case lval::SymbolValKind:
- Out << '$' << cast<lval::SymbolVal>(this)->getSymbol();
- break;
-
- case lval::GotoLabelKind:
- Out << "&&"
- << cast<lval::GotoLabel>(this)->getLabel()->getID()->getName();
- break;
-
- case lval::MemRegionKind:
- Out << '&' << cast<lval::MemRegionVal>(this)->getRegion()->getString();
- break;
-
- case lval::FuncValKind:
- Out << "function "
- << cast<lval::FuncVal>(this)->getDecl()->getIdentifier()->getName();
- break;
-
- case lval::StringLiteralValKind:
- Out << "literal \""
- << cast<lval::StringLiteralVal>(this)->getLiteral()->getStrData()
- << "\"";
- break;
-
- case lval::FieldOffsetKind: {
- const lval::FieldOffset& C = *cast<lval::FieldOffset>(this);
- C.getBase().print(Out);
- Out << "." << C.getFieldDecl()->getName() << " (field LVal)";
- break;
- }
-
- case lval::ArrayOffsetKind: {
- const lval::ArrayOffset& C = *cast<lval::ArrayOffset>(this);
- C.getBase().print(Out);
- Out << "[";
- C.getOffset().print(Out);
- Out << "] (lval array entry)";
- break;
- }
-
- default:
- assert (false && "Pretty-printing not implemented for this LVal.");
- break;
- }
-}
diff --git a/clang/lib/Analysis/SymbolManager.cpp b/clang/lib/Analysis/SymbolManager.cpp
deleted file mode 100644
index 24d2ed725309..000000000000
--- a/clang/lib/Analysis/SymbolManager.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//== SymbolManager.h - Management of Symbolic Values ------------*- 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 SymbolManager, a class that manages symbolic values
-// created for use by GRExprEngine and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-
-using namespace clang;
-
-SymbolID SymbolManager::getSymbol(VarDecl* D) {
-
- assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ||
- D->hasGlobalStorage());
-
- llvm::FoldingSetNodeID profile;
-
- ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
-
- if (PD)
- SymbolDataParmVar::Profile(profile, PD);
- else
- SymbolDataGlobalVar::Profile(profile, D);
-
- void* InsertPos;
-
- SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
-
- if (SD)
- return SD->getSymbol();
-
- if (PD) {
- SD = (SymbolData*) BPAlloc.Allocate<SymbolDataParmVar>();
- new (SD) SymbolDataParmVar(SymbolCounter, PD);
- }
- else {
- SD = (SymbolData*) BPAlloc.Allocate<SymbolDataGlobalVar>();
- new (SD) SymbolDataGlobalVar(SymbolCounter, D);
- }
-
- DataSet.InsertNode(SD, InsertPos);
-
- DataMap[SymbolCounter] = SD;
- return SymbolCounter++;
-}
-
-SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
-
- llvm::FoldingSetNodeID profile;
- SymbolDataContentsOf::Profile(profile, sym);
- void* InsertPos;
-
- SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
-
- if (SD)
- return SD->getSymbol();
-
- SD = (SymbolData*) BPAlloc.Allocate<SymbolDataContentsOf>();
- new (SD) SymbolDataContentsOf(SymbolCounter, sym);
-
-
- DataSet.InsertNode(SD, InsertPos);
- DataMap[SymbolCounter] = SD;
-
- return SymbolCounter++;
-}
-
-SymbolID SymbolManager::getConjuredSymbol(Expr* E, QualType T, unsigned Count) {
-
- llvm::FoldingSetNodeID profile;
- SymbolConjured::Profile(profile, E, T, Count);
- void* InsertPos;
-
- SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
-
- if (SD)
- return SD->getSymbol();
-
- SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
- new (SD) SymbolConjured(SymbolCounter, E, T, Count);
-
- DataSet.InsertNode(SD, InsertPos);
- DataMap[SymbolCounter] = SD;
-
- return SymbolCounter++;
-}
-
-const SymbolData& SymbolManager::getSymbolData(SymbolID Sym) const {
- DataMapTy::const_iterator I = DataMap.find(Sym);
- assert (I != DataMap.end());
- return *I->second;
-}
-
-
-QualType SymbolData::getType(const SymbolManager& SymMgr) const {
- switch (getKind()) {
- default:
- assert (false && "getType() not implemented for this symbol.");
-
- case ParmKind:
- return cast<SymbolDataParmVar>(this)->getDecl()->getType();
-
- case GlobalKind:
- return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
-
- case ContentsOfKind: {
- SymbolID x = cast<SymbolDataContentsOf>(this)->getContainerSymbol();
- QualType T = SymMgr.getSymbolData(x).getType(SymMgr);
- return T->getAsPointerType()->getPointeeType();
- }
-
- case ConjuredKind:
- return cast<SymbolConjured>(this)->getType();
- }
-}
-
-SymbolManager::~SymbolManager() {}
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
deleted file mode 100644
index a02e544506e1..000000000000
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-//==- UninitializedValues.cpp - Find Uninitialized Values -------*- C++ --*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Uninitialized Values analysis for source-level CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/Analyses/UninitializedValues.h"
-#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
-#include "llvm/Support/Compiler.h"
-
-#include "llvm/ADT/SmallPtrSet.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Dataflow initialization logic.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN RegisterDecls
- : public CFGRecStmtDeclVisitor<RegisterDecls> {
-
- UninitializedValues::AnalysisDataTy& AD;
-public:
- RegisterDecls(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
-
- void VisitVarDecl(VarDecl* VD) { AD.Register(VD); }
- CFG& getCFG() { return AD.getCFG(); }
-};
-
-} // end anonymous namespace
-
-void UninitializedValues::InitializeValues(const CFG& cfg) {
- RegisterDecls R(getAnalysisData());
- cfg.VisitBlockStmts(R);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN TransferFuncs
- : public CFGStmtVisitor<TransferFuncs,bool> {
-
- UninitializedValues::ValTy V;
- UninitializedValues::AnalysisDataTy& AD;
-public:
- TransferFuncs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
-
- UninitializedValues::ValTy& getVal() { return V; }
- CFG& getCFG() { return AD.getCFG(); }
-
- void SetTopValue(UninitializedValues::ValTy& X) {
- X.resetValues(AD);
- }
-
- bool VisitDeclRefExpr(DeclRefExpr* DR);
- bool VisitBinaryOperator(BinaryOperator* B);
- bool VisitUnaryOperator(UnaryOperator* U);
- bool VisitStmt(Stmt* S);
- bool VisitCallExpr(CallExpr* C);
- bool VisitDeclStmt(DeclStmt* D);
- bool VisitConditionalOperator(ConditionalOperator* C);
-
- bool Visit(Stmt *S);
- bool BlockStmt_VisitExpr(Expr* E);
-
- void VisitTerminator(CFGBlock* B) { }
-};
-
-static const bool Initialized = true;
-static const bool Uninitialized = false;
-
-bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
-
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
- if (VD->isBlockVarDecl()) {
-
- if (AD.Observer)
- AD.Observer->ObserveDeclRefExpr(V, AD, DR, VD);
-
- // Pseudo-hack to prevent cascade of warnings. If an accessed variable
- // is uninitialized, then we are already going to flag a warning for
- // this variable, which a "source" of uninitialized values.
- // We can otherwise do a full "taint" of uninitialized values. The
- // client has both options by toggling AD.FullUninitTaint.
-
- if (AD.FullUninitTaint)
- return V(VD,AD);
- }
-
- return Initialized;
-}
-
-static VarDecl* FindBlockVarDecl(Expr* E) {
-
- // Blast through casts and parentheses to find any DeclRefExprs that
- // refer to a block VarDecl.
-
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
- if (VD->isBlockVarDecl()) return VD;
-
- return NULL;
-}
-
-bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
-
- if (VarDecl* VD = FindBlockVarDecl(B->getLHS()))
- if (B->isAssignmentOp()) {
- if (B->getOpcode() == BinaryOperator::Assign)
- return V(VD,AD) = Visit(B->getRHS());
- else // Handle +=, -=, *=, etc. We do want '&', not '&&'.
- return V(VD,AD) = Visit(B->getLHS()) & Visit(B->getRHS());
- }
-
- return VisitStmt(B);
-}
-
-bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
- for (DeclStmt::decl_iterator I=S->decl_begin(), E=S->decl_end(); I!=E; ++I) {
- VarDecl *VD = dyn_cast<VarDecl>(*I);
- if (VD && VD->isBlockVarDecl()) {
- if (Stmt* I = VD->getInit())
- V(VD,AD) = AD.FullUninitTaint ? V(cast<Expr>(I),AD) : Initialized;
- else {
- // Special case for declarations of array types. For things like:
- //
- // char x[10];
- //
- // we should treat "x" as being initialized, because the variable
- // "x" really refers to the memory block. Clearly x[1] is
- // uninitialized, but expressions like "(char *) x" really do refer to
- // an initialized value. This simple dataflow analysis does not reason
- // about the contents of arrays, although it could be potentially
- // extended to do so if the array were of constant size.
- if (VD->getType()->isArrayType())
- V(VD,AD) = Initialized;
- else
- V(VD,AD) = Uninitialized;
- }
- }
- }
- return Uninitialized; // Value is never consumed.
-}
-
-bool TransferFuncs::VisitCallExpr(CallExpr* C) {
- VisitChildren(C);
- return Initialized;
-}
-
-bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
- switch (U->getOpcode()) {
- case UnaryOperator::AddrOf: {
- VarDecl* VD = FindBlockVarDecl(U->getSubExpr());
- if (VD && VD->isBlockVarDecl())
- return V(VD,AD) = Initialized;
- break;
- }
-
- case UnaryOperator::SizeOf:
- return Initialized;
-
- default:
- break;
- }
-
- return Visit(U->getSubExpr());
-}
-
-bool TransferFuncs::VisitConditionalOperator(ConditionalOperator* C) {
- Visit(C->getCond());
-
- bool rhsResult = Visit(C->getRHS());
- // Handle the GNU extension for missing LHS.
- if (Expr *lhs = C->getLHS())
- return Visit(lhs) & rhsResult; // Yes: we want &, not &&.
- else
- return rhsResult;
-}
-
-bool TransferFuncs::VisitStmt(Stmt* S) {
- bool x = Initialized;
-
- // We don't stop at the first subexpression that is Uninitialized because
- // evaluating some subexpressions may result in propogating "Uninitialized"
- // or "Initialized" to variables referenced in the other subexpressions.
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
- if (*I && Visit(*I) == Uninitialized) x = Uninitialized;
-
- return x;
-}
-
-bool TransferFuncs::Visit(Stmt *S) {
- if (AD.isTracked(static_cast<Expr*>(S))) return V(static_cast<Expr*>(S),AD);
- else return static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(S);
-}
-
-bool TransferFuncs::BlockStmt_VisitExpr(Expr* E) {
- bool x = static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(E);
- if (AD.isTracked(E)) V(E,AD) = x;
- return x;
-}
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Merge operator.
-//
-// In our transfer functions we take the approach that any
-// combination of uninitialized values, e.g.
-// Uninitialized + ___ = Uninitialized.
-//
-// Merges take the same approach, preferring soundness. At a confluence point,
-// if any predecessor has a variable marked uninitialized, the value is
-// uninitialized at the confluence point.
-//===----------------------------------------------------------------------===//
-
-namespace {
- typedef ExprDeclBitVector_Types::Intersect Merge;
- typedef DataflowSolver<UninitializedValues,TransferFuncs,Merge> Solver;
-}
-
-//===----------------------------------------------------------------------===//
-// Uninitialized values checker. Scan an AST and flag variable uses
-//===----------------------------------------------------------------------===//
-
-UninitializedValues_ValueTypes::ObserverTy::~ObserverTy() {}
-
-namespace {
-class VISIBILITY_HIDDEN UninitializedValuesChecker
- : public UninitializedValues::ObserverTy {
-
- ASTContext &Ctx;
- Diagnostic &Diags;
- llvm::SmallPtrSet<VarDecl*,10> AlreadyWarned;
-
-public:
- UninitializedValuesChecker(ASTContext &ctx, Diagnostic &diags)
- : Ctx(ctx), Diags(diags) {}
-
- virtual void ObserveDeclRefExpr(UninitializedValues::ValTy& V,
- UninitializedValues::AnalysisDataTy& AD,
- DeclRefExpr* DR, VarDecl* VD) {
-
- assert ( AD.isTracked(VD) && "Unknown VarDecl.");
-
- if (V(VD,AD) == Uninitialized)
- if (AlreadyWarned.insert(VD))
- Diags.Report(Ctx.getFullLoc(DR->getSourceRange().getBegin()),
- diag::warn_uninit_val);
- }
-};
-} // end anonymous namespace
-
-namespace clang {
-void CheckUninitializedValues(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags,
- bool FullUninitTaint) {
-
- // Compute the uninitialized values information.
- UninitializedValues U(cfg);
- U.getAnalysisData().FullUninitTaint = FullUninitTaint;
- Solver S(U);
- S.runOnCFG(cfg);
-
- // Scan for DeclRefExprs that use uninitialized values.
- UninitializedValuesChecker Observer(Ctx,Diags);
- U.getAnalysisData().Observer = &Observer;
- S.runOnAllBlocks(cfg);
-}
-} // end namespace clang
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
deleted file mode 100644
index 0f8f314f15c8..000000000000
--- a/clang/lib/Basic/Diagnostic.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-//===--- Diagnostic.cpp - C Language Family Diagnostic Handling -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Diagnostic-related interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include <cassert>
-#include <vector>
-#include <map>
-#include <cstring>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Builtin Diagnostic information
-//===----------------------------------------------------------------------===//
-
-/// Flag values for diagnostics.
-enum {
- // Diagnostic classes.
- NOTE = 0x01,
- WARNING = 0x02,
- EXTENSION = 0x03,
- EXTWARN = 0x04,
- ERROR = 0x05,
- class_mask = 0x07
-};
-
-/// DiagnosticFlags - A set of flags, or'd together, that describe the
-/// diagnostic.
-static unsigned char DiagnosticFlags[] = {
-#define DIAG(ENUM,FLAGS,DESC) FLAGS,
-#include "clang/Basic/DiagnosticKinds.def"
- 0
-};
-
-/// getDiagClass - Return the class field of the diagnostic.
-///
-static unsigned getBuiltinDiagClass(unsigned DiagID) {
- assert(DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
- "Diagnostic ID out of range!");
- return DiagnosticFlags[DiagID] & class_mask;
-}
-
-/// DiagnosticText - An english message to print for the diagnostic. These
-/// should be localized.
-static const char * const DiagnosticText[] = {
-#define DIAG(ENUM,FLAGS,DESC) DESC,
-#include "clang/Basic/DiagnosticKinds.def"
- 0
-};
-
-//===----------------------------------------------------------------------===//
-// Custom Diagnostic information
-//===----------------------------------------------------------------------===//
-
-namespace clang {
- namespace diag {
- class CustomDiagInfo {
- typedef std::pair<Diagnostic::Level, std::string> DiagDesc;
- std::vector<DiagDesc> DiagInfo;
- std::map<DiagDesc, unsigned> DiagIDs;
- public:
-
- /// getDescription - Return the description of the specified custom
- /// diagnostic.
- const char *getDescription(unsigned DiagID) const {
- assert(this && DiagID-diag::NUM_BUILTIN_DIAGNOSTICS < DiagInfo.size() &&
- "Invalid diagnosic ID");
- return DiagInfo[DiagID-diag::NUM_BUILTIN_DIAGNOSTICS].second.c_str();
- }
-
- /// getLevel - Return the level of the specified custom diagnostic.
- Diagnostic::Level getLevel(unsigned DiagID) const {
- assert(this && DiagID-diag::NUM_BUILTIN_DIAGNOSTICS < DiagInfo.size() &&
- "Invalid diagnosic ID");
- return DiagInfo[DiagID-diag::NUM_BUILTIN_DIAGNOSTICS].first;
- }
-
- unsigned getOrCreateDiagID(Diagnostic::Level L, const char *Message) {
- DiagDesc D(L, Message);
- // Check to see if it already exists.
- std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
- if (I != DiagIDs.end() && I->first == D)
- return I->second;
-
- // If not, assign a new ID.
- unsigned ID = DiagInfo.size()+diag::NUM_BUILTIN_DIAGNOSTICS;
- DiagIDs.insert(std::make_pair(D, ID));
- DiagInfo.push_back(D);
- return ID;
- }
- };
-
- } // end diag namespace
-} // end clang namespace
-
-
-//===----------------------------------------------------------------------===//
-// Common Diagnostic implementation
-//===----------------------------------------------------------------------===//
-
-Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
- IgnoreAllWarnings = false;
- WarningsAsErrors = false;
- WarnOnExtensions = false;
- ErrorOnExtensions = false;
- SuppressSystemWarnings = false;
- // Clear all mappings, setting them to MAP_DEFAULT.
- memset(DiagMappings, 0, sizeof(DiagMappings));
-
- ErrorOccurred = false;
- NumDiagnostics = 0;
- NumErrors = 0;
- CustomDiagInfo = 0;
-}
-
-Diagnostic::~Diagnostic() {
- delete CustomDiagInfo;
-}
-
-/// getCustomDiagID - Return an ID for a diagnostic with the specified message
-/// and level. If this is the first request for this diagnosic, it is
-/// registered and created, otherwise the existing ID is returned.
-unsigned Diagnostic::getCustomDiagID(Level L, const char *Message) {
- if (CustomDiagInfo == 0)
- CustomDiagInfo = new diag::CustomDiagInfo();
- return CustomDiagInfo->getOrCreateDiagID(L, Message);
-}
-
-
-/// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
-/// level of the specified diagnostic ID is a Note, Warning, or Extension.
-/// Note that this only works on builtin diagnostics, not custom ones.
-bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) {
- return DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
- getBuiltinDiagClass(DiagID) < ERROR;
-}
-
-
-/// getDescription - Given a diagnostic ID, return a description of the
-/// issue.
-const char *Diagnostic::getDescription(unsigned DiagID) {
- if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS)
- return DiagnosticText[DiagID];
- else
- return CustomDiagInfo->getDescription(DiagID);
-}
-
-/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
-/// object, classify the specified diagnostic ID into a Level, consumable by
-/// the DiagnosticClient.
-Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
- // Handle custom diagnostics, which cannot be mapped.
- if (DiagID >= diag::NUM_BUILTIN_DIAGNOSTICS)
- return CustomDiagInfo->getLevel(DiagID);
-
- unsigned DiagClass = getBuiltinDiagClass(DiagID);
-
- // Specific non-error diagnostics may be mapped to various levels from ignored
- // to error.
- if (DiagClass < ERROR) {
- switch (getDiagnosticMapping((diag::kind)DiagID)) {
- case diag::MAP_DEFAULT: break;
- case diag::MAP_IGNORE: return Diagnostic::Ignored;
- case diag::MAP_WARNING: DiagClass = WARNING; break;
- case diag::MAP_ERROR: DiagClass = ERROR; break;
- }
- }
-
- // Map diagnostic classes based on command line argument settings.
- if (DiagClass == EXTENSION) {
- if (ErrorOnExtensions)
- DiagClass = ERROR;
- else if (WarnOnExtensions)
- DiagClass = WARNING;
- else
- return Ignored;
- } else if (DiagClass == EXTWARN) {
- DiagClass = ErrorOnExtensions ? ERROR : WARNING;
- }
-
- // If warnings are globally mapped to ignore or error, do it.
- if (DiagClass == WARNING) {
- if (IgnoreAllWarnings)
- return Diagnostic::Ignored;
- if (WarningsAsErrors)
- DiagClass = ERROR;
- }
-
- switch (DiagClass) {
- default: assert(0 && "Unknown diagnostic class!");
- case NOTE: return Diagnostic::Note;
- case WARNING: return Diagnostic::Warning;
- case ERROR: return Diagnostic::Error;
- }
-}
-
-/// Report - Issue the message to the client.
-/// DiagID is a member of the diag::kind enum.
-void Diagnostic::Report(DiagnosticClient* C,
- FullSourceLoc Loc, unsigned DiagID,
- const std::string *Strs, unsigned NumStrs,
- const SourceRange *Ranges, unsigned NumRanges) {
-
- // Figure out the diagnostic level of this message.
- Diagnostic::Level DiagLevel = getDiagnosticLevel(DiagID);
-
- // If the client doesn't care about this message, don't issue it.
- if (DiagLevel == Diagnostic::Ignored)
- return;
-
- // Set the diagnostic client if it isn't set already.
- if (!C) C = Client;
-
- // If this is not an error and we are in a system header, ignore it. We
- // have to check on the original DiagID here, because we also want to
- // ignore extensions and warnings in -Werror and -pedantic-errors modes,
- // which *map* warnings/extensions to errors.
- if (SuppressSystemWarnings &&
- DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
- getBuiltinDiagClass(DiagID) != ERROR &&
- Loc.isValid() && Loc.isFileID() && Loc.isInSystemHeader())
- return;
-
- if (DiagLevel >= Diagnostic::Error) {
- ErrorOccurred = true;
-
- if (C != 0 && C == Client)
- ++NumErrors;
- }
-
- // Finally, report it.
-
- if (C != 0)
- C->HandleDiagnostic(*this, DiagLevel, Loc, (diag::kind)DiagID,
- Strs, NumStrs, Ranges, NumRanges);
-
- if (C != 0 && C == Client)
- ++NumDiagnostics;
-}
-
-
-DiagnosticClient::~DiagnosticClient() {}
-
-std::string DiagnosticClient::FormatDiagnostic(Diagnostic &Diags,
- Diagnostic::Level Level,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs) {
- std::string Msg = Diags.getDescription(ID);
-
- // Replace all instances of %0 in Msg with 'Extra'.
- for (unsigned i = 0; i < Msg.size() - 1; ++i) {
- if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
- unsigned StrNo = Msg[i + 1] - '0';
- Msg = std::string(Msg.begin(), Msg.begin() + i) +
- (StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
- std::string(Msg.begin() + i + 2, Msg.end());
- }
- }
-
- return Msg;
-}
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp
deleted file mode 100644
index cfc08ed084b1..000000000000
--- a/clang/lib/Basic/FileManager.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-///===--- FileManager.cpp - File System Probing and Caching ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the FileManager interface.
-//
-//===----------------------------------------------------------------------===//
-//
-// TODO: This should index all interesting directories with dirent calls.
-// getdirentries ?
-// opendir/readdir_r/closedir ?
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/FileManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Config/config.h"
-using namespace clang;
-
-// FIXME: Enhance libsystem to support inode and other fields.
-#include <sys/stat.h>
-
-#if defined(_MSC_VER)
-#define S_ISDIR(s) (_S_IFDIR & s)
-#endif
-
-/// NON_EXISTENT_DIR - A special value distinct from null that is used to
-/// represent a dir name that doesn't exist on the disk.
-#define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
-
-#ifdef LLVM_ON_WIN32
-
-#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/' || (x) == '\\')
-
-namespace {
- static std::string GetFullPath(const char *relPath)
- {
- char *absPathStrPtr = _fullpath(NULL, relPath, 0);
- assert(absPathStrPtr && "_fullpath() returned NULL!");
-
- std::string absPath(absPathStrPtr);
-
- free(absPathStrPtr);
- return absPath;
- }
-}
-
-class FileManager::UniqueDirContainer {
- /// UniqueDirs - Cache from full path to existing directories/files.
- ///
- llvm::StringMap<DirectoryEntry> UniqueDirs;
-
-public:
- DirectoryEntry &getDirectory(const char *Name, struct stat &StatBuf) {
- std::string FullPath(GetFullPath(Name));
- return UniqueDirs.GetOrCreateValue(
- FullPath.c_str(),
- FullPath.c_str() + FullPath.size()
- ).getValue();
- }
-
- size_t size() { return UniqueDirs.size(); }
-};
-
-class FileManager::UniqueFileContainer {
- /// UniqueFiles - Cache from full path to existing directories/files.
- ///
- llvm::StringMap<FileEntry> UniqueFiles;
-
-public:
- FileEntry &getFile(const char *Name, struct stat &StatBuf) {
- std::string FullPath(GetFullPath(Name));
- return UniqueFiles.GetOrCreateValue(
- FullPath.c_str(),
- FullPath.c_str() + FullPath.size()
- ).getValue();
- }
-
- size_t size() { return UniqueFiles.size(); }
-};
-
-#else
-
-#define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/')
-
-class FileManager::UniqueDirContainer {
- /// UniqueDirs - Cache from ID's to existing directories/files.
- ///
- std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
-
-public:
- DirectoryEntry &getDirectory(const char *Name, struct stat &StatBuf) {
- return UniqueDirs[std::make_pair(StatBuf.st_dev, StatBuf.st_ino)];
- }
-
- size_t size() { return UniqueDirs.size(); }
-};
-
-class FileManager::UniqueFileContainer {
- /// UniqueFiles - Cache from ID's to existing directories/files.
- ///
- std::set<FileEntry> UniqueFiles;
-
-public:
- FileEntry &getFile(const char *Name, struct stat &StatBuf) {
- return
- const_cast<FileEntry&>(
- *UniqueFiles.insert(FileEntry(StatBuf.st_dev,
- StatBuf.st_ino)).first);
- }
-
- size_t size() { return UniqueFiles.size(); }
-};
-
-#endif
-
-
-FileManager::FileManager() : UniqueDirs(*new UniqueDirContainer),
- UniqueFiles(*new UniqueFileContainer),
- DirEntries(64), FileEntries(64), NextFileUID(0)
-{
- NumDirLookups = NumFileLookups = 0;
- NumDirCacheMisses = NumFileCacheMisses = 0;
-}
-
-FileManager::~FileManager() {
- delete &UniqueDirs;
- delete &UniqueFiles;
-}
-
-
-/// getDirectory - Lookup, cache, and verify the specified directory. This
-/// returns null if the directory doesn't exist.
-///
-const DirectoryEntry *FileManager::getDirectory(const char *NameStart,
- const char *NameEnd) {
- ++NumDirLookups;
- llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt =
- DirEntries.GetOrCreateValue(NameStart, NameEnd);
-
- // See if there is already an entry in the map.
- if (NamedDirEnt.getValue())
- return NamedDirEnt.getValue() == NON_EXISTENT_DIR
- ? 0 : NamedDirEnt.getValue();
-
- ++NumDirCacheMisses;
-
- // By default, initialize it to invalid.
- NamedDirEnt.setValue(NON_EXISTENT_DIR);
-
- // Get the null-terminated directory name as stored as the key of the
- // DirEntries map.
- const char *InterndDirName = NamedDirEnt.getKeyData();
-
- // Check to see if the directory exists.
- struct stat StatBuf;
- if (stat(InterndDirName, &StatBuf) || // Error stat'ing.
- !S_ISDIR(StatBuf.st_mode)) // Not a directory?
- return 0;
-
- // It exists. See if we have already opened a directory with the same inode.
- // This occurs when one dir is symlinked to another, for example.
- DirectoryEntry &UDE = UniqueDirs.getDirectory(InterndDirName, StatBuf);
-
- NamedDirEnt.setValue(&UDE);
- if (UDE.getName()) // Already have an entry with this inode, return it.
- return &UDE;
-
- // Otherwise, we don't have this directory yet, add it. We use the string
- // key from the DirEntries map as the string.
- UDE.Name = InterndDirName;
- return &UDE;
-}
-
-/// NON_EXISTENT_FILE - A special value distinct from null that is used to
-/// represent a filename that doesn't exist on the disk.
-#define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
-
-/// getFile - Lookup, cache, and verify the specified file. This returns null
-/// if the file doesn't exist.
-///
-const FileEntry *FileManager::getFile(const char *NameStart,
- const char *NameEnd) {
- ++NumFileLookups;
-
- // See if there is already an entry in the map.
- llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
- FileEntries.GetOrCreateValue(NameStart, NameEnd);
-
- // See if there is already an entry in the map.
- if (NamedFileEnt.getValue())
- return NamedFileEnt.getValue() == NON_EXISTENT_FILE
- ? 0 : NamedFileEnt.getValue();
-
- ++NumFileCacheMisses;
-
- // By default, initialize it to invalid.
- NamedFileEnt.setValue(NON_EXISTENT_FILE);
-
- // Figure out what directory it is in. If the string contains a / in it,
- // strip off everything after it.
- // FIXME: this logic should be in sys::Path.
- const char *SlashPos = NameEnd-1;
- while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
- --SlashPos;
-
- const DirectoryEntry *DirInfo;
- if (SlashPos < NameStart) {
- // Use the current directory if file has no path component.
- const char *Name = ".";
- DirInfo = getDirectory(Name, Name+1);
- } else if (SlashPos == NameEnd-1)
- return 0; // If filename ends with a /, it's a directory.
- else
- DirInfo = getDirectory(NameStart, SlashPos);
-
- if (DirInfo == 0) // Directory doesn't exist, file can't exist.
- return 0;
-
- // Get the null-terminated file name as stored as the key of the
- // FileEntries map.
- const char *InterndFileName = NamedFileEnt.getKeyData();
-
- // FIXME: Use the directory info to prune this, before doing the stat syscall.
- // FIXME: This will reduce the # syscalls.
-
- // Nope, there isn't. Check to see if the file exists.
- struct stat StatBuf;
- //llvm::cerr << "STATING: " << Filename;
- if (stat(InterndFileName, &StatBuf) || // Error stat'ing.
- S_ISDIR(StatBuf.st_mode)) { // A directory?
- // If this file doesn't exist, we leave a null in FileEntries for this path.
- //llvm::cerr << ": Not existing\n";
- return 0;
- }
- //llvm::cerr << ": exists\n";
-
- // It exists. See if we have already opened a file with the same inode.
- // This occurs when one dir is symlinked to another, for example.
- FileEntry &UFE = UniqueFiles.getFile(InterndFileName, StatBuf);
-
- NamedFileEnt.setValue(&UFE);
- if (UFE.getName()) // Already have an entry with this inode, return it.
- return &UFE;
-
- // Otherwise, we don't have this directory yet, add it.
- // FIXME: Change the name to be a char* that points back to the 'FileEntries'
- // key.
- UFE.Name = InterndFileName;
- UFE.Size = StatBuf.st_size;
- UFE.ModTime = StatBuf.st_mtime;
- UFE.Dir = DirInfo;
- UFE.UID = NextFileUID++;
- return &UFE;
-}
-
-void FileManager::PrintStats() const {
- llvm::cerr << "\n*** File Manager Stats:\n";
- llvm::cerr << UniqueFiles.size() << " files found, "
- << UniqueDirs.size() << " dirs found.\n";
- llvm::cerr << NumDirLookups << " dir lookups, "
- << NumDirCacheMisses << " dir cache misses.\n";
- llvm::cerr << NumFileLookups << " file lookups, "
- << NumFileCacheMisses << " file cache misses.\n";
-
- //llvm::cerr << PagesMapped << BytesOfPagesMapped << FSLookups;
-}
diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp
deleted file mode 100644
index e650993bd04b..000000000000
--- a/clang/lib/Basic/IdentifierTable.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the IdentifierInfo, IdentifierVisitor, and
-// IdentifierTable interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// IdentifierInfo Implementation
-//===----------------------------------------------------------------------===//
-
-IdentifierInfo::IdentifierInfo() {
- TokenID = tok::identifier;
- ObjCID = tok::objc_not_keyword;
- BuiltinID = 0;
- HasMacro = false;
- IsExtension = false;
- IsPoisoned = false;
- IsCPPOperatorKeyword = false;
- FETokenInfo = 0;
-}
-
-//===----------------------------------------------------------------------===//
-// IdentifierTable Implementation
-//===----------------------------------------------------------------------===//
-
-IdentifierTable::IdentifierTable(const LangOptions &LangOpts)
- // Start with space for 8K identifiers.
- : HashTable(8192) {
-
- // Populate the identifier table with info about keywords for the current
- // language.
- AddKeywords(LangOpts);
-}
-
-// This cstor is intended to be used only for serialization.
-IdentifierTable::IdentifierTable() : HashTable(8192) {}
-
-//===----------------------------------------------------------------------===//
-// Language Keyword Implementation
-//===----------------------------------------------------------------------===//
-
-/// AddKeyword - This method is used to associate a token ID with specific
-/// identifiers because they are language keywords. This causes the lexer to
-/// automatically map matching identifiers to specialized token codes.
-///
-/// The C90/C99/CPP/CPP0x flags are set to 0 if the token should be
-/// enabled in the specified langauge, set to 1 if it is an extension
-/// in the specified language, and set to 2 if disabled in the
-/// specified language.
-static void AddKeyword(const char *Keyword, unsigned KWLen,
- tok::TokenKind TokenCode,
- int C90, int C99, int CXX, int CXX0x, int BoolSupport,
- const LangOptions &LangOpts, IdentifierTable &Table) {
- int Flags = 0;
- if (BoolSupport != 0) {
- Flags = LangOpts.CPlusPlus? 0 : LangOpts.Boolean ? BoolSupport : 2;
- } else if (LangOpts.CPlusPlus) {
- Flags = LangOpts.CPlusPlus0x ? CXX0x : CXX;
- } else if (LangOpts.C99) {
- Flags = C99;
- } else {
- Flags = C90;
- }
-
- // Don't add this keyword if disabled in this language or if an extension
- // and extensions are disabled.
- if (Flags + LangOpts.NoExtensions >= 2) return;
-
- IdentifierInfo &Info = Table.get(Keyword, Keyword+KWLen);
- Info.setTokenID(TokenCode);
- Info.setIsExtensionToken(Flags == 1);
-}
-
-static void AddAlias(const char *Keyword, unsigned KWLen,
- tok::TokenKind AliaseeID,
- const char *AliaseeKeyword, unsigned AliaseeKWLen,
- const LangOptions &LangOpts, IdentifierTable &Table) {
- IdentifierInfo &AliasInfo = Table.get(Keyword, Keyword+KWLen);
- IdentifierInfo &AliaseeInfo = Table.get(AliaseeKeyword,
- AliaseeKeyword+AliaseeKWLen);
- AliasInfo.setTokenID(AliaseeID);
- AliasInfo.setIsExtensionToken(AliaseeInfo.isExtensionToken());
-}
-
-/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
-/// representations.
-static void AddCXXOperatorKeyword(const char *Keyword, unsigned KWLen,
- tok::TokenKind TokenCode,
- IdentifierTable &Table) {
- IdentifierInfo &Info = Table.get(Keyword, Keyword + KWLen);
- Info.setTokenID(TokenCode);
- Info.setIsCPlusPlusOperatorKeyword();
-}
-
-/// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or
-/// "property".
-static void AddObjCKeyword(tok::ObjCKeywordKind ObjCID,
- const char *Name, unsigned NameLen,
- IdentifierTable &Table) {
- Table.get(Name, Name+NameLen).setObjCKeywordID(ObjCID);
-}
-
-/// AddKeywords - Add all keywords to the symbol table.
-///
-void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
- enum {
- C90Shift = 0,
- EXTC90 = 1 << C90Shift,
- NOTC90 = 2 << C90Shift,
- C99Shift = 2,
- EXTC99 = 1 << C99Shift,
- NOTC99 = 2 << C99Shift,
- CPPShift = 4,
- EXTCPP = 1 << CPPShift,
- NOTCPP = 2 << CPPShift,
- CPP0xShift = 6,
- EXTCPP0x = 1 << CPP0xShift,
- NOTCPP0x = 2 << CPP0xShift,
- BoolShift = 8,
- BOOLSUPPORT = 1 << BoolShift,
- Mask = 3
- };
-
- // Add keywords and tokens for the current language.
-#define KEYWORD(NAME, FLAGS) \
- AddKeyword(#NAME, strlen(#NAME), tok::kw_ ## NAME, \
- ((FLAGS) >> C90Shift) & Mask, \
- ((FLAGS) >> C99Shift) & Mask, \
- ((FLAGS) >> CPPShift) & Mask, \
- ((FLAGS) >> CPP0xShift) & Mask, \
- ((FLAGS) >> BoolShift) & Mask, LangOpts, *this);
-#define ALIAS(NAME, TOK) \
- AddAlias(NAME, strlen(NAME), tok::kw_ ## TOK, #TOK, strlen(#TOK), \
- LangOpts, *this);
-#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
- if (LangOpts.CXXOperatorNames) \
- AddCXXOperatorKeyword(#NAME, strlen(#NAME), tok::ALIAS, *this);
-#define OBJC1_AT_KEYWORD(NAME) \
- if (LangOpts.ObjC1) \
- AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this);
-#define OBJC2_AT_KEYWORD(NAME) \
- if (LangOpts.ObjC2) \
- AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this);
-#include "clang/Basic/TokenKinds.def"
-}
-
-tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
- // We use a perfect hash function here involving the length of the keyword,
- // the first and third character. For preprocessor ID's there are no
- // collisions (if there were, the switch below would complain about duplicate
- // case values). Note that this depends on 'if' being null terminated.
-
-#define HASH(LEN, FIRST, THIRD) \
- (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
-#define CASE(LEN, FIRST, THIRD, NAME) \
- case HASH(LEN, FIRST, THIRD): \
- return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
-
- unsigned Len = getLength();
- if (Len < 2) return tok::pp_not_keyword;
- const char *Name = getName();
- switch (HASH(Len, Name[0], Name[2])) {
- default: return tok::pp_not_keyword;
- CASE( 2, 'i', '\0', if);
- CASE( 4, 'e', 'i', elif);
- CASE( 4, 'e', 's', else);
- CASE( 4, 'l', 'n', line);
- CASE( 4, 's', 'c', sccs);
- CASE( 5, 'e', 'd', endif);
- CASE( 5, 'e', 'r', error);
- CASE( 5, 'i', 'e', ident);
- CASE( 5, 'i', 'd', ifdef);
- CASE( 5, 'u', 'd', undef);
-
- CASE( 6, 'a', 's', assert);
- CASE( 6, 'd', 'f', define);
- CASE( 6, 'i', 'n', ifndef);
- CASE( 6, 'i', 'p', import);
- CASE( 6, 'p', 'a', pragma);
-
- CASE( 7, 'd', 'f', defined);
- CASE( 7, 'i', 'c', include);
- CASE( 7, 'w', 'r', warning);
-
- CASE( 8, 'u', 'a', unassert);
- CASE(12, 'i', 'c', include_next);
-#undef CASE
-#undef HASH
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Stats Implementation
-//===----------------------------------------------------------------------===//
-
-/// PrintStats - Print statistics about how well the identifier table is doing
-/// at hashing identifiers.
-void IdentifierTable::PrintStats() const {
- unsigned NumBuckets = HashTable.getNumBuckets();
- unsigned NumIdentifiers = HashTable.getNumItems();
- unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
- unsigned AverageIdentifierSize = 0;
- unsigned MaxIdentifierLength = 0;
-
- // TODO: Figure out maximum times an identifier had to probe for -stats.
- for (llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator>::const_iterator
- I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
- unsigned IdLen = I->getKeyLength();
- AverageIdentifierSize += IdLen;
- if (MaxIdentifierLength < IdLen)
- MaxIdentifierLength = IdLen;
- }
-
- fprintf(stderr, "\n*** Identifier Table Stats:\n");
- fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers);
- fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
- fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
- NumIdentifiers/(double)NumBuckets);
- fprintf(stderr, "Ave identifier length: %f\n",
- (AverageIdentifierSize/(double)NumIdentifiers));
- fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
-
- // Compute statistics about the memory allocated for identifiers.
- HashTable.getAllocator().PrintStats();
-}
-
-//===----------------------------------------------------------------------===//
-// SelectorTable Implementation
-//===----------------------------------------------------------------------===//
-
-unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
- return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
-}
-
-
-/// MultiKeywordSelector - One of these variable length records is kept for each
-/// selector containing more than one keyword. We use a folding set
-/// to unique aggregate names (keyword selectors in ObjC parlance). Access to
-/// this class is provided strictly through Selector.
-namespace clang {
-class MultiKeywordSelector : public llvm::FoldingSetNode {
- friend SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer&);
- MultiKeywordSelector(unsigned nKeys) : NumArgs(nKeys) {}
-public:
- unsigned NumArgs;
-
- // Constructor for keyword selectors.
- MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
- assert((nKeys > 1) && "not a multi-keyword selector");
- NumArgs = nKeys;
-
- // Fill in the trailing keyword array.
- IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
- for (unsigned i = 0; i != nKeys; ++i)
- KeyInfo[i] = IIV[i];
- }
-
- // getName - Derive the full selector name and return it.
- std::string getName() const;
-
- unsigned getNumArgs() const { return NumArgs; }
-
- typedef IdentifierInfo *const *keyword_iterator;
- keyword_iterator keyword_begin() const {
- return reinterpret_cast<keyword_iterator>(this+1);
- }
- keyword_iterator keyword_end() const {
- return keyword_begin()+NumArgs;
- }
- IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
- assert(i < NumArgs && "getIdentifierInfoForSlot(): illegal index");
- return keyword_begin()[i];
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- keyword_iterator ArgTys, unsigned NumArgs) {
- ID.AddInteger(NumArgs);
- for (unsigned i = 0; i != NumArgs; ++i)
- ID.AddPointer(ArgTys[i]);
- }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, keyword_begin(), NumArgs);
- }
-};
-} // end namespace clang.
-
-unsigned Selector::getNumArgs() const {
- unsigned IIF = getIdentifierInfoFlag();
- if (IIF == ZeroArg)
- return 0;
- if (IIF == OneArg)
- return 1;
- // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
- MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
- return SI->getNumArgs();
-}
-
-IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
- if (IdentifierInfo *II = getAsIdentifierInfo()) {
- assert(argIndex == 0 && "illegal keyword index");
- return II;
- }
- // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
- MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
- return SI->getIdentifierInfoForSlot(argIndex);
-}
-
-std::string MultiKeywordSelector::getName() const {
- std::string Result;
- unsigned Length = 0;
- for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
- if (*I)
- Length += (*I)->getLength();
- ++Length; // :
- }
-
- Result.reserve(Length);
-
- for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
- if (*I)
- Result.insert(Result.end(), (*I)->getName(),
- (*I)->getName()+(*I)->getLength());
- Result.push_back(':');
- }
-
- return Result;
-}
-
-std::string Selector::getName() const {
- if (IdentifierInfo *II = getAsIdentifierInfo()) {
- if (getNumArgs() == 0)
- return II->getName();
-
- std::string Res = II->getName();
- Res += ":";
- return Res;
- }
-
- // We have a multiple keyword selector (no embedded flags).
- return reinterpret_cast<MultiKeywordSelector *>(InfoPtr)->getName();
-}
-
-
-Selector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) {
- if (nKeys < 2)
- return Selector(IIV[0], nKeys);
-
- llvm::FoldingSet<MultiKeywordSelector> *SelTab;
-
- SelTab = static_cast<llvm::FoldingSet<MultiKeywordSelector> *>(Impl);
-
- // Unique selector, to guarantee there is one per name.
- llvm::FoldingSetNodeID ID;
- MultiKeywordSelector::Profile(ID, IIV, nKeys);
-
- void *InsertPos = 0;
- if (MultiKeywordSelector *SI = SelTab->FindNodeOrInsertPos(ID, InsertPos))
- return Selector(SI);
-
- // MultiKeywordSelector objects are not allocated with new because they have a
- // variable size array (for parameter types) at the end of them.
- MultiKeywordSelector *SI =
- (MultiKeywordSelector*)malloc(sizeof(MultiKeywordSelector) +
- nKeys*sizeof(IdentifierInfo *));
- new (SI) MultiKeywordSelector(nKeys, IIV);
- SelTab->InsertNode(SI, InsertPos);
- return Selector(SI);
-}
-
-SelectorTable::SelectorTable() {
- Impl = new llvm::FoldingSet<MultiKeywordSelector>;
-}
-
-SelectorTable::~SelectorTable() {
- delete static_cast<llvm::FoldingSet<MultiKeywordSelector> *>(Impl);
-}
-
-//===----------------------------------------------------------------------===//
-// Serialization for IdentifierInfo and IdentifierTable.
-//===----------------------------------------------------------------------===//
-
-void IdentifierInfo::Emit(llvm::Serializer& S) const {
- S.EmitInt(getTokenID());
- S.EmitInt(getBuiltinID());
- S.EmitInt(getObjCKeywordID());
- S.EmitBool(hasMacroDefinition());
- S.EmitBool(isExtensionToken());
- S.EmitBool(isPoisoned());
- S.EmitBool(isCPlusPlusOperatorKeyword());
- // FIXME: FETokenInfo
-}
-
-void IdentifierInfo::Read(llvm::Deserializer& D) {
- setTokenID((tok::TokenKind) D.ReadInt());
- setBuiltinID(D.ReadInt());
- setObjCKeywordID((tok::ObjCKeywordKind) D.ReadInt());
- setHasMacroDefinition(D.ReadBool());
- setIsExtensionToken(D.ReadBool());
- setIsPoisoned(D.ReadBool());
- setIsCPlusPlusOperatorKeyword(D.ReadBool());
- // FIXME: FETokenInfo
-}
-
-void IdentifierTable::Emit(llvm::Serializer& S) const {
- S.EnterBlock();
-
- S.EmitPtr(this);
-
- for (iterator I=begin(), E=end(); I != E; ++I) {
- const char* Key = I->getKeyData();
- const IdentifierInfo* Info = &I->getValue();
-
- bool KeyRegistered = S.isRegistered(Key);
- bool InfoRegistered = S.isRegistered(Info);
-
- if (KeyRegistered || InfoRegistered) {
- // These acrobatics are so that we don't incur the cost of registering
- // a pointer with the backpatcher during deserialization if nobody
- // references the object.
- S.EmitPtr(InfoRegistered ? Info : NULL);
- S.EmitPtr(KeyRegistered ? Key : NULL);
- S.EmitCStr(Key);
- S.Emit(*Info);
- }
- }
-
- S.ExitBlock();
-}
-
-IdentifierTable* IdentifierTable::CreateAndRegister(llvm::Deserializer& D) {
- llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
-
- std::vector<char> buff;
- buff.reserve(200);
-
- IdentifierTable* t = new IdentifierTable();
- D.RegisterPtr(t);
-
- while (!D.FinishedBlock(BLoc)) {
- llvm::SerializedPtrID InfoPtrID = D.ReadPtrID();
- llvm::SerializedPtrID KeyPtrID = D.ReadPtrID();
-
- D.ReadCStr(buff);
-
- llvm::StringMapEntry<IdentifierInfo>& Entry =
- t->HashTable.GetOrCreateValue(&buff[0],&buff[0]+buff.size());
-
- D.Read(Entry.getValue());
-
- if (InfoPtrID)
- D.RegisterRef(InfoPtrID,Entry.getValue());
-
- if (KeyPtrID)
- D.RegisterPtr(KeyPtrID,Entry.getKeyData());
- }
-
- return t;
-}
-
-//===----------------------------------------------------------------------===//
-// Serialization for Selector and SelectorTable.
-//===----------------------------------------------------------------------===//
-
-void Selector::Emit(llvm::Serializer& S) const {
- S.EmitInt(getIdentifierInfoFlag());
- S.EmitPtr(reinterpret_cast<void*>(InfoPtr & ~ArgFlags));
-}
-
-Selector Selector::ReadVal(llvm::Deserializer& D) {
- unsigned flag = D.ReadInt();
-
- uintptr_t ptr;
- D.ReadUIntPtr(ptr,false); // No backpatching.
-
- return Selector(ptr | flag);
-}
-
-void SelectorTable::Emit(llvm::Serializer& S) const {
- typedef llvm::FoldingSet<MultiKeywordSelector>::iterator iterator;
- llvm::FoldingSet<MultiKeywordSelector> *SelTab;
- SelTab = static_cast<llvm::FoldingSet<MultiKeywordSelector> *>(Impl);
-
- S.EnterBlock();
-
- S.EmitPtr(this);
-
- for (iterator I=SelTab->begin(), E=SelTab->end(); I != E; ++I) {
- if (!S.isRegistered(&*I))
- continue;
-
- S.FlushRecord(); // Start a new record.
-
- S.EmitPtr(&*I);
- S.EmitInt(I->getNumArgs());
-
- for (MultiKeywordSelector::keyword_iterator KI = I->keyword_begin(),
- KE = I->keyword_end(); KI != KE; ++KI)
- S.EmitPtr(*KI);
- }
-
- S.ExitBlock();
-}
-
-SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer& D) {
- llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
-
- SelectorTable* t = new SelectorTable();
- D.RegisterPtr(t);
-
- llvm::FoldingSet<MultiKeywordSelector>& SelTab =
- *static_cast<llvm::FoldingSet<MultiKeywordSelector>*>(t->Impl);
-
- while (!D.FinishedBlock(BLoc)) {
-
- llvm::SerializedPtrID PtrID = D.ReadPtrID();
- unsigned nKeys = D.ReadInt();
-
- MultiKeywordSelector *SI =
- (MultiKeywordSelector*)malloc(sizeof(MultiKeywordSelector) +
- nKeys*sizeof(IdentifierInfo *));
-
- new (SI) MultiKeywordSelector(nKeys);
-
- D.RegisterPtr(PtrID,SI);
-
- IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(SI+1);
-
- for (unsigned i = 0; i != nKeys; ++i)
- D.ReadPtr(KeyInfo[i],false);
-
- SelTab.GetOrInsertNode(SI);
- }
-
- return t;
-}
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
deleted file mode 100644
index 6119afc79061..000000000000
--- a/clang/lib/Basic/LangOptions.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//===--- LangOptions.cpp - Language feature info --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the methods for LangOptions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/LangOptions.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-
-using namespace clang;
-
-void LangOptions::Emit(llvm::Serializer& S) const {
- S.EmitBool((bool) Trigraphs);
- S.EmitBool((bool) BCPLComment);
- S.EmitBool((bool) DollarIdents);
- S.EmitBool((bool) Digraphs);
- S.EmitBool((bool) HexFloats);
- S.EmitBool((bool) C99);
- S.EmitBool((bool) Microsoft);
- S.EmitBool((bool) CPlusPlus);
- S.EmitBool((bool) CPlusPlus0x);
- S.EmitBool((bool) NoExtensions);
- S.EmitBool((bool) CXXOperatorNames);
- S.EmitBool((bool) ObjC1);
- S.EmitBool((bool) ObjC2);
- S.EmitBool((unsigned) GC);
- S.EmitBool((bool) PascalStrings);
- S.EmitBool((bool) Boolean);
- S.EmitBool((bool) WritableStrings);
- S.EmitBool((bool) LaxVectorConversions);
-}
-
-void LangOptions::Read(llvm::Deserializer& D) {
- Trigraphs = D.ReadBool() ? 1 : 0;
- BCPLComment = D.ReadBool() ? 1 : 0;
- DollarIdents = D.ReadBool() ? 1 : 0;
- Digraphs = D.ReadBool() ? 1 : 0;
- HexFloats = D.ReadBool() ? 1 : 0;
- C99 = D.ReadBool() ? 1 : 0;
- Microsoft = D.ReadBool() ? 1 : 0;
- CPlusPlus = D.ReadBool() ? 1 : 0;
- CPlusPlus0x = D.ReadBool() ? 1 : 0;
- NoExtensions = D.ReadBool() ? 1 : 0;
- CXXOperatorNames = D.ReadBool() ? 1 : 0;
- ObjC1 = D.ReadBool() ? 1 : 0;
- ObjC2 = D.ReadBool() ? 1 : 0;
- GC = D.ReadInt();
- PascalStrings = D.ReadBool() ? 1 : 0;
- Boolean = D.ReadBool() ? 1 : 0;
- WritableStrings = D.ReadBool() ? 1 : 0;
- LaxVectorConversions = D.ReadBool() ? 1 : 0;
-}
diff --git a/clang/lib/Basic/Makefile b/clang/lib/Basic/Makefile
deleted file mode 100644
index e95d6dbfa35c..000000000000
--- a/clang/lib/Basic/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- clang/lib/Basic/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the Basic library for the C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangBasic
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Basic/SourceLocation.cpp b/clang/lib/Basic/SourceLocation.cpp
deleted file mode 100644
index 5236bfaffba2..000000000000
--- a/clang/lib/Basic/SourceLocation.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-//==--- SourceLocation.cpp - Compact identifier for Source Files -*- 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 serialization methods for the SourceLocation class.
-// This file defines accessor methods for the FullSourceLoc class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-using namespace clang;
-
-void SourceLocation::Emit(llvm::Serializer& S) const {
- S.EmitInt(getRawEncoding());
-}
-
-SourceLocation SourceLocation::ReadVal(llvm::Deserializer& D) {
- return SourceLocation::getFromRawEncoding(D.ReadInt());
-}
-
-void SourceRange::Emit(llvm::Serializer& S) const {
- B.Emit(S);
- E.Emit(S);
-}
-
-SourceRange SourceRange::ReadVal(llvm::Deserializer& D) {
- SourceLocation A = SourceLocation::ReadVal(D);
- SourceLocation B = SourceLocation::ReadVal(D);
- return SourceRange(A,B);
-}
-
-FullSourceLoc FullSourceLoc::getLogicalLoc() const {
- assert (isValid());
- return FullSourceLoc(SrcMgr->getLogicalLoc(Loc), *SrcMgr);
-}
-
-FullSourceLoc FullSourceLoc::getPhysicalLoc() const {
- assert (isValid());
- return FullSourceLoc(SrcMgr->getPhysicalLoc(Loc), *SrcMgr);
-}
-
-FullSourceLoc FullSourceLoc::getIncludeLoc() const {
- assert (isValid());
- return FullSourceLoc(SrcMgr->getIncludeLoc(Loc), *SrcMgr);
-}
-
-unsigned FullSourceLoc::getLineNumber() const {
- assert (isValid());
- return SrcMgr->getLineNumber(Loc);
-}
-
-unsigned FullSourceLoc::getColumnNumber() const {
- assert (isValid());
- return SrcMgr->getColumnNumber(Loc);
-}
-
-
-unsigned FullSourceLoc::getLogicalLineNumber() const {
- assert (isValid());
- return SrcMgr->getLogicalLineNumber(Loc);
-}
-
-unsigned FullSourceLoc::getLogicalColumnNumber() const {
- assert (isValid());
- return SrcMgr->getLogicalColumnNumber(Loc);
-}
-
-unsigned FullSourceLoc::getPhysicalLineNumber() const {
- assert (isValid());
- return SrcMgr->getPhysicalLineNumber(Loc);
-}
-
-unsigned FullSourceLoc::getPhysicalColumnNumber() const {
- assert (isValid());
- return SrcMgr->getPhysicalColumnNumber(Loc);
-}
-
-const char* FullSourceLoc::getSourceName() const {
- assert (isValid());
- return SrcMgr->getSourceName(Loc);
-}
-
-const FileEntry* FullSourceLoc::getFileEntryForLoc() const {
- assert (isValid());
- return SrcMgr->getFileEntryForLoc(Loc);
-}
-
-bool FullSourceLoc::isInSystemHeader() const {
- assert (isValid());
- return SrcMgr->isInSystemHeader(Loc);
-}
-
-
-const char * FullSourceLoc::getCharacterData() const {
- assert (isValid());
- return SrcMgr->getCharacterData(Loc);
-}
-
-const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const {
- assert (isValid());
- return SrcMgr->getBuffer(Loc.getFileID());
-}
-
-unsigned FullSourceLoc::getCanonicalFileID() const {
- return SrcMgr->getCanonicalFileID(Loc);
-}
-
-void FullSourceLoc::dump() const {
- if (!isValid()) {
- fprintf(stderr, "Invalid Loc\n");
- return;
- }
-
- if (isFileID()) {
- // The logical and physical pos is identical for file locs.
- fprintf(stderr, "File Loc from '%s': %d: %d\n",
- getSourceName(), getLogicalLineNumber(),
- getLogicalColumnNumber());
- } else {
- fprintf(stderr, "Macro Loc (\n Physical: ");
- getPhysicalLoc().dump();
- fprintf(stderr, " Logical: ");
- getLogicalLoc().dump();
- fprintf(stderr, ")\n");
- }
-}
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
deleted file mode 100644
index 1eed0bc14320..000000000000
--- a/clang/lib/Basic/SourceManager.cpp
+++ /dev/null
@@ -1,516 +0,0 @@
-//===--- SourceManager.cpp - Track and cache source files -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the SourceManager interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Path.h"
-#include "llvm/Bitcode/Serialize.h"
-#include "llvm/Bitcode/Deserialize.h"
-#include "llvm/Support/Streams.h"
-#include <algorithm>
-using namespace clang;
-using namespace SrcMgr;
-using llvm::MemoryBuffer;
-
-ContentCache::~ContentCache() {
- delete Buffer;
- delete [] SourceLineCache;
-}
-
-/// getFileInfo - Create or return a cached FileInfo for the specified file.
-///
-const ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) {
-
- assert(FileEnt && "Didn't specify a file entry to use?");
- // Do we already have information about this file?
- std::set<ContentCache>::iterator I =
- FileInfos.lower_bound(ContentCache(FileEnt));
-
- if (I != FileInfos.end() && I->Entry == FileEnt)
- return &*I;
-
- // Nope, get information.
- const MemoryBuffer *File =
- MemoryBuffer::getFile(FileEnt->getName(), 0, FileEnt->getSize());
- if (File == 0)
- return 0;
-
- ContentCache& Entry = const_cast<ContentCache&>(*FileInfos.insert(I,FileEnt));
-
- Entry.Buffer = File;
- Entry.SourceLineCache = 0;
- Entry.NumLines = 0;
- return &Entry;
-}
-
-
-/// createMemBufferContentCache - Create a new ContentCache for the specified
-/// memory buffer. This does no caching.
-const ContentCache*
-SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
- // Add a new ContentCache to the MemBufferInfos list and return it. We
- // must default construct the object first that the instance actually
- // stored within MemBufferInfos actually owns the Buffer, and not any
- // temporary we would use in the call to "push_back".
- MemBufferInfos.push_back(ContentCache());
- ContentCache& Entry = const_cast<ContentCache&>(MemBufferInfos.back());
- Entry.Buffer = Buffer;
- return &Entry;
-}
-
-
-/// createFileID - Create a new fileID for the specified ContentCache and
-/// include position. This works regardless of whether the ContentCache
-/// corresponds to a file or some other input source.
-unsigned SourceManager::createFileID(const ContentCache *File,
- SourceLocation IncludePos,
- SrcMgr::Characteristic_t FileCharacter) {
- // If FileEnt is really large (e.g. it's a large .i file), we may not be able
- // to fit an arbitrary position in the file in the FilePos field. To handle
- // this, we create one FileID for each chunk of the file that fits in a
- // FilePos field.
- unsigned FileSize = File->Buffer->getBufferSize();
- if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
- FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter));
- assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
- "Ran out of file ID's!");
- return FileIDs.size();
- }
-
- // Create one FileID for each chunk of the file.
- unsigned Result = FileIDs.size()+1;
-
- unsigned ChunkNo = 0;
- while (1) {
- FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File,
- FileCharacter));
-
- if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
- FileSize -= (1 << SourceLocation::FilePosBits);
- }
-
- assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
- "Ran out of file ID's!");
- return Result;
-}
-
-/// getInstantiationLoc - Return a new SourceLocation that encodes the fact
-/// that a token from physloc PhysLoc should actually be referenced from
-/// InstantiationLoc.
-SourceLocation SourceManager::getInstantiationLoc(SourceLocation PhysLoc,
- SourceLocation InstantLoc) {
- // The specified source location may be a mapped location, due to a macro
- // instantiation or #line directive. Strip off this information to find out
- // where the characters are actually located.
- PhysLoc = getPhysicalLoc(PhysLoc);
-
- // Resolve InstantLoc down to a real logical location.
- InstantLoc = getLogicalLoc(InstantLoc);
-
-
- // If the last macro id is close to the currently requested location, try to
- // reuse it. This implements a small cache.
- for (int i = MacroIDs.size()-1, e = MacroIDs.size()-6; i >= 0 && i != e; --i){
- MacroIDInfo &LastOne = MacroIDs[i];
-
- // The instanitation point and source physloc have to exactly match to reuse
- // (for now). We could allow "nearby" instantiations in the future.
- if (LastOne.getVirtualLoc() != InstantLoc ||
- LastOne.getPhysicalLoc().getFileID() != PhysLoc.getFileID())
- continue;
-
- // Check to see if the physloc of the token came from near enough to reuse.
- int PhysDelta = PhysLoc.getRawFilePos() -
- LastOne.getPhysicalLoc().getRawFilePos();
- if (SourceLocation::isValidMacroPhysOffs(PhysDelta))
- return SourceLocation::getMacroLoc(i, PhysDelta);
- }
-
-
- MacroIDs.push_back(MacroIDInfo::get(InstantLoc, PhysLoc));
- return SourceLocation::getMacroLoc(MacroIDs.size()-1, 0);
-}
-
-/// getBufferData - Return a pointer to the start and end of the character
-/// data for the specified FileID.
-std::pair<const char*, const char*>
-SourceManager::getBufferData(unsigned FileID) const {
- const llvm::MemoryBuffer *Buf = getBuffer(FileID);
- return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
-}
-
-
-/// getCharacterData - Return a pointer to the start of the specified location
-/// in the appropriate MemoryBuffer.
-const char *SourceManager::getCharacterData(SourceLocation SL) const {
- // Note that this is a hot function in the getSpelling() path, which is
- // heavily used by -E mode.
- SL = getPhysicalLoc(SL);
-
- return getContentCache(SL.getFileID())->Buffer->getBufferStart() +
- getFullFilePos(SL);
-}
-
-
-/// getColumnNumber - Return the column # for the specified file position.
-/// this is significantly cheaper to compute than the line number. This returns
-/// zero if the column number isn't known.
-unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
- unsigned FileID = Loc.getFileID();
- if (FileID == 0) return 0;
-
- unsigned FilePos = getFullFilePos(Loc);
- const MemoryBuffer *Buffer = getBuffer(FileID);
- const char *Buf = Buffer->getBufferStart();
-
- unsigned LineStart = FilePos;
- while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
- --LineStart;
- return FilePos-LineStart+1;
-}
-
-/// getSourceName - This method returns the name of the file or buffer that
-/// the SourceLocation specifies. This can be modified with #line directives,
-/// etc.
-const char *SourceManager::getSourceName(SourceLocation Loc) const {
- unsigned FileID = Loc.getFileID();
- if (FileID == 0) return "";
- return getContentCache(FileID)->Buffer->getBufferIdentifier();
-}
-
-static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
-static void ComputeLineNumbers(ContentCache* FI) {
- const MemoryBuffer *Buffer = FI->Buffer;
-
- // Find the file offsets of all of the *physical* source lines. This does
- // not look at trigraphs, escaped newlines, or anything else tricky.
- std::vector<unsigned> LineOffsets;
-
- // Line #1 starts at char 0.
- LineOffsets.push_back(0);
-
- const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
- const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
- unsigned Offs = 0;
- while (1) {
- // Skip over the contents of the line.
- // TODO: Vectorize this? This is very performance sensitive for programs
- // with lots of diagnostics and in -E mode.
- const unsigned char *NextBuf = (const unsigned char *)Buf;
- while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
- ++NextBuf;
- Offs += NextBuf-Buf;
- Buf = NextBuf;
-
- if (Buf[0] == '\n' || Buf[0] == '\r') {
- // If this is \n\r or \r\n, skip both characters.
- if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
- ++Offs, ++Buf;
- ++Offs, ++Buf;
- LineOffsets.push_back(Offs);
- } else {
- // Otherwise, this is a null. If end of file, exit.
- if (Buf == End) break;
- // Otherwise, skip the null.
- ++Offs, ++Buf;
- }
- }
-
- // Copy the offsets into the FileInfo structure.
- FI->NumLines = LineOffsets.size();
- FI->SourceLineCache = new unsigned[LineOffsets.size()];
- std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
-}
-
-/// getLineNumber - Given a SourceLocation, return the physical line number
-/// for the position indicated. This requires building and caching a table of
-/// line offsets for the MemoryBuffer, so this is not cheap: use only when
-/// about to emit a diagnostic.
-unsigned SourceManager::getLineNumber(SourceLocation Loc) {
- unsigned FileID = Loc.getFileID();
- if (FileID == 0) return 0;
-
- ContentCache* Content;
-
- if (LastLineNoFileIDQuery == FileID)
- Content = LastLineNoContentCache;
- else
- Content = const_cast<ContentCache*>(getContentCache(FileID));
-
- // If this is the first use of line information for this buffer, compute the
- /// SourceLineCache for it on demand.
- if (Content->SourceLineCache == 0)
- ComputeLineNumbers(Content);
-
- // Okay, we know we have a line number table. Do a binary search to find the
- // line number that this character position lands on.
- unsigned *SourceLineCache = Content->SourceLineCache;
- unsigned *SourceLineCacheStart = SourceLineCache;
- unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
-
- unsigned QueriedFilePos = getFullFilePos(Loc)+1;
-
- // If the previous query was to the same file, we know both the file pos from
- // that query and the line number returned. This allows us to narrow the
- // search space from the entire file to something near the match.
- if (LastLineNoFileIDQuery == FileID) {
- if (QueriedFilePos >= LastLineNoFilePos) {
- SourceLineCache = SourceLineCache+LastLineNoResult-1;
-
- // The query is likely to be nearby the previous one. Here we check to
- // see if it is within 5, 10 or 20 lines. It can be far away in cases
- // where big comment blocks and vertical whitespace eat up lines but
- // contribute no tokens.
- if (SourceLineCache+5 < SourceLineCacheEnd) {
- if (SourceLineCache[5] > QueriedFilePos)
- SourceLineCacheEnd = SourceLineCache+5;
- else if (SourceLineCache+10 < SourceLineCacheEnd) {
- if (SourceLineCache[10] > QueriedFilePos)
- SourceLineCacheEnd = SourceLineCache+10;
- else if (SourceLineCache+20 < SourceLineCacheEnd) {
- if (SourceLineCache[20] > QueriedFilePos)
- SourceLineCacheEnd = SourceLineCache+20;
- }
- }
- }
- } else {
- SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
- }
- }
-
- // If the spread is large, do a "radix" test as our initial guess, based on
- // the assumption that lines average to approximately the same length.
- // NOTE: This is currently disabled, as it does not appear to be profitable in
- // initial measurements.
- if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
- unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
-
- // Take a stab at guessing where it is.
- unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
-
- // Check for -10 and +10 lines.
- unsigned LowerBound = std::max(int(ApproxPos-10), 0);
- unsigned UpperBound = std::min(ApproxPos+10, FileLen);
-
- // If the computed lower bound is less than the query location, move it in.
- if (SourceLineCache < SourceLineCacheStart+LowerBound &&
- SourceLineCacheStart[LowerBound] < QueriedFilePos)
- SourceLineCache = SourceLineCacheStart+LowerBound;
-
- // If the computed upper bound is greater than the query location, move it.
- if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
- SourceLineCacheStart[UpperBound] >= QueriedFilePos)
- SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
- }
-
- unsigned *Pos
- = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
- unsigned LineNo = Pos-SourceLineCacheStart;
-
- LastLineNoFileIDQuery = FileID;
- LastLineNoContentCache = Content;
- LastLineNoFilePos = QueriedFilePos;
- LastLineNoResult = LineNo;
- return LineNo;
-}
-
-/// PrintStats - Print statistics to stderr.
-///
-void SourceManager::PrintStats() const {
- llvm::cerr << "\n*** Source Manager Stats:\n";
- llvm::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
- << " mem buffers mapped, " << FileIDs.size()
- << " file ID's allocated.\n";
- llvm::cerr << " " << FileIDs.size() << " normal buffer FileID's, "
- << MacroIDs.size() << " macro expansion FileID's.\n";
-
- unsigned NumLineNumsComputed = 0;
- unsigned NumFileBytesMapped = 0;
- for (std::set<ContentCache>::const_iterator I =
- FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
- NumLineNumsComputed += I->SourceLineCache != 0;
- NumFileBytesMapped += I->Buffer->getBufferSize();
- }
-
- llvm::cerr << NumFileBytesMapped << " bytes of files mapped, "
- << NumLineNumsComputed << " files with line #'s computed.\n";
-}
-
-//===----------------------------------------------------------------------===//
-// Serialization.
-//===----------------------------------------------------------------------===//
-
-void ContentCache::Emit(llvm::Serializer& S) const {
- S.FlushRecord();
- S.EmitPtr(this);
-
- if (Entry) {
- llvm::sys::Path Fname(Buffer->getBufferIdentifier());
-
- if (Fname.isAbsolute())
- S.EmitCStr(Fname.c_str());
- else {
- // Create an absolute path.
- // FIXME: This will potentially contain ".." and "." in the path.
- llvm::sys::Path path = llvm::sys::Path::GetCurrentDirectory();
- path.appendComponent(Fname.c_str());
- S.EmitCStr(path.c_str());
- }
- }
- else {
- const char* p = Buffer->getBufferStart();
- const char* e = Buffer->getBufferEnd();
-
- S.EmitInt(e-p);
-
- for ( ; p != e; ++p)
- S.EmitInt(*p);
- }
-
- S.FlushRecord();
-}
-
-void ContentCache::ReadToSourceManager(llvm::Deserializer& D,
- SourceManager& SMgr,
- FileManager* FMgr,
- std::vector<char>& Buf) {
- if (FMgr) {
- llvm::SerializedPtrID PtrID = D.ReadPtrID();
- D.ReadCStr(Buf,false);
-
- // Create/fetch the FileEntry.
- const char* start = &Buf[0];
- const FileEntry* E = FMgr->getFile(start,start+Buf.size());
-
- // FIXME: Ideally we want a lazy materialization of the ContentCache
- // anyway, because we don't want to read in source files unless this
- // is absolutely needed.
- if (!E)
- D.RegisterPtr(PtrID,NULL);
- else
- // Get the ContextCache object and register it with the deserializer.
- D.RegisterPtr(PtrID,SMgr.getContentCache(E));
- }
- else {
- // Register the ContextCache object with the deserializer.
- SMgr.MemBufferInfos.push_back(ContentCache());
- ContentCache& Entry = const_cast<ContentCache&>(SMgr.MemBufferInfos.back());
- D.RegisterPtr(&Entry);
-
- // Create the buffer.
- unsigned Size = D.ReadInt();
- Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size);
-
- // Read the contents of the buffer.
- char* p = const_cast<char*>(Entry.Buffer->getBufferStart());
- for (unsigned i = 0; i < Size ; ++i)
- p[i] = D.ReadInt();
- }
-}
-
-void FileIDInfo::Emit(llvm::Serializer& S) const {
- S.Emit(IncludeLoc);
- S.EmitInt(ChunkNo);
- S.EmitPtr(Content);
-}
-
-FileIDInfo FileIDInfo::ReadVal(llvm::Deserializer& D) {
- FileIDInfo I;
- I.IncludeLoc = SourceLocation::ReadVal(D);
- I.ChunkNo = D.ReadInt();
- D.ReadPtr(I.Content,false);
- return I;
-}
-
-void MacroIDInfo::Emit(llvm::Serializer& S) const {
- S.Emit(VirtualLoc);
- S.Emit(PhysicalLoc);
-}
-
-MacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) {
- MacroIDInfo I;
- I.VirtualLoc = SourceLocation::ReadVal(D);
- I.PhysicalLoc = SourceLocation::ReadVal(D);
- return I;
-}
-
-void SourceManager::Emit(llvm::Serializer& S) const {
- S.EnterBlock();
- S.EmitPtr(this);
- S.EmitInt(MainFileID);
-
- // Emit: FileInfos. Just emit the file name.
- S.EnterBlock();
-
- std::for_each(FileInfos.begin(),FileInfos.end(),
- S.MakeEmitter<ContentCache>());
-
- S.ExitBlock();
-
- // Emit: MemBufferInfos
- S.EnterBlock();
-
- std::for_each(MemBufferInfos.begin(), MemBufferInfos.end(),
- S.MakeEmitter<ContentCache>());
-
- S.ExitBlock();
-
- // Emit: FileIDs
- S.EmitInt(FileIDs.size());
- std::for_each(FileIDs.begin(), FileIDs.end(), S.MakeEmitter<FileIDInfo>());
-
- // Emit: MacroIDs
- S.EmitInt(MacroIDs.size());
- std::for_each(MacroIDs.begin(), MacroIDs.end(), S.MakeEmitter<MacroIDInfo>());
-
- S.ExitBlock();
-}
-
-SourceManager*
-SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){
- SourceManager *M = new SourceManager();
- D.RegisterPtr(M);
-
- // Read: the FileID of the main source file of the translation unit.
- M->MainFileID = D.ReadInt();
-
- std::vector<char> Buf;
-
- { // Read: FileInfos.
- llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
- while (!D.FinishedBlock(BLoc))
- ContentCache::ReadToSourceManager(D,*M,&FMgr,Buf);
- }
-
- { // Read: MemBufferInfos.
- llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
- while (!D.FinishedBlock(BLoc))
- ContentCache::ReadToSourceManager(D,*M,NULL,Buf);
- }
-
- // Read: FileIDs.
- unsigned Size = D.ReadInt();
- M->FileIDs.reserve(Size);
- for (; Size > 0 ; --Size)
- M->FileIDs.push_back(FileIDInfo::ReadVal(D));
-
- // Read: MacroIDs.
- Size = D.ReadInt();
- M->MacroIDs.reserve(Size);
- for (; Size > 0 ; --Size)
- M->MacroIDs.push_back(MacroIDInfo::ReadVal(D));
-
- return M;
-}
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
deleted file mode 100644
index 20692ba5b13d..000000000000
--- a/clang/lib/Basic/TargetInfo.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-//===--- TargetInfo.cpp - Information about Target machine ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the TargetInfo and TargetInfoImpl interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/STLExtras.h"
-#include <cstdlib>
-using namespace clang;
-
-// TargetInfo Constructor.
-TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
- // Set defaults. Defaults are set for a 32-bit RISC platform,
- // like PPC or SPARC.
- // These should be overridden by concrete targets as needed.
- CharIsSigned = true;
- PointerWidth = PointerAlign = 32;
- WCharWidth = WCharAlign = 32;
- IntWidth = IntAlign = 32;
- LongWidth = LongAlign = 32;
- LongLongWidth = LongLongAlign = 64;
- FloatWidth = 32;
- FloatAlign = 32;
- DoubleWidth = 64;
- DoubleAlign = 64;
- LongDoubleWidth = 64;
- LongDoubleAlign = 64;
- FloatFormat = &llvm::APFloat::IEEEsingle;
- DoubleFormat = &llvm::APFloat::IEEEdouble;
- LongDoubleFormat = &llvm::APFloat::IEEEdouble;
- DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64";
- UserLabelPrefix = "_";
-}
-
-// Out of line virtual dtor for TargetInfo.
-TargetInfo::~TargetInfo() {}
-
-//===----------------------------------------------------------------------===//
-
-
-static void removeGCCRegisterPrefix(const char *&Name) {
- if (Name[0] == '%' || Name[0] == '#')
- Name++;
-}
-
-/// isValidGCCRegisterName - Returns whether the passed in string
-/// is a valid register name according to GCC. This is used by Sema for
-/// inline asm statements.
-bool TargetInfo::isValidGCCRegisterName(const char *Name) const {
- const char * const *Names;
- unsigned NumNames;
-
- // Get rid of any register prefix.
- removeGCCRegisterPrefix(Name);
-
-
- if (strcmp(Name, "memory") == 0 ||
- strcmp(Name, "cc") == 0)
- return true;
-
- getGCCRegNames(Names, NumNames);
-
- // If we have a number it maps to an entry in the register name array.
- if (isdigit(Name[0])) {
- char *End;
- int n = (int)strtol(Name, &End, 0);
- if (*End == 0)
- return n >= 0 && (unsigned)n < NumNames;
- }
-
- // Check register names.
- for (unsigned i = 0; i < NumNames; i++) {
- if (strcmp(Name, Names[i]) == 0)
- return true;
- }
-
- // Now check aliases.
- const GCCRegAlias *Aliases;
- unsigned NumAliases;
-
- getGCCRegAliases(Aliases, NumAliases);
- for (unsigned i = 0; i < NumAliases; i++) {
- for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
- if (!Aliases[i].Aliases[j])
- break;
- if (strcmp(Aliases[i].Aliases[j], Name) == 0)
- return true;
- }
- }
-
- return false;
-}
-
-const char *TargetInfo::getNormalizedGCCRegisterName(const char *Name) const {
- assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
-
- removeGCCRegisterPrefix(Name);
-
- const char * const *Names;
- unsigned NumNames;
-
- getGCCRegNames(Names, NumNames);
-
- // First, check if we have a number.
- if (isdigit(Name[0])) {
- char *End;
- int n = (int)strtol(Name, &End, 0);
- if (*End == 0) {
- assert(n >= 0 && (unsigned)n < NumNames &&
- "Out of bounds register number!");
- return Names[n];
- }
- }
-
- // Now check aliases.
- const GCCRegAlias *Aliases;
- unsigned NumAliases;
-
- getGCCRegAliases(Aliases, NumAliases);
- for (unsigned i = 0; i < NumAliases; i++) {
- for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
- if (!Aliases[i].Aliases[j])
- break;
- if (strcmp(Aliases[i].Aliases[j], Name) == 0)
- return Aliases[i].Register;
- }
- }
-
- return Name;
-}
-
-bool TargetInfo::validateOutputConstraint(const char *Name,
- ConstraintInfo &info) const
-{
- // An output constraint must start with '=' or '+'
- if (*Name != '=' && *Name != '+')
- return false;
-
- if (*Name == '+')
- info = CI_ReadWrite;
- else
- info = CI_None;
-
- Name++;
- while (*Name) {
- switch (*Name) {
- default:
- if (!validateAsmConstraint(*Name, info)) {
- // FIXME: We temporarily return false
- // so we can add more constraints as we hit it.
- // Eventually, an unknown constraint should just be treated as 'g'.
- return false;
- }
- case '&': // early clobber.
- break;
- case 'r': // general register.
- info = (ConstraintInfo)(info|CI_AllowsRegister);
- break;
- case 'm': // memory operand.
- info = (ConstraintInfo)(info|CI_AllowsMemory);
- break;
- case 'g': // general register, memory operand or immediate integer.
- info = (ConstraintInfo)(info|CI_AllowsMemory|CI_AllowsRegister);
- break;
- }
-
- Name++;
- }
-
- return true;
-}
-
-bool TargetInfo::validateInputConstraint(const char *Name,
- unsigned NumOutputs,
- ConstraintInfo &info) const {
- while (*Name) {
- switch (*Name) {
- default:
- // Check if we have a matching constraint
- if (*Name >= '0' && *Name <= '9') {
- unsigned i = *Name - '0';
-
- // Check if matching constraint is out of bounds.
- if (i >= NumOutputs)
- return false;
- } else if (!validateAsmConstraint(*Name, info)) {
- // FIXME: This error return is in place temporarily so we can
- // add more constraints as we hit it. Eventually, an unknown
- // constraint should just be treated as 'g'.
- return false;
- }
- case '%': // commutative
- // FIXME: Fail if % is used with the last operand.
- break;
- case 'i': // immediate integer.
- case 'I':
- case 'n': // immediate integer with a known value.
- break;
- case 'r': // general register.
- info = (ConstraintInfo)(info|CI_AllowsRegister);
- break;
- case 'm': // memory operand.
- info = (ConstraintInfo)(info|CI_AllowsMemory);
- break;
- case 'g': // general register, memory operand or immediate integer.
- info = (ConstraintInfo)(info|CI_AllowsMemory|CI_AllowsRegister);
- break;
- }
-
- Name++;
- }
-
- return true;
-}
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
deleted file mode 100644
index 531d0520ccf1..000000000000
--- a/clang/lib/Basic/Targets.cpp
+++ /dev/null
@@ -1,856 +0,0 @@
-//===--- Targets.cpp - Implement -arch option and targets -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements construction of a TargetInfo object from a
-// target triple.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Builtins.h"
-#include "clang/AST/TargetBuiltins.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/APFloat.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Common code shared among targets.
-//===----------------------------------------------------------------------===//
-
-static void Define(std::vector<char> &Buf, const char *Macro,
- const char *Val = "1") {
- const char *Def = "#define ";
- Buf.insert(Buf.end(), Def, Def+strlen(Def));
- Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
- Buf.push_back(' ');
- Buf.insert(Buf.end(), Val, Val+strlen(Val));
- Buf.push_back('\n');
-}
-
-//===----------------------------------------------------------------------===//
-// Defines specific to certain operating systems.
-//===----------------------------------------------------------------------===//
-
-static void getSolarisDefines(std::vector<char> &Defs) {
- Define(Defs, "__SUN__");
- Define(Defs, "__SOLARIS__");
-}
-
-static void getDragonFlyDefines(std::vector<char> &Defs) {
- // DragonFly defines; list based off of gcc output
- Define(Defs, "__DragonFly__");
- Define(Defs, "__DragonFly_cc_version", "100001");
- Define(Defs, "__ELF__");
- Define(Defs, "__KPRINTF_ATTRIBUTE__");
- Define(Defs, "__tune_i386__");
- Define(Defs, "unix");
- Define(Defs, "__unix");
- Define(Defs, "__unix__");
-}
-
-static void getLinuxDefines(std::vector<char> &Defs) {
- // Linux defines; list based off of gcc output
- Define(Defs, "__unix__");
- Define(Defs, "__unix");
- Define(Defs, "unix");
- Define(Defs, "__linux__");
- Define(Defs, "__linux");
- Define(Defs, "linux");
- Define(Defs, "__gnu_linux__");
-}
-
-static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
- Define(Defs, "__APPLE__");
- Define(Defs, "__MACH__");
-
- // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
- const char *Darwin = strstr(Triple, "-darwin");
- if (Darwin) {
- char DarwinStr[] = "1000";
- Darwin += strlen("-darwin");
- if (Darwin[0] >= '0' && Darwin[0] <= '9') {
- unsigned DarwinNo = Darwin[0]-'0';
- ++Darwin;
-
- // Handle "darwin11".
- if (DarwinNo == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
- DarwinNo = 10+Darwin[0]-'0';
- ++Darwin;
- }
-
- if (DarwinNo >= 4 && DarwinNo <= 13) { // 10.0-10.9
- // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
- DarwinStr[2] = '0' + DarwinNo-4;
- }
-
- // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
- if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
- Darwin[2] == '\0')
- DarwinStr[3] = Darwin[1];
-
- }
- Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Defines specific to certain architectures.
-//===----------------------------------------------------------------------===//
-
-/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
-/// not tied to a specific subtarget.
-static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
- // Target identification.
- Define(Defs, "__ppc__");
- Define(Defs, "_ARCH_PPC");
- Define(Defs, "__POWERPC__");
- if (is64Bit) {
- Define(Defs, "_ARCH_PPC64");
- Define(Defs, "_LP64");
- Define(Defs, "__LP64__");
- Define(Defs, "__ppc64__");
- } else {
- Define(Defs, "__ppc__");
- }
-
- // Target properties.
- Define(Defs, "_BIG_ENDIAN");
- Define(Defs, "__BIG_ENDIAN__");
-
- // Subtarget options.
- Define(Defs, "__NATURAL_ALIGNMENT__");
- Define(Defs, "__REGISTER_PREFIX__", "");
-
- // FIXME: Should be controlled by command line option.
- Define(Defs, "__LONG_DOUBLE_128__");
-}
-
-/// getX86Defines - Return a set of the X86-specific #defines that are
-/// not tied to a specific subtarget.
-static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
- // Target identification.
- if (is64Bit) {
- Define(Defs, "_LP64");
- Define(Defs, "__LP64__");
- Define(Defs, "__amd64__");
- Define(Defs, "__amd64");
- Define(Defs, "__x86_64");
- Define(Defs, "__x86_64__");
- } else {
- Define(Defs, "__i386__");
- Define(Defs, "__i386");
- Define(Defs, "i386");
- }
-
- // Target properties.
- Define(Defs, "__LITTLE_ENDIAN__");
-
- // Subtarget options.
- Define(Defs, "__nocona");
- Define(Defs, "__nocona__");
- Define(Defs, "__tune_nocona__");
- Define(Defs, "__SSE2_MATH__");
- Define(Defs, "__SSE2__");
- Define(Defs, "__SSE_MATH__");
- Define(Defs, "__SSE__");
- Define(Defs, "__MMX__");
- Define(Defs, "__REGISTER_PREFIX__", "");
-}
-
-/// getARMDefines - Return a set of the ARM-specific #defines that are
-/// not tied to a specific subtarget.
-static void getARMDefines(std::vector<char> &Defs) {
- // Target identification.
- Define(Defs, "__arm");
- Define(Defs, "__arm__");
-
- // Target properties.
- Define(Defs, "__LITTLE_ENDIAN__");
-
- // Subtarget options. [hard coded to v6 for now]
- Define(Defs, "__ARM_ARCH_6K__");
- Define(Defs, "__ARMEL__");
- Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
-}
-
-//===----------------------------------------------------------------------===//
-// Specific target implementations.
-//===----------------------------------------------------------------------===//
-
-namespace {
-// PPC abstract base class
-class PPCTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
- static const char * const GCCRegNames[];
- static const TargetInfo::GCCRegAlias GCCRegAliases[];
-
-public:
- PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
- CharIsSigned = false;
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- Records = BuiltinInfo;
- NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
- }
- virtual const char *getVAListDeclaration() const {
- return "typedef struct __va_list_tag {"
- " unsigned char gpr;"
- " unsigned char fpr;"
- " unsigned short reserved;"
- " void* overflow_arg_area;"
- " void* reg_save_area;"
- "} __builtin_va_list[1];";
- }
- virtual const char *getTargetPrefix() const {
- return "ppc";
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const;
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const;
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- switch (c) {
- default: return false;
- case 'O': // Zero
- return true;
- case 'b': // Base register
- case 'f': // Floating point register
- info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
- return true;
- }
- }
- virtual const char *getClobbers() const {
- return "";
- }
-};
-
-const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
-#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
-#include "clang/AST/PPCBuiltins.def"
-};
-
-const char * const PPCTargetInfo::GCCRegNames[] = {
- "0", "1", "2", "3", "4", "5", "6", "7",
- "8", "9", "10", "11", "12", "13", "14", "15",
- "16", "17", "18", "19", "20", "21", "22", "23",
- "24", "25", "26", "27", "28", "29", "30", "31",
- "0", "1", "2", "3", "4", "5", "6", "7",
- "8", "9", "10", "11", "12", "13", "14", "15",
- "16", "17", "18", "19", "20", "21", "22", "23",
- "24", "25", "26", "27", "28", "29", "30", "31",
- "mq", "lr", "ctr", "ap",
- "0", "1", "2", "3", "4", "5", "6", "7",
- "xer",
- "0", "1", "2", "3", "4", "5", "6", "7",
- "8", "9", "10", "11", "12", "13", "14", "15",
- "16", "17", "18", "19", "20", "21", "22", "23",
- "24", "25", "26", "27", "28", "29", "30", "31",
- "vrsave", "vscr",
- "spe_acc", "spefscr",
- "sfp"
-};
-
-void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
-}
-
-const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
- // While some of these aliases do map to different registers
- // they still share the same register name.
- { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
- { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
- { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
- { { "cr3", "fr3", "r3", "v3"}, "3" },
- { { "cr4", "fr4", "r4", "v4"}, "4" },
- { { "cr5", "fr5", "r5", "v5"}, "5" },
- { { "cr6", "fr6", "r6", "v6"}, "6" },
- { { "cr7", "fr7", "r7", "v7"}, "7" },
- { { "fr8", "r8", "v8"}, "8" },
- { { "fr9", "r9", "v9"}, "9" },
- { { "fr10", "r10", "v10"}, "10" },
- { { "fr11", "r11", "v11"}, "11" },
- { { "fr12", "r12", "v12"}, "12" },
- { { "fr13", "r13", "v13"}, "13" },
- { { "fr14", "r14", "v14"}, "14" },
- { { "fr15", "r15", "v15"}, "15" },
- { { "fr16", "r16", "v16"}, "16" },
- { { "fr17", "r17", "v17"}, "17" },
- { { "fr18", "r18", "v18"}, "18" },
- { { "fr19", "r19", "v19"}, "19" },
- { { "fr20", "r20", "v20"}, "20" },
- { { "fr21", "r21", "v21"}, "21" },
- { { "fr22", "r22", "v22"}, "22" },
- { { "fr23", "r23", "v23"}, "23" },
- { { "fr24", "r24", "v24"}, "24" },
- { { "fr25", "r25", "v25"}, "25" },
- { { "fr26", "r26", "v26"}, "26" },
- { { "fr27", "r27", "v27"}, "27" },
- { { "fr28", "r28", "v28"}, "28" },
- { { "fr29", "r29", "v29"}, "29" },
- { { "fr30", "r30", "v30"}, "30" },
- { { "fr31", "r31", "v31"}, "31" },
-};
-
-void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- Aliases = GCCRegAliases;
- NumAliases = llvm::array_lengthof(GCCRegAliases);
-}
-} // end anonymous namespace.
-
-namespace {
-class PPC32TargetInfo : public PPCTargetInfo {
-public:
- PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
- DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- getPowerPCDefines(Defines, false);
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class PPC64TargetInfo : public PPCTargetInfo {
-public:
- PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
- DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- getPowerPCDefines(Defines, true);
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class DarwinPPCTargetInfo : public PPC32TargetInfo {
-public:
- DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- PPC32TargetInfo::getTargetDefines(Defines);
- getDarwinDefines(Defines, getTargetTriple());
- }
-
- virtual bool useNeXTRuntimeAsDefault() const { return true; }
-};
-} // end anonymous namespace.
-
-namespace {
-class DarwinPPC64TargetInfo : public PPC64TargetInfo {
-public:
- DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- PPC64TargetInfo::getTargetDefines(Defines);
- getDarwinDefines(Defines, getTargetTriple());
- }
-
- virtual bool useNeXTRuntimeAsDefault() const { return true; }
-};
-} // end anonymous namespace.
-
-namespace {
-// Namespace for x86 abstract base class
-const Builtin::Info BuiltinInfo[] = {
-#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
-#include "clang/AST/X86Builtins.def"
-};
-
-const char *GCCRegNames[] = {
- "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
- "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
- "argp", "flags", "fspr", "dirflag", "frame",
- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
- "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
-};
-
-const TargetInfo::GCCRegAlias GCCRegAliases[] = {
- { { "al", "ah", "eax", "rax" }, "ax" },
- { { "bl", "bh", "ebx", "rbx" }, "bx" },
- { { "cl", "ch", "ecx", "rcx" }, "cx" },
- { { "dl", "dh", "edx", "rdx" }, "dx" },
- { { "esi", "rsi" }, "si" },
- { { "edi", "rdi" }, "di" },
- { { "esp", "rsp" }, "sp" },
- { { "ebp", "rbp" }, "bp" },
-};
-
-// X86 target abstract base class; x86-32 and x86-64 are very close, so
-// most of the implementation can be shared.
-class X86TargetInfo : public TargetInfo {
-public:
- X86TargetInfo(const std::string& triple) : TargetInfo(triple) {
- LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- Records = BuiltinInfo;
- NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
- }
- virtual const char *getTargetPrefix() const {
- return "x86";
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- Aliases = GCCRegAliases;
- NumAliases = llvm::array_lengthof(GCCRegAliases);
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const;
- virtual std::string convertConstraint(const char Constraint) const;
- virtual const char *getClobbers() const {
- return "~{dirflag},~{fpsr},~{flags}";
- }
-};
-
-bool
-X86TargetInfo::validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- switch (c) {
- default: return false;
- case 'a': // eax.
- case 'b': // ebx.
- case 'c': // ecx.
- case 'd': // edx.
- case 'S': // esi.
- case 'D': // edi.
- case 'A': // edx:eax.
- case 't': // top of floating point stack.
- case 'u': // second from top of floating point stack.
- case 'q': // Any register accessible as [r]l: a, b, c, and d.
- case 'y': // Any MMX register.
- case 'x': // Any SSE register.
- case 'Q': // Any register accessible as [r]h: a, b, c, and d.
- case 'Z': // 32-bit integer constant for use with zero-extending x86_64
- // instructions.
- case 'N': // unsigned 8-bit integer constant for use with in and out
- // instructions.
- info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
- return true;
- }
-}
-
-std::string
-X86TargetInfo::convertConstraint(const char Constraint) const {
- switch (Constraint) {
- case 'a': return std::string("{ax}");
- case 'b': return std::string("{bx}");
- case 'c': return std::string("{cx}");
- case 'd': return std::string("{dx}");
- case 'S': return std::string("{si}");
- case 'D': return std::string("{di}");
- case 't': // top of floating point stack.
- return std::string("{st}");
- case 'u': // second from top of floating point stack.
- return std::string("{st(1)}"); // second from top of floating point stack.
- default:
- return std::string(1, Constraint);
- }
-}
-} // end anonymous namespace
-
-namespace {
-// X86-32 generic target
-class X86_32TargetInfo : public X86TargetInfo {
-public:
- X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
- DoubleAlign = LongLongAlign = 32;
- LongDoubleWidth = 96;
- LongDoubleAlign = 32;
- DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
- "a0:0:64-f80:32:32";
- }
- virtual const char *getVAListDeclaration() const {
- return "typedef char* __builtin_va_list;";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- getX86Defines(Defines, false);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-32 Darwin (OS X) target
-class DarwinI386TargetInfo : public X86_32TargetInfo {
-public:
- DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
- LongDoubleWidth = 128;
- LongDoubleAlign = 128;
- DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
- "a0:0:64-f80:128:128";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Defines);
- getDarwinDefines(Defines, getTargetTriple());
- }
- virtual bool useNeXTRuntimeAsDefault() const { return true; }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-32 DragonFly target
-class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
-public:
- DragonFlyX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Defines);
- getDragonFlyDefines(Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-32 Linux target
-class LinuxX86_32TargetInfo : public X86_32TargetInfo {
-public:
- LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
- UserLabelPrefix = "";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Defines);
- getLinuxDefines(Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-32 Windows target
-class WindowsX86_32TargetInfo : public X86_32TargetInfo {
-public:
- WindowsX86_32TargetInfo(const std::string& triple)
- : X86_32TargetInfo(triple) {
- // FIXME: Fix wchar_t.
- // FIXME: We should probably enable -fms-extensions by default for
- // this target.
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Defines);
- // This list is based off of the the list of things MingW defines
- Define(Defines, "__WIN32__");
- Define(Defines, "__WIN32");
- Define(Defines, "_WIN32");
- Define(Defines, "WIN32");
- Define(Defines, "__WINNT__");
- Define(Defines, "__WINNT");
- Define(Defines, "WINNT");
- Define(Defines, "_X86_");
- Define(Defines, "__MSVCRT__");
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-64 generic target
-class X86_64TargetInfo : public X86TargetInfo {
-public:
- X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
- LongDoubleWidth = 128;
- LongDoubleAlign = 128;
- DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
- "a0:0:64-f80:128:128";
- }
- virtual const char *getVAListDeclaration() const {
- return "typedef struct __va_list_tag {"
- " unsigned gp_offset;"
- " unsigned fp_offset;"
- " void* overflow_arg_area;"
- " void* reg_save_area;"
- "} __builtin_va_list[1];";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- getX86Defines(Defines, true);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-64 Linux target
-class LinuxX86_64TargetInfo : public X86_64TargetInfo {
-public:
- LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
- UserLabelPrefix = "";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- X86_64TargetInfo::getTargetDefines(Defines);
- getLinuxDefines(Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-64 Darwin (OS X) target
-class DarwinX86_64TargetInfo : public X86_64TargetInfo {
-public:
- DarwinX86_64TargetInfo(const std::string& triple) :
- X86_64TargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- X86_64TargetInfo::getTargetDefines(Defines);
- getDarwinDefines(Defines, getTargetTriple());
- }
-
- virtual bool useNeXTRuntimeAsDefault() const { return true; }
-};
-} // end anonymous namespace.
-
-namespace {
-class ARMTargetInfo : public TargetInfo {
-public:
- ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
- // FIXME: Are the defaults correct for ARM?
- DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- getARMDefines(Defines);
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- // FIXME: Implement.
- Records = 0;
- NumRecords = 0;
- }
- virtual const char *getVAListDeclaration() const {
- return "typedef char* __builtin_va_list;";
- }
- virtual const char *getTargetPrefix() const {
- return "arm";
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- // FIXME: Implement.
- Names = 0;
- NumNames = 0;
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- // FIXME: Implement.
- Aliases = 0;
- NumAliases = 0;
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- // FIXME: Check if this is complete
- switch (c) {
- default:
- case 'l': // r0-r7
- case 'h': // r8-r15
- case 'w': // VFP Floating point register single precision
- case 'P': // VFP Floating point register double precision
- info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
- return true;
- }
- return false;
- }
- virtual const char *getClobbers() const {
- // FIXME: Is this really right?
- return "";
- }
-};
-} // end anonymous namespace.
-
-
-namespace {
-class DarwinARMTargetInfo : public ARMTargetInfo {
-public:
- DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- ARMTargetInfo::getTargetDefines(Defines);
- getDarwinDefines(Defines, getTargetTriple());
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class SparcV8TargetInfo : public TargetInfo {
-public:
- SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
- // FIXME: Support Sparc quad-precision long double?
- DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
- }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- // FIXME: This is missing a lot of important defines; some of the
- // missing stuff is likely to break system headers.
- Define(Defines, "__sparc");
- Define(Defines, "__sparc__");
- Define(Defines, "__sparcv8");
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- // FIXME: Implement!
- }
- virtual const char *getVAListDeclaration() const {
- return "typedef void* __builtin_va_list;";
- }
- virtual const char *getTargetPrefix() const {
- return "sparc";
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- // FIXME: Implement!
- Names = 0;
- NumNames = 0;
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- // FIXME: Implement!
- Aliases = 0;
- NumAliases = 0;
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- // FIXME: Implement!
- return false;
- }
- virtual const char *getClobbers() const {
- // FIXME: Implement!
- return "";
- }
-};
-
-} // end anonymous namespace.
-
-namespace {
-class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
-public:
- SolarisSparcV8TargetInfo(const std::string& triple) :
- SparcV8TargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- SparcV8TargetInfo::getTargetDefines(Defines);
- getSolarisDefines(Defines);
- }
-};
-} // end anonymous namespace.
-
-namespace {
- class PIC16TargetInfo : public TargetInfo{
- public:
- PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
- // FIXME: Is IntAlign really supposed to be 16? There seems
- // little point on a platform with 8-bit loads.
- IntWidth = IntAlign = LongAlign = LongLongAlign = PointerWidth = 16;
- LongWidth = 16;
- PointerAlign = 8;
- DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
- }
- virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
- virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- Define(Defines, "__pic16");
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {}
- virtual const char *getVAListDeclaration() const { return "";}
- virtual const char *getClobbers() const {return "";}
- virtual const char *getTargetPrefix() const {return "";}
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {}
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- return true;
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {}
- virtual bool useGlobalsForAutomaticVariables() const {return true;}
- };
-}
-
-//===----------------------------------------------------------------------===//
-// Driver code
-//===----------------------------------------------------------------------===//
-
-static inline bool IsX86(const std::string& TT) {
- return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
- TT[4] == '-' && TT[1] - '3' < 6);
-}
-
-/// CreateTargetInfo - Return the target info object for the specified target
-/// triple.
-TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
- // OS detection; this isn't really anywhere near complete.
- // Additions and corrections are welcome.
- bool isDarwin = T.find("-darwin") != std::string::npos;
- bool isDragonFly = T.find("-dragonfly") != std::string::npos;
- bool isSolaris = T.find("-solaris") != std::string::npos;
- bool isLinux = T.find("-linux") != std::string::npos;
- bool isWindows = T.find("-windows") != std::string::npos ||
- T.find("-win32") != std::string::npos ||
- T.find("-mingw") != std::string::npos;
-
- if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
- if (isDarwin)
- return new DarwinPPCTargetInfo(T);
- return new PPC32TargetInfo(T);
- }
-
- if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
- if (isDarwin)
- return new DarwinPPC64TargetInfo(T);
- return new PPC64TargetInfo(T);
- }
-
- if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
- if (isDarwin)
- return new DarwinARMTargetInfo(T);
- return new ARMTargetInfo(T);
- }
-
- if (T.find("sparc-") == 0) {
- if (isSolaris)
- return new SolarisSparcV8TargetInfo(T);
- return new SparcV8TargetInfo(T);
- }
-
- if (T.find("x86_64-") == 0) {
- if (isDarwin)
- return new DarwinX86_64TargetInfo(T);
- if (isLinux)
- return new LinuxX86_64TargetInfo(T);
- return new X86_64TargetInfo(T);
- }
-
- if (T.find("pic16-") == 0)
- return new PIC16TargetInfo(T);
-
- if (IsX86(T)) {
- if (isDarwin)
- return new DarwinI386TargetInfo(T);
- if (isLinux)
- return new LinuxX86_32TargetInfo(T);
- if (isDragonFly)
- return new DragonFlyX86_32TargetInfo(T);
- if (isWindows)
- return new WindowsX86_32TargetInfo(T);
- return new X86_32TargetInfo(T);
- }
-
- return NULL;
-}
-
diff --git a/clang/lib/Basic/TokenKinds.cpp b/clang/lib/Basic/TokenKinds.cpp
deleted file mode 100644
index bde8a5598b4b..000000000000
--- a/clang/lib/Basic/TokenKinds.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===--- TokenKinds.cpp - Token Kinds Support -----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the TokenKind enum and support functions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/TokenKinds.h"
-
-#include <cassert>
-using namespace clang;
-
-static const char * const TokNames[] = {
-#define TOK(X) #X,
-#define KEYWORD(X,Y) #X,
-#include "clang/Basic/TokenKinds.def"
- 0
-};
-
-const char *tok::getTokenName(enum TokenKind Kind) {
- assert(Kind < tok::NUM_TOKENS);
- return TokNames[Kind];
-}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
deleted file mode 100644
index 29d77b6e82b3..000000000000
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ /dev/null
@@ -1,952 +0,0 @@
-//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
-//
-// 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 emit Builtin calls as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/TargetBuiltins.h"
-#include "llvm/Intrinsics.h"
-using namespace clang;
-using namespace CodeGen;
-using namespace llvm;
-
-/// Utility to insert an atomic instruction based Instrinsic::ID and
-// the expression node
-static RValue EmitBinaryAtomic(CodeGenFunction& CFG,
- Intrinsic::ID Id, const CallExpr *E) {
- const llvm::Type *ResType[2];
- ResType[0] = CFG.ConvertType(E->getType());
- ResType[1] = CFG.ConvertType(E->getArg(0)->getType());
- Value *AtomF = CFG.CGM.getIntrinsic(Id, ResType, 2);
- return RValue::get(CFG.Builder.CreateCall2(AtomF,
- CFG.EmitScalarExpr(E->getArg(0)),
- CFG.EmitScalarExpr(E->getArg(1))));
-}
-
-RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
- // See if we can constant fold this builtin. If so, don't emit it at all.
- APValue Result;
- if (E->tryEvaluate(Result, CGM.getContext())) {
- if (Result.isInt())
- return RValue::get(llvm::ConstantInt::get(Result.getInt()));
- assert(Result.isFloat() && "Unsupported constant type");
- return RValue::get(llvm::ConstantFP::get(Result.getFloat()));
- }
-
- switch (BuiltinID) {
- default: break; // Handle intrinsics and libm functions below.
- case Builtin::BI__builtin___CFStringMakeConstantString:
- return RValue::get(CGM.EmitConstantExpr(E, 0));
- case Builtin::BI__builtin_stdarg_start:
- case Builtin::BI__builtin_va_start:
- case Builtin::BI__builtin_va_end: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
- const llvm::Type *DestType =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- if (ArgValue->getType() != DestType)
- ArgValue = Builder.CreateBitCast(ArgValue, DestType,
- ArgValue->getNameStart());
-
- Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ?
- Intrinsic::vaend : Intrinsic::vastart;
- return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
- }
- case Builtin::BI__builtin_va_copy: {
- // FIXME: This does not yet handle architectures where va_list is a struct.
- Value *DstPtr = EmitScalarExpr(E->getArg(0));
- Value *SrcValue = EmitScalarExpr(E->getArg(1));
-
- Value *SrcPtr = CreateTempAlloca(SrcValue->getType(), "dst_ptr");
-
- Builder.CreateStore(SrcValue, SrcPtr, false);
-
- const llvm::Type *Type =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-
- DstPtr = Builder.CreateBitCast(DstPtr, Type);
- SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
- return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy),
- DstPtr, SrcPtr));
- }
- case Builtin::BI__builtin_abs: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
- Value *CmpResult =
- Builder.CreateICmpSGE(ArgValue, Constant::getNullValue(ArgValue->getType()),
- "abscond");
- Value *Result =
- Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
-
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_ctz:
- case Builtin::BI__builtin_ctzl:
- case Builtin::BI__builtin_ctzll: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
- if (Result->getType() != ResultType)
- Result = Builder.CreateIntCast(Result, ResultType, "cast");
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_clz:
- case Builtin::BI__builtin_clzl:
- case Builtin::BI__builtin_clzll: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1);
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
- if (Result->getType() != ResultType)
- Result = Builder.CreateIntCast(Result, ResultType, "cast");
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_ffs:
- case Builtin::BI__builtin_ffsl:
- case Builtin::BI__builtin_ffsll: {
- // ffs(x) -> x ? cttz(x) + 1 : 0
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"),
- ConstantInt::get(ArgType, 1), "tmp");
- Value *Zero = llvm::Constant::getNullValue(ArgType);
- Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
- Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
- if (Result->getType() != ResultType)
- Result = Builder.CreateIntCast(Result, ResultType, "cast");
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_parity:
- case Builtin::BI__builtin_parityl:
- case Builtin::BI__builtin_parityll: {
- // parity(x) -> ctpop(x) & 1
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp");
- Value *Result = Builder.CreateAnd(Tmp, ConstantInt::get(ArgType, 1),
- "tmp");
- if (Result->getType() != ResultType)
- Result = Builder.CreateIntCast(Result, ResultType, "cast");
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_popcount:
- case Builtin::BI__builtin_popcountl:
- case Builtin::BI__builtin_popcountll: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
- if (Result->getType() != ResultType)
- Result = Builder.CreateIntCast(Result, ResultType, "cast");
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_expect:
- // FIXME: pass expect through to LLVM
- return RValue::get(EmitScalarExpr(E->getArg(0)));
- case Builtin::BI__builtin_bswap32:
- case Builtin::BI__builtin_bswap64: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
- return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
- }
- case Builtin::BI__builtin_object_size: {
- // FIXME: Implement. For now we just always fail and pretend we
- // don't know the object size.
- llvm::APSInt TypeArg =
- E->getArg(1)->getIntegerConstantExprValue(CGM.getContext());
- const llvm::Type *ResType = ConvertType(E->getType());
- // bool UseSubObject = TypeArg.getZExtValue() & 1;
- bool UseMinimum = TypeArg.getZExtValue() & 2;
- return RValue::get(ConstantInt::get(ResType, UseMinimum ? 0 : -1LL));
- }
- case Builtin::BI__builtin_prefetch: {
- Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
- // FIXME: Technically these constants should of type 'int', yes?
- RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
- ConstantInt::get(llvm::Type::Int32Ty, 0);
- Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
- ConstantInt::get(llvm::Type::Int32Ty, 3);
- Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0);
- return RValue::get(Builder.CreateCall3(F, Address, RW, Locality));
- }
- case Builtin::BI__builtin_trap: {
- Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0);
- return RValue::get(Builder.CreateCall(F));
- }
-
- case Builtin::BI__builtin_powi:
- case Builtin::BI__builtin_powif:
- case Builtin::BI__builtin_powil: {
- Value *Base = EmitScalarExpr(E->getArg(0));
- Value *Exponent = EmitScalarExpr(E->getArg(1));
- const llvm::Type *ArgType = Base->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1);
- return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
- }
-
- case Builtin::BI__builtin_isgreater:
- case Builtin::BI__builtin_isgreaterequal:
- case Builtin::BI__builtin_isless:
- case Builtin::BI__builtin_islessequal:
- case Builtin::BI__builtin_islessgreater:
- case Builtin::BI__builtin_isunordered: {
- // Ordered comparisons: we know the arguments to these are matching scalar
- // floating point values.
- Value *LHS = EmitScalarExpr(E->getArg(0));
- Value *RHS = EmitScalarExpr(E->getArg(1));
-
- switch (BuiltinID) {
- default: assert(0 && "Unknown ordered comparison");
- case Builtin::BI__builtin_isgreater:
- LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_isgreaterequal:
- LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_isless:
- LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_islessequal:
- LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_islessgreater:
- LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_isunordered:
- LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
- break;
- }
- // ZExt bool to int type.
- return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
- "tmp"));
- }
- case Builtin::BI__builtin_alloca: {
- // FIXME: LLVM IR Should allow alloca with an i64 size!
- Value *Size = EmitScalarExpr(E->getArg(0));
- Size = Builder.CreateIntCast(Size, llvm::Type::Int32Ty, false, "tmp");
- return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty, Size, "tmp"));
- }
- case Builtin::BI__builtin_bzero: {
- Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemSetFn(), Address,
- llvm::ConstantInt::get(llvm::Type::Int8Ty, 0),
- EmitScalarExpr(E->getArg(1)),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
- return RValue::get(Address);
- }
- case Builtin::BI__builtin_memcpy: {
- Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemCpyFn(), Address,
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
- return RValue::get(Address);
- }
- case Builtin::BI__builtin_memmove: {
- Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemMoveFn(), Address,
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
- return RValue::get(Address);
- }
- case Builtin::BI__builtin_memset: {
- Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemSetFn(), Address,
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
- return RValue::get(Address);
- }
- case Builtin::BI__builtin_return_address: {
- Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0);
- return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0))));
- }
- case Builtin::BI__builtin_frame_address: {
- Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
- return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0))));
- }
- case Builtin::BI__sync_fetch_and_add:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E);
- case Builtin::BI__sync_fetch_and_sub:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E);
- case Builtin::BI__sync_fetch_and_min:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E);
- case Builtin::BI__sync_fetch_and_max:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E);
- case Builtin::BI__sync_fetch_and_umin:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E);
- case Builtin::BI__sync_fetch_and_umax:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E);
- case Builtin::BI__sync_fetch_and_and:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E);
- case Builtin::BI__sync_fetch_and_or:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E);
- case Builtin::BI__sync_fetch_and_xor:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E);
- case Builtin::BI__sync_val_compare_and_swap: {
- const llvm::Type *ResType[2];
- ResType[0]= ConvertType(E->getType());
- ResType[1] = ConvertType(E->getArg(0)->getType());
- Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
- return RValue::get(Builder.CreateCall3(AtomF,
- EmitScalarExpr(E->getArg(0)),
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2))));
- }
- case Builtin::BI__sync_lock_test_and_set:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
- }
-
- // If this is an alias for a libm function (e.g. __builtin_sin) turn it into
- // that function.
- if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
- return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID),
- E->getCallee()->getType(), E->arg_begin(),
- E->arg_end());
-
- // See if we have a target specific intrinsic.
- Intrinsic::ID IntrinsicID;
- const char *TargetPrefix = Target.getTargetPrefix();
- const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
-#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-#include "llvm/Intrinsics.gen"
-#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-
- if (IntrinsicID != Intrinsic::not_intrinsic) {
- SmallVector<Value*, 16> Args;
-
- Function *F = CGM.getIntrinsic(IntrinsicID);
- const llvm::FunctionType *FTy = F->getFunctionType();
-
- for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
- Value *ArgValue = EmitScalarExpr(E->getArg(i));
-
- // If the intrinsic arg type is different from the builtin arg type
- // we need to do a bit cast.
- const llvm::Type *PTy = FTy->getParamType(i);
- if (PTy != ArgValue->getType()) {
- assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
- "Must be able to losslessly bit cast to param");
- ArgValue = Builder.CreateBitCast(ArgValue, PTy);
- }
-
- Args.push_back(ArgValue);
- }
-
- Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
- QualType BuiltinRetType = E->getType();
-
- const llvm::Type *RetTy = llvm::Type::VoidTy;
- if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
-
- if (RetTy != V->getType()) {
- assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
- "Must be able to losslessly bit cast result type");
- V = Builder.CreateBitCast(V, RetTy);
- }
-
- return RValue::get(V);
- }
-
- // See if we have a target specific builtin that needs to be lowered.
- Value *V = 0;
-
- if (strcmp(TargetPrefix, "x86") == 0)
- V = EmitX86BuiltinExpr(BuiltinID, E);
- else if (strcmp(TargetPrefix, "ppc") == 0)
- V = EmitPPCBuiltinExpr(BuiltinID, E);
-
- if (V)
- return RValue::get(V);
-
- ErrorUnsupported(E, "builtin function");
-
- // Unknown builtin, for now just dump it out and return undef.
- if (hasAggregateLLVMType(E->getType()))
- return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
- return RValue::get(UndefValue::get(ConvertType(E->getType())));
-}
-
-Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
- const CallExpr *E) {
-
- llvm::SmallVector<Value*, 4> Ops;
-
- for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
- Ops.push_back(EmitScalarExpr(E->getArg(i)));
-
- switch (BuiltinID) {
- default: return 0;
- case X86::BI__builtin_ia32_mulps:
- return Builder.CreateMul(Ops[0], Ops[1], "mulps");
- case X86::BI__builtin_ia32_mulpd:
- return Builder.CreateMul(Ops[0], Ops[1], "mulpd");
- case X86::BI__builtin_ia32_pand:
- case X86::BI__builtin_ia32_pand128:
- return Builder.CreateAnd(Ops[0], Ops[1], "pand");
- case X86::BI__builtin_ia32_por:
- case X86::BI__builtin_ia32_por128:
- return Builder.CreateOr(Ops[0], Ops[1], "por");
- case X86::BI__builtin_ia32_pxor:
- case X86::BI__builtin_ia32_pxor128:
- return Builder.CreateXor(Ops[0], Ops[1], "pxor");
- case X86::BI__builtin_ia32_pandn:
- case X86::BI__builtin_ia32_pandn128:
- Ops[0] = Builder.CreateNot(Ops[0], "tmp");
- return Builder.CreateAnd(Ops[0], Ops[1], "pandn");
- case X86::BI__builtin_ia32_paddb:
- case X86::BI__builtin_ia32_paddb128:
- case X86::BI__builtin_ia32_paddd:
- case X86::BI__builtin_ia32_paddd128:
- case X86::BI__builtin_ia32_paddq:
- case X86::BI__builtin_ia32_paddq128:
- case X86::BI__builtin_ia32_paddw:
- case X86::BI__builtin_ia32_paddw128:
- case X86::BI__builtin_ia32_addps:
- case X86::BI__builtin_ia32_addpd:
- return Builder.CreateAdd(Ops[0], Ops[1], "add");
- case X86::BI__builtin_ia32_psubb:
- case X86::BI__builtin_ia32_psubb128:
- case X86::BI__builtin_ia32_psubd:
- case X86::BI__builtin_ia32_psubd128:
- case X86::BI__builtin_ia32_psubq:
- case X86::BI__builtin_ia32_psubq128:
- case X86::BI__builtin_ia32_psubw:
- case X86::BI__builtin_ia32_psubw128:
- case X86::BI__builtin_ia32_subps:
- case X86::BI__builtin_ia32_subpd:
- return Builder.CreateSub(Ops[0], Ops[1], "sub");
- case X86::BI__builtin_ia32_divps:
- return Builder.CreateFDiv(Ops[0], Ops[1], "divps");
- case X86::BI__builtin_ia32_divpd:
- return Builder.CreateFDiv(Ops[0], Ops[1], "divpd");
- case X86::BI__builtin_ia32_pmullw:
- case X86::BI__builtin_ia32_pmullw128:
- return Builder.CreateMul(Ops[0], Ops[1], "pmul");
- case X86::BI__builtin_ia32_punpckhbw:
- return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15,
- "punpckhbw");
- case X86::BI__builtin_ia32_punpckhbw128:
- return EmitShuffleVector(Ops[0], Ops[1], 8, 24, 9, 25, 10, 26, 11, 27,
- 12, 28, 13, 29, 14, 30, 15, 31,
- "punpckhbw");
- case X86::BI__builtin_ia32_punpckhwd:
- return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhwd");
- case X86::BI__builtin_ia32_punpckhwd128:
- return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15,
- "punpckhwd");
- case X86::BI__builtin_ia32_punpckhdq:
- return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhdq");
- case X86::BI__builtin_ia32_punpckhdq128:
- return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhdq");
- case X86::BI__builtin_ia32_punpckhqdq128:
- return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhqdq");
- case X86::BI__builtin_ia32_punpcklbw:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11,
- "punpcklbw");
- case X86::BI__builtin_ia32_punpcklwd:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpcklwd");
- case X86::BI__builtin_ia32_punpckldq:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpckldq");
- case X86::BI__builtin_ia32_punpckldq128:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpckldq");
- case X86::BI__builtin_ia32_punpcklqdq128:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpcklqdq");
- case X86::BI__builtin_ia32_pslldi128:
- case X86::BI__builtin_ia32_psllqi128:
- case X86::BI__builtin_ia32_psllwi128:
- case X86::BI__builtin_ia32_psradi128:
- case X86::BI__builtin_ia32_psrawi128:
- case X86::BI__builtin_ia32_psrldi128:
- case X86::BI__builtin_ia32_psrlqi128:
- case X86::BI__builtin_ia32_psrlwi128: {
- Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
- const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2);
- llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty),
- Ops[1], Zero, "insert");
- Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
- const char *name = 0;
- Intrinsic::ID ID = Intrinsic::not_intrinsic;
-
- switch (BuiltinID) {
- default: assert(0 && "Unsupported shift intrinsic!");
- case X86::BI__builtin_ia32_pslldi128:
- name = "pslldi";
- ID = Intrinsic::x86_sse2_psll_d;
- break;
- case X86::BI__builtin_ia32_psllqi128:
- name = "psllqi";
- ID = Intrinsic::x86_sse2_psll_q;
- break;
- case X86::BI__builtin_ia32_psllwi128:
- name = "psllwi";
- ID = Intrinsic::x86_sse2_psll_w;
- break;
- case X86::BI__builtin_ia32_psradi128:
- name = "psradi";
- ID = Intrinsic::x86_sse2_psra_d;
- break;
- case X86::BI__builtin_ia32_psrawi128:
- name = "psrawi";
- ID = Intrinsic::x86_sse2_psra_w;
- break;
- case X86::BI__builtin_ia32_psrldi128:
- name = "psrldi";
- ID = Intrinsic::x86_sse2_psrl_d;
- break;
- case X86::BI__builtin_ia32_psrlqi128:
- name = "psrlqi";
- ID = Intrinsic::x86_sse2_psrl_q;
- break;
- case X86::BI__builtin_ia32_psrlwi128:
- name = "psrlwi";
- ID = Intrinsic::x86_sse2_psrl_w;
- break;
- }
- llvm::Function *F = CGM.getIntrinsic(ID);
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_pslldi:
- case X86::BI__builtin_ia32_psllqi:
- case X86::BI__builtin_ia32_psllwi:
- case X86::BI__builtin_ia32_psradi:
- case X86::BI__builtin_ia32_psrawi:
- case X86::BI__builtin_ia32_psrldi:
- case X86::BI__builtin_ia32_psrlqi:
- case X86::BI__builtin_ia32_psrlwi: {
- Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
- const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 1);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
- const char *name = 0;
- Intrinsic::ID ID = Intrinsic::not_intrinsic;
-
- switch (BuiltinID) {
- default: assert(0 && "Unsupported shift intrinsic!");
- case X86::BI__builtin_ia32_pslldi:
- name = "pslldi";
- ID = Intrinsic::x86_mmx_psll_d;
- break;
- case X86::BI__builtin_ia32_psllqi:
- name = "psllqi";
- ID = Intrinsic::x86_mmx_psll_q;
- break;
- case X86::BI__builtin_ia32_psllwi:
- name = "psllwi";
- ID = Intrinsic::x86_mmx_psll_w;
- break;
- case X86::BI__builtin_ia32_psradi:
- name = "psradi";
- ID = Intrinsic::x86_mmx_psra_d;
- break;
- case X86::BI__builtin_ia32_psrawi:
- name = "psrawi";
- ID = Intrinsic::x86_mmx_psra_w;
- break;
- case X86::BI__builtin_ia32_psrldi:
- name = "psrldi";
- ID = Intrinsic::x86_mmx_psrl_d;
- break;
- case X86::BI__builtin_ia32_psrlqi:
- name = "psrlqi";
- ID = Intrinsic::x86_mmx_psrl_q;
- break;
- case X86::BI__builtin_ia32_psrlwi:
- name = "psrlwi";
- ID = Intrinsic::x86_mmx_psrl_w;
- break;
- }
- llvm::Function *F = CGM.getIntrinsic(ID);
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_pshuflw: {
- unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[0],
- i & 0x3, (i & 0xc) >> 2,
- (i & 0x30) >> 4, (i & 0xc0) >> 6, 4, 5, 6, 7,
- "pshuflw");
- }
- case X86::BI__builtin_ia32_pshufhw: {
- unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[0], 0, 1, 2, 3,
- 4 + (i & 0x3), 4 + ((i & 0xc) >> 2),
- 4 + ((i & 0x30) >> 4), 4 + ((i & 0xc0) >> 6),
- "pshufhw");
- }
- case X86::BI__builtin_ia32_pshufd: {
- unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[0],
- i & 0x3, (i & 0xc) >> 2,
- (i & 0x30) >> 4, (i & 0xc0) >> 6,
- "pshufd");
- }
- case X86::BI__builtin_ia32_vec_init_v4hi:
- case X86::BI__builtin_ia32_vec_init_v8qi:
- case X86::BI__builtin_ia32_vec_init_v2si:
- return EmitVector(&Ops[0], Ops.size());
- case X86::BI__builtin_ia32_vec_ext_v2si:
- case X86::BI__builtin_ia32_vec_ext_v2di:
- case X86::BI__builtin_ia32_vec_ext_v4sf:
- case X86::BI__builtin_ia32_vec_ext_v4si:
- case X86::BI__builtin_ia32_vec_ext_v2df:
- return Builder.CreateExtractElement(Ops[0], Ops[1], "result");
- case X86::BI__builtin_ia32_cmpordss:
- case X86::BI__builtin_ia32_cmpordsd:
- case X86::BI__builtin_ia32_cmpunordss:
- case X86::BI__builtin_ia32_cmpunordsd:
- case X86::BI__builtin_ia32_cmpeqss:
- case X86::BI__builtin_ia32_cmpeqsd:
- case X86::BI__builtin_ia32_cmpltss:
- case X86::BI__builtin_ia32_cmpltsd:
- case X86::BI__builtin_ia32_cmpless:
- case X86::BI__builtin_ia32_cmplesd:
- case X86::BI__builtin_ia32_cmpneqss:
- case X86::BI__builtin_ia32_cmpneqsd:
- case X86::BI__builtin_ia32_cmpnltss:
- case X86::BI__builtin_ia32_cmpnltsd:
- case X86::BI__builtin_ia32_cmpnless:
- case X86::BI__builtin_ia32_cmpnlesd: {
- unsigned i = 0;
- const char *name = 0;
- switch (BuiltinID) {
- default: assert(0 && "Unknown compare builtin!");
- case X86::BI__builtin_ia32_cmpeqss:
- case X86::BI__builtin_ia32_cmpeqsd:
- i = 0;
- name = "cmpeq";
- break;
- case X86::BI__builtin_ia32_cmpltss:
- case X86::BI__builtin_ia32_cmpltsd:
- i = 1;
- name = "cmplt";
- break;
- case X86::BI__builtin_ia32_cmpless:
- case X86::BI__builtin_ia32_cmplesd:
- i = 2;
- name = "cmple";
- break;
- case X86::BI__builtin_ia32_cmpunordss:
- case X86::BI__builtin_ia32_cmpunordsd:
- i = 3;
- name = "cmpunord";
- break;
- case X86::BI__builtin_ia32_cmpneqss:
- case X86::BI__builtin_ia32_cmpneqsd:
- i = 4;
- name = "cmpneq";
- break;
- case X86::BI__builtin_ia32_cmpnltss:
- case X86::BI__builtin_ia32_cmpnltsd:
- i = 5;
- name = "cmpntl";
- break;
- case X86::BI__builtin_ia32_cmpnless:
- case X86::BI__builtin_ia32_cmpnlesd:
- i = 6;
- name = "cmpnle";
- break;
- case X86::BI__builtin_ia32_cmpordss:
- case X86::BI__builtin_ia32_cmpordsd:
- i = 7;
- name = "cmpord";
- break;
- }
-
- llvm::Function *F;
- if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() ==
- llvm::Type::FloatTy)
- F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
- else
- F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd);
-
- Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_ldmxcsr: {
- llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
- Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp");
- Builder.CreateStore(Ops[0], Tmp);
- return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
- Builder.CreateBitCast(Tmp, PtrTy));
- }
- case X86::BI__builtin_ia32_stmxcsr: {
- llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
- Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp");
- One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
- Builder.CreateBitCast(Tmp, PtrTy));
- return Builder.CreateLoad(Tmp, "stmxcsr");
- }
- case X86::BI__builtin_ia32_cmpordps:
- case X86::BI__builtin_ia32_cmpordpd:
- case X86::BI__builtin_ia32_cmpunordps:
- case X86::BI__builtin_ia32_cmpunordpd:
- case X86::BI__builtin_ia32_cmpeqps:
- case X86::BI__builtin_ia32_cmpeqpd:
- case X86::BI__builtin_ia32_cmpltps:
- case X86::BI__builtin_ia32_cmpltpd:
- case X86::BI__builtin_ia32_cmpleps:
- case X86::BI__builtin_ia32_cmplepd:
- case X86::BI__builtin_ia32_cmpneqps:
- case X86::BI__builtin_ia32_cmpneqpd:
- case X86::BI__builtin_ia32_cmpngtps:
- case X86::BI__builtin_ia32_cmpngtpd:
- case X86::BI__builtin_ia32_cmpnltps:
- case X86::BI__builtin_ia32_cmpnltpd:
- case X86::BI__builtin_ia32_cmpgtps:
- case X86::BI__builtin_ia32_cmpgtpd:
- case X86::BI__builtin_ia32_cmpgeps:
- case X86::BI__builtin_ia32_cmpgepd:
- case X86::BI__builtin_ia32_cmpngeps:
- case X86::BI__builtin_ia32_cmpngepd:
- case X86::BI__builtin_ia32_cmpnleps:
- case X86::BI__builtin_ia32_cmpnlepd: {
- unsigned i = 0;
- const char *name = 0;
- bool ShouldSwap = false;
- switch (BuiltinID) {
- default: assert(0 && "Unknown compare builtin!");
- case X86::BI__builtin_ia32_cmpeqps:
- case X86::BI__builtin_ia32_cmpeqpd: i = 0; name = "cmpeq"; break;
- case X86::BI__builtin_ia32_cmpltps:
- case X86::BI__builtin_ia32_cmpltpd: i = 1; name = "cmplt"; break;
- case X86::BI__builtin_ia32_cmpleps:
- case X86::BI__builtin_ia32_cmplepd: i = 2; name = "cmple"; break;
- case X86::BI__builtin_ia32_cmpunordps:
- case X86::BI__builtin_ia32_cmpunordpd: i = 3; name = "cmpunord"; break;
- case X86::BI__builtin_ia32_cmpneqps:
- case X86::BI__builtin_ia32_cmpneqpd: i = 4; name = "cmpneq"; break;
- case X86::BI__builtin_ia32_cmpnltps:
- case X86::BI__builtin_ia32_cmpnltpd: i = 5; name = "cmpntl"; break;
- case X86::BI__builtin_ia32_cmpnleps:
- case X86::BI__builtin_ia32_cmpnlepd: i = 6; name = "cmpnle"; break;
- case X86::BI__builtin_ia32_cmpordps:
- case X86::BI__builtin_ia32_cmpordpd: i = 7; name = "cmpord"; break;
- case X86::BI__builtin_ia32_cmpgtps:
- case X86::BI__builtin_ia32_cmpgtpd:
- ShouldSwap = true;
- i = 1;
- name = "cmpgt";
- break;
- case X86::BI__builtin_ia32_cmpgeps:
- case X86::BI__builtin_ia32_cmpgepd:
- i = 2;
- name = "cmpge";
- ShouldSwap = true;
- break;
- case X86::BI__builtin_ia32_cmpngtps:
- case X86::BI__builtin_ia32_cmpngtpd:
- i = 5;
- name = "cmpngt";
- ShouldSwap = true;
- break;
- case X86::BI__builtin_ia32_cmpngeps:
- case X86::BI__builtin_ia32_cmpngepd:
- i = 6;
- name = "cmpnge";
- ShouldSwap = true;
- break;
- }
-
- if (ShouldSwap)
- std::swap(Ops[0], Ops[1]);
-
- llvm::Function *F;
- if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() ==
- llvm::Type::FloatTy)
- F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
- else
- F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd);
-
- Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_movss:
- return EmitShuffleVector(Ops[0], Ops[1], 4, 1, 2, 3, "movss");
- case X86::BI__builtin_ia32_shufps: {
- unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[1],
- i & 0x3, (i & 0xc) >> 2,
- ((i & 0x30) >> 4) + 4,
- ((i & 0xc0) >> 6) + 4, "shufps");
- }
- case X86::BI__builtin_ia32_shufpd: {
- unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[1], i & 1, (i & 2) + 2, "shufpd");
- }
- case X86::BI__builtin_ia32_punpcklbw128:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 16, 1, 17, 2, 18, 3, 19,
- 4, 20, 5, 21, 6, 22, 7, 23,
- "punpcklbw");
- case X86::BI__builtin_ia32_punpcklwd128:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11,
- "punpcklwd");
- case X86::BI__builtin_ia32_movlhps:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 1, 4, 5, "movlhps");
- case X86::BI__builtin_ia32_movhlps:
- return EmitShuffleVector(Ops[0], Ops[1], 6, 7, 2, 3, "movhlps");
- case X86::BI__builtin_ia32_unpckhps:
- return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "unpckhps");
- case X86::BI__builtin_ia32_unpcklps:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "unpcklps");
- case X86::BI__builtin_ia32_unpckhpd:
- return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "unpckhpd");
- case X86::BI__builtin_ia32_unpcklpd:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "unpcklpd");
- case X86::BI__builtin_ia32_movsd:
- return EmitShuffleVector(Ops[0], Ops[1], 2, 1, "movsd");
- case X86::BI__builtin_ia32_movqv4si: {
- llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2);
- return Builder.CreateBitCast(Ops[0], Ty);
- }
- case X86::BI__builtin_ia32_loadlps:
- case X86::BI__builtin_ia32_loadhps: {
- // FIXME: This should probably be represented as
- // shuffle (dst, (v4f32 (insert undef, (load i64), 0)), shuf mask hi/lo)
- const llvm::Type *EltTy = llvm::Type::DoubleTy;
- const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
- const llvm::Type *OrigTy = Ops[0]->getType();
- unsigned Index = BuiltinID == X86::BI__builtin_ia32_loadlps ? 0 : 1;
- llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index);
- Ops[1] = Builder.CreateBitCast(Ops[1], llvm::PointerType::getUnqual(EltTy));
- Ops[1] = Builder.CreateLoad(Ops[1], "tmp");
- Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
- Ops[0] = Builder.CreateInsertElement(Ops[0], Ops[1], Idx, "loadps");
- return Builder.CreateBitCast(Ops[0], OrigTy, "loadps");
- }
- case X86::BI__builtin_ia32_loadlpd:
- case X86::BI__builtin_ia32_loadhpd: {
- Ops[1] = Builder.CreateLoad(Ops[1], "tmp");
- unsigned Index = BuiltinID == X86::BI__builtin_ia32_loadlpd ? 0 : 1;
- llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index);
- return Builder.CreateInsertElement(Ops[0], Ops[1], Idx, "loadpd");
- }
- case X86::BI__builtin_ia32_storehps:
- case X86::BI__builtin_ia32_storelps: {
- const llvm::Type *EltTy = llvm::Type::Int64Ty;
- llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
- llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
-
- // cast val v2i64
- Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
-
- // extract (0, 1)
- unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
- llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index);
- Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
-
- // cast pointer to i64 & store
- Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
- return Builder.CreateStore(Ops[1], Ops[0]);
- }
- case X86::BI__builtin_ia32_loadlv4si: {
- // load i64
- const llvm::Type *EltTy = llvm::Type::Int64Ty;
- llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
- Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
- Ops[0] = Builder.CreateLoad(Ops[0], "load");
-
- // scalar to vector: insert i64 into 2 x i64 undef
- llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
- llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- Ops[0] = Builder.CreateInsertElement(llvm::UndefValue::get(VecTy),
- Ops[0], Zero, "s2v");
-
- // shuffle into zero vector.
- std::vector<llvm::Constant *>Elts;
- Elts.resize(2, llvm::ConstantInt::get(EltTy, 0));
- llvm::Value *ZV = ConstantVector::get(Elts);
- Ops[0] = EmitShuffleVector(ZV, Ops[0], 2, 1, "loadl");
-
- // bitcast to result.
- return Builder.CreateBitCast(Ops[0],
- llvm::VectorType::get(llvm::Type::Int32Ty, 4));
- }
- case X86::BI__builtin_ia32_vec_set_v4hi:
- case X86::BI__builtin_ia32_vec_set_v8hi:
- return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2], "pinsrw");
- case X86::BI__builtin_ia32_andps:
- case X86::BI__builtin_ia32_andpd:
- case X86::BI__builtin_ia32_andnps:
- case X86::BI__builtin_ia32_andnpd:
- case X86::BI__builtin_ia32_orps:
- case X86::BI__builtin_ia32_orpd:
- case X86::BI__builtin_ia32_xorpd:
- case X86::BI__builtin_ia32_xorps: {
- const llvm::Type *ITy = llvm::VectorType::get(llvm::Type::Int32Ty, 4);
- const llvm::Type *FTy = Ops[0]->getType();
- Ops[0] = Builder.CreateBitCast(Ops[0], ITy, "bitcast");
- Ops[1] = Builder.CreateBitCast(Ops[1], ITy, "bitcast");
- switch (BuiltinID) {
- case X86::BI__builtin_ia32_andps:
- Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andps");
- break;
- case X86::BI__builtin_ia32_andpd:
- Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andpd");
- break;
- case X86::BI__builtin_ia32_andnps:
- Ops[0] = Builder.CreateNot(Ops[0], "not");
- Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnps");
- break;
- case X86::BI__builtin_ia32_andnpd:
- Ops[0] = Builder.CreateNot(Ops[0], "not");
- Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnpd");
- break;
- case X86::BI__builtin_ia32_orps:
- Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orps");
- break;
- case X86::BI__builtin_ia32_orpd:
- Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orpd");
- break;
- case X86::BI__builtin_ia32_xorps:
- Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorps");
- break;
- case X86::BI__builtin_ia32_xorpd:
- Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorpd");
- break;
- }
- return Builder.CreateBitCast(Ops[0], FTy, "bitcast");
- }
- }
-}
-
-Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
- const CallExpr *E) {
- switch (BuiltinID) {
- default: return 0;
- }
-}
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
deleted file mode 100644
index e12a68b4a77e..000000000000
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation.
-//
-//===----------------------------------------------------------------------===//
-
-// We might split this into multiple files if it gets too unwieldy
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/ADT/StringExtras.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-using llvm::utostr;
-
-
-// FIXME: Name mangling should be moved to a separate class.
-
-static void mangleDeclContextInternal(const DeclContext *D, std::string &S)
-{
- // FIXME: Should ObjcMethodDecl have the TranslationUnitDecl as its parent?
- assert(!D->getParent() || isa<TranslationUnitDecl>(D->getParent()) &&
- "Only one level of decl context mangling is currently supported!");
-
- if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
- S += utostr(FD->getIdentifier()->getLength());
- S += FD->getIdentifier()->getName();
-
- if (FD->param_size() == 0)
- S += 'v';
- else
- assert(0 && "mangling of types not supported yet!");
- } else if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
-
- // FIXME: This should really use GetNameForMethod from CGObjCMac.
- std::string Name;
- Name += MD->isInstance() ? '-' : '+';
- Name += '[';
- Name += MD->getClassInterface()->getName();
- Name += ' ';
- Name += MD->getSelector().getName();
- Name += ']';
- S += utostr(Name.length());
- S += Name;
- } else
- assert(0 && "Unsupported decl type!");
-}
-
-static void mangleVarDeclInternal(const VarDecl &D, std::string &S)
-{
- S += 'Z';
- mangleDeclContextInternal(D.getDeclContext(), S);
- S += 'E';
-
- S += utostr(D.getIdentifier()->getLength());
- S += D.getIdentifier()->getName();
-}
-
-static std::string mangleVarDecl(const VarDecl& D)
-{
- std::string S = "_Z";
-
- mangleVarDeclInternal(D, S);
-
- return S;
-}
-
-static std::string mangleGuardVariable(const VarDecl& D)
-{
- std::string S = "_ZGV";
-
- mangleVarDeclInternal(D, S);
-
- return S;
-}
-
-llvm::GlobalValue *
-CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
-{
- assert(!getContext().getLangOptions().ThreadsafeStatics &&
- "thread safe statics are currently not supported!");
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
-
- // FIXME: If the function is inline, the linkage should be weak.
- llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::InternalLinkage;
-
- // Create the guard variable.
- llvm::GlobalValue *GuardV =
- new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
- linkage,
- llvm::Constant::getNullValue(llvm::Type::Int64Ty),
- mangleGuardVariable(D),
- &CGM.getModule());
-
- // FIXME: Address space.
- const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
-
- // Load the first byte of the guard variable.
- llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
- "tmp");
-
- // Compare it against 0.
- llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
- llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
-
- llvm::BasicBlock *InitBlock = llvm::BasicBlock::Create("init");
- llvm::BasicBlock *EndBlock = llvm::BasicBlock::Create("initend");
-
- // If the guard variable is 0, jump to the initializer code.
- Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
-
- EmitBlock(InitBlock);
-
- llvm::GlobalValue *GV =
- new llvm::GlobalVariable(LTy, false,
- llvm::GlobalValue::InternalLinkage,
- llvm::Constant::getNullValue(LTy),
- mangleVarDecl(D),
- &CGM.getModule(), 0,
- D.getType().getAddressSpace());
-
- const Expr *Init = D.getInit();
- if (!hasAggregateLLVMType(Init->getType())) {
- llvm::Value *V = EmitScalarExpr(Init);
- Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
- } else if (Init->getType()->isAnyComplexType()) {
- EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
- } else {
- EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
- }
-
- Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
- Builder.CreateBitCast(GuardV, PtrTy));
-
- EmitBlock(EndBlock);
- return GV;
-}
-
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
deleted file mode 100644
index a246ade82c2b..000000000000
--- a/clang/lib/CodeGen/CGCall.cpp
+++ /dev/null
@@ -1,798 +0,0 @@
-//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// These classes wrap the information about a call or function
-// definition used to handle ABI compliancy.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGCall.h"
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Attributes.h"
-using namespace clang;
-using namespace CodeGen;
-
-/***/
-
-// FIXME: Use iterator and sidestep silly type array creation.
-
-CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP)
- : IsVariadic(true)
-{
- ArgTypes.push_back(FTNP->getResultType());
-}
-
-CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP)
- : IsVariadic(FTP->isVariadic())
-{
- ArgTypes.push_back(FTP->getResultType());
- for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
- ArgTypes.push_back(FTP->getArgType(i));
-}
-
-// FIXME: Is there really any reason to have this still?
-CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
-{
- const FunctionType *FTy = FD->getType()->getAsFunctionType();
- const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
-
- ArgTypes.push_back(FTy->getResultType());
- if (FTP) {
- IsVariadic = FTP->isVariadic();
- for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
- ArgTypes.push_back(FTP->getArgType(i));
- } else {
- IsVariadic = true;
- }
-}
-
-CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
- const ASTContext &Context)
- : IsVariadic(MD->isVariadic())
-{
- ArgTypes.push_back(MD->getResultType());
- ArgTypes.push_back(MD->getSelfDecl()->getType());
- ArgTypes.push_back(Context.getObjCSelType());
- for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
- e = MD->param_end(); i != e; ++i)
- ArgTypes.push_back((*i)->getType());
-}
-
-ArgTypeIterator CGFunctionInfo::argtypes_begin() const {
- return ArgTypes.begin();
-}
-
-ArgTypeIterator CGFunctionInfo::argtypes_end() const {
- return ArgTypes.end();
-}
-
-/***/
-
-CGCallInfo::CGCallInfo(QualType _ResultType, const CallArgList &_Args) {
- ArgTypes.push_back(_ResultType);
- for (CallArgList::const_iterator i = _Args.begin(), e = _Args.end(); i!=e; ++i)
- ArgTypes.push_back(i->second);
-}
-
-ArgTypeIterator CGCallInfo::argtypes_begin() const {
- return ArgTypes.begin();
-}
-
-ArgTypeIterator CGCallInfo::argtypes_end() const {
- return ArgTypes.end();
-}
-
-/***/
-
-/// ABIArgInfo - Helper class to encapsulate information about how a
-/// specific C type should be passed to or returned from a function.
-class ABIArgInfo {
-public:
- enum Kind {
- Default,
- StructRet, /// Only valid for aggregate return types.
-
- Coerce, /// Only valid for aggregate return types, the argument
- /// should be accessed by coercion to a provided type.
-
- ByVal, /// Only valid for aggregate argument types. The
- /// structure should be passed "byval" with the
- /// specified alignment (0 indicates default
- /// alignment).
-
- Expand, /// Only valid for aggregate argument types. The
- /// structure should be expanded into consecutive
- /// arguments for its constituent fields. Currently
- /// expand is only allowed on structures whose fields
- /// are all scalar types or are themselves expandable
- /// types.
-
- KindFirst=Default, KindLast=Expand
- };
-
-private:
- Kind TheKind;
- const llvm::Type *TypeData;
- unsigned UIntData;
-
- ABIArgInfo(Kind K, const llvm::Type *TD=0,
- unsigned UI=0) : TheKind(K),
- TypeData(TD),
- UIntData(0) {}
-public:
- static ABIArgInfo getDefault() {
- return ABIArgInfo(Default);
- }
- static ABIArgInfo getStructRet() {
- return ABIArgInfo(StructRet);
- }
- static ABIArgInfo getCoerce(const llvm::Type *T) {
- assert(T->isSingleValueType() && "Can only coerce to simple types");
- return ABIArgInfo(Coerce, T);
- }
- static ABIArgInfo getByVal(unsigned Alignment) {
- return ABIArgInfo(ByVal, 0, Alignment);
- }
- static ABIArgInfo getExpand() {
- return ABIArgInfo(Expand);
- }
-
- Kind getKind() const { return TheKind; }
- bool isDefault() const { return TheKind == Default; }
- bool isStructRet() const { return TheKind == StructRet; }
- bool isCoerce() const { return TheKind == Coerce; }
- bool isByVal() const { return TheKind == ByVal; }
- bool isExpand() const { return TheKind == Expand; }
-
- // Coerce accessors
- const llvm::Type *getCoerceToType() const {
- assert(TheKind == Coerce && "Invalid kind!");
- return TypeData;
- }
-
- // ByVal accessors
- unsigned getByValAlignment() const {
- assert(TheKind == ByVal && "Invalid kind!");
- return UIntData;
- }
-};
-
-/***/
-
-/// isEmptyStruct - Return true iff a structure has no non-empty
-/// members. Note that a structure with a flexible array member is not
-/// considered empty.
-static bool isEmptyStruct(QualType T) {
- const RecordType *RT = T->getAsStructureType();
- if (!RT)
- return 0;
- const RecordDecl *RD = RT->getDecl();
- if (RD->hasFlexibleArrayMember())
- return false;
- for (RecordDecl::field_const_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- const FieldDecl *FD = *i;
- if (!isEmptyStruct(FD->getType()))
- return false;
- }
- return true;
-}
-
-/// isSingleElementStruct - Determine if a structure is a "single
-/// element struct", i.e. it has exactly one non-empty field or
-/// exactly one field which is itself a single element
-/// struct. Structures with flexible array members are never
-/// considered single element structs.
-///
-/// \return The field declaration for the single non-empty field, if
-/// it exists.
-static const FieldDecl *isSingleElementStruct(QualType T) {
- const RecordType *RT = T->getAsStructureType();
- if (!RT)
- return 0;
-
- const RecordDecl *RD = RT->getDecl();
- if (RD->hasFlexibleArrayMember())
- return 0;
-
- const FieldDecl *Found = 0;
- for (RecordDecl::field_const_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- const FieldDecl *FD = *i;
- QualType FT = FD->getType();
-
- if (isEmptyStruct(FT)) {
- // Ignore
- } else if (Found) {
- return 0;
- } else if (!CodeGenFunction::hasAggregateLLVMType(FT)) {
- Found = FD;
- } else {
- Found = isSingleElementStruct(FT);
- if (!Found)
- return 0;
- }
- }
-
- return Found;
-}
-
-static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) {
- if (!Ty->getAsBuiltinType() && !Ty->isPointerType())
- return false;
-
- uint64_t Size = Context.getTypeSize(Ty);
- return Size == 32 || Size == 64;
-}
-
-static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
- ASTContext &Context) {
- for (RecordDecl::field_const_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- const FieldDecl *FD = *i;
-
- if (!is32Or64BitBasicType(FD->getType(), Context))
- return false;
-
- // If this is a bit-field we need to make sure it is still a
- // 32-bit or 64-bit type.
- if (Expr *BW = FD->getBitWidth()) {
- unsigned Width = BW->getIntegerConstantExprValue(Context).getZExtValue();
- if (Width <= 16)
- return false;
- }
- }
- return true;
-}
-
-static ABIArgInfo classifyReturnType(QualType RetTy,
- ASTContext &Context) {
- assert(!RetTy->isArrayType() &&
- "Array types cannot be passed directly.");
- if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
- // Classify "single element" structs as their element type.
- const FieldDecl *SeltFD = isSingleElementStruct(RetTy);
- if (SeltFD) {
- QualType SeltTy = SeltFD->getType()->getDesugaredType();
- if (const BuiltinType *BT = SeltTy->getAsBuiltinType()) {
- // FIXME: This is gross, it would be nice if we could just
- // pass back SeltTy and have clients deal with it. Is it worth
- // supporting coerce to both LLVM and clang Types?
- if (BT->isIntegerType()) {
- uint64_t Size = Context.getTypeSize(SeltTy);
- return ABIArgInfo::getCoerce(llvm::IntegerType::get((unsigned) Size));
- } else if (BT->getKind() == BuiltinType::Float) {
- return ABIArgInfo::getCoerce(llvm::Type::FloatTy);
- } else if (BT->getKind() == BuiltinType::Double) {
- return ABIArgInfo::getCoerce(llvm::Type::DoubleTy);
- }
- } else if (SeltTy->isPointerType()) {
- // FIXME: It would be really nice if this could come out as
- // the proper pointer type.
- llvm::Type *PtrTy =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- return ABIArgInfo::getCoerce(PtrTy);
- }
- }
-
- uint64_t Size = Context.getTypeSize(RetTy);
- if (Size == 8) {
- return ABIArgInfo::getCoerce(llvm::Type::Int8Ty);
- } else if (Size == 16) {
- return ABIArgInfo::getCoerce(llvm::Type::Int16Ty);
- } else if (Size == 32) {
- return ABIArgInfo::getCoerce(llvm::Type::Int32Ty);
- } else if (Size == 64) {
- return ABIArgInfo::getCoerce(llvm::Type::Int64Ty);
- } else {
- return ABIArgInfo::getStructRet();
- }
- } else {
- return ABIArgInfo::getDefault();
- }
-}
-
-static ABIArgInfo classifyArgumentType(QualType Ty,
- ASTContext &Context) {
- assert(!Ty->isArrayType() && "Array types cannot be passed directly.");
- if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
- // Structures with flexible arrays are always byval.
- if (const RecordType *RT = Ty->getAsStructureType())
- if (RT->getDecl()->hasFlexibleArrayMember())
- return ABIArgInfo::getByVal(0);
-
- // Expand empty structs (i.e. ignore)
- uint64_t Size = Context.getTypeSize(Ty);
- if (Ty->isStructureType() && Size == 0)
- return ABIArgInfo::getExpand();
-
- // Expand structs with size <= 128-bits which consist only of
- // basic types (int, long long, float, double, xxx*). This is
- // non-recursive and does not ignore empty fields.
- if (const RecordType *RT = Ty->getAsStructureType()) {
- if (Context.getTypeSize(Ty) <= 4*32 &&
- areAllFields32Or64BitBasicType(RT->getDecl(), Context))
- return ABIArgInfo::getExpand();
- }
-
- return ABIArgInfo::getByVal(0);
- } else {
- return ABIArgInfo::getDefault();
- }
-}
-
-static ABIArgInfo getABIReturnInfo(QualType Ty,
- ASTContext &Context) {
- ABIArgInfo Info = classifyReturnType(Ty, Context);
- // Ensure default on aggregate types is StructRet.
- if (Info.isDefault() && CodeGenFunction::hasAggregateLLVMType(Ty))
- return ABIArgInfo::getStructRet();
- return Info;
-}
-
-static ABIArgInfo getABIArgumentInfo(QualType Ty,
- ASTContext &Context) {
- ABIArgInfo Info = classifyArgumentType(Ty, Context);
- // Ensure default on aggregate types is ByVal.
- if (Info.isDefault() && CodeGenFunction::hasAggregateLLVMType(Ty))
- return ABIArgInfo::getByVal(0);
- return Info;
-}
-
-/***/
-
-void CodeGenTypes::GetExpandedTypes(QualType Ty,
- std::vector<const llvm::Type*> &ArgTys) {
- const RecordType *RT = Ty->getAsStructureType();
- assert(RT && "Can only expand structure types.");
- const RecordDecl *RD = RT->getDecl();
- assert(!RD->hasFlexibleArrayMember() &&
- "Cannot expand structure with flexible array.");
-
- for (RecordDecl::field_const_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- const FieldDecl *FD = *i;
- assert(!FD->isBitField() &&
- "Cannot expand structure with bit-field members.");
-
- QualType FT = FD->getType();
- if (CodeGenFunction::hasAggregateLLVMType(FT)) {
- GetExpandedTypes(FT, ArgTys);
- } else {
- ArgTys.push_back(ConvertType(FT));
- }
- }
-}
-
-llvm::Function::arg_iterator
-CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
- llvm::Function::arg_iterator AI) {
- const RecordType *RT = Ty->getAsStructureType();
- assert(RT && "Can only expand structure types.");
-
- RecordDecl *RD = RT->getDecl();
- assert(LV.isSimple() &&
- "Unexpected non-simple lvalue during struct expansion.");
- llvm::Value *Addr = LV.getAddress();
- for (RecordDecl::field_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- FieldDecl *FD = *i;
- QualType FT = FD->getType();
-
- // FIXME: What are the right qualifiers here?
- LValue LV = EmitLValueForField(Addr, FD, false, 0);
- if (CodeGenFunction::hasAggregateLLVMType(FT)) {
- AI = ExpandTypeFromArgs(FT, LV, AI);
- } else {
- EmitStoreThroughLValue(RValue::get(AI), LV, FT);
- ++AI;
- }
- }
-
- return AI;
-}
-
-void
-CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
- llvm::SmallVector<llvm::Value*, 16> &Args) {
- const RecordType *RT = Ty->getAsStructureType();
- assert(RT && "Can only expand structure types.");
-
- RecordDecl *RD = RT->getDecl();
- assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
- llvm::Value *Addr = RV.getAggregateAddr();
- for (RecordDecl::field_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- FieldDecl *FD = *i;
- QualType FT = FD->getType();
-
- // FIXME: What are the right qualifiers here?
- LValue LV = EmitLValueForField(Addr, FD, false, 0);
- if (CodeGenFunction::hasAggregateLLVMType(FT)) {
- ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), Args);
- } else {
- RValue RV = EmitLoadOfLValue(LV, FT);
- assert(RV.isScalar() &&
- "Unexpected non-scalar rvalue during struct expansion.");
- Args.push_back(RV.getScalarVal());
- }
- }
-}
-
-/***/
-
-const llvm::FunctionType *
-CodeGenTypes::GetFunctionType(const CGCallInfo &CI, bool IsVariadic) {
- return GetFunctionType(CI.argtypes_begin(), CI.argtypes_end(), IsVariadic);
-}
-
-const llvm::FunctionType *
-CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
- return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), FI.isVariadic());
-}
-
-const llvm::FunctionType *
-CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end,
- bool IsVariadic) {
- std::vector<const llvm::Type*> ArgTys;
-
- const llvm::Type *ResultType = 0;
-
- QualType RetTy = *begin;
- ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
- switch (RetAI.getKind()) {
- case ABIArgInfo::ByVal:
- case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
-
- case ABIArgInfo::Default:
- if (RetTy->isVoidType()) {
- ResultType = llvm::Type::VoidTy;
- } else {
- ResultType = ConvertType(RetTy);
- }
- break;
-
- case ABIArgInfo::StructRet: {
- ResultType = llvm::Type::VoidTy;
- const llvm::Type *STy = ConvertType(RetTy);
- ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
- break;
- }
-
- case ABIArgInfo::Coerce:
- ResultType = RetAI.getCoerceToType();
- break;
- }
-
- for (++begin; begin != end; ++begin) {
- ABIArgInfo AI = getABIArgumentInfo(*begin, getContext());
- const llvm::Type *Ty = ConvertType(*begin);
-
- switch (AI.getKind()) {
- case ABIArgInfo::Coerce:
- case ABIArgInfo::StructRet:
- assert(0 && "Invalid ABI kind for non-return argument");
-
- case ABIArgInfo::ByVal:
- // byval arguments are always on the stack, which is addr space #0.
- ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
- assert(AI.getByValAlignment() == 0 && "FIXME: alignment unhandled");
- break;
-
- case ABIArgInfo::Default:
- ArgTys.push_back(Ty);
- break;
-
- case ABIArgInfo::Expand:
- GetExpandedTypes(*begin, ArgTys);
- break;
- }
- }
-
- return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
-}
-
-bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
- return getABIReturnInfo(RetTy, getContext()).isStructRet();
-}
-
-void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl,
- ArgTypeIterator begin,
- ArgTypeIterator end,
- AttributeListType &PAL) {
- unsigned FuncAttrs = 0;
- unsigned RetAttrs = 0;
-
- if (TargetDecl) {
- if (TargetDecl->getAttr<NoThrowAttr>())
- FuncAttrs |= llvm::Attribute::NoUnwind;
- if (TargetDecl->getAttr<NoReturnAttr>())
- FuncAttrs |= llvm::Attribute::NoReturn;
- if (TargetDecl->getAttr<PureAttr>())
- FuncAttrs |= llvm::Attribute::ReadOnly;
- if (TargetDecl->getAttr<ConstAttr>())
- FuncAttrs |= llvm::Attribute::ReadNone;
- }
-
- QualType RetTy = *begin;
- unsigned Index = 1;
- ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
- switch (RetAI.getKind()) {
- case ABIArgInfo::Default:
- if (RetTy->isPromotableIntegerType()) {
- if (RetTy->isSignedIntegerType()) {
- RetAttrs |= llvm::Attribute::SExt;
- } else if (RetTy->isUnsignedIntegerType()) {
- RetAttrs |= llvm::Attribute::ZExt;
- }
- }
- break;
-
- case ABIArgInfo::StructRet:
- PAL.push_back(llvm::AttributeWithIndex::get(Index,
- llvm::Attribute::StructRet|
- llvm::Attribute::NoAlias));
- ++Index;
- break;
-
- case ABIArgInfo::Coerce:
- break;
-
- case ABIArgInfo::ByVal:
- case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
- }
-
- if (RetAttrs)
- PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs));
- for (++begin; begin != end; ++begin) {
- QualType ParamType = *begin;
- unsigned Attributes = 0;
- ABIArgInfo AI = getABIArgumentInfo(ParamType, getContext());
-
- switch (AI.getKind()) {
- case ABIArgInfo::StructRet:
- case ABIArgInfo::Coerce:
- assert(0 && "Invalid ABI kind for non-return argument");
-
- case ABIArgInfo::ByVal:
- Attributes |= llvm::Attribute::ByVal;
- assert(AI.getByValAlignment() == 0 && "FIXME: alignment unhandled");
- break;
-
- case ABIArgInfo::Default:
- if (ParamType->isPromotableIntegerType()) {
- if (ParamType->isSignedIntegerType()) {
- Attributes |= llvm::Attribute::SExt;
- } else if (ParamType->isUnsignedIntegerType()) {
- Attributes |= llvm::Attribute::ZExt;
- }
- }
- break;
-
- case ABIArgInfo::Expand: {
- std::vector<const llvm::Type*> Tys;
- // FIXME: This is rather inefficient. Do we ever actually need
- // to do anything here? The result should be just reconstructed
- // on the other side, so extension should be a non-issue.
- getTypes().GetExpandedTypes(ParamType, Tys);
- Index += Tys.size();
- continue;
- }
- }
-
- if (Attributes)
- PAL.push_back(llvm::AttributeWithIndex::get(Index, Attributes));
- ++Index;
- }
- if (FuncAttrs)
- PAL.push_back(llvm::AttributeWithIndex::get(~0, FuncAttrs));
-
-}
-
-void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
- QualType RetTy,
- const FunctionArgList &Args) {
- // Emit allocs for param decls. Give the LLVM Argument nodes names.
- llvm::Function::arg_iterator AI = Fn->arg_begin();
-
- // Name the struct return argument.
- if (CGM.ReturnTypeUsesSret(RetTy)) {
- AI->setName("agg.result");
- ++AI;
- }
-
- for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
- i != e; ++i) {
- const VarDecl *Arg = i->first;
- QualType Ty = i->second;
- ABIArgInfo ArgI = getABIArgumentInfo(Ty, getContext());
-
- switch (ArgI.getKind()) {
- case ABIArgInfo::ByVal:
- case ABIArgInfo::Default: {
- assert(AI != Fn->arg_end() && "Argument mismatch!");
- llvm::Value* V = AI;
- if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
- // This must be a promotion, for something like
- // "void a(x) short x; {..."
- V = EmitScalarConversion(V, Ty, Arg->getType());
- }
- EmitParmDecl(*Arg, V);
- break;
- }
-
- case ABIArgInfo::Expand: {
- // If this was structure was expand into multiple arguments then
- // we need to create a temporary and reconstruct it from the
- // arguments.
- std::string Name(Arg->getName());
- llvm::Value *Temp = CreateTempAlloca(ConvertType(Ty),
- (Name + ".addr").c_str());
- // FIXME: What are the right qualifiers here?
- llvm::Function::arg_iterator End =
- ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp,0), AI);
- EmitParmDecl(*Arg, Temp);
-
- // Name the arguments used in expansion and increment AI.
- unsigned Index = 0;
- for (; AI != End; ++AI, ++Index)
- AI->setName(Name + "." + llvm::utostr(Index));
- continue;
- }
-
- case ABIArgInfo::Coerce:
- case ABIArgInfo::StructRet:
- assert(0 && "Invalid ABI kind for non-return argument");
- }
-
- ++AI;
- }
- assert(AI == Fn->arg_end() && "Argument mismatch!");
-}
-
-void CodeGenFunction::EmitFunctionEpilog(QualType RetTy,
- llvm::Value *ReturnValue) {
- llvm::Value *RV = 0;
-
- // Functions with no result always return void.
- if (ReturnValue) {
- ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
-
- switch (RetAI.getKind()) {
- case ABIArgInfo::StructRet:
- EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
- break;
-
- case ABIArgInfo::Default:
- RV = Builder.CreateLoad(ReturnValue);
- break;
-
- case ABIArgInfo::Coerce: {
- const llvm::Type *CoerceToPTy =
- llvm::PointerType::getUnqual(RetAI.getCoerceToType());
- RV = Builder.CreateLoad(Builder.CreateBitCast(ReturnValue, CoerceToPTy));
- break;
- }
-
- case ABIArgInfo::ByVal:
- case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
- }
- }
-
- if (RV) {
- Builder.CreateRet(RV);
- } else {
- Builder.CreateRetVoid();
- }
-}
-
-RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
- QualType RetTy,
- const CallArgList &CallArgs) {
- llvm::SmallVector<llvm::Value*, 16> Args;
-
- // Handle struct-return functions by passing a pointer to the
- // location that we would like to return into.
- ABIArgInfo RetAI = getABIReturnInfo(RetTy, getContext());
- switch (RetAI.getKind()) {
- case ABIArgInfo::StructRet:
- // Create a temporary alloca to hold the result of the call. :(
- Args.push_back(CreateTempAlloca(ConvertType(RetTy)));
- break;
-
- case ABIArgInfo::Default:
- case ABIArgInfo::Coerce:
- break;
-
- case ABIArgInfo::ByVal:
- case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
- }
-
- for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
- I != E; ++I) {
- ABIArgInfo ArgInfo = getABIArgumentInfo(I->second, getContext());
- RValue RV = I->first;
-
- switch (ArgInfo.getKind()) {
- case ABIArgInfo::ByVal: // Default is byval
- case ABIArgInfo::Default:
- if (RV.isScalar()) {
- Args.push_back(RV.getScalarVal());
- } else if (RV.isComplex()) {
- // Make a temporary alloca to pass the argument.
- Args.push_back(CreateTempAlloca(ConvertType(I->second)));
- StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
- } else {
- Args.push_back(RV.getAggregateAddr());
- }
- break;
-
- case ABIArgInfo::StructRet:
- case ABIArgInfo::Coerce:
- assert(0 && "Invalid ABI kind for non-return argument");
- break;
-
- case ABIArgInfo::Expand:
- ExpandTypeToArgs(I->second, RV, Args);
- break;
- }
- }
-
- llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
- CGCallInfo CallInfo(RetTy, CallArgs);
-
- // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
- CodeGen::AttributeListType AttributeList;
- CGM.ConstructAttributeList(0,
- CallInfo.argtypes_begin(), CallInfo.argtypes_end(),
- AttributeList);
- CI->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(),
- AttributeList.size()));
-
- if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
- CI->setCallingConv(F->getCallingConv());
- if (CI->getType() != llvm::Type::VoidTy)
- CI->setName("call");
-
- switch (RetAI.getKind()) {
- case ABIArgInfo::StructRet:
- if (RetTy->isAnyComplexType())
- return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
- else
- // Struct return.
- return RValue::getAggregate(Args[0]);
-
- case ABIArgInfo::Default:
- return RValue::get(RetTy->isVoidType() ? 0 : CI);
-
- case ABIArgInfo::Coerce: {
- const llvm::Type *CoerceToPTy =
- llvm::PointerType::getUnqual(RetAI.getCoerceToType());
- llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "tmp");
- Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy));
- return RValue::getAggregate(V);
- }
-
- case ABIArgInfo::ByVal:
- case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
- }
-
- assert(0 && "Unhandled ABIArgInfo::Kind");
- return RValue::get(0);
-}
diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h
deleted file mode 100644
index 744344a7acc5..000000000000
--- a/clang/lib/CodeGen/CGCall.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// These classes wrap the information about a call or function
-// definition used to handle ABI compliancy.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CGCALL_H
-#define CLANG_CODEGEN_CGCALL_H
-
-#include "clang/AST/Type.h"
-
-#include "CGValue.h"
-
-namespace llvm {
- class Function;
- struct AttributeWithIndex;
- class Value;
-
- template<typename T, unsigned> class SmallVector;
-}
-
-namespace clang {
- class ASTContext;
- class Decl;
- class FunctionDecl;
- class ObjCMethodDecl;
- class VarDecl;
-
-namespace CodeGen {
- typedef llvm::SmallVector<llvm::AttributeWithIndex, 8> AttributeListType;
-
- /// CallArgList - Type for representing both the value and type of
- /// arguments in a call.
- typedef llvm::SmallVector<std::pair<RValue, QualType>, 16> CallArgList;
-
- /// FunctionArgList - Type for representing both the decl and type
- /// of parameters to a function. The decl must be either a
- /// ParmVarDecl or ImplicitParamDecl.
- typedef llvm::SmallVector<std::pair<const VarDecl*, QualType>,
- 16> FunctionArgList;
-
- // FIXME: This should be a better iterator type so that we can avoid
- // construction of the ArgTypes smallvectors.
- typedef llvm::SmallVector<QualType, 16>::const_iterator ArgTypeIterator;
-
- /// CGFunctionInfo - Class to encapsulate the information about a
- /// function definition.
- class CGFunctionInfo {
- bool IsVariadic;
-
- llvm::SmallVector<QualType, 16> ArgTypes;
-
- public:
- CGFunctionInfo(const FunctionTypeNoProto *FTNP);
- CGFunctionInfo(const FunctionTypeProto *FTP);
- CGFunctionInfo(const FunctionDecl *FD);
- CGFunctionInfo(const ObjCMethodDecl *MD,
- const ASTContext &Context);
-
- bool isVariadic() const { return IsVariadic; }
-
- ArgTypeIterator argtypes_begin() const;
- ArgTypeIterator argtypes_end() const;
- };
-
- /// CGCallInfo - Class to encapsulate the arguments and clang types
- /// used in a call.
- class CGCallInfo {
- llvm::SmallVector<QualType, 16> ArgTypes;
-
- public:
- CGCallInfo(QualType _ResultType, const CallArgList &Args);
-
- ArgTypeIterator argtypes_begin() const;
- ArgTypeIterator argtypes_end() const;
- };
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
deleted file mode 100644
index d6902bb93e78..000000000000
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ /dev/null
@@ -1,788 +0,0 @@
-//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This coordinates the debug information generation while generating code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGDebugInfo.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Module.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Target/TargetMachine.h"
-using namespace clang;
-using namespace clang::CodeGen;
-
-CGDebugInfo::CGDebugInfo(CodeGenModule *m)
-: M(m)
-, CurLoc()
-, PrevLoc()
-, CompileUnitCache()
-, TypeCache()
-, StopPointFn(NULL)
-, FuncStartFn(NULL)
-, DeclareFn(NULL)
-, RegionStartFn(NULL)
-, RegionEndFn(NULL)
-, CompileUnitAnchor(NULL)
-, SubprogramAnchor(NULL)
-, GlobalVariableAnchor(NULL)
-, RegionStack()
-, VariableDescList()
-, GlobalVarDescList()
-, EnumDescList()
-, SubrangeDescList()
-, Subprogram(NULL)
-{
- SR = new llvm::DISerializer();
- SR->setModule (&M->getModule());
-}
-
-CGDebugInfo::~CGDebugInfo()
-{
- delete SR;
-
- // Free CompileUnitCache.
- for (std::map<unsigned, llvm::CompileUnitDesc *>::iterator I
- = CompileUnitCache.begin(); I != CompileUnitCache.end(); ++I) {
- delete I->second;
- }
- CompileUnitCache.clear();
-
- // Free TypeCache.
- for (std::map<void *, llvm::TypeDesc *>::iterator I
- = TypeCache.begin(); I != TypeCache.end(); ++I) {
- delete I->second;
- }
- TypeCache.clear();
-
- // Free region descriptors.
- for (std::vector<llvm::DebugInfoDesc *>::iterator I
- = RegionStack.begin(); I != RegionStack.end(); ++I) {
- delete *I;
- }
-
- // Free local var descriptors.
- for (std::vector<llvm::VariableDesc *>::iterator I
- = VariableDescList.begin(); I != VariableDescList.end(); ++I) {
- delete *I;
- }
-
- // Free global var descriptors.
- for (std::vector<llvm::GlobalVariableDesc *>::iterator I
- = GlobalVarDescList.begin(); I != GlobalVarDescList.end(); ++I) {
- delete *I;
- }
-
- // Free enum constants descriptors.
- for (std::vector<llvm::EnumeratorDesc *>::iterator I
- = EnumDescList.begin(); I != EnumDescList.end(); ++I) {
- delete *I;
- }
-
- // Free subrange descriptors.
- for (std::vector<llvm::SubrangeDesc *>::iterator I
- = SubrangeDescList.begin(); I != SubrangeDescList.end(); ++I) {
- delete *I;
- }
-
- delete CompileUnitAnchor;
- delete SubprogramAnchor;
- delete GlobalVariableAnchor;
-}
-
-void CGDebugInfo::setLocation(SourceLocation loc) {
- CurLoc = M->getContext().getSourceManager().getLogicalLoc(loc);
-}
-
-/// getCastValueFor - Return a llvm representation for a given debug information
-/// descriptor cast to an empty struct pointer.
-llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) {
- return llvm::ConstantExpr::getBitCast(SR->Serialize(DD),
- SR->getEmptyStructPtrType());
-}
-
-/// getValueFor - Return a llvm representation for a given debug information
-/// descriptor.
-llvm::Value *CGDebugInfo::getValueFor(llvm::DebugInfoDesc *DD) {
- return SR->Serialize(DD);
-}
-
-/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
-/// one if necessary.
-llvm::CompileUnitDesc
-*CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) {
-
- // See if this compile unit has been used before.
- llvm::CompileUnitDesc *&Slot = CompileUnitCache[Loc.getFileID()];
- if (Slot) return Slot;
-
- // Create new compile unit.
- // FIXME: Where to free these?
- // One way is to iterate over the CompileUnitCache in ~CGDebugInfo.
- llvm::CompileUnitDesc *Unit = new llvm::CompileUnitDesc();
-
- // Make sure we have an anchor.
- if (!CompileUnitAnchor) {
- CompileUnitAnchor = new llvm::AnchorDesc(Unit);
- }
-
- // Get source file information.
- SourceManager &SM = M->getContext().getSourceManager();
- const FileEntry *FE = SM.getFileEntryForLoc(Loc);
- const char *FileName, *DirName;
- if (FE) {
- FileName = FE->getName();
- DirName = FE->getDir()->getName();
- } else {
- FileName = SM.getSourceName(Loc);
- DirName = "";
- }
-
- Unit->setAnchor(CompileUnitAnchor);
- Unit->setFileName(FileName);
- Unit->setDirectory(DirName);
-
- // Set up producer name.
- // FIXME: Do not know how to get clang version yet.
- Unit->setProducer("clang");
-
- // Set up Language number.
- // FIXME: Handle other languages as well.
- Unit->setLanguage(llvm::dwarf::DW_LANG_C89);
-
- // Update cache.
- Slot = Unit;
-
- return Unit;
-}
-
-
-/// getOrCreateCVRType - Get the CVR qualified type from the cache or create
-/// a new one if necessary.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateCVRType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- // We will create a Derived type.
- llvm::DerivedTypeDesc *DTy = NULL;
- llvm::TypeDesc *FromTy = NULL;
-
- if (type.isConstQualified()) {
- DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_const_type);
- type.removeConst();
- FromTy = getOrCreateType(type, Unit);
- } else if (type.isVolatileQualified()) {
- DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_volatile_type);
- type.removeVolatile();
- FromTy = getOrCreateType(type, Unit);
- } else if (type.isRestrictQualified()) {
- DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_restrict_type);
- type.removeRestrict();
- FromTy = getOrCreateType(type, Unit);
- }
-
- // No need to fill in the Name, Line, Size, Alignment, Offset in case of // CVR derived types.
- DTy->setContext(Unit);
- DTy->setFromType(FromTy);
-
- return DTy;
-}
-
-
-/// getOrCreateBuiltinType - Get the Basic type from the cache or create a new
-/// one if necessary.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateBuiltinType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- assert (type->getTypeClass() == Type::Builtin);
-
- const BuiltinType *BT = type->getAsBuiltinType();
-
- unsigned Encoding = 0;
- switch (BT->getKind())
- {
- case BuiltinType::Void:
- return NULL;
- case BuiltinType::UChar:
- case BuiltinType::Char_U:
- Encoding = llvm::dwarf::DW_ATE_unsigned_char;
- break;
- case BuiltinType::Char_S:
- case BuiltinType::SChar:
- Encoding = llvm::dwarf::DW_ATE_signed_char;
- break;
- case BuiltinType::UShort:
- case BuiltinType::UInt:
- case BuiltinType::ULong:
- case BuiltinType::ULongLong:
- Encoding = llvm::dwarf::DW_ATE_unsigned;
- break;
- case BuiltinType::Short:
- case BuiltinType::Int:
- case BuiltinType::Long:
- case BuiltinType::LongLong:
- Encoding = llvm::dwarf::DW_ATE_signed;
- break;
- case BuiltinType::Bool:
- Encoding = llvm::dwarf::DW_ATE_boolean;
- break;
- case BuiltinType::Float:
- case BuiltinType::Double:
- Encoding = llvm::dwarf::DW_ATE_float;
- break;
- default:
- Encoding = llvm::dwarf::DW_ATE_signed;
- break;
- }
-
- // Ty will have contain the resulting type.
- llvm::BasicTypeDesc *BTy = new llvm::BasicTypeDesc();
-
- // Get the name and location early to assist debugging.
- const char *TyName = BT->getName();
-
- // Bit size, align and offset of the type.
- uint64_t Size = M->getContext().getTypeSize(type);
- uint64_t Align = M->getContext().getTypeAlign(type);
- uint64_t Offset = 0;
-
- // If the type is defined, fill in the details.
- if (BTy) {
- BTy->setContext(Unit);
- BTy->setName(TyName);
- BTy->setSize(Size);
- BTy->setAlign(Align);
- BTy->setOffset(Offset);
- BTy->setEncoding(Encoding);
- }
-
- return BTy;
-}
-
-llvm::TypeDesc *
-CGDebugInfo::getOrCreatePointerType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- // type*
- llvm::DerivedTypeDesc *DTy =
- new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_pointer_type);
-
- // Handle the derived type.
- const PointerType *PTRT = type->getAsPointerType();
- llvm::TypeDesc *FromTy = getOrCreateType(PTRT->getPointeeType(), Unit);
-
- // Get the name and location early to assist debugging.
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Line = SM.getLogicalLineNumber(CurLoc);
-
- // Bit size, align and offset of the type.
- uint64_t Size = M->getContext().getTypeSize(type);
- uint64_t Align = M->getContext().getTypeAlign(type);
- uint64_t Offset = 0;
-
- // If the type is defined, fill in the details.
- if (DTy) {
- DTy->setContext(Unit);
- DTy->setLine(Line);
- DTy->setSize(Size);
- DTy->setAlign(Align);
- DTy->setOffset(Offset);
- DTy->setFromType(FromTy);
- }
-
- return DTy;
-}
-
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateTypedefType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- // typedefs are derived from some other type.
- llvm::DerivedTypeDesc *DTy =
- new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_typedef);
-
- // Handle derived type.
- const TypedefType *TDT = type->getAsTypedefType();
- llvm::TypeDesc *FromTy = getOrCreateType(TDT->LookThroughTypedefs(),
- Unit);
-
- // Get the name and location early to assist debugging.
- const char *TyName = TDT->getDecl()->getName();
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Line = SM.getLogicalLineNumber(TDT->getDecl()->getLocation());
-
- // If the type is defined, fill in the details.
- if (DTy) {
- DTy->setContext(Unit);
- DTy->setFile(getOrCreateCompileUnit(TDT->getDecl()->getLocation()));
- DTy->setLine(Line);
- DTy->setName(TyName);
- DTy->setFromType(FromTy);
- }
-
- return DTy;
-}
-
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateFunctionType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- llvm::CompositeTypeDesc *SubrTy =
- new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_subroutine_type);
-
- // Prepare to add the arguments for the subroutine.
- std::vector<llvm::DebugInfoDesc *> &Elements = SubrTy->getElements();
-
- // Get result type.
- const FunctionType *FT = type->getAsFunctionType();
- llvm::TypeDesc *ArgTy = getOrCreateType(FT->getResultType(), Unit);
- if (ArgTy) Elements.push_back(ArgTy);
-
- // Set up remainder of arguments.
- if (type->getTypeClass() == Type::FunctionProto) {
- const FunctionTypeProto *FTPro = dyn_cast<FunctionTypeProto>(type);
- for (unsigned int i =0; i < FTPro->getNumArgs(); i++) {
- QualType ParamType = FTPro->getArgType(i);
- ArgTy = getOrCreateType(ParamType, Unit);
- if (ArgTy) Elements.push_back(ArgTy);
- }
- }
-
- // FIXME: set other fields file, line here.
- SubrTy->setContext(Unit);
-
- return SubrTy;
-}
-
-/// getOrCreateRecordType - get structure or union type.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateRecordType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- llvm::CompositeTypeDesc *RecType;
- if(type->isStructureType())
- RecType = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_structure_type);
- else if(type->isUnionType())
- RecType = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_union_type);
- else
- return NULL;
-
- RecordDecl *RecDecl = type->getAsRecordType()->getDecl();
- const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(RecDecl);
-
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Line = SM.getLogicalLineNumber(RecDecl->getLocation());
-
- std::vector<llvm::DebugInfoDesc *> &Elements = RecType->getElements();
-
- // Add the members.
- int NumMembers = RecDecl->getNumMembers();
- for (int i = 0; i < NumMembers; i++) {
- FieldDecl *Member = RecDecl->getMember(i);
- llvm::TypeDesc *MemberTy = getOrCreateType(Member->getType(), Unit);
- MemberTy->setOffset(RL.getFieldOffset(i));
- Elements.push_back(MemberTy);
- }
-
- // Fill in the blanks.
- if(RecType) {
- RecType->setContext(Unit);
- RecType->setName(RecDecl->getName());
- RecType->setFile(getOrCreateCompileUnit(RecDecl->getLocation()));
- RecType->setLine(Line);
- RecType->setSize(RL.getSize());
- RecType->setAlign(RL.getAlignment());
- RecType->setOffset(0);
- }
- return(RecType);
-}
-
-/// getOrCreateEnumType - get Enum type.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateEnumType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- llvm::CompositeTypeDesc *EnumTy
- = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_enumeration_type);
-
- EnumType *EType = dyn_cast<EnumType>(type);
- if (!EType) return(NULL);
-
- EnumDecl *EDecl = EType->getDecl();
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Line = SM.getLogicalLineNumber(EDecl->getLocation());
-
- // Size, align and offset of the type.
- uint64_t Size = M->getContext().getTypeSize(type);
- uint64_t Align = M->getContext().getTypeAlign(type);
-
- // Create descriptors for enum members.
- std::vector<llvm::DebugInfoDesc *> &Elements = EnumTy->getElements();
- EnumConstantDecl *ElementList = EDecl->getEnumConstantList();
- while (ElementList) {
- llvm::EnumeratorDesc *EnumDesc = new llvm::EnumeratorDesc();
- // push it to the enum desc list so that we can free it later.
- EnumDescList.push_back(EnumDesc);
-
- const char *ElementName = ElementList->getName();
- uint64_t Value = ElementList->getInitVal().getZExtValue();
-
- EnumDesc->setName(ElementName);
- EnumDesc->setValue(Value);
- Elements.push_back(EnumDesc);
- if (ElementList->getNextDeclarator())
- ElementList
- = dyn_cast<EnumConstantDecl>(ElementList->getNextDeclarator());
- else
- break;
- }
-
- // Fill in the blanks.
- if (EnumTy) {
- EnumTy->setContext(Unit);
- EnumTy->setName(EDecl->getName());
- EnumTy->setSize(Size);
- EnumTy->setAlign(Align);
- EnumTy->setOffset(0);
- EnumTy->setFile(getOrCreateCompileUnit(EDecl->getLocation()));
- EnumTy->setLine(Line);
- }
- return EnumTy;
-}
-
-/// getOrCreateArrayType - get or create array types.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateArrayType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- llvm::CompositeTypeDesc *ArrayTy
- = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_array_type);
-
- // Size, align and offset of the type.
- uint64_t Size = M->getContext().getTypeSize(type);
- uint64_t Align = M->getContext().getTypeAlign(type);
-
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Line = SM.getLogicalLineNumber(CurLoc);
-
- // Add the dimensions of the array.
- std::vector<llvm::DebugInfoDesc *> &Elements = ArrayTy->getElements();
- do {
- const ArrayType *AT = M->getContext().getAsArrayType(type);
- llvm::SubrangeDesc *Subrange = new llvm::SubrangeDesc();
-
- // push it back on the subrange desc list so that we can free it later.
- SubrangeDescList.push_back(Subrange);
-
- uint64_t Upper = 0;
- if (const ConstantArrayType *ConstArrTy = dyn_cast<ConstantArrayType>(AT)) {
- Upper = ConstArrTy->getSize().getZExtValue() - 1;
- }
- Subrange->setLo(0);
- Subrange->setHi(Upper);
- Elements.push_back(Subrange);
- type = AT->getElementType();
- } while (type->isArrayType());
-
- ArrayTy->setFromType(getOrCreateType(type, Unit));
-
- if (ArrayTy) {
- ArrayTy->setContext(Unit);
- ArrayTy->setSize(Size);
- ArrayTy->setAlign(Align);
- ArrayTy->setOffset(0);
- ArrayTy->setFile(getOrCreateCompileUnit(CurLoc));
- ArrayTy->setLine(Line);
- }
- return ArrayTy;
-}
-
-
-/// getOrCreateTaggedType - get or create structure/union/Enum type.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateTaggedType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- if (type->isStructureType() || type->isUnionType())
- return getOrCreateRecordType(type, Unit);
- else if (type->isEnumeralType())
- return getOrCreateEnumType(type, Unit);
- else
- return NULL;
-}
-
-/// getOrCreateType - Get the type from the cache or create a new
-/// one if necessary.
-llvm::TypeDesc *
-CGDebugInfo::getOrCreateType(QualType type, llvm::CompileUnitDesc *Unit)
-{
- if (type.isNull())
- return NULL;
-
- // Check to see if the compile unit already has created this type.
- llvm::TypeDesc *&Slot = TypeCache[type.getAsOpaquePtr()];
- if (Slot) return Slot;
-
- // We need to check for the CVR qualifiers as the first thing.
- if (type.getCVRQualifiers()) {
- Slot = getOrCreateCVRType (type, Unit);
- return Slot;
- }
-
- // Work out details of type.
- switch(type->getTypeClass()) {
- case Type::Complex:
- case Type::Reference:
- case Type::Vector:
- case Type::ExtVector:
- case Type::ASQual:
- case Type::ObjCInterface:
- case Type::ObjCQualifiedInterface:
- case Type::ObjCQualifiedId:
- case Type::TypeOfExp:
- case Type::TypeOfTyp:
- default:
- {
- return NULL;
- }
-
- case Type::TypeName:
- Slot = getOrCreateTypedefType(type, Unit);
- break;
-
- case Type::FunctionProto:
- case Type::FunctionNoProto:
- Slot = getOrCreateFunctionType(type, Unit);
- break;
-
- case Type::Builtin:
- Slot = getOrCreateBuiltinType(type, Unit);
- break;
-
- case Type::Pointer:
- Slot = getOrCreatePointerType(type, Unit);
- break;
-
- case Type::Tagged:
- Slot = getOrCreateTaggedType(type, Unit);
- break;
-
- case Type::ConstantArray:
- case Type::VariableArray:
- case Type::IncompleteArray:
- Slot = getOrCreateArrayType(type, Unit);
- break;
- }
-
- return Slot;
-}
-
-/// EmitFunctionStart - Constructs the debug code for entering a function -
-/// "llvm.dbg.func.start.".
-void CGDebugInfo::EmitFunctionStart(const FunctionDecl *FnDecl,
- llvm::Function *Fn,
- llvm::IRBuilder<> &Builder)
-{
- // Create subprogram descriptor.
- Subprogram = new llvm::SubprogramDesc();
-
- // Make sure we have an anchor.
- if (!SubprogramAnchor) {
- SubprogramAnchor = new llvm::AnchorDesc(Subprogram);
- }
-
- // Get name information.
- Subprogram->setName(FnDecl->getName());
- Subprogram->setFullName(FnDecl->getName());
-
- // Gather location information.
- llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Loc = SM.getLogicalLineNumber(CurLoc);
-
- // Get Function Type.
- QualType type = FnDecl->getResultType();
- llvm::TypeDesc *SPTy = getOrCreateType(type, Unit);
-
- Subprogram->setAnchor(SubprogramAnchor);
- Subprogram->setContext(Unit);
- Subprogram->setFile(Unit);
- Subprogram->setLine(Loc);
- Subprogram->setType(SPTy);
- Subprogram->setIsStatic(Fn->hasInternalLinkage());
- Subprogram->setIsDefinition(true);
-
- // Lazily construct llvm.dbg.func.start.
- if (!FuncStartFn)
- FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
- llvm::Intrinsic::dbg_func_start);
-
- // Call llvm.dbg.func.start which also implicitly calls llvm.dbg.stoppoint.
- Builder.CreateCall(FuncStartFn, getCastValueFor(Subprogram), "");
-
- // Push function on region stack.
- RegionStack.push_back(Subprogram);
-}
-
-
-void
-CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder<> &Builder)
-{
- if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
-
- // Don't bother if things are the same as last time.
- SourceManager &SM = M->getContext().getSourceManager();
- if (CurLoc == PrevLoc
- || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc)
- && SM.isFromSameFile(CurLoc, PrevLoc)))
- return;
-
- // Update last state.
- PrevLoc = CurLoc;
-
- // Get the appropriate compile unit.
- llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
-
- // Lazily construct llvm.dbg.stoppoint function.
- if (!StopPointFn)
- StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
- llvm::Intrinsic::dbg_stoppoint);
-
- uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc);
- uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc);
-
- // Invoke llvm.dbg.stoppoint
- Builder.CreateCall3(StopPointFn,
- llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo),
- getCastValueFor(Unit), "");
-}
-
-/// EmitRegionStart- Constructs the debug code for entering a declarative
-/// region - "llvm.dbg.region.start.".
-void CGDebugInfo::EmitRegionStart(llvm::Function *Fn,
- llvm::IRBuilder<> &Builder)
-{
- llvm::BlockDesc *Block = new llvm::BlockDesc();
- if (RegionStack.size() > 0)
- Block->setContext(RegionStack.back());
- RegionStack.push_back(Block);
-
- // Lazily construct llvm.dbg.region.start function.
- if (!RegionStartFn)
- RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
- llvm::Intrinsic::dbg_region_start);
-
- // Call llvm.dbg.func.start.
- Builder.CreateCall(RegionStartFn, getCastValueFor(Block), "");
-}
-
-/// EmitRegionEnd - Constructs the debug code for exiting a declarative
-/// region - "llvm.dbg.region.end."
-void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder<> &Builder)
-{
- // Lazily construct llvm.dbg.region.end function.
- if (!RegionEndFn)
- RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(),
- llvm::Intrinsic::dbg_region_end);
-
- // Provide an region stop point.
- EmitStopPoint(Fn, Builder);
-
- // Call llvm.dbg.func.end.
- llvm::DebugInfoDesc *DID = RegionStack.back();
- Builder.CreateCall(RegionEndFn, getCastValueFor(DID), "");
- RegionStack.pop_back();
-}
-
-/// EmitDeclare - Emit local variable declaration debug info.
-void CGDebugInfo::EmitDeclare(const VarDecl *decl, unsigned Tag,
- llvm::Value *AI,
- llvm::IRBuilder<> &Builder)
-{
- // FIXME: If it is a compiler generated temporary then return.
-
- // Construct llvm.dbg.declare function.
- if (!DeclareFn)
- DeclareFn = llvm::Intrinsic::getDeclaration(&M->getModule(),
- llvm::Intrinsic::dbg_declare);
-
- // Get type information.
- llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
- llvm::TypeDesc *TyDesc = getOrCreateType(decl->getType(), Unit);
-
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Loc = SM.getLogicalLineNumber(CurLoc);
-
- // Construct variable.
- llvm::VariableDesc *Variable = new llvm::VariableDesc(Tag);
- Variable->setContext(RegionStack.back());
- Variable->setName(decl->getName());
- Variable->setFile(Unit);
- Variable->setLine(Loc);
- Variable->setType(TyDesc);
-
- // Push it onto the list so that we can free it.
- VariableDescList.push_back(Variable);
-
- // Cast the AllocA result to a {}* for the call to llvm.dbg.declare.
- // These bit cast instructions will get freed when the basic block is
- // deleted. So do not need to free them explicity.
- const llvm::PointerType *EmpPtr = SR->getEmptyStructPtrType();
- llvm::Value *AllocACast = new llvm::BitCastInst(AI, EmpPtr, decl->getName(),
- Builder.GetInsertBlock());
-
- // Call llvm.dbg.declare.
- Builder.CreateCall2(DeclareFn, AllocACast, getCastValueFor(Variable), "");
-}
-
-/// EmitGlobalVariable - Emit information about a global variable.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *GV,
- const VarDecl *decl)
-{
- // Create global variable debug descriptor.
- llvm::GlobalVariableDesc *Global = new llvm::GlobalVariableDesc();
-
- // Push it onto the list so that we can free it.
- GlobalVarDescList.push_back(Global);
-
- // Make sure we have an anchor.
- if (!GlobalVariableAnchor)
- GlobalVariableAnchor = new llvm::AnchorDesc(Global);
-
- // Get name information.
- Global->setName(decl->getName());
- Global->setFullName(decl->getName());
-
- llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
- SourceManager &SM = M->getContext().getSourceManager();
- uint64_t Loc = SM.getLogicalLineNumber(CurLoc);
-
- llvm::TypeDesc *TyD = getOrCreateType(decl->getType(), Unit);
-
- // Fill in the Global information.
- Global->setAnchor(GlobalVariableAnchor);
- Global->setContext(Unit);
- Global->setFile(Unit);
- Global->setLine(Loc);
- Global->setType(TyD);
- Global->setIsDefinition(true);
- Global->setIsStatic(GV->hasInternalLinkage());
- Global->setGlobalVariable(GV);
-
- // Make sure global is created if needed.
- getValueFor(Global);
-}
-
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
deleted file mode 100644
index 7e41143837c3..000000000000
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the source level debug info generator for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CGDEBUGINFO_H
-#define CLANG_CODEGEN_CGDEBUGINFO_H
-
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/IRBuilder.h"
-#include <map>
-#include <vector>
-
-
-namespace llvm {
- class Function;
- class DISerializer;
- class CompileUnitDesc;
- class BasicBlock;
- class AnchorDesc;
- class DebugInfoDesc;
- class Value;
- class TypeDesc;
- class VariableDesc;
- class SubprogramDesc;
- class GlobalVariable;
- class GlobalVariableDesc;
- class EnumeratorDesc;
- class SubrangeDesc;
-}
-
-namespace clang {
- class FunctionDecl;
- class VarDecl;
-namespace CodeGen {
- class CodeGenModule;
-
-/// CGDebugInfo - This class gathers all debug information during compilation
-/// and is responsible for emitting to llvm globals or pass directly to
-/// the backend.
-class CGDebugInfo {
-private:
- CodeGenModule *M;
- llvm::DISerializer *SR;
- SourceLocation CurLoc;
- SourceLocation PrevLoc;
-
- typedef llvm::IRBuilder<> BuilderType;
-
- /// CompileUnitCache - Cache of previously constructed CompileUnits.
- std::map<unsigned, llvm::CompileUnitDesc *> CompileUnitCache;
-
- /// TypeCache - Cache of previously constructed Types.
- std::map<void *, llvm::TypeDesc *> TypeCache;
-
- llvm::Function *StopPointFn;
- llvm::Function *FuncStartFn;
- llvm::Function *DeclareFn;
- llvm::Function *RegionStartFn;
- llvm::Function *RegionEndFn;
- llvm::AnchorDesc *CompileUnitAnchor;
- llvm::AnchorDesc *SubprogramAnchor;
- llvm::AnchorDesc *GlobalVariableAnchor;
- std::vector<llvm::DebugInfoDesc *> RegionStack;
- std::vector<llvm::VariableDesc *> VariableDescList;
- std::vector<llvm::GlobalVariableDesc *> GlobalVarDescList;
- std::vector<llvm::EnumeratorDesc *> EnumDescList;
- std::vector<llvm::SubrangeDesc *> SubrangeDescList;
- llvm::SubprogramDesc *Subprogram;
-
- /// Helper functions for getOrCreateType.
- llvm::TypeDesc *getOrCreateCVRType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateBuiltinType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateTypedefType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreatePointerType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateFunctionType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateRecordType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateEnumType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateTaggedType(QualType type,
- llvm::CompileUnitDesc *unit);
- llvm::TypeDesc *getOrCreateArrayType(QualType type,
- llvm::CompileUnitDesc *unit);
-
-public:
- CGDebugInfo(CodeGenModule *m);
- ~CGDebugInfo();
-
- void setLocation(SourceLocation loc);
-
- /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
- /// source line.
- void EmitStopPoint(llvm::Function *Fn, BuilderType &Builder);
-
- /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate
- /// start of a new function
- void EmitFunctionStart(const FunctionDecl *FnDecl, llvm::Function *Fn,
- BuilderType &Builder);
-
- /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start
- /// of a new block.
- void EmitRegionStart(llvm::Function *Fn, BuilderType &Builder);
-
- /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a
- /// block.
- void EmitRegionEnd(llvm::Function *Fn, BuilderType &Builder);
-
- /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
- void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
- BuilderType &Builder);
-
- /// EmitGlobalVariable - Emit information about a global variable.
- void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *decl);
-
- /// getOrCreateCompileUnit - Get the compile unit from the cache or create a
- /// new one if necessary.
- llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc);
-
- /// getOrCreateType - Get the type from the cache or create a new type if
- /// necessary.
- llvm::TypeDesc *getOrCreateType(QualType type, llvm::CompileUnitDesc *unit);
-
- /// getCastValueFor - Return a llvm representation for a given debug
- /// information descriptor cast to an empty struct pointer.
- llvm::Value *getCastValueFor(llvm::DebugInfoDesc *DD);
-
- /// getValueFor - Return a llvm representation for a given debug information
- /// descriptor.
- llvm::Value *getValueFor(llvm::DebugInfoDesc *DD);
-};
-} // namespace CodeGen
-} // namespace clang
-
-#endif
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
deleted file mode 100644
index 6ab227d95a8f..000000000000
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
-//
-// 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 emit Decl nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGDebugInfo.h"
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Type.h"
-#include "llvm/Support/Dwarf.h"
-using namespace clang;
-using namespace CodeGen;
-
-
-void CodeGenFunction::EmitDecl(const Decl &D) {
- switch (D.getKind()) {
- default: assert(0 && "Unknown decl kind!");
- case Decl::ParmVar:
- assert(0 && "Parmdecls should not be in declstmts!");
- case Decl::Typedef: // typedef int X;
- case Decl::Function: // void X();
- case Decl::Struct: // struct X;
- case Decl::Union: // union X;
- case Decl::Class: // class X;
- case Decl::Enum: // enum X;
- case Decl::EnumConstant: // enum ? { X = ? }
- case Decl::CXXStruct: // struct X; [C++]
- case Decl::CXXUnion: // union X; [C++]
- case Decl::CXXClass: // class X; [C++]
- // None of these decls require codegen support.
- return;
-
- case Decl::Var: {
- const VarDecl &VD = cast<VarDecl>(D);
- assert(VD.isBlockVarDecl() &&
- "Should not see file-scope variables inside a function!");
- return EmitBlockVarDecl(VD);
- }
- }
-}
-
-/// EmitBlockVarDecl - This method handles emission of any variable declaration
-/// inside a function, including static vars etc.
-void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
- switch (D.getStorageClass()) {
- case VarDecl::Static:
- return EmitStaticBlockVarDecl(D);
- case VarDecl::Extern:
- // Don't emit it now, allow it to be emitted lazily on its first use.
- return;
- default:
- assert((D.getStorageClass() == VarDecl::None ||
- D.getStorageClass() == VarDecl::Auto ||
- D.getStorageClass() == VarDecl::Register) &&
- "Unknown storage class");
- return EmitLocalBlockVarDecl(D);
- }
-}
-
-llvm::GlobalValue *
-CodeGenFunction::GenerateStaticBlockVarDecl(const VarDecl &D,
- bool NoInit,
- const char *Separator) {
- QualType Ty = D.getType();
- assert(Ty->isConstantSizeType() && "VLAs can't be static");
-
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
- llvm::Constant *Init = 0;
- if ((D.getInit() == 0) || NoInit) {
- Init = llvm::Constant::getNullValue(LTy);
- } else {
- if (D.getInit()->isConstantExpr(getContext(), 0))
- Init = CGM.EmitConstantExpr(D.getInit(), this);
- else {
- assert(getContext().getLangOptions().CPlusPlus &&
- "only C++ supports non-constant static initializers!");
- return GenerateStaticCXXBlockVarDecl(D);
- }
- }
-
- assert(Init && "Unable to create initialiser for static decl");
-
- std::string ContextName;
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl))
- ContextName = FD->getName();
- else if (isa<ObjCMethodDecl>(CurFuncDecl))
- ContextName = std::string(CurFn->getNameStart(),
- CurFn->getNameStart() + CurFn->getNameLen());
- else
- assert(0 && "Unknown context for block var decl");
-
- llvm::GlobalValue *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init, ContextName + Separator + D.getName(),
- &CGM.getModule(), 0, Ty.getAddressSpace());
-
- return GV;
-}
-
-void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
-
- llvm::GlobalValue *GV = GenerateStaticBlockVarDecl(D, false, ".");
-
- if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
- SourceManager &SM = CGM.getContext().getSourceManager();
- llvm::Constant *Ann =
- CGM.EmitAnnotateAttr(GV, AA, SM.getLogicalLineNumber(D.getLocation()));
- CGM.AddAnnotation(Ann);
- }
-
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
- const llvm::Type *LPtrTy =
- llvm::PointerType::get(LTy, D.getType().getAddressSpace());
- DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
-
- // Emit global variable debug descriptor for static vars.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if(DI) {
- if(D.getLocation().isValid())
- DI->setLocation(D.getLocation());
- DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
- }
-
-}
-
-/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
-/// variable declaration with auto, register, or no storage class specifier.
-/// These turn into simple stack objects, or GlobalValues depending on target.
-void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
- QualType Ty = D.getType();
-
- llvm::Value *DeclPtr;
- if (Ty->isConstantSizeType()) {
- if (!Target.useGlobalsForAutomaticVariables()) {
- // A normal fixed sized variable becomes an alloca in the entry block.
- const llvm::Type *LTy = ConvertType(Ty);
- llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getName());
- unsigned align = getContext().getTypeAlign(Ty);
- if (const AlignedAttr* AA = D.getAttr<AlignedAttr>())
- align = std::max(align, AA->getAlignment());
- Alloc->setAlignment(align >> 3);
- DeclPtr = Alloc;
- } else {
- // Targets that don't support recursion emit locals as globals.
- const char *Class =
- D.getStorageClass() == VarDecl::Register ? ".reg." : ".auto.";
- DeclPtr = GenerateStaticBlockVarDecl(D, true, Class);
- }
- } else {
- CGM.ErrorUnsupported(&D, "variable-length array");
-
- // FIXME: VLA: Add VLA support. For now just make up enough to let
- // the compile go through.
- const llvm::Type *LTy = ConvertType(Ty);
- llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getName());
- DeclPtr = Alloc;
- }
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
- DMEntry = DeclPtr;
-
- // Emit debug info for local var declaration.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if(DI) {
- if(D.getLocation().isValid())
- DI->setLocation(D.getLocation());
- DI->EmitDeclare(&D, llvm::dwarf::DW_TAG_auto_variable,
- DeclPtr, Builder);
- }
-
- // If this local has an initializer, emit it now.
- if (const Expr *Init = D.getInit()) {
- if (!hasAggregateLLVMType(Init->getType())) {
- llvm::Value *V = EmitScalarExpr(Init);
- Builder.CreateStore(V, DeclPtr, D.getType().isVolatileQualified());
- } else if (Init->getType()->isAnyComplexType()) {
- EmitComplexExprIntoAddr(Init, DeclPtr, D.getType().isVolatileQualified());
- } else {
- EmitAggExpr(Init, DeclPtr, D.getType().isVolatileQualified());
- }
- }
-}
-
-/// Emit an alloca (or GlobalValue depending on target)
-/// for the specified parameter and set up LocalDeclMap.
-void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) {
- // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
- assert(isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) &&
- "Invalid argument to EmitParmDecl");
- QualType Ty = D.getType();
-
- llvm::Value *DeclPtr;
- if (!Ty->isConstantSizeType()) {
- // Variable sized values always are passed by-reference.
- DeclPtr = Arg;
- } else if (Target.useGlobalsForAutomaticVariables()) {
- DeclPtr = GenerateStaticBlockVarDecl(D, true, ".arg.");
- } else {
- // A fixed sized single-value variable becomes an alloca in the entry block.
- const llvm::Type *LTy = ConvertType(Ty);
- if (LTy->isSingleValueType()) {
- // TODO: Alignment
- std::string Name(D.getName());
- Name += ".addr";
- DeclPtr = CreateTempAlloca(LTy, Name.c_str());
-
- // Store the initial value into the alloca.
- Builder.CreateStore(Arg, DeclPtr,Ty.isVolatileQualified());
- } else {
- // Otherwise, if this is an aggregate, just use the input pointer.
- DeclPtr = Arg;
- }
- Arg->setName(D.getName());
- }
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
- DMEntry = DeclPtr;
-
- // Emit debug info for param declaration.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if(DI) {
- if(D.getLocation().isValid())
- DI->setLocation(D.getLocation());
- DI->EmitDeclare(&D, llvm::dwarf::DW_TAG_arg_variable,
- DeclPtr, Builder);
- }
-
-}
-
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
deleted file mode 100644
index 872e3d1af4ae..000000000000
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ /dev/null
@@ -1,887 +0,0 @@
-//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
-//
-// 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 emit Expr nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "CGCall.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Target/TargetData.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===--------------------------------------------------------------------===//
-// Miscellaneous Helper Methods
-//===--------------------------------------------------------------------===//
-
-/// CreateTempAlloca - This creates a alloca and inserts it into the entry
-/// block.
-llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
- const char *Name) {
- return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
-}
-
-/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
-/// expression and compare the result against zero, returning an Int1Ty value.
-llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
- QualType BoolTy = getContext().BoolTy;
- if (!E->getType()->isAnyComplexType())
- return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
-
- return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
-}
-
-/// EmitAnyExpr - Emit code to compute the specified expression which can have
-/// any type. The result is returned as an RValue struct. If this is an
-/// aggregate expression, the aggloc/agglocvolatile arguments indicate where
-/// the result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
- bool isAggLocVolatile) {
- if (!hasAggregateLLVMType(E->getType()))
- return RValue::get(EmitScalarExpr(E));
- else if (E->getType()->isAnyComplexType())
- return RValue::getComplex(EmitComplexExpr(E));
-
- EmitAggExpr(E, AggLoc, isAggLocVolatile);
- return RValue::getAggregate(AggLoc);
-}
-
-/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result
-/// will always be accessible even if no aggregate location is
-/// provided.
-RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc,
- bool isAggLocVolatile) {
- if (!AggLoc && hasAggregateLLVMType(E->getType()) &&
- !E->getType()->isAnyComplexType())
- AggLoc = CreateTempAlloca(ConvertType(E->getType()), "agg.tmp");
- return EmitAnyExpr(E, AggLoc, isAggLocVolatile);
-}
-
-/// getAccessedFieldNo - Given an encoded value and a result number, return
-/// the input field number being accessed.
-unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
- const llvm::Constant *Elts) {
- if (isa<llvm::ConstantAggregateZero>(Elts))
- return 0;
-
- return cast<llvm::ConstantInt>(Elts->getOperand(Idx))->getZExtValue();
-}
-
-
-//===----------------------------------------------------------------------===//
-// LValue Expression Emission
-//===----------------------------------------------------------------------===//
-
-LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
- const char *Name) {
- ErrorUnsupported(E, Name);
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return LValue::MakeAddr(llvm::UndefValue::get(Ty),
- E->getType().getCVRQualifiers());
-}
-
-/// EmitLValue - Emit code to compute a designator that specifies the location
-/// of the expression.
-///
-/// This can return one of two things: a simple address or a bitfield
-/// reference. In either case, the LLVM Value* in the LValue structure is
-/// guaranteed to be an LLVM pointer type.
-///
-/// If this returns a bitfield reference, nothing about the pointee type of
-/// the LLVM value is known: For example, it may not be a pointer to an
-/// integer.
-///
-/// If this returns a normal address, and if the lvalue's C type is fixed
-/// size, this method guarantees that the returned pointer type will point to
-/// an LLVM type of the same size of the lvalue's type. If the lvalue has a
-/// variable length type, this is not possible.
-///
-LValue CodeGenFunction::EmitLValue(const Expr *E) {
- switch (E->getStmtClass()) {
- default: return EmitUnsupportedLValue(E, "l-value expression");
-
- case Expr::BinaryOperatorClass:
- return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
- case Expr::CallExprClass: return EmitCallExprLValue(cast<CallExpr>(E));
- case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
- case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
- case Expr::PredefinedExprClass:
- return EmitPredefinedLValue(cast<PredefinedExpr>(E));
- case Expr::StringLiteralClass:
- return EmitStringLiteralLValue(cast<StringLiteral>(E));
-
- case Expr::CXXConditionDeclExprClass:
- return EmitCXXConditionDeclLValue(cast<CXXConditionDeclExpr>(E));
-
- case Expr::ObjCMessageExprClass:
- return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
- case Expr::ObjCIvarRefExprClass:
- return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
- case Expr::ObjCPropertyRefExprClass:
- return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
-
- case Expr::UnaryOperatorClass:
- return EmitUnaryOpLValue(cast<UnaryOperator>(E));
- case Expr::ArraySubscriptExprClass:
- return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
- case Expr::ExtVectorElementExprClass:
- return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
- case Expr::MemberExprClass: return EmitMemberExpr(cast<MemberExpr>(E));
- case Expr::CompoundLiteralExprClass:
- return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
- }
-}
-
-/// EmitLoadOfLValue - Given an expression that represents a value lvalue,
-/// this method emits the address of the lvalue, then loads the result as an
-/// rvalue, returning the rvalue.
-RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
- if (LV.isSimple()) {
- llvm::Value *Ptr = LV.getAddress();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
-
- // Simple scalar l-value.
- if (EltTy->isSingleValueType()) {
- llvm::Value *V = Builder.CreateLoad(Ptr, LV.isVolatileQualified(),"tmp");
-
- // Bool can have different representation in memory than in registers.
- if (ExprType->isBooleanType()) {
- if (V->getType() != llvm::Type::Int1Ty)
- V = Builder.CreateTrunc(V, llvm::Type::Int1Ty, "tobool");
- }
-
- return RValue::get(V);
- }
-
- assert(ExprType->isFunctionType() && "Unknown scalar value");
- return RValue::get(Ptr);
- }
-
- if (LV.isVectorElt()) {
- llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(),
- LV.isVolatileQualified(), "tmp");
- return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
- "vecext"));
- }
-
- // If this is a reference to a subset of the elements of a vector, either
- // shuffle the input or extract/insert them as appropriate.
- if (LV.isExtVectorElt())
- return EmitLoadOfExtVectorElementLValue(LV, ExprType);
-
- if (LV.isBitfield())
- return EmitLoadOfBitfieldLValue(LV, ExprType);
-
- if (LV.isPropertyRef())
- return EmitLoadOfPropertyRefLValue(LV, ExprType);
-
- assert(0 && "Unknown LValue type!");
- //an invalid RValue, but the assert will
- //ensure that this point is never reached
- return RValue();
-}
-
-RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
- QualType ExprType) {
- unsigned StartBit = LV.getBitfieldStartBit();
- unsigned BitfieldSize = LV.getBitfieldSize();
- llvm::Value *Ptr = LV.getBitfieldAddr();
-
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- unsigned EltTySize = CGM.getTargetData().getTypeSizeInBits(EltTy);
-
- // In some cases the bitfield may straddle two memory locations.
- // Currently we load the entire bitfield, then do the magic to
- // sign-extend it if necessary. This results in somewhat more code
- // than necessary for the common case (one load), since two shifts
- // accomplish both the masking and sign extension.
- unsigned LowBits = std::min(BitfieldSize, EltTySize - StartBit);
- llvm::Value *Val = Builder.CreateLoad(Ptr, LV.isVolatileQualified(), "tmp");
-
- // Shift to proper location.
- Val = Builder.CreateLShr(Val, llvm::ConstantInt::get(EltTy, StartBit),
- "bf.lo");
-
- // Mask off unused bits.
- llvm::Constant *LowMask =
- llvm::ConstantInt::get(llvm::APInt::getLowBitsSet(EltTySize, LowBits));
- Val = Builder.CreateAnd(Val, LowMask, "bf.lo.cleared");
-
- // Fetch the high bits if necessary.
- if (LowBits < BitfieldSize) {
- unsigned HighBits = BitfieldSize - LowBits;
- llvm::Value *HighPtr =
- Builder.CreateGEP(Ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, 1),
- "bf.ptr.hi");
- llvm::Value *HighVal = Builder.CreateLoad(HighPtr,
- LV.isVolatileQualified(),
- "tmp");
-
- // Mask off unused bits.
- llvm::Constant *HighMask =
- llvm::ConstantInt::get(llvm::APInt::getLowBitsSet(EltTySize, HighBits));
- HighVal = Builder.CreateAnd(HighVal, HighMask, "bf.lo.cleared");
-
- // Shift to proper location and or in to bitfield value.
- HighVal = Builder.CreateShl(HighVal,
- llvm::ConstantInt::get(EltTy, LowBits));
- Val = Builder.CreateOr(Val, HighVal, "bf.val");
- }
-
- // Sign extend if necessary.
- if (LV.isBitfieldSigned()) {
- llvm::Value *ExtraBits = llvm::ConstantInt::get(EltTy,
- EltTySize - BitfieldSize);
- Val = Builder.CreateAShr(Builder.CreateShl(Val, ExtraBits),
- ExtraBits, "bf.val.sext");
- }
-
- // The bitfield type and the normal type differ when the storage sizes
- // differ (currently just _Bool).
- Val = Builder.CreateIntCast(Val, ConvertType(ExprType), false, "tmp");
-
- return RValue::get(Val);
-}
-
-RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
- QualType ExprType) {
- return EmitObjCPropertyGet(LV.getPropertyRefExpr());
-}
-
-// If this is a reference to a subset of the elements of a vector, either
-// shuffle the input or extract/insert them as appropriate.
-RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
- QualType ExprType) {
- llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(),
- LV.isVolatileQualified(), "tmp");
-
- const llvm::Constant *Elts = LV.getExtVectorElts();
-
- // If the result of the expression is a non-vector type, we must be
- // extracting a single element. Just codegen as an extractelement.
- const VectorType *ExprVT = ExprType->getAsVectorType();
- if (!ExprVT) {
- unsigned InIdx = getAccessedFieldNo(0, Elts);
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
- return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
- }
-
- // If the source and destination have the same number of elements, use a
- // vector shuffle instead of insert/extracts.
- unsigned NumResultElts = ExprVT->getNumElements();
- unsigned NumSourceElts =
- cast<llvm::VectorType>(Vec->getType())->getNumElements();
-
- if (NumResultElts == NumSourceElts) {
- llvm::SmallVector<llvm::Constant*, 4> Mask;
- for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = getAccessedFieldNo(i, Elts);
- Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
- }
-
- llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
- Vec = Builder.CreateShuffleVector(Vec,
- llvm::UndefValue::get(Vec->getType()),
- MaskV, "tmp");
- return RValue::get(Vec);
- }
-
- // Start out with an undef of the result type.
- llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
-
- // Extract/Insert each element of the result.
- for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = getAccessedFieldNo(i, Elts);
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
- Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
-
- llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp");
- }
-
- return RValue::get(Result);
-}
-
-
-
-/// EmitStoreThroughLValue - Store the specified rvalue into the specified
-/// lvalue, where both are guaranteed to the have the same type, and that type
-/// is 'Ty'.
-void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
- QualType Ty) {
- if (!Dst.isSimple()) {
- if (Dst.isVectorElt()) {
- // Read/modify/write the vector, inserting the new element.
- llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(),
- Dst.isVolatileQualified(), "tmp");
- Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
- Dst.getVectorIdx(), "vecins");
- Builder.CreateStore(Vec, Dst.getVectorAddr(),Dst.isVolatileQualified());
- return;
- }
-
- // If this is an update of extended vector elements, insert them as
- // appropriate.
- if (Dst.isExtVectorElt())
- return EmitStoreThroughExtVectorComponentLValue(Src, Dst, Ty);
-
- if (Dst.isBitfield())
- return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
-
- if (Dst.isPropertyRef())
- return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty);
-
- assert(0 && "Unknown LValue type");
- }
-
- llvm::Value *DstAddr = Dst.getAddress();
- assert(Src.isScalar() && "Can't emit an agg store with this method");
- // FIXME: Handle volatility etc.
- const llvm::Type *SrcTy = Src.getScalarVal()->getType();
- const llvm::PointerType *DstPtr = cast<llvm::PointerType>(DstAddr->getType());
- const llvm::Type *AddrTy = DstPtr->getElementType();
- unsigned AS = DstPtr->getAddressSpace();
-
- if (AddrTy != SrcTy)
- DstAddr = Builder.CreateBitCast(DstAddr,
- llvm::PointerType::get(SrcTy, AS),
- "storetmp");
- Builder.CreateStore(Src.getScalarVal(), DstAddr, Dst.isVolatileQualified());
-}
-
-void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
- QualType Ty) {
- unsigned StartBit = Dst.getBitfieldStartBit();
- unsigned BitfieldSize = Dst.getBitfieldSize();
- llvm::Value *Ptr = Dst.getBitfieldAddr();
-
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- unsigned EltTySize = CGM.getTargetData().getTypeSizeInBits(EltTy);
-
- // Get the new value, cast to the appropriate type and masked to
- // exactly the size of the bit-field.
- llvm::Value *NewVal = Src.getScalarVal();
- NewVal = Builder.CreateIntCast(NewVal, EltTy, false, "tmp");
- llvm::Constant *Mask =
- llvm::ConstantInt::get(llvm::APInt::getLowBitsSet(EltTySize, BitfieldSize));
- NewVal = Builder.CreateAnd(NewVal, Mask, "bf.value");
-
- // In some cases the bitfield may straddle two memory locations.
- // Emit the low part first and check to see if the high needs to be
- // done.
- unsigned LowBits = std::min(BitfieldSize, EltTySize - StartBit);
- llvm::Value *LowVal = Builder.CreateLoad(Ptr, Dst.isVolatileQualified(),
- "bf.prev.low");
-
- // Compute the mask for zero-ing the low part of this bitfield.
- llvm::Constant *InvMask =
- llvm::ConstantInt::get(~llvm::APInt::getBitsSet(EltTySize, StartBit,
- StartBit + LowBits));
-
- // Compute the new low part as
- // LowVal = (LowVal & InvMask) | (NewVal << StartBit),
- // with the shift of NewVal implicitly stripping the high bits.
- llvm::Value *NewLowVal =
- Builder.CreateShl(NewVal, llvm::ConstantInt::get(EltTy, StartBit),
- "bf.value.lo");
- LowVal = Builder.CreateAnd(LowVal, InvMask, "bf.prev.lo.cleared");
- LowVal = Builder.CreateOr(LowVal, NewLowVal, "bf.new.lo");
-
- // Write back.
- Builder.CreateStore(LowVal, Ptr, Dst.isVolatileQualified());
-
- // If the low part doesn't cover the bitfield emit a high part.
- if (LowBits < BitfieldSize) {
- unsigned HighBits = BitfieldSize - LowBits;
- llvm::Value *HighPtr =
- Builder.CreateGEP(Ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, 1),
- "bf.ptr.hi");
- llvm::Value *HighVal = Builder.CreateLoad(HighPtr,
- Dst.isVolatileQualified(),
- "bf.prev.hi");
-
- // Compute the mask for zero-ing the high part of this bitfield.
- llvm::Constant *InvMask =
- llvm::ConstantInt::get(~llvm::APInt::getLowBitsSet(EltTySize, HighBits));
-
- // Compute the new high part as
- // HighVal = (HighVal & InvMask) | (NewVal lshr LowBits),
- // where the high bits of NewVal have already been cleared and the
- // shift stripping the low bits.
- llvm::Value *NewHighVal =
- Builder.CreateLShr(NewVal, llvm::ConstantInt::get(EltTy, LowBits),
- "bf.value.high");
- HighVal = Builder.CreateAnd(HighVal, InvMask, "bf.prev.hi.cleared");
- HighVal = Builder.CreateOr(HighVal, NewHighVal, "bf.new.hi");
-
- // Write back.
- Builder.CreateStore(HighVal, HighPtr, Dst.isVolatileQualified());
- }
-}
-
-void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
- LValue Dst,
- QualType Ty) {
- EmitObjCPropertySet(Dst.getPropertyRefExpr(), Src);
-}
-
-void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
- LValue Dst,
- QualType Ty) {
- // This access turns into a read/modify/write of the vector. Load the input
- // value now.
- llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddr(),
- Dst.isVolatileQualified(), "tmp");
- const llvm::Constant *Elts = Dst.getExtVectorElts();
-
- llvm::Value *SrcVal = Src.getScalarVal();
-
- if (const VectorType *VTy = Ty->getAsVectorType()) {
- unsigned NumSrcElts = VTy->getNumElements();
-
- // Extract/Insert each element.
- for (unsigned i = 0; i != NumSrcElts; ++i) {
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Elt = Builder.CreateExtractElement(SrcVal, Elt, "tmp");
-
- unsigned Idx = getAccessedFieldNo(i, Elts);
- llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Idx);
- Vec = Builder.CreateInsertElement(Vec, Elt, OutIdx, "tmp");
- }
- } else {
- // If the Src is a scalar (not a vector) it must be updating one element.
- unsigned InIdx = getAccessedFieldNo(0, Elts);
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
- Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
- }
-
- Builder.CreateStore(Vec, Dst.getExtVectorAddr(), Dst.isVolatileQualified());
-}
-
-
-LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
- const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
-
- if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD) ||
- isa<ImplicitParamDecl>(VD))) {
- if (VD->getStorageClass() == VarDecl::Extern)
- return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
- E->getType().getCVRQualifiers());
- else {
- llvm::Value *V = LocalDeclMap[VD];
- assert(V && "BlockVarDecl not entered in LocalDeclMap?");
- return LValue::MakeAddr(V, E->getType().getCVRQualifiers());
- }
- } else if (VD && VD->isFileVarDecl()) {
- return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
- E->getType().getCVRQualifiers());
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
- return LValue::MakeAddr(CGM.GetAddrOfFunction(FD),
- E->getType().getCVRQualifiers());
- }
- else if (const ImplicitParamDecl *IPD =
- dyn_cast<ImplicitParamDecl>(E->getDecl())) {
- llvm::Value *V = LocalDeclMap[IPD];
- assert(V && "BlockVarDecl not entered in LocalDeclMap?");
- return LValue::MakeAddr(V, E->getType().getCVRQualifiers());
- }
- assert(0 && "Unimp declref");
- //an invalid LValue, but the assert will
- //ensure that this point is never reached.
- return LValue();
-}
-
-LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
- // __extension__ doesn't affect lvalue-ness.
- if (E->getOpcode() == UnaryOperator::Extension)
- return EmitLValue(E->getSubExpr());
-
- QualType ExprTy = getContext().getCanonicalType(E->getSubExpr()->getType());
- switch (E->getOpcode()) {
- default: assert(0 && "Unknown unary operator lvalue!");
- case UnaryOperator::Deref:
- return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()),
- ExprTy->getAsPointerType()->getPointeeType()
- .getCVRQualifiers());
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- LValue LV = EmitLValue(E->getSubExpr());
- unsigned Idx = E->getOpcode() == UnaryOperator::Imag;
- return LValue::MakeAddr(Builder.CreateStructGEP(LV.getAddress(),
- Idx, "idx"),
- ExprTy.getCVRQualifiers());
- }
-}
-
-LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
- return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E), 0);
-}
-
-LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
- std::string FunctionName;
- if(const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
- FunctionName = FD->getName();
- } else if (isa<ObjCMethodDecl>(CurFuncDecl)) {
- // Just get the mangled name.
- FunctionName = CurFn->getName();
- } else {
- return EmitUnsupportedLValue(E, "predefined expression");
- }
- std::string GlobalVarName;
-
- switch (E->getIdentType()) {
- default:
- return EmitUnsupportedLValue(E, "predefined expression");
- case PredefinedExpr::Func:
- GlobalVarName = "__func__.";
- break;
- case PredefinedExpr::Function:
- GlobalVarName = "__FUNCTION__.";
- break;
- case PredefinedExpr::PrettyFunction:
- // FIXME:: Demangle C++ method names
- GlobalVarName = "__PRETTY_FUNCTION__.";
- break;
- }
-
- GlobalVarName += FunctionName;
-
- // FIXME: Can cache/reuse these within the module.
- llvm::Constant *C = llvm::ConstantArray::get(FunctionName);
-
- // Create a global variable for this.
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, GlobalVarName, CurFn->getParent());
- return LValue::MakeAddr(C,0);
-}
-
-LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
- // The index must always be an integer, which is not an aggregate. Emit it.
- llvm::Value *Idx = EmitScalarExpr(E->getIdx());
-
- // If the base is a vector type, then we are forming a vector element lvalue
- // with this subscript.
- if (E->getBase()->getType()->isVectorType()) {
- // Emit the vector as an lvalue to get its address.
- LValue LHS = EmitLValue(E->getBase());
- assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
- // FIXME: This should properly sign/zero/extend or truncate Idx to i32.
- return LValue::MakeVectorElt(LHS.getAddress(), Idx,
- E->getBase()->getType().getCVRQualifiers());
- }
-
- // The base must be a pointer, which is not an aggregate. Emit it.
- llvm::Value *Base = EmitScalarExpr(E->getBase());
-
- // Extend or truncate the index type to 32 or 64-bits.
- QualType IdxTy = E->getIdx()->getType();
- bool IdxSigned = IdxTy->isSignedIntegerType();
- unsigned IdxBitwidth = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
- if (IdxBitwidth != LLVMPointerWidth)
- Idx = Builder.CreateIntCast(Idx, llvm::IntegerType::get(LLVMPointerWidth),
- IdxSigned, "idxprom");
-
- // We know that the pointer points to a type of the correct size, unless the
- // size is a VLA.
- if (!E->getType()->isConstantSizeType())
- return EmitUnsupportedLValue(E, "VLA index");
- QualType ExprTy = getContext().getCanonicalType(E->getBase()->getType());
-
- return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"),
- ExprTy->getAsPointerType()->getPointeeType()
- .getCVRQualifiers());
-}
-
-static
-llvm::Constant *GenerateConstantVector(llvm::SmallVector<unsigned, 4> &Elts) {
- llvm::SmallVector<llvm::Constant *, 4> CElts;
-
- for (unsigned i = 0, e = Elts.size(); i != e; ++i)
- CElts.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, Elts[i]));
-
- return llvm::ConstantVector::get(&CElts[0], CElts.size());
-}
-
-LValue CodeGenFunction::
-EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
- // Emit the base vector as an l-value.
- LValue Base = EmitLValue(E->getBase());
-
- // Encode the element access list into a vector of unsigned indices.
- llvm::SmallVector<unsigned, 4> Indices;
- E->getEncodedElementAccess(Indices);
-
- if (Base.isSimple()) {
- llvm::Constant *CV = GenerateConstantVector(Indices);
- return LValue::MakeExtVectorElt(Base.getAddress(), CV,
- E->getBase()->getType().getCVRQualifiers());
- }
- assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
-
- llvm::Constant *BaseElts = Base.getExtVectorElts();
- llvm::SmallVector<llvm::Constant *, 4> CElts;
-
- for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
- if (isa<llvm::ConstantAggregateZero>(BaseElts))
- CElts.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
- else
- CElts.push_back(BaseElts->getOperand(Indices[i]));
- }
- llvm::Constant *CV = llvm::ConstantVector::get(&CElts[0], CElts.size());
- return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
- E->getBase()->getType().getCVRQualifiers());
-}
-
-LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
- bool isUnion = false;
- Expr *BaseExpr = E->getBase();
- llvm::Value *BaseValue = NULL;
- unsigned CVRQualifiers=0;
-
- // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
- if (E->isArrow()) {
- BaseValue = EmitScalarExpr(BaseExpr);
- const PointerType *PTy =
- cast<PointerType>(getContext().getCanonicalType(BaseExpr->getType()));
- if (PTy->getPointeeType()->isUnionType())
- isUnion = true;
- CVRQualifiers = PTy->getPointeeType().getCVRQualifiers();
- }
- else {
- LValue BaseLV = EmitLValue(BaseExpr);
- // FIXME: this isn't right for bitfields.
- BaseValue = BaseLV.getAddress();
- if (BaseExpr->getType()->isUnionType())
- isUnion = true;
- CVRQualifiers = BaseExpr->getType().getCVRQualifiers();
- }
-
- FieldDecl *Field = E->getMemberDecl();
- return EmitLValueForField(BaseValue, Field, isUnion, CVRQualifiers);
-}
-
-LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
- FieldDecl* Field,
- bool isUnion,
- unsigned CVRQualifiers)
-{
- llvm::Value *V;
- unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
-
- if (Field->isBitField()) {
- // FIXME: CodeGenTypes should expose a method to get the appropriate
- // type for FieldTy (the appropriate type is ABI-dependent).
- const llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(Field->getType());
- const llvm::PointerType *BaseTy =
- cast<llvm::PointerType>(BaseValue->getType());
- unsigned AS = BaseTy->getAddressSpace();
- BaseValue = Builder.CreateBitCast(BaseValue,
- llvm::PointerType::get(FieldTy, AS),
- "tmp");
- V = Builder.CreateGEP(BaseValue,
- llvm::ConstantInt::get(llvm::Type::Int32Ty, idx),
- "tmp");
-
- CodeGenTypes::BitFieldInfo bitFieldInfo =
- CGM.getTypes().getBitFieldInfo(Field);
- return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
- Field->getType()->isSignedIntegerType(),
- Field->getType().getCVRQualifiers()|CVRQualifiers);
- }
-
- V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
-
- // Match union field type.
- if (isUnion) {
- const llvm::Type *FieldTy =
- CGM.getTypes().ConvertTypeForMem(Field->getType());
- const llvm::PointerType * BaseTy =
- cast<llvm::PointerType>(BaseValue->getType());
- unsigned AS = BaseTy->getAddressSpace();
- V = Builder.CreateBitCast(V,
- llvm::PointerType::get(FieldTy, AS),
- "tmp");
- }
-
- return LValue::MakeAddr(V,
- Field->getType().getCVRQualifiers()|CVRQualifiers);
-}
-
-LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E)
-{
- const llvm::Type *LTy = ConvertType(E->getType());
- llvm::Value *DeclPtr = CreateTempAlloca(LTy, ".compoundliteral");
-
- const Expr* InitExpr = E->getInitializer();
- LValue Result = LValue::MakeAddr(DeclPtr, E->getType().getCVRQualifiers());
-
- if (E->getType()->isComplexType()) {
- EmitComplexExprIntoAddr(InitExpr, DeclPtr, false);
- } else if (hasAggregateLLVMType(E->getType())) {
- EmitAnyExpr(InitExpr, DeclPtr, false);
- } else {
- EmitStoreThroughLValue(EmitAnyExpr(InitExpr), Result, E->getType());
- }
-
- return Result;
-}
-
-//===--------------------------------------------------------------------===//
-// Expression Emission
-//===--------------------------------------------------------------------===//
-
-
-RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
- if (const ImplicitCastExpr *IcExpr =
- dyn_cast<const ImplicitCastExpr>(E->getCallee()))
- if (const DeclRefExpr *DRExpr =
- dyn_cast<const DeclRefExpr>(IcExpr->getSubExpr()))
- if (const FunctionDecl *FDecl =
- dyn_cast<const FunctionDecl>(DRExpr->getDecl()))
- if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
- return EmitBuiltinExpr(builtinID, E);
-
- llvm::Value *Callee = EmitScalarExpr(E->getCallee());
- return EmitCallExpr(Callee, E->getCallee()->getType(),
- E->arg_begin(), E->arg_end());
-}
-
-RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr,
- CallExpr::const_arg_iterator ArgBeg,
- CallExpr::const_arg_iterator ArgEnd) {
-
- llvm::Value *Callee = EmitScalarExpr(FnExpr);
- return EmitCallExpr(Callee, FnExpr->getType(), ArgBeg, ArgEnd);
-}
-
-LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
- // Can only get l-value for binary operator expressions which are a
- // simple assignment of aggregate type.
- if (E->getOpcode() != BinaryOperator::Assign)
- return EmitUnsupportedLValue(E, "binary l-value expression");
-
- llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
- EmitAggExpr(E, Temp, false);
- // FIXME: Are these qualifiers correct?
- return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers());
-}
-
-LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
- // Can only get l-value for call expression returning aggregate type
- RValue RV = EmitCallExpr(E);
- // FIXME: can this be volatile?
- return LValue::MakeAddr(RV.getAggregateAddr(),
- E->getType().getCVRQualifiers());
-}
-
-LValue
-CodeGenFunction::EmitCXXConditionDeclLValue(const CXXConditionDeclExpr *E) {
- EmitLocalBlockVarDecl(*E->getVarDecl());
- return EmitDeclRefLValue(E);
-}
-
-LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
- // Can only get l-value for message expression returning aggregate type
- RValue RV = EmitObjCMessageExpr(E);
- // FIXME: can this be volatile?
- return LValue::MakeAddr(RV.getAggregateAddr(),
- E->getType().getCVRQualifiers());
-}
-
-llvm::Value *CodeGenFunction::EmitIvarOffset(ObjCInterfaceDecl *Interface,
- const ObjCIvarDecl *Ivar) {
- // Objective-C objects are traditionally C structures with their layout
- // defined at compile-time. In some implementations, their layout is not
- // defined until run time in order to allow instance variables to be added to
- // a class without recompiling all of the subclasses. If this is the case
- // then the CGObjCRuntime subclass must return true to LateBoundIvars and
- // implement the lookup itself.
- if (CGM.getObjCRuntime().LateBoundIVars())
- assert(0 && "late-bound ivars are unsupported");
-
- const llvm::Type *InterfaceLTy =
- CGM.getTypes().ConvertType(getContext().getObjCInterfaceType(Interface));
- const llvm::StructLayout *Layout =
- CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceLTy));
- uint64_t Offset =
- Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Ivar));
-
- return llvm::ConstantInt::get(CGM.getTypes().ConvertType(getContext().LongTy),
- Offset);
-}
-
-LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue,
- const ObjCIvarDecl *Ivar,
- unsigned CVRQualifiers) {
- // See comment in EmitIvarOffset.
- if (CGM.getObjCRuntime().LateBoundIVars())
- assert(0 && "late-bound ivars are unsupported");
-
- if (Ivar->isBitField())
- assert(0 && "ivar bitfields are unsupported");
-
- // TODO: Add a special case for isa (index 0)
- unsigned Index = CGM.getTypes().getLLVMFieldNo(Ivar);
-
- llvm::Value *V = Builder.CreateStructGEP(BaseValue, Index, "tmp");
- return LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers);
-}
-
-LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
- // FIXME: A lot of the code below could be shared with EmitMemberExpr.
- llvm::Value *BaseValue = 0;
- const Expr *BaseExpr = E->getBase();
- unsigned CVRQualifiers = 0;
- if (E->isArrow()) {
- BaseValue = EmitScalarExpr(BaseExpr);
- const PointerType *PTy =
- cast<PointerType>(getContext().getCanonicalType(BaseExpr->getType()));
- CVRQualifiers = PTy->getPointeeType().getCVRQualifiers();
- } else {
- LValue BaseLV = EmitLValue(BaseExpr);
- // FIXME: this isn't right for bitfields.
- BaseValue = BaseLV.getAddress();
- CVRQualifiers = BaseExpr->getType().getCVRQualifiers();
- }
-
- return EmitLValueForIvar(BaseValue, E->getDecl(), CVRQualifiers);
-}
-
-LValue
-CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
- // This is a special l-value that just issues sends when we load or
- // store through it.
- return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers());
-}
-
-RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
- CallExpr::const_arg_iterator ArgBeg,
- CallExpr::const_arg_iterator ArgEnd) {
-
- // The callee type will always be a pointer to function type, get the function
- // type.
- FnType = FnType->getAsPointerType()->getPointeeType();
- QualType ResultType = FnType->getAsFunctionType()->getResultType();
-
- CallArgList Args;
- for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I)
- Args.push_back(std::make_pair(EmitAnyExprToTemp(*I),
- I->getType()));
-
- return EmitCall(Callee, ResultType, Args);
-}
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
deleted file mode 100644
index 9041c17671de..000000000000
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
-//
-// 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 emit Aggregate Expr nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/StmtVisitor.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Intrinsics.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===----------------------------------------------------------------------===//
-// Aggregate Expression Emitter
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
- CodeGenFunction &CGF;
- llvm::IRBuilder<> &Builder;
- llvm::Value *DestPtr;
- bool VolatileDest;
-public:
- AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
- : CGF(cgf), Builder(CGF.Builder),
- DestPtr(destPtr), VolatileDest(volatileDest) {
- }
-
- //===--------------------------------------------------------------------===//
- // Utilities
- //===--------------------------------------------------------------------===//
-
- /// EmitAggLoadOfLValue - Given an expression with aggregate type that
- /// represents a value lvalue, this method emits the address of the lvalue,
- /// then loads the result into DestPtr.
- void EmitAggLoadOfLValue(const Expr *E);
-
- void EmitNonConstInit(InitListExpr *E);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- void VisitStmt(Stmt *S) {
- CGF.ErrorUnsupported(S, "aggregate expression");
- }
- void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
-
- // l-values.
- void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
- void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
- void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
- void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
- void VisitCompoundLiteralExpr(CompoundLiteralExpr *E)
- { EmitAggLoadOfLValue(E); }
-
- void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- EmitAggLoadOfLValue(E);
- }
-
- // Operators.
- // case Expr::UnaryOperatorClass:
- // case Expr::CastExprClass:
- void VisitImplicitCastExpr(ImplicitCastExpr *E);
- void VisitCallExpr(const CallExpr *E);
- void VisitStmtExpr(const StmtExpr *E);
- void VisitBinaryOperator(const BinaryOperator *BO);
- void VisitBinAssign(const BinaryOperator *E);
- void VisitOverloadExpr(const OverloadExpr *E);
- void VisitBinComma(const BinaryOperator *E);
-
- void VisitObjCMessageExpr(ObjCMessageExpr *E);
- void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
- EmitAggLoadOfLValue(E);
- }
- void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
-
- void VisitConditionalOperator(const ConditionalOperator *CO);
- void VisitInitListExpr(InitListExpr *E);
- void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
- Visit(DAE->getExpr());
- }
- void VisitVAArgExpr(VAArgExpr *E);
-
- void EmitInitializationToLValue(Expr *E, LValue Address);
- void EmitNullInitializationToLValue(LValue Address, QualType T);
- // case Expr::ChooseExprClass:
-
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-/// EmitAggLoadOfLValue - Given an expression with aggregate type that
-/// represents a value lvalue, this method emits the address of the lvalue,
-/// then loads the result into DestPtr.
-void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
- LValue LV = CGF.EmitLValue(E);
- assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
- llvm::Value *SrcPtr = LV.getAddress();
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
-}
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-void AggExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
- assert(CGF.getContext().typesAreCompatible(
- E->getSubExpr()->getType().getUnqualifiedType(),
- E->getType().getUnqualifiedType()) &&
- "Implicit cast types must be compatible");
- Visit(E->getSubExpr());
-}
-
-void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
- RValue RV = CGF.EmitCallExpr(E);
- assert(RV.isAggregate() && "Return value must be aggregate value!");
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
- RValue RV = CGF.EmitObjCMessageExpr(E);
- assert(RV.isAggregate() && "Return value must be aggregate value!");
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
- RValue RV = CGF.EmitObjCPropertyGet(E);
- assert(RV.isAggregate() && "Return value must be aggregate value!");
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
- RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->arg_end(CGF.getContext()));
-
- assert(RV.isAggregate() && "Return value must be aggregate value!");
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
- CGF.EmitAnyExpr(E->getLHS());
- CGF.EmitAggExpr(E->getRHS(), DestPtr, false);
-}
-
-void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
-}
-
-void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
- CGF.ErrorUnsupported(E, "aggregate binary expression");
-}
-
-void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
- // For an assignment to work, the value on the right has
- // to be compatible with the value on the left.
- assert(CGF.getContext().typesAreCompatible(
- E->getLHS()->getType().getUnqualifiedType(),
- E->getRHS()->getType().getUnqualifiedType())
- && "Invalid assignment");
- LValue LHS = CGF.EmitLValue(E->getLHS());
-
- // We have to special case property setters, otherwise we must have
- // a simple lvalue (no aggregates inside vectors, bitfields).
- if (LHS.isPropertyRef()) {
- // FIXME: Volatility?
- llvm::Value *AggLoc = DestPtr;
- if (!AggLoc)
- AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType()));
- CGF.EmitAggExpr(E->getRHS(), AggLoc, false);
- CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
- RValue::getAggregate(AggLoc));
- } else {
- // Codegen the RHS so that it stores directly into the LHS.
- CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
-
- if (DestPtr == 0)
- return;
-
- // If the result of the assignment is used, copy the RHS there also.
- CGF.EmitAggregateCopy(DestPtr, LHS.getAddress(), E->getType());
- }
-}
-
-void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
- llvm::BasicBlock *LHSBlock = llvm::BasicBlock::Create("cond.?");
- llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("cond.:");
- llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("cond.cont");
-
- llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
- Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
-
- CGF.EmitBlock(LHSBlock);
-
- // Handle the GNU extension for missing LHS.
- assert(E->getLHS() && "Must have LHS for aggregate value");
-
- Visit(E->getLHS());
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(RHSBlock);
-
- Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(ContBlock);
-}
-
-void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
- llvm::Value *ArgValue = CGF.EmitLValue(VE->getSubExpr()).getAddress();
- llvm::Value *V = Builder.CreateVAArg(ArgValue, CGF.ConvertType(VE->getType()));
- if (DestPtr)
- // FIXME: volatility
- Builder.CreateStore(V, DestPtr);
-}
-
-void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {
-
- const llvm::PointerType *APType =
- cast<llvm::PointerType>(DestPtr->getType());
- const llvm::Type *DestType = APType->getElementType();
-
- if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(DestType)) {
- unsigned NumInitElements = E->getNumInits();
-
- unsigned i;
- for (i = 0; i != NumInitElements; ++i) {
- llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
- Expr *Init = E->getInit(i);
- if (isa<InitListExpr>(Init))
- CGF.EmitAggExpr(Init, NextVal, VolatileDest);
- else
- // FIXME: volatility
- Builder.CreateStore(CGF.EmitScalarExpr(Init), NextVal);
- }
-
- // Emit remaining default initializers
- unsigned NumArrayElements = AType->getNumElements();
- QualType QType = E->getInit(0)->getType();
- const llvm::Type *EType = AType->getElementType();
- for (/*Do not initialize i*/; i < NumArrayElements; ++i) {
- llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
- if (EType->isSingleValueType())
- // FIXME: volatility
- Builder.CreateStore(llvm::Constant::getNullValue(EType), NextVal);
- else
- CGF.EmitAggregateClear(NextVal, QType);
- }
- } else
- assert(false && "Invalid initializer");
-}
-
-void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
- // FIXME: Are initializers affected by volatile?
- if (E->getType()->isComplexType()) {
- CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
- } else if (CGF.hasAggregateLLVMType(E->getType())) {
- CGF.EmitAnyExpr(E, LV.getAddress(), false);
- } else {
- CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, E->getType());
- }
-}
-
-void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
- if (!CGF.hasAggregateLLVMType(T)) {
- // For non-aggregates, we can store zero
- llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
- CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
- } else {
- // Otherwise, just memset the whole thing to zero. This is legal
- // because in LLVM, all default initializers are guaranteed to have a
- // bit pattern of all zeros.
- // There's a potential optimization opportunity in combining
- // memsets; that would be easy for arrays, but relatively
- // difficult for structures with the current code.
- llvm::Value *MemSet = CGF.CGM.getIntrinsic(llvm::Intrinsic::memset_i64);
- uint64_t Size = CGF.getContext().getTypeSize(T);
-
- const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- llvm::Value* DestPtr = Builder.CreateBitCast(LV.getAddress(), BP, "tmp");
- Builder.CreateCall4(MemSet, DestPtr,
- llvm::ConstantInt::get(llvm::Type::Int8Ty, 0),
- llvm::ConstantInt::get(llvm::Type::Int64Ty, Size/8),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
- }
-}
-
-void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
- // FIXME: For constant expressions, call into const expr emitter so
- // that we can emit a memcpy instead of storing the individual
- // members. This is purely for perf; both codepaths lead to
- // equivalent (although not necessarily identical) code. It's worth
- // noting that LLVM keeps on getting smarter, though, so it might
- // not be worth bothering.
-
- // Handle initialization of an array.
- if (E->getType()->isArrayType()) {
- const llvm::PointerType *APType =
- cast<llvm::PointerType>(DestPtr->getType());
- const llvm::ArrayType *AType =
- cast<llvm::ArrayType>(APType->getElementType());
-
- uint64_t NumInitElements = E->getNumInits();
-
- if (E->getNumInits() > 0) {
- QualType T1 = E->getType();
- QualType T2 = E->getInit(0)->getType();
- if (CGF.getContext().getCanonicalType(T1).getUnqualifiedType() ==
- CGF.getContext().getCanonicalType(T2).getUnqualifiedType()) {
- EmitAggLoadOfLValue(E->getInit(0));
- return;
- }
- }
-
- uint64_t NumArrayElements = AType->getNumElements();
- QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
- ElementType =CGF.getContext().getAsArrayType(ElementType)->getElementType();
-
- unsigned CVRqualifier = ElementType.getCVRQualifiers();
-
- for (uint64_t i = 0; i != NumArrayElements; ++i) {
- llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
- if (i < NumInitElements)
- EmitInitializationToLValue(E->getInit(i),
- LValue::MakeAddr(NextVal, CVRqualifier));
- else
- EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, CVRqualifier),
- ElementType);
- }
- return;
- }
-
- assert(E->getType()->isRecordType() && "Only support structs/unions here!");
-
- // Do struct initialization; this code just sets each individual member
- // to the approprate value. This makes bitfield support automatic;
- // the disadvantage is that the generated code is more difficult for
- // the optimizer, especially with bitfields.
- unsigned NumInitElements = E->getNumInits();
- RecordDecl *SD = E->getType()->getAsRecordType()->getDecl();
- unsigned NumMembers = SD->getNumMembers() - SD->hasFlexibleArrayMember();
- unsigned CurInitVal = 0;
- bool isUnion = E->getType()->isUnionType();
-
- // Here we iterate over the fields; this makes it simpler to both
- // default-initialize fields and skip over unnamed fields.
- for (unsigned CurFieldNo = 0; CurFieldNo != NumMembers; ++CurFieldNo) {
- FieldDecl *CurField = SD->getMember(CurFieldNo);
- if (CurField->getIdentifier() == 0) {
- // Initializers can't initialize unnamed fields, e.g. "int : 20;"
- continue;
- }
- // FIXME: volatility
- LValue FieldLoc = CGF.EmitLValueForField(DestPtr, CurField, isUnion,0);
- if (CurInitVal < NumInitElements) {
- // Store the initializer into the field
- // This will probably have to get a bit smarter when we support
- // designators in initializers
- EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc);
- } else {
- // We're out of initalizers; default-initialize to null
- EmitNullInitializationToLValue(FieldLoc, CurField->getType());
- }
-
- // Unions only initialize one field.
- // (things can get weird with designators, but they aren't
- // supported yet.)
- if (E->getType()->isUnionType())
- break;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Entry Points into this File
-//===----------------------------------------------------------------------===//
-
-/// EmitAggExpr - Emit the computation of the specified expression of
-/// aggregate type. The result is computed into DestPtr. Note that if
-/// DestPtr is null, the value of the aggregate expression is not needed.
-void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
- bool VolatileDest) {
- assert(E && hasAggregateLLVMType(E->getType()) &&
- "Invalid aggregate expression to emit");
-
- AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
-}
-
-void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
- assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
-
- EmitMemSetToZero(DestPtr, Ty);
-}
-
-void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
- llvm::Value *SrcPtr, QualType Ty) {
- assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
-
- // Aggregate assignment turns into llvm.memmove.
- const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- if (DestPtr->getType() != BP)
- DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
- if (SrcPtr->getType() != BP)
- SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
-
- // Get size and alignment info for this aggregate.
- std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
-
- Builder.CreateCall4(CGM.getMemMoveFn(),
- DestPtr, SrcPtr,
- // TypeInfo.first describes size in bits.
- llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
- llvm::ConstantInt::get(llvm::Type::Int32Ty,
- TypeInfo.second/8));
-}
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
deleted file mode 100644
index abd0ca8527e0..000000000000
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
-//
-// 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 emit Expr nodes with complex types as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/StmtVisitor.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Compiler.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===----------------------------------------------------------------------===//
-// Complex Expression Emitter
-//===----------------------------------------------------------------------===//
-
-typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
-
-namespace {
-class VISIBILITY_HIDDEN ComplexExprEmitter
- : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
- CodeGenFunction &CGF;
- llvm::IRBuilder<> &Builder;
-public:
- ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
- }
-
-
- //===--------------------------------------------------------------------===//
- // Utilities
- //===--------------------------------------------------------------------===//
-
- /// EmitLoadOfLValue - Given an expression with complex type that represents a
- /// value l-value, this method emits the address of the l-value, then loads
- /// and returns the result.
- ComplexPairTy EmitLoadOfLValue(const Expr *E) {
- LValue LV = CGF.EmitLValue(E);
- // FIXME: Volatile
- return EmitLoadOfComplex(LV.getAddress(), false);
- }
-
- /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
- /// the real and imaginary pieces.
- ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
-
- /// EmitStoreOfComplex - Store the specified real/imag parts into the
- /// specified value pointer.
- void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
-
- /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
- ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
- QualType DestType);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- ComplexPairTy VisitStmt(Stmt *S) {
- S->dump(CGF.getContext().getSourceManager());
- assert(0 && "Stmt can't have complex result type!");
- return ComplexPairTy();
- }
- ComplexPairTy VisitExpr(Expr *S);
- ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
- ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
-
- // l-values.
- ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
-
- // FIXME: CompoundLiteralExpr
-
- ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
- ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
- // Unlike for scalars, we don't have to worry about function->ptr demotion
- // here.
- return EmitCast(E->getSubExpr(), E->getType());
- }
- ComplexPairTy VisitCastExpr(CastExpr *E) {
- return EmitCast(E->getSubExpr(), E->getType());
- }
- ComplexPairTy VisitCallExpr(const CallExpr *E);
- ComplexPairTy VisitStmtExpr(const StmtExpr *E);
- ComplexPairTy VisitOverloadExpr(const OverloadExpr *OE);
-
- // Operators.
- ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
- bool isInc, bool isPre);
- ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, false, false);
- }
- ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, true, false);
- }
- ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, false, true);
- }
- ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, true, true);
- }
- ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- ComplexPairTy VisitUnaryMinus (const UnaryOperator *E);
- ComplexPairTy VisitUnaryNot (const UnaryOperator *E);
- // LNot,SizeOf,AlignOf,Real,Imag never return complex.
- ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
- return Visit(DAE->getExpr());
- }
- ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
- assert(E->getType()->isAnyComplexType() && "Expected complex type!");
- QualType Elem = E->getType()->getAsComplexType()->getElementType();
- llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
- return ComplexPairTy(Null, Null);
- }
-
- struct BinOpInfo {
- ComplexPairTy LHS;
- ComplexPairTy RHS;
- QualType Ty; // Computation Type.
- };
-
- BinOpInfo EmitBinOps(const BinaryOperator *E);
- ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)
- (const BinOpInfo &));
-
- ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
- ComplexPairTy EmitBinSub(const BinOpInfo &Op);
- ComplexPairTy EmitBinMul(const BinOpInfo &Op);
- ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
-
- ComplexPairTy VisitBinMul(const BinaryOperator *E) {
- return EmitBinMul(EmitBinOps(E));
- }
- ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
- return EmitBinAdd(EmitBinOps(E));
- }
- ComplexPairTy VisitBinSub(const BinaryOperator *E) {
- return EmitBinSub(EmitBinOps(E));
- }
- ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
- return EmitBinDiv(EmitBinOps(E));
- }
-
- // Compound assignments.
- ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
- }
- ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
- }
- ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
- }
- ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
- }
-
- // GCC rejects rem/and/or/xor for integer complex.
- // Logical and/or always return int, never complex.
-
- // No comparisons produce a complex result.
- ComplexPairTy VisitBinAssign (const BinaryOperator *E);
- ComplexPairTy VisitBinComma (const BinaryOperator *E);
-
-
- ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
- ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
-
- ComplexPairTy VisitInitListExpr(InitListExpr *E);
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
-/// load the real and imaginary pieces, returning them as Real/Imag.
-ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
- bool isVolatile) {
- llvm::SmallString<64> Name(SrcPtr->getNameStart(),
- SrcPtr->getNameStart()+SrcPtr->getNameLen());
-
- Name += ".realp";
- llvm::Value *RealPtr = Builder.CreateStructGEP(SrcPtr, 0, Name.c_str());
-
- Name.pop_back(); // .realp -> .real
- llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str());
-
- Name.resize(Name.size()-4); // .real -> .imagp
- Name += "imagp";
-
- llvm::Value *ImagPtr = Builder.CreateStructGEP(SrcPtr, 1, Name.c_str());
-
- Name.pop_back(); // .imagp -> .imag
- llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str());
- return ComplexPairTy(Real, Imag);
-}
-
-/// EmitStoreOfComplex - Store the specified real/imag parts into the
-/// specified value pointer.
-void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
- bool isVolatile) {
- llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
- llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
-
- Builder.CreateStore(Val.first, RealPtr, isVolatile);
- Builder.CreateStore(Val.second, ImagPtr, isVolatile);
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
- CGF.ErrorUnsupported(E, "complex expression");
- const llvm::Type *EltTy =
- CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
- llvm::Value *U = llvm::UndefValue::get(EltTy);
- return ComplexPairTy(U, U);
-}
-
-ComplexPairTy ComplexExprEmitter::
-VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
- llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
- return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
-}
-
-
-ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
- return CGF.EmitCallExpr(E).getComplexVal();
-}
-
-ComplexPairTy ComplexExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
- return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->arg_end(CGF.getContext())).getComplexVal();
-}
-
-ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
-}
-
-/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
-ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
- QualType SrcType,
- QualType DestType) {
- // Get the src/dest element type.
- SrcType = SrcType->getAsComplexType()->getElementType();
- DestType = DestType->getAsComplexType()->getElementType();
-
- // C99 6.3.1.6: When a value of complextype is converted to another
- // complex type, both the real and imaginary parts followthe conversion
- // rules for the corresponding real types.
- Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
- Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
- return Val;
-}
-
-ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
- // Two cases here: cast from (complex to complex) and (scalar to complex).
- if (Op->getType()->isAnyComplexType())
- return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
-
- // C99 6.3.1.7: When a value of real type is converted to a complex type, the
- // real part of the complex result value is determined by the rules of
- // conversion to the corresponding real type and the imaginary part of the
- // complex result value is a positive zero or an unsigned zero.
- llvm::Value *Elt = CGF.EmitScalarExpr(Op);
-
- // Convert the input element to the element type of the complex.
- DestTy = DestTy->getAsComplexType()->getElementType();
- Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
-
- // Return (realval, 0).
- return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
-}
-
-ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
- bool isInc, bool isPre) {
- LValue LV = CGF.EmitLValue(E->getSubExpr());
- // FIXME: Handle volatile!
- ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(), false);
-
- uint64_t AmountVal = isInc ? 1 : -1;
-
- llvm::Value *NextVal;
- if (isa<llvm::IntegerType>(InVal.first->getType()))
- NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal);
- else if (InVal.first->getType() == llvm::Type::FloatTy)
- // FIXME: Handle long double.
- NextVal =
- llvm::ConstantFP::get(llvm::APFloat(static_cast<float>(AmountVal)));
- else {
- // FIXME: Handle long double.
- assert(InVal.first->getType() == llvm::Type::DoubleTy);
- NextVal =
- llvm::ConstantFP::get(llvm::APFloat(static_cast<double>(AmountVal)));
- }
-
- // Add the inc/dec to the real part.
- NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
-
- ComplexPairTy IncVal(NextVal, InVal.second);
-
- // Store the updated result through the lvalue.
- EmitStoreOfComplex(IncVal, LV.getAddress(), false); /* FIXME: Volatile */
-
- // If this is a postinc, return the value read from memory, otherwise use the
- // updated value.
- return isPre ? IncVal : InVal;
-}
-
-ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
- ComplexPairTy Op = Visit(E->getSubExpr());
- llvm::Value *ResR = Builder.CreateNeg(Op.first, "neg.r");
- llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
- // ~(a+ib) = a + i*-b
- ComplexPairTy Op = Visit(E->getSubExpr());
- llvm::Value *ResI = Builder.CreateNeg(Op.second, "conj.i");
- return ComplexPairTy(Op.first, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
- llvm::Value *ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");
- llvm::Value *ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
- llvm::Value *ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
- llvm::Value *ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-
-ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
- llvm::Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
- llvm::Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
- llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
-
- llvm::Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
- llvm::Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
- llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
- llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
- llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
-
- // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
- llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
- llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
- llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
-
- llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
- llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
- llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
-
- llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
- llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
- llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
-
- llvm::Value *DSTr, *DSTi;
- if (Tmp3->getType()->isFloatingPoint()) {
- DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
- DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
- } else {
- if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) {
- DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
- DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
- } else {
- DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
- DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
- }
- }
-
- return ComplexPairTy(DSTr, DSTi);
-}
-
-ComplexExprEmitter::BinOpInfo
-ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
- BinOpInfo Ops;
- Ops.LHS = Visit(E->getLHS());
- Ops.RHS = Visit(E->getRHS());
- Ops.Ty = E->getType();
- return Ops;
-}
-
-
-// Compound assignments.
-ComplexPairTy ComplexExprEmitter::
-EmitCompoundAssign(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
- QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
-
- // Load the LHS and RHS operands.
- LValue LHSLV = CGF.EmitLValue(E->getLHS());
-
- BinOpInfo OpInfo;
- OpInfo.Ty = E->getComputationType();
-
- // We know the LHS is a complex lvalue.
- OpInfo.LHS = EmitLoadOfComplex(LHSLV.getAddress(), false);// FIXME: Volatile.
- OpInfo.LHS = EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
-
- // It is possible for the RHS to be complex or scalar.
- OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
-
- // Expand the binary operator.
- ComplexPairTy Result = (this->*Func)(OpInfo);
-
- // Truncate the result back to the LHS type.
- Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
-
- // Store the result value into the LHS lvalue.
- EmitStoreOfComplex(Result, LHSLV.getAddress(), false); // FIXME: VOLATILE
- return Result;
-}
-
-ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
- assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
- CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
- "Invalid assignment");
- // Emit the RHS.
- ComplexPairTy Val = Visit(E->getRHS());
-
- // Compute the address to store into.
- LValue LHS = CGF.EmitLValue(E->getLHS());
-
- // Store into it.
- // FIXME: Volatility!
- EmitStoreOfComplex(Val, LHS.getAddress(), false);
- return Val;
-}
-
-ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
- CGF.EmitStmt(E->getLHS());
- return Visit(E->getRHS());
-}
-
-ComplexPairTy ComplexExprEmitter::
-VisitConditionalOperator(const ConditionalOperator *E) {
- llvm::BasicBlock *LHSBlock = llvm::BasicBlock::Create("cond.?");
- llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("cond.:");
- llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("cond.cont");
-
- llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
- Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
-
- CGF.EmitBlock(LHSBlock);
-
- // Handle the GNU extension for missing LHS.
- assert(E->getLHS() && "Must have LHS for complex value");
-
- ComplexPairTy LHS = Visit(E->getLHS());
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(RHSBlock);
-
- ComplexPairTy RHS = Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(ContBlock);
-
- // Create a PHI node for the real part.
- llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
- RealPN->reserveOperandSpace(2);
- RealPN->addIncoming(LHS.first, LHSBlock);
- RealPN->addIncoming(RHS.first, RHSBlock);
-
- // Create a PHI node for the imaginary part.
- llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
- ImagPN->reserveOperandSpace(2);
- ImagPN->addIncoming(LHS.second, LHSBlock);
- ImagPN->addIncoming(RHS.second, RHSBlock);
-
- return ComplexPairTy(RealPN, ImagPN);
-}
-
-ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
- // Emit the LHS or RHS as appropriate.
- return Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() :E->getRHS());
-}
-
-ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
- if (E->getNumInits())
- return Visit(E->getInit(0));
-
- // Empty init list intializes to null
- QualType Ty = E->getType()->getAsComplexType()->getElementType();
- const llvm::Type* LTy = CGF.ConvertType(Ty);
- llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
- return ComplexPairTy(zeroConstant, zeroConstant);
-}
-
-//===----------------------------------------------------------------------===//
-// Entry Point into this File
-//===----------------------------------------------------------------------===//
-
-/// EmitComplexExpr - Emit the computation of the specified expression of
-/// complex type, ignoring the result.
-ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
- assert(E && E->getType()->isAnyComplexType() &&
- "Invalid complex expression to emit");
-
- return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
-}
-
-/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
-/// of complex type, storing into the specified Value*.
-void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
- llvm::Value *DestAddr,
- bool DestIsVolatile) {
- assert(E && E->getType()->isAnyComplexType() &&
- "Invalid complex expression to emit");
- ComplexExprEmitter Emitter(*this);
- ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
- Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
-}
-
-/// StoreComplexToAddr - Store a complex number into the specified address.
-void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V,
- llvm::Value *DestAddr,
- bool DestIsVolatile) {
- ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile);
-}
-
-/// LoadComplexFromAddr - Load a complex number from the specified address.
-ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr,
- bool SrcIsVolatile) {
- return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile);
-}
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
deleted file mode 100644
index 69abbcc984c1..000000000000
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ /dev/null
@@ -1,861 +0,0 @@
-//===--- CGExprConstant.cpp - Emit LLVM Code from Constant Expressions ----===//
-//
-// 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 emit Constant Expr nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/StmtVisitor.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Target/TargetData.h"
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-class VISIBILITY_HIDDEN ConstExprEmitter :
- public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
- CodeGenModule &CGM;
- CodeGenFunction *CGF;
-public:
- ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf)
- : CGM(cgm), CGF(cgf) {
- }
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- llvm::Constant *VisitStmt(Stmt *S) {
- CGM.ErrorUnsupported(S, "constant expression");
- QualType T = cast<Expr>(S)->getType();
- return llvm::UndefValue::get(CGM.getTypes().ConvertType(T));
- }
-
- llvm::Constant *VisitParenExpr(ParenExpr *PE) {
- return Visit(PE->getSubExpr());
- }
-
- // Leaves
- llvm::Constant *VisitIntegerLiteral(const IntegerLiteral *E) {
- return llvm::ConstantInt::get(E->getValue());
- }
- llvm::Constant *VisitFloatingLiteral(const FloatingLiteral *E) {
- return llvm::ConstantFP::get(E->getValue());
- }
- llvm::Constant *VisitCharacterLiteral(const CharacterLiteral *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
- llvm::Constant *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
- llvm::Constant *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
- return llvm::Constant::getNullValue(ConvertType(E->getType()));
- }
- llvm::Constant *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
- std::string S(E->getString()->getStrData(),
- E->getString()->getByteLength());
- llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(S);
- return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
- }
-
- llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- return Visit(E->getInitializer());
- }
-
- llvm::Constant *VisitCastExpr(CastExpr* E) {
- llvm::Constant *C = Visit(E->getSubExpr());
-
- return EmitConversion(C, E->getSubExpr()->getType(), E->getType());
- }
-
- llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
- return Visit(DAE->getExpr());
- }
-
- llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) {
- std::vector<llvm::Constant*> Elts;
- const llvm::ArrayType *AType =
- cast<llvm::ArrayType>(ConvertType(ILE->getType()));
- unsigned NumInitElements = ILE->getNumInits();
- // FIXME: Check for wide strings
- if (NumInitElements > 0 && isa<StringLiteral>(ILE->getInit(0)) &&
- ILE->getType()->getArrayElementTypeNoTypeQual()->isCharType())
- return Visit(ILE->getInit(0));
- const llvm::Type *ElemTy = AType->getElementType();
- unsigned NumElements = AType->getNumElements();
-
- // Initialising an array requires us to automatically
- // initialise any elements that have not been initialised explicitly
- unsigned NumInitableElts = std::min(NumInitElements, NumElements);
-
- // Copy initializer elements.
- unsigned i = 0;
- bool RewriteType = false;
- for (; i < NumInitableElts; ++i) {
- llvm::Constant *C = Visit(ILE->getInit(i));
- RewriteType |= (C->getType() != ElemTy);
- Elts.push_back(C);
- }
-
- // Initialize remaining array elements.
- for (; i < NumElements; ++i)
- Elts.push_back(llvm::Constant::getNullValue(ElemTy));
-
- if (RewriteType) {
- // FIXME: Try to avoid packing the array
- std::vector<const llvm::Type*> Types;
- for (unsigned i = 0; i < Elts.size(); ++i)
- Types.push_back(Elts[i]->getType());
- const llvm::StructType *SType = llvm::StructType::get(Types, true);
- return llvm::ConstantStruct::get(SType, Elts);
- }
-
- return llvm::ConstantArray::get(AType, Elts);
- }
-
- void InsertBitfieldIntoStruct(std::vector<llvm::Constant*>& Elts,
- FieldDecl* Field, Expr* E) {
- // Calculate the value to insert
- llvm::Constant *C = Visit(E);
- llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C);
- if (!CI) {
- CGM.ErrorUnsupported(E, "bitfield initialization");
- return;
- }
- llvm::APInt V = CI->getValue();
-
- // Calculate information about the relevant field
- const llvm::Type* Ty = CI->getType();
- const llvm::TargetData &TD = CGM.getTypes().getTargetData();
- unsigned size = TD.getTypeStoreSizeInBits(Ty);
- unsigned fieldOffset = CGM.getTypes().getLLVMFieldNo(Field) * size;
- CodeGenTypes::BitFieldInfo bitFieldInfo =
- CGM.getTypes().getBitFieldInfo(Field);
- fieldOffset += bitFieldInfo.Begin;
-
- // Find where to start the insertion
- // FIXME: This is O(n^2) in the number of bit-fields!
- // FIXME: This won't work if the struct isn't completely packed!
- unsigned offset = 0, i = 0;
- while (offset < (fieldOffset & -8))
- offset += TD.getTypeStoreSizeInBits(Elts[i++]->getType());
-
- // Advance over 0 sized elements (must terminate in bounds since
- // the bitfield must have a size).
- while (TD.getTypeStoreSizeInBits(Elts[i]->getType()) == 0)
- ++i;
-
- // Promote the size of V if necessary
- // FIXME: This should never occur, but currently it can because
- // initializer constants are cast to bool, and because clang is
- // not enforcing bitfield width limits.
- if (bitFieldInfo.Size > V.getBitWidth())
- V.zext(bitFieldInfo.Size);
-
- // Insert the bits into the struct
- // FIXME: This algorthm is only correct on X86!
- // FIXME: THis algorthm assumes bit-fields only have byte-size elements!
- unsigned bitsToInsert = bitFieldInfo.Size;
- unsigned curBits = std::min(8 - (fieldOffset & 7), bitsToInsert);
- unsigned byte = V.getLoBits(curBits).getZExtValue() << (fieldOffset & 7);
- do {
- llvm::Constant* byteC = llvm::ConstantInt::get(llvm::Type::Int8Ty, byte);
- Elts[i] = llvm::ConstantExpr::getOr(Elts[i], byteC);
- ++i;
- V = V.lshr(curBits);
- bitsToInsert -= curBits;
-
- if (!bitsToInsert)
- break;
-
- curBits = bitsToInsert > 8 ? 8 : bitsToInsert;
- byte = V.getLoBits(curBits).getZExtValue();
- } while (true);
- }
-
- llvm::Constant *EmitStructInitialization(InitListExpr *ILE) {
- const llvm::StructType *SType =
- cast<llvm::StructType>(ConvertType(ILE->getType()));
- RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
- std::vector<llvm::Constant*> Elts;
-
- // Initialize the whole structure to zero.
- for (unsigned i = 0; i < SType->getNumElements(); ++i) {
- const llvm::Type *FieldTy = SType->getElementType(i);
- Elts.push_back(llvm::Constant::getNullValue(FieldTy));
- }
-
- // Copy initializer elements. Skip padding fields.
- unsigned EltNo = 0; // Element no in ILE
- int FieldNo = 0; // Field no in RecordDecl
- bool RewriteType = false;
- while (EltNo < ILE->getNumInits() && FieldNo < RD->getNumMembers()) {
- FieldDecl* curField = RD->getMember(FieldNo);
- FieldNo++;
- if (!curField->getIdentifier())
- continue;
-
- if (curField->isBitField()) {
- InsertBitfieldIntoStruct(Elts, curField, ILE->getInit(EltNo));
- } else {
- unsigned FieldNo = CGM.getTypes().getLLVMFieldNo(curField);
- llvm::Constant* C = Visit(ILE->getInit(EltNo));
- RewriteType |= (C->getType() != Elts[FieldNo]->getType());
- Elts[FieldNo] = C;
- }
- EltNo++;
- }
-
- if (RewriteType) {
- // FIXME: Make this work for non-packed structs
- assert(SType->isPacked() && "Cannot recreate unpacked structs");
- std::vector<const llvm::Type*> Types;
- for (unsigned i = 0; i < Elts.size(); ++i)
- Types.push_back(Elts[i]->getType());
- SType = llvm::StructType::get(Types, true);
- }
-
- return llvm::ConstantStruct::get(SType, Elts);
- }
-
- llvm::Constant *EmitUnionInitialization(InitListExpr *ILE) {
- RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
- const llvm::Type *Ty = ConvertType(ILE->getType());
-
- // Find the field decl we're initializing, if any
- int FieldNo = 0; // Field no in RecordDecl
- FieldDecl* curField = 0;
- while (FieldNo < RD->getNumMembers()) {
- curField = RD->getMember(FieldNo);
- FieldNo++;
- if (curField->getIdentifier())
- break;
- }
-
- if (!curField || !curField->getIdentifier() || ILE->getNumInits() == 0)
- return llvm::Constant::getNullValue(Ty);
-
- if (curField->isBitField()) {
- // Create a dummy struct for bit-field insertion
- unsigned NumElts = CGM.getTargetData().getABITypeSize(Ty) / 8;
- llvm::Constant* NV = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
- std::vector<llvm::Constant*> Elts(NumElts, NV);
-
- InsertBitfieldIntoStruct(Elts, curField, ILE->getInit(0));
- const llvm::ArrayType *RetTy =
- llvm::ArrayType::get(NV->getType(), NumElts);
- return llvm::ConstantArray::get(RetTy, Elts);
- }
-
- llvm::Constant *C = Visit(ILE->getInit(0));
-
- // Build a struct with the union sub-element as the first member,
- // and padded to the appropriate size
- std::vector<llvm::Constant*> Elts;
- std::vector<const llvm::Type*> Types;
- Elts.push_back(C);
- Types.push_back(C->getType());
- unsigned CurSize = CGM.getTargetData().getTypeStoreSize(C->getType());
- unsigned TotalSize = CGM.getTargetData().getTypeStoreSize(Ty);
- while (CurSize < TotalSize) {
- Elts.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty));
- Types.push_back(llvm::Type::Int8Ty);
- CurSize++;
- }
-
- // This always generates a packed struct
- // FIXME: Try to generate an unpacked struct when we can
- llvm::StructType* STy = llvm::StructType::get(Types, true);
- return llvm::ConstantStruct::get(STy, Elts);
- }
-
- llvm::Constant *EmitVectorInitialization(InitListExpr *ILE) {
- const llvm::VectorType *VType =
- cast<llvm::VectorType>(ConvertType(ILE->getType()));
- const llvm::Type *ElemTy = VType->getElementType();
- std::vector<llvm::Constant*> Elts;
- unsigned NumElements = VType->getNumElements();
- unsigned NumInitElements = ILE->getNumInits();
-
- unsigned NumInitableElts = std::min(NumInitElements, NumElements);
-
- // Copy initializer elements.
- unsigned i = 0;
- for (; i < NumInitableElts; ++i) {
- llvm::Constant *C = Visit(ILE->getInit(i));
- Elts.push_back(C);
- }
-
- for (; i < NumElements; ++i)
- Elts.push_back(llvm::Constant::getNullValue(ElemTy));
-
- return llvm::ConstantVector::get(VType, Elts);
- }
-
- llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
- if (ILE->getType()->isScalarType()) {
- // We have a scalar in braces. Just use the first element.
- if (ILE->getNumInits() > 0)
- return Visit(ILE->getInit(0));
-
- const llvm::Type* RetTy = CGM.getTypes().ConvertType(ILE->getType());
- return llvm::Constant::getNullValue(RetTy);
- }
-
- if (ILE->getType()->isArrayType())
- return EmitArrayInitialization(ILE);
-
- if (ILE->getType()->isStructureType())
- return EmitStructInitialization(ILE);
-
- if (ILE->getType()->isUnionType())
- return EmitUnionInitialization(ILE);
-
- if (ILE->getType()->isVectorType())
- return EmitVectorInitialization(ILE);
-
- assert(0 && "Unable to handle InitListExpr");
- // Get rid of control reaches end of void function warning.
- // Not reached.
- return 0;
- }
-
- llvm::Constant *VisitImplicitCastExpr(ImplicitCastExpr *ICExpr) {
- Expr* SExpr = ICExpr->getSubExpr();
- QualType SType = SExpr->getType();
- llvm::Constant *C; // the intermediate expression
- QualType T; // the type of the intermediate expression
- if (SType->isArrayType()) {
- // Arrays decay to a pointer to the first element
- // VLAs would require special handling, but they can't occur here
- C = EmitLValue(SExpr);
- llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Ops[] = {Idx0, Idx0};
- C = llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
- T = CGM.getContext().getArrayDecayedType(SType);
- } else if (SType->isFunctionType()) {
- // Function types decay to a pointer to the function
- C = EmitLValue(SExpr);
- T = CGM.getContext().getPointerType(SType);
- } else {
- C = Visit(SExpr);
- T = SType;
- }
-
- // Perform the conversion; note that an implicit cast can both promote
- // and convert an array/function
- return EmitConversion(C, T, ICExpr->getType());
- }
-
- llvm::Constant *VisitStringLiteral(StringLiteral *E) {
- assert(!E->getType()->isPointerType() && "Strings are always arrays");
-
- // Otherwise this must be a string initializing an array in a static
- // initializer. Don't emit it as the address of the string, emit the string
- // data itself as an inline array.
- return llvm::ConstantArray::get(CGM.GetStringForStringLiteral(E), false);
- }
-
- llvm::Constant *VisitDeclRefExpr(DeclRefExpr *E) {
- const ValueDecl *Decl = E->getDecl();
- if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(Decl))
- return llvm::ConstantInt::get(EC->getInitVal());
- assert(0 && "Unsupported decl ref type!");
- return 0;
- }
-
- llvm::Constant *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
- return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf());
- }
-
- llvm::Constant *VisitAddrLabelExpr(const AddrLabelExpr *E) {
- assert(CGF && "Invalid address of label expression outside function.");
- llvm::Constant *C =
- llvm::ConstantInt::get(llvm::Type::Int32Ty,
- CGF->GetIDForAddrOfLabel(E->getLabel()));
- return llvm::ConstantExpr::getIntToPtr(C, ConvertType(E->getType()));
- }
-
- // Unary operators
- llvm::Constant *VisitUnaryPlus(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- llvm::Constant *VisitUnaryMinus(const UnaryOperator *E) {
- return llvm::ConstantExpr::getNeg(Visit(E->getSubExpr()));
- }
- llvm::Constant *VisitUnaryNot(const UnaryOperator *E) {
- return llvm::ConstantExpr::getNot(Visit(E->getSubExpr()));
- }
- llvm::Constant *VisitUnaryLNot(const UnaryOperator *E) {
- llvm::Constant *SubExpr = Visit(E->getSubExpr());
-
- if (E->getSubExpr()->getType()->isRealFloatingType()) {
- // Compare against 0.0 for fp scalars.
- llvm::Constant *Zero = llvm::Constant::getNullValue(SubExpr->getType());
- SubExpr = llvm::ConstantExpr::getFCmp(llvm::FCmpInst::FCMP_UEQ, SubExpr,
- Zero);
- } else {
- assert((E->getSubExpr()->getType()->isIntegerType() ||
- E->getSubExpr()->getType()->isPointerType()) &&
- "Unknown scalar type to convert");
- // Compare against an integer or pointer null.
- llvm::Constant *Zero = llvm::Constant::getNullValue(SubExpr->getType());
- SubExpr = llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, SubExpr,
- Zero);
- }
-
- return llvm::ConstantExpr::getZExt(SubExpr, ConvertType(E->getType()));
- }
- llvm::Constant *VisitUnarySizeOf(const UnaryOperator *E) {
- return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
- }
- llvm::Constant *VisitUnaryAlignOf(const UnaryOperator *E) {
- return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
- }
- llvm::Constant *VisitUnaryAddrOf(const UnaryOperator *E) {
- return EmitLValue(E->getSubExpr());
- }
- llvm::Constant *VisitUnaryOffsetOf(const UnaryOperator *E) {
- int64_t Val = E->evaluateOffsetOf(CGM.getContext());
-
- assert(E->getType()->isIntegerType() && "Result type must be an integer!");
-
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGM.getContext().getTypeSize(E->getType()));
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
- }
-
- llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
-
- // Binary operators
- llvm::Constant *VisitBinOr(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- return llvm::ConstantExpr::getOr(LHS, RHS);
- }
- llvm::Constant *VisitBinSub(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- if (!isa<llvm::PointerType>(RHS->getType())) {
- // pointer - int
- if (isa<llvm::PointerType>(LHS->getType())) {
- llvm::Constant *Idx = llvm::ConstantExpr::getNeg(RHS);
-
- return llvm::ConstantExpr::getGetElementPtr(LHS, &Idx, 1);
- }
-
- // int - int
- return llvm::ConstantExpr::getSub(LHS, RHS);
- }
-
- assert(isa<llvm::PointerType>(LHS->getType()));
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- const QualType Type = E->getLHS()->getType();
- const QualType ElementType = Type->getAsPointerType()->getPointeeType();
-
- LHS = llvm::ConstantExpr::getPtrToInt(LHS, ResultType);
- RHS = llvm::ConstantExpr::getPtrToInt(RHS, ResultType);
-
- llvm::Constant *sub = llvm::ConstantExpr::getSub(LHS, RHS);
- llvm::Constant *size = EmitSizeAlignOf(ElementType, E->getType(), true);
- return llvm::ConstantExpr::getSDiv(sub, size);
- }
-
- llvm::Constant *VisitBinShl(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- // LLVM requires the LHS and RHS to be the same type: promote or truncate the
- // RHS to the same size as the LHS.
- if (LHS->getType() != RHS->getType())
- RHS = llvm::ConstantExpr::getIntegerCast(RHS, LHS->getType(), false);
-
- return llvm::ConstantExpr::getShl(LHS, RHS);
- }
-
- llvm::Constant *VisitBinMul(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- return llvm::ConstantExpr::getMul(LHS, RHS);
- }
-
- llvm::Constant *VisitBinDiv(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- if (LHS->getType()->isFPOrFPVector())
- return llvm::ConstantExpr::getFDiv(LHS, RHS);
- else if (E->getType()->isUnsignedIntegerType())
- return llvm::ConstantExpr::getUDiv(LHS, RHS);
- else
- return llvm::ConstantExpr::getSDiv(LHS, RHS);
- }
-
- llvm::Constant *VisitBinAdd(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- if (!E->getType()->isPointerType())
- return llvm::ConstantExpr::getAdd(LHS, RHS);
-
- llvm::Constant *Ptr, *Idx;
- if (isa<llvm::PointerType>(LHS->getType())) { // pointer + int
- Ptr = LHS;
- Idx = RHS;
- } else { // int + pointer
- Ptr = RHS;
- Idx = LHS;
- }
-
- return llvm::ConstantExpr::getGetElementPtr(Ptr, &Idx, 1);
- }
-
- llvm::Constant *VisitBinAnd(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- return llvm::ConstantExpr::getAnd(LHS, RHS);
- }
-
- llvm::Constant *EmitCmp(const BinaryOperator *E,
- llvm::CmpInst::Predicate SignedPred,
- llvm::CmpInst::Predicate UnsignedPred,
- llvm::CmpInst::Predicate FloatPred) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
- llvm::Constant *Result;
- if (LHS->getType()->isInteger() ||
- isa<llvm::PointerType>(LHS->getType())) {
- if (E->getLHS()->getType()->isSignedIntegerType())
- Result = llvm::ConstantExpr::getICmp(SignedPred, LHS, RHS);
- else
- Result = llvm::ConstantExpr::getICmp(UnsignedPred, LHS, RHS);
- } else if (LHS->getType()->isFloatingPoint()) {
- Result = llvm::ConstantExpr::getFCmp(FloatPred, LHS, RHS);
- } else {
- CGM.ErrorUnsupported(E, "constant expression");
- Result = llvm::ConstantInt::getFalse();
- }
-
- const llvm::Type* ResultType = ConvertType(E->getType());
- return llvm::ConstantExpr::getZExtOrBitCast(Result, ResultType);
- }
-
- llvm::Constant *VisitBinNE(const BinaryOperator *E) {
- return EmitCmp(E, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_NE,
- llvm::CmpInst::FCMP_ONE);
- }
-
- llvm::Constant *VisitBinEQ(const BinaryOperator *E) {
- return EmitCmp(E, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_EQ,
- llvm::CmpInst::FCMP_OEQ);
- }
-
- llvm::Constant *VisitBinLT(const BinaryOperator *E) {
- return EmitCmp(E, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_ULT,
- llvm::CmpInst::FCMP_OLT);
- }
-
- llvm::Constant *VisitBinLE(const BinaryOperator *E) {
- return EmitCmp(E, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_ULE,
- llvm::CmpInst::FCMP_OLE);
- }
-
- llvm::Constant *VisitBinGT(const BinaryOperator *E) {
- return EmitCmp(E, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_UGT,
- llvm::CmpInst::FCMP_OGT);
- }
-
- llvm::Constant *VisitBinGE(const BinaryOperator *E) {
- return EmitCmp(E, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGE,
- llvm::CmpInst::FCMP_OGE);
- }
-
- llvm::Constant *VisitConditionalOperator(const ConditionalOperator *E) {
- llvm::Constant *Cond = Visit(E->getCond());
- llvm::Constant *CondVal = EmitConversionToBool(Cond, E->getType());
- llvm::ConstantInt *CondValInt = dyn_cast<llvm::ConstantInt>(CondVal);
- if (!CondValInt) {
- CGM.ErrorUnsupported(E, "constant expression");
- return llvm::Constant::getNullValue(ConvertType(E->getType()));
- }
- if (CondValInt->isOne()) {
- if (E->getLHS())
- return Visit(E->getLHS());
- return Cond;
- }
-
- return Visit(E->getRHS());
- }
-
- llvm::Constant *VisitCallExpr(const CallExpr *E) {
- APValue Result;
- if (E->tryEvaluate(Result, CGM.getContext())) {
- if (Result.isInt())
- return llvm::ConstantInt::get(Result.getInt());
- if (Result.isFloat())
- return llvm::ConstantFP::get(Result.getFloat());
- }
-
- // Handle __builtin___CFStringMakeConstantString.
- if (E->isBuiltinCall() ==Builtin::BI__builtin___CFStringMakeConstantString){
- const Expr *Arg = E->getArg(0);
-
- while (1) {
- if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
- Arg = PE->getSubExpr();
- else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = CE->getSubExpr();
- else
- break;
- }
-
- const StringLiteral *Literal = cast<StringLiteral>(Arg);
- std::string S(Literal->getStrData(), Literal->getByteLength());
- return CGM.GetAddrOfConstantCFString(S);
- }
-
- CGM.ErrorUnsupported(E, "constant call expression");
- return llvm::Constant::getNullValue(ConvertType(E->getType()));
- }
-
- // Utility methods
- const llvm::Type *ConvertType(QualType T) {
- return CGM.getTypes().ConvertType(T);
- }
-
- llvm::Constant *EmitConversionToBool(llvm::Constant *Src, QualType SrcType) {
- assert(SrcType->isCanonical() && "EmitConversion strips typedefs");
-
- if (SrcType->isRealFloatingType()) {
- // Compare against 0.0 for fp scalars.
- llvm::Constant *Zero = llvm::Constant::getNullValue(Src->getType());
- return llvm::ConstantExpr::getFCmp(llvm::FCmpInst::FCMP_UNE, Src, Zero);
- }
-
- assert((SrcType->isIntegerType() || SrcType->isPointerType()) &&
- "Unknown scalar type to convert");
-
- // Compare against an integer or pointer null.
- llvm::Constant *Zero = llvm::Constant::getNullValue(Src->getType());
- return llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_NE, Src, Zero);
- }
-
- llvm::Constant *EmitConversion(llvm::Constant *Src, QualType SrcType,
- QualType DstType) {
- SrcType = CGM.getContext().getCanonicalType(SrcType);
- DstType = CGM.getContext().getCanonicalType(DstType);
- if (SrcType == DstType) return Src;
-
- // Handle conversions to bool first, they are special: comparisons against 0.
- if (DstType->isBooleanType())
- return EmitConversionToBool(Src, SrcType);
-
- const llvm::Type *DstTy = ConvertType(DstType);
-
- // Ignore conversions like int -> uint.
- if (Src->getType() == DstTy)
- return Src;
-
- // Handle pointer conversions next: pointers can only be converted to/from
- // other pointers and integers.
- if (isa<llvm::PointerType>(DstTy)) {
- // The source value may be an integer, or a pointer.
- if (isa<llvm::PointerType>(Src->getType()))
- return llvm::ConstantExpr::getBitCast(Src, DstTy);
- assert(SrcType->isIntegerType() &&"Not ptr->ptr or int->ptr conversion?");
- return llvm::ConstantExpr::getIntToPtr(Src, DstTy);
- }
-
- if (isa<llvm::PointerType>(Src->getType())) {
- // Must be an ptr to int cast.
- assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
- return llvm::ConstantExpr::getPtrToInt(Src, DstTy);
- }
-
- // A scalar source can be splatted to a vector of the same element type
- if (isa<llvm::VectorType>(DstTy) && !isa<VectorType>(SrcType)) {
- const llvm::VectorType *VT = cast<llvm::VectorType>(DstTy);
- assert((VT->getElementType() == Src->getType()) &&
- "Vector element type must match scalar type to splat.");
- unsigned NumElements = DstType->getAsVectorType()->getNumElements();
- llvm::SmallVector<llvm::Constant*, 16> Elements;
- for (unsigned i = 0; i < NumElements; i++)
- Elements.push_back(Src);
-
- return llvm::ConstantVector::get(&Elements[0], NumElements);
- }
-
- if (isa<llvm::VectorType>(Src->getType()) ||
- isa<llvm::VectorType>(DstTy)) {
- return llvm::ConstantExpr::getBitCast(Src, DstTy);
- }
-
- // Finally, we have the arithmetic types: real int/float.
- if (isa<llvm::IntegerType>(Src->getType())) {
- bool InputSigned = SrcType->isSignedIntegerType();
- if (isa<llvm::IntegerType>(DstTy))
- return llvm::ConstantExpr::getIntegerCast(Src, DstTy, InputSigned);
- else if (InputSigned)
- return llvm::ConstantExpr::getSIToFP(Src, DstTy);
- else
- return llvm::ConstantExpr::getUIToFP(Src, DstTy);
- }
-
- assert(Src->getType()->isFloatingPoint() && "Unknown real conversion");
- if (isa<llvm::IntegerType>(DstTy)) {
- if (DstType->isSignedIntegerType())
- return llvm::ConstantExpr::getFPToSI(Src, DstTy);
- else
- return llvm::ConstantExpr::getFPToUI(Src, DstTy);
- }
-
- assert(DstTy->isFloatingPoint() && "Unknown real conversion");
- if (DstTy->getTypeID() < Src->getType()->getTypeID())
- return llvm::ConstantExpr::getFPTrunc(Src, DstTy);
- else
- return llvm::ConstantExpr::getFPExtend(Src, DstTy);
- }
-
- llvm::Constant *EmitSizeAlignOf(QualType TypeToSize,
- QualType RetType, bool isSizeOf) {
- std::pair<uint64_t, unsigned> Info =
- CGM.getContext().getTypeInfo(TypeToSize);
-
- uint64_t Val = isSizeOf ? Info.first : Info.second;
- Val /= 8; // Return size in bytes, not bits.
-
- assert(RetType->isIntegerType() && "Result type must be an integer!");
-
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGM.getContext().getTypeSize(RetType));
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
- }
-
- llvm::Constant *EmitLValue(Expr *E) {
- switch (E->getStmtClass()) {
- default: break;
- case Expr::ParenExprClass:
- // Elide parenthesis
- return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
- case Expr::CompoundLiteralExprClass: {
- // Note that due to the nature of compound literals, this is guaranteed
- // to be the only use of the variable, so we just generate it here.
- CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
- llvm::Constant* C = Visit(CLE->getInitializer());
- C = new llvm::GlobalVariable(C->getType(),E->getType().isConstQualified(),
- llvm::GlobalValue::InternalLinkage,
- C, ".compoundliteral", &CGM.getModule());
- return C;
- }
- case Expr::DeclRefExprClass: {
- ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
- return CGM.GetAddrOfFunction(FD);
- if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
- if (VD->isFileVarDecl())
- return CGM.GetAddrOfGlobalVar(VD);
- else if (VD->isBlockVarDecl()) {
- assert(CGF && "Can't access static local vars without CGF");
- return CGF->GetAddrOfStaticLocalVar(VD);
- }
- }
- break;
- }
- case Expr::MemberExprClass: {
- MemberExpr* ME = cast<MemberExpr>(E);
- llvm::Constant *Base;
- if (ME->isArrow())
- Base = Visit(ME->getBase());
- else
- Base = EmitLValue(ME->getBase());
-
- unsigned FieldNumber = CGM.getTypes().getLLVMFieldNo(ME->getMemberDecl());
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
- FieldNumber);
- llvm::Value *Ops[] = {Zero, Idx};
- return llvm::ConstantExpr::getGetElementPtr(Base, Ops, 2);
- }
- case Expr::ArraySubscriptExprClass: {
- ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
- llvm::Constant *Base = Visit(ASExpr->getBase());
- llvm::Constant *Index = Visit(ASExpr->getIdx());
- assert(!ASExpr->getBase()->getType()->isVectorType() &&
- "Taking the address of a vector component is illegal!");
- return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
- }
- case Expr::StringLiteralClass:
- return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
- case Expr::UnaryOperatorClass: {
- UnaryOperator *Exp = cast<UnaryOperator>(E);
- switch (Exp->getOpcode()) {
- default: break;
- case UnaryOperator::Extension:
- // Extension is just a wrapper for expressions
- return EmitLValue(Exp->getSubExpr());
- case UnaryOperator::Real:
- case UnaryOperator::Imag: {
- // The address of __real or __imag is just a GEP off the address
- // of the internal expression
- llvm::Constant* C = EmitLValue(Exp->getSubExpr());
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
- Exp->getOpcode() == UnaryOperator::Imag);
- llvm::Value *Ops[] = {Zero, Idx};
- return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
- }
- case UnaryOperator::Deref:
- // The address of a deref is just the value of the expression
- return Visit(Exp->getSubExpr());
- }
- break;
- }
- }
- CGM.ErrorUnsupported(E, "constant l-value expression");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return llvm::UndefValue::get(Ty);
- }
-};
-
-} // end anonymous namespace.
-
-
-llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
- CodeGenFunction *CGF) {
- QualType type = Context.getCanonicalType(E->getType());
-
- if (type->isIntegerType()) {
- llvm::APSInt Value(static_cast<uint32_t>(Context.getTypeSize(type)));
- if (E->isIntegerConstantExpr(Value, Context)) {
- return llvm::ConstantInt::get(Value);
- }
- }
-
- llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
- if (C->getType() == llvm::Type::Int1Ty) {
- const llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
- C = llvm::ConstantExpr::getZExt(C, BoolTy);
- }
- return C;
-}
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
deleted file mode 100644
index 88b8c9edefd5..000000000000
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ /dev/null
@@ -1,1235 +0,0 @@
-//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
-//
-// 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 emit Expr nodes with scalar LLVM types as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Support/Compiler.h"
-#include <cstdarg>
-
-using namespace clang;
-using namespace CodeGen;
-using llvm::Value;
-
-//===----------------------------------------------------------------------===//
-// Scalar Expression Emitter
-//===----------------------------------------------------------------------===//
-
-struct BinOpInfo {
- Value *LHS;
- Value *RHS;
- QualType Ty; // Computation Type.
- const BinaryOperator *E;
-};
-
-namespace {
-class VISIBILITY_HIDDEN ScalarExprEmitter
- : public StmtVisitor<ScalarExprEmitter, Value*> {
- CodeGenFunction &CGF;
- llvm::IRBuilder<> &Builder;
-
-public:
-
- ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf),
- Builder(CGF.Builder) {
- }
-
- //===--------------------------------------------------------------------===//
- // Utilities
- //===--------------------------------------------------------------------===//
-
- const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
- LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
-
- Value *EmitLoadOfLValue(LValue LV, QualType T) {
- return CGF.EmitLoadOfLValue(LV, T).getScalarVal();
- }
-
- /// EmitLoadOfLValue - Given an expression with complex type that represents a
- /// value l-value, this method emits the address of the l-value, then loads
- /// and returns the result.
- Value *EmitLoadOfLValue(const Expr *E) {
- // FIXME: Volatile
- return EmitLoadOfLValue(EmitLValue(E), E->getType());
- }
-
- /// EmitConversionToBool - Convert the specified expression value to a
- /// boolean (i1) truth value. This is equivalent to "Val != 0".
- Value *EmitConversionToBool(Value *Src, QualType DstTy);
-
- /// EmitScalarConversion - Emit a conversion from the specified type to the
- /// specified destination type, both of which are LLVM scalar types.
- Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy);
-
- /// EmitComplexToScalarConversion - Emit a conversion from the specified
- /// complex type to the specified destination type, where the destination
- /// type is an LLVM scalar type.
- Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
- QualType SrcTy, QualType DstTy);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- Value *VisitStmt(Stmt *S) {
- S->dump(CGF.getContext().getSourceManager());
- assert(0 && "Stmt can't have complex result type!");
- return 0;
- }
- Value *VisitExpr(Expr *S);
- Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); }
-
- // Leaves.
- Value *VisitIntegerLiteral(const IntegerLiteral *E) {
- return llvm::ConstantInt::get(E->getValue());
- }
- Value *VisitFloatingLiteral(const FloatingLiteral *E) {
- return llvm::ConstantFP::get(E->getValue());
- }
- Value *VisitCharacterLiteral(const CharacterLiteral *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
- Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
- Value *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
- return llvm::Constant::getNullValue(ConvertType(E->getType()));
- }
- Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()),
- CGF.getContext().typesAreCompatible(
- E->getArgType1(), E->getArgType2()));
- }
- Value *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
- return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf());
- }
- Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
- llvm::Value *V =
- llvm::ConstantInt::get(llvm::Type::Int32Ty,
- CGF.GetIDForAddrOfLabel(E->getLabel()));
-
- return Builder.CreateIntToPtr(V, ConvertType(E->getType()));
- }
-
- // l-values.
- Value *VisitDeclRefExpr(DeclRefExpr *E) {
- if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(E->getDecl()))
- return llvm::ConstantInt::get(EC->getInitVal());
- return EmitLoadOfLValue(E);
- }
- Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
- return CGF.EmitObjCSelectorExpr(E);
- }
- Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
- return CGF.EmitObjCProtocolExpr(E);
- }
- Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
- return EmitLoadOfLValue(E);
- }
- Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
- return EmitLoadOfLValue(E);
- }
- Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
- return CGF.EmitObjCMessageExpr(E).getScalarVal();
- }
-
- Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
- Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
- Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
- Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
- Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { return EmitLoadOfLValue(E); }
- Value *VisitStringLiteral(Expr *E) { return EmitLValue(E).getAddress(); }
- Value *VisitPredefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); }
-
- Value *VisitInitListExpr(InitListExpr *E) {
- unsigned NumInitElements = E->getNumInits();
-
- const llvm::VectorType *VType =
- dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
-
- // We have a scalar in braces. Just use the first element.
- if (!VType)
- return Visit(E->getInit(0));
-
- unsigned NumVectorElements = VType->getNumElements();
- const llvm::Type *ElementType = VType->getElementType();
-
- // Emit individual vector element stores.
- llvm::Value *V = llvm::UndefValue::get(VType);
-
- // Emit initializers
- unsigned i;
- for (i = 0; i < NumInitElements; ++i) {
- Value *NewV = Visit(E->getInit(i));
- Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- V = Builder.CreateInsertElement(V, NewV, Idx);
- }
-
- // Emit remaining default initializers
- for (/* Do not initialize i*/; i < NumVectorElements; ++i) {
- Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- llvm::Value *NewV = llvm::Constant::getNullValue(ElementType);
- V = Builder.CreateInsertElement(V, NewV, Idx);
- }
-
- return V;
- }
-
- Value *VisitImplicitCastExpr(const ImplicitCastExpr *E);
- Value *VisitCastExpr(const CastExpr *E) {
- return EmitCastExpr(E->getSubExpr(), E->getType());
- }
- Value *EmitCastExpr(const Expr *E, QualType T);
-
- Value *VisitCallExpr(const CallExpr *E) {
- return CGF.EmitCallExpr(E).getScalarVal();
- }
-
- Value *VisitStmtExpr(const StmtExpr *E);
-
- // Unary Operators.
- Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre);
- Value *VisitUnaryPostDec(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, false, false);
- }
- Value *VisitUnaryPostInc(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, true, false);
- }
- Value *VisitUnaryPreDec(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, false, true);
- }
- Value *VisitUnaryPreInc(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, true, true);
- }
- Value *VisitUnaryAddrOf(const UnaryOperator *E) {
- return EmitLValue(E->getSubExpr()).getAddress();
- }
- Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
- Value *VisitUnaryPlus(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- Value *VisitUnaryMinus (const UnaryOperator *E);
- Value *VisitUnaryNot (const UnaryOperator *E);
- Value *VisitUnaryLNot (const UnaryOperator *E);
- Value *VisitUnarySizeOf (const UnaryOperator *E) {
- return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
- }
- Value *VisitUnaryAlignOf (const UnaryOperator *E) {
- return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
- }
- Value *EmitSizeAlignOf(QualType TypeToSize, QualType RetType,
- bool isSizeOf);
- Value *VisitUnaryReal (const UnaryOperator *E);
- Value *VisitUnaryImag (const UnaryOperator *E);
- Value *VisitUnaryExtension(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- Value *VisitUnaryOffsetOf(const UnaryOperator *E);
- Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
- return Visit(DAE->getExpr());
- }
-
- // Binary Operators.
- Value *EmitMul(const BinOpInfo &Ops) {
- return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
- }
- Value *EmitDiv(const BinOpInfo &Ops);
- Value *EmitRem(const BinOpInfo &Ops);
- Value *EmitAdd(const BinOpInfo &Ops);
- Value *EmitSub(const BinOpInfo &Ops);
- Value *EmitShl(const BinOpInfo &Ops);
- Value *EmitShr(const BinOpInfo &Ops);
- Value *EmitAnd(const BinOpInfo &Ops) {
- return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
- }
- Value *EmitXor(const BinOpInfo &Ops) {
- return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
- }
- Value *EmitOr (const BinOpInfo &Ops) {
- return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
- }
-
- BinOpInfo EmitBinOps(const BinaryOperator *E);
- Value *EmitCompoundAssign(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
-
- // Binary operators and binary compound assignment operators.
-#define HANDLEBINOP(OP) \
- Value *VisitBin ## OP(const BinaryOperator *E) { \
- return Emit ## OP(EmitBinOps(E)); \
- } \
- Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
- return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
- }
- HANDLEBINOP(Mul);
- HANDLEBINOP(Div);
- HANDLEBINOP(Rem);
- HANDLEBINOP(Add);
- HANDLEBINOP(Sub);
- HANDLEBINOP(Shl);
- HANDLEBINOP(Shr);
- HANDLEBINOP(And);
- HANDLEBINOP(Xor);
- HANDLEBINOP(Or);
-#undef HANDLEBINOP
-
- // Comparisons.
- Value *EmitCompare(const BinaryOperator *E, unsigned UICmpOpc,
- unsigned SICmpOpc, unsigned FCmpOpc);
-#define VISITCOMP(CODE, UI, SI, FP) \
- Value *VisitBin##CODE(const BinaryOperator *E) { \
- return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
- llvm::FCmpInst::FP); }
- VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT);
- VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT);
- VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE);
- VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE);
- VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ);
- VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE);
-#undef VISITCOMP
-
- Value *VisitBinAssign (const BinaryOperator *E);
-
- Value *VisitBinLAnd (const BinaryOperator *E);
- Value *VisitBinLOr (const BinaryOperator *E);
- Value *VisitBinComma (const BinaryOperator *E);
-
- // Other Operators.
- Value *VisitConditionalOperator(const ConditionalOperator *CO);
- Value *VisitChooseExpr(ChooseExpr *CE);
- Value *VisitOverloadExpr(OverloadExpr *OE);
- Value *VisitVAArgExpr(VAArgExpr *VE);
- Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
- return CGF.EmitObjCStringLiteral(E);
- }
- Value *VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-/// EmitConversionToBool - Convert the specified expression value to a
-/// boolean (i1) truth value. This is equivalent to "Val != 0".
-Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
- assert(SrcType->isCanonical() && "EmitScalarConversion strips typedefs");
-
- if (SrcType->isRealFloatingType()) {
- // Compare against 0.0 for fp scalars.
- llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
- return Builder.CreateFCmpUNE(Src, Zero, "tobool");
- }
-
- assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
- "Unknown scalar type to convert");
-
- // Because of the type rules of C, we often end up computing a logical value,
- // then zero extending it to int, then wanting it as a logical value again.
- // Optimize this common case.
- if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(Src)) {
- if (ZI->getOperand(0)->getType() == llvm::Type::Int1Ty) {
- Value *Result = ZI->getOperand(0);
- // If there aren't any more uses, zap the instruction to save space.
- // Note that there can be more uses, for example if this
- // is the result of an assignment.
- if (ZI->use_empty())
- ZI->eraseFromParent();
- return Result;
- }
- }
-
- // Compare against an integer or pointer null.
- llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
- return Builder.CreateICmpNE(Src, Zero, "tobool");
-}
-
-/// EmitScalarConversion - Emit a conversion from the specified type to the
-/// specified destination type, both of which are LLVM scalar types.
-Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
- QualType DstType) {
- SrcType = CGF.getContext().getCanonicalType(SrcType);
- DstType = CGF.getContext().getCanonicalType(DstType);
- if (SrcType == DstType) return Src;
-
- if (DstType->isVoidType()) return 0;
-
- // Handle conversions to bool first, they are special: comparisons against 0.
- if (DstType->isBooleanType())
- return EmitConversionToBool(Src, SrcType);
-
- const llvm::Type *DstTy = ConvertType(DstType);
-
- // Ignore conversions like int -> uint.
- if (Src->getType() == DstTy)
- return Src;
-
- // Handle pointer conversions next: pointers can only be converted
- // to/from other pointers and integers. Check for pointer types in
- // terms of LLVM, as some native types (like Obj-C id) may map to a
- // pointer type.
- if (isa<llvm::PointerType>(DstTy)) {
- // The source value may be an integer, or a pointer.
- if (isa<llvm::PointerType>(Src->getType()))
- return Builder.CreateBitCast(Src, DstTy, "conv");
- assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
- return Builder.CreateIntToPtr(Src, DstTy, "conv");
- }
-
- if (isa<llvm::PointerType>(Src->getType())) {
- // Must be an ptr to int cast.
- assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
- return Builder.CreatePtrToInt(Src, DstTy, "conv");
- }
-
- // A scalar can be splatted to an extended vector of the same element type
- if (DstType->isExtVectorType() && !isa<VectorType>(SrcType) &&
- cast<llvm::VectorType>(DstTy)->getElementType() == Src->getType())
- return CGF.EmitVector(&Src, DstType->getAsVectorType()->getNumElements(),
- true);
-
- // Allow bitcast from vector to integer/fp of the same size.
- if (isa<llvm::VectorType>(Src->getType()) ||
- isa<llvm::VectorType>(DstTy))
- return Builder.CreateBitCast(Src, DstTy, "conv");
-
- // Finally, we have the arithmetic types: real int/float.
- if (isa<llvm::IntegerType>(Src->getType())) {
- bool InputSigned = SrcType->isSignedIntegerType();
- if (isa<llvm::IntegerType>(DstTy))
- return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
- else if (InputSigned)
- return Builder.CreateSIToFP(Src, DstTy, "conv");
- else
- return Builder.CreateUIToFP(Src, DstTy, "conv");
- }
-
- assert(Src->getType()->isFloatingPoint() && "Unknown real conversion");
- if (isa<llvm::IntegerType>(DstTy)) {
- if (DstType->isSignedIntegerType())
- return Builder.CreateFPToSI(Src, DstTy, "conv");
- else
- return Builder.CreateFPToUI(Src, DstTy, "conv");
- }
-
- assert(DstTy->isFloatingPoint() && "Unknown real conversion");
- if (DstTy->getTypeID() < Src->getType()->getTypeID())
- return Builder.CreateFPTrunc(Src, DstTy, "conv");
- else
- return Builder.CreateFPExt(Src, DstTy, "conv");
-}
-
-/// EmitComplexToScalarConversion - Emit a conversion from the specified
-/// complex type to the specified destination type, where the destination
-/// type is an LLVM scalar type.
-Value *ScalarExprEmitter::
-EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
- QualType SrcTy, QualType DstTy) {
- // Get the source element type.
- SrcTy = SrcTy->getAsComplexType()->getElementType();
-
- // Handle conversions to bool first, they are special: comparisons against 0.
- if (DstTy->isBooleanType()) {
- // Complex != 0 -> (Real != 0) | (Imag != 0)
- Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy);
- Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy);
- return Builder.CreateOr(Src.first, Src.second, "tobool");
- }
-
- // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
- // the imaginary part of the complex value is discarded and the value of the
- // real part is converted according to the conversion rules for the
- // corresponding real type.
- return EmitScalarConversion(Src.first, SrcTy, DstTy);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-Value *ScalarExprEmitter::VisitExpr(Expr *E) {
- CGF.ErrorUnsupported(E, "scalar expression");
- if (E->getType()->isVoidType())
- return 0;
- return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
-}
-
-Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
- llvm::SmallVector<llvm::Constant*, 32> indices;
- for (unsigned i = 2; i < E->getNumSubExprs(); i++) {
- indices.push_back(cast<llvm::Constant>(CGF.EmitScalarExpr(E->getExpr(i))));
- }
- Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
- Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
- Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
- return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
-}
-
-Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- // Emit subscript expressions in rvalue context's. For most cases, this just
- // loads the lvalue formed by the subscript expr. However, we have to be
- // careful, because the base of a vector subscript is occasionally an rvalue,
- // so we can't get it as an lvalue.
- if (!E->getBase()->getType()->isVectorType())
- return EmitLoadOfLValue(E);
-
- // Handle the vector case. The base must be a vector, the index must be an
- // integer value.
- Value *Base = Visit(E->getBase());
- Value *Idx = Visit(E->getIdx());
-
- // FIXME: Convert Idx to i32 type.
- return Builder.CreateExtractElement(Base, Idx, "vecext");
-}
-
-/// VisitImplicitCastExpr - Implicit casts are the same as normal casts, but
-/// also handle things like function to pointer-to-function decay, and array to
-/// pointer decay.
-Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
- const Expr *Op = E->getSubExpr();
-
- // If this is due to array->pointer conversion, emit the array expression as
- // an l-value.
- if (Op->getType()->isArrayType()) {
- // FIXME: For now we assume that all source arrays map to LLVM arrays. This
- // will not true when we add support for VLAs.
- Value *V = EmitLValue(Op).getAddress(); // Bitfields can't be arrays.
-
- if (!(isa<llvm::PointerType>(V->getType()) &&
- isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
- ->getElementType()))) {
- CGF.ErrorUnsupported(E, "variable-length array cast", true);
- if (E->getType()->isVoidType())
- return 0;
- return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
- }
- V = Builder.CreateStructGEP(V, 0, "arraydecay");
-
- // The resultant pointer type can be implicitly casted to other pointer
- // types as well (e.g. void*) and can be implicitly converted to integer.
- const llvm::Type *DestTy = ConvertType(E->getType());
- if (V->getType() != DestTy) {
- if (isa<llvm::PointerType>(DestTy))
- V = Builder.CreateBitCast(V, DestTy, "ptrconv");
- else {
- assert(isa<llvm::IntegerType>(DestTy) && "Unknown array decay");
- V = Builder.CreatePtrToInt(V, DestTy, "ptrconv");
- }
- }
- return V;
-
- } else if (E->getType()->isReferenceType()) {
- return EmitLValue(Op).getAddress();
- }
-
- return EmitCastExpr(Op, E->getType());
-}
-
-
-// VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts
-// have to handle a more broad range of conversions than explicit casts, as they
-// handle things like function to ptr-to-function decay etc.
-Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) {
- // Handle cases where the source is an non-complex type.
-
- if (!CGF.hasAggregateLLVMType(E->getType())) {
- Value *Src = Visit(const_cast<Expr*>(E));
-
- // Use EmitScalarConversion to perform the conversion.
- return EmitScalarConversion(Src, E->getType(), DestTy);
- }
-
- if (E->getType()->isAnyComplexType()) {
- // Handle cases where the source is a complex type.
- return EmitComplexToScalarConversion(CGF.EmitComplexExpr(E), E->getType(),
- DestTy);
- }
-
- // Okay, this is a cast from an aggregate. It must be a cast to void. Just
- // evaluate the result and return.
- CGF.EmitAggExpr(E, 0, false);
- return 0;
-}
-
-Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- return CGF.EmitCompoundStmt(*E->getSubStmt(),
- !E->getType()->isVoidType()).getScalarVal();
-}
-
-
-//===----------------------------------------------------------------------===//
-// Unary Operators
-//===----------------------------------------------------------------------===//
-
-Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
- bool isInc, bool isPre) {
- LValue LV = EmitLValue(E->getSubExpr());
- // FIXME: Handle volatile!
- Value *InVal = CGF.EmitLoadOfLValue(LV, // false
- E->getSubExpr()->getType()).getScalarVal();
-
- int AmountVal = isInc ? 1 : -1;
-
- Value *NextVal;
- if (isa<llvm::PointerType>(InVal->getType())) {
- // FIXME: This isn't right for VLAs.
- NextVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
- NextVal = Builder.CreateGEP(InVal, NextVal, "ptrincdec");
- } else {
- // Add the inc/dec to the real part.
- if (isa<llvm::IntegerType>(InVal->getType()))
- NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
- else if (InVal->getType() == llvm::Type::FloatTy)
- NextVal =
- llvm::ConstantFP::get(llvm::APFloat(static_cast<float>(AmountVal)));
- else if (InVal->getType() == llvm::Type::DoubleTy)
- NextVal =
- llvm::ConstantFP::get(llvm::APFloat(static_cast<double>(AmountVal)));
- else {
- llvm::APFloat F(static_cast<float>(AmountVal));
- F.convert(CGF.Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero);
- NextVal = llvm::ConstantFP::get(F);
- }
- NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
- }
-
- // Store the updated result through the lvalue.
- CGF.EmitStoreThroughLValue(RValue::get(NextVal), LV,
- E->getSubExpr()->getType());
-
- // If this is a postinc, return the value read from memory, otherwise use the
- // updated value.
- return isPre ? NextVal : InVal;
-}
-
-
-Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
- Value *Op = Visit(E->getSubExpr());
- return Builder.CreateNeg(Op, "neg");
-}
-
-Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
- Value *Op = Visit(E->getSubExpr());
- return Builder.CreateNot(Op, "neg");
-}
-
-Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
- // Compare operand to zero.
- Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
-
- // Invert value.
- // TODO: Could dynamically modify easy computations here. For example, if
- // the operand is an icmp ne, turn into icmp eq.
- BoolVal = Builder.CreateNot(BoolVal, "lnot");
-
- // ZExt result to int.
- return Builder.CreateZExt(BoolVal, CGF.LLVMIntTy, "lnot.ext");
-}
-
-/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as
-/// an integer (RetType).
-Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize,
- QualType RetType,bool isSizeOf){
- assert(RetType->isIntegerType() && "Result type must be an integer!");
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGF.getContext().getTypeSize(RetType));
-
- // sizeof(void) and __alignof__(void) = 1 as a gcc extension. Also
- // for function types.
- // FIXME: what is alignof a function type in gcc?
- if (TypeToSize->isVoidType() || TypeToSize->isFunctionType())
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1));
-
- /// FIXME: This doesn't handle VLAs yet!
- std::pair<uint64_t, unsigned> Info = CGF.getContext().getTypeInfo(TypeToSize);
-
- uint64_t Val = isSizeOf ? Info.first : Info.second;
- Val /= 8; // Return size in bytes, not bits.
-
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
-}
-
-Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
- Expr *Op = E->getSubExpr();
- if (Op->getType()->isAnyComplexType())
- return CGF.EmitComplexExpr(Op).first;
- return Visit(Op);
-}
-Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
- Expr *Op = E->getSubExpr();
- if (Op->getType()->isAnyComplexType())
- return CGF.EmitComplexExpr(Op).second;
-
- // __imag on a scalar returns zero. Emit it the subexpr to ensure side
- // effects are evaluated.
- CGF.EmitScalarExpr(Op);
- return llvm::Constant::getNullValue(ConvertType(E->getType()));
-}
-
-Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E)
-{
- int64_t Val = E->evaluateOffsetOf(CGF.getContext());
-
- assert(E->getType()->isIntegerType() && "Result type must be an integer!");
-
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGF.getContext().getTypeSize(E->getType()));
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
-}
-
-//===----------------------------------------------------------------------===//
-// Binary Operators
-//===----------------------------------------------------------------------===//
-
-BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
- BinOpInfo Result;
- Result.LHS = Visit(E->getLHS());
- Result.RHS = Visit(E->getRHS());
- Result.Ty = E->getType();
- Result.E = E;
- return Result;
-}
-
-Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
- QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
-
- BinOpInfo OpInfo;
-
- // Load the LHS and RHS operands.
- LValue LHSLV = EmitLValue(E->getLHS());
- OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
-
- // Determine the computation type. If the RHS is complex, then this is one of
- // the add/sub/mul/div operators. All of these operators can be computed in
- // with just their real component even though the computation domain really is
- // complex.
- QualType ComputeType = E->getComputationType();
-
- // If the computation type is complex, then the RHS is complex. Emit the RHS.
- if (const ComplexType *CT = ComputeType->getAsComplexType()) {
- ComputeType = CT->getElementType();
-
- // Emit the RHS, only keeping the real component.
- OpInfo.RHS = CGF.EmitComplexExpr(E->getRHS()).first;
- RHSTy = RHSTy->getAsComplexType()->getElementType();
- } else {
- // Otherwise the RHS is a simple scalar value.
- OpInfo.RHS = Visit(E->getRHS());
- }
-
- QualType LComputeTy, RComputeTy, ResultTy;
-
- // Compound assignment does not contain enough information about all
- // the types involved for pointer arithmetic cases. Figure it out
- // here for now.
- if (E->getLHS()->getType()->isPointerType()) {
- // Pointer arithmetic cases: ptr +=,-= int and ptr -= ptr,
- assert((E->getOpcode() == BinaryOperator::AddAssign ||
- E->getOpcode() == BinaryOperator::SubAssign) &&
- "Invalid compound assignment operator on pointer type.");
- LComputeTy = E->getLHS()->getType();
-
- if (E->getRHS()->getType()->isPointerType()) {
- // Degenerate case of (ptr -= ptr) allowed by GCC implicit cast
- // extension, the conversion from the pointer difference back to
- // the LHS type is handled at the end.
- assert(E->getOpcode() == BinaryOperator::SubAssign &&
- "Invalid compound assignment operator on pointer type.");
- RComputeTy = E->getLHS()->getType();
- ResultTy = CGF.getContext().getPointerDiffType();
- } else {
- RComputeTy = E->getRHS()->getType();
- ResultTy = LComputeTy;
- }
- } else if (E->getRHS()->getType()->isPointerType()) {
- // Degenerate case of (int += ptr) allowed by GCC implicit cast
- // extension.
- assert(E->getOpcode() == BinaryOperator::AddAssign &&
- "Invalid compound assignment operator on pointer type.");
- LComputeTy = E->getLHS()->getType();
- RComputeTy = E->getRHS()->getType();
- ResultTy = RComputeTy;
- } else {
- LComputeTy = RComputeTy = ResultTy = ComputeType;
- }
-
- // Convert the LHS/RHS values to the computation type.
- OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, LComputeTy);
- OpInfo.RHS = EmitScalarConversion(OpInfo.RHS, RHSTy, RComputeTy);
- OpInfo.Ty = ResultTy;
- OpInfo.E = E;
-
- // Expand the binary operator.
- Value *Result = (this->*Func)(OpInfo);
-
- // Convert the result back to the LHS type.
- Result = EmitScalarConversion(Result, ResultTy, LHSTy);
-
- // Store the result value into the LHS lvalue.
- CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, LHSTy);
-
- // For bitfields, we need the value in the bitfield. Note that
- // property references do not reload their value (even though the
- // setter may have changed it).
- // FIXME: This adds an extra bitfield load
- if (LHSLV.isBitfield())
- Result = EmitLoadOfLValue(LHSLV, LHSTy);
- return Result;
-}
-
-
-Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
- if (Ops.LHS->getType()->isFPOrFPVector())
- return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
- else if (Ops.Ty->isUnsignedIntegerType())
- return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
- else
- return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
-}
-
-Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
- // Rem in C can't be a floating point type: C99 6.5.5p2.
- if (Ops.Ty->isUnsignedIntegerType())
- return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
- else
- return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
-}
-
-
-Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
- if (!Ops.Ty->isPointerType())
- return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
-
- // FIXME: What about a pointer to a VLA?
- Value *Ptr, *Idx;
- Expr *IdxExp;
- if (isa<llvm::PointerType>(Ops.LHS->getType())) { // pointer + int
- Ptr = Ops.LHS;
- Idx = Ops.RHS;
- IdxExp = Ops.E->getRHS();
- } else { // int + pointer
- Ptr = Ops.RHS;
- Idx = Ops.LHS;
- IdxExp = Ops.E->getLHS();
- }
-
- unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
- if (Width < CGF.LLVMPointerWidth) {
- // Zero or sign extend the pointer value based on whether the index is
- // signed or not.
- const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
- if (IdxExp->getType()->isSignedIntegerType())
- Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
- else
- Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
- }
-
- return Builder.CreateGEP(Ptr, Idx, "add.ptr");
-}
-
-Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
- if (!isa<llvm::PointerType>(Ops.LHS->getType()))
- return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
-
- if (!isa<llvm::PointerType>(Ops.RHS->getType())) {
- // pointer - int
- Value *Idx = Ops.RHS;
- unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
- if (Width < CGF.LLVMPointerWidth) {
- // Zero or sign extend the pointer value based on whether the index is
- // signed or not.
- const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
- if (Ops.E->getRHS()->getType()->isSignedIntegerType())
- Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
- else
- Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
- }
- Idx = Builder.CreateNeg(Idx, "sub.ptr.neg");
-
- // FIXME: The pointer could point to a VLA.
- // The GNU void* - int case is automatically handled here because
- // our LLVM type for void* is i8*.
- return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
- } else {
- // pointer - pointer
- Value *LHS = Ops.LHS;
- Value *RHS = Ops.RHS;
-
- const QualType LHSType = Ops.E->getLHS()->getType();
- const QualType LHSElementType = LHSType->getAsPointerType()->getPointeeType();
- uint64_t ElementSize;
-
- // Handle GCC extension for pointer arithmetic on void* types.
- if (LHSElementType->isVoidType()) {
- ElementSize = 1;
- } else {
- ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
- }
-
- const llvm::Type *ResultType = ConvertType(Ops.Ty);
- LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
- RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
- Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
-
- // HACK: LLVM doesn't have an divide instruction that 'knows' there is no
- // remainder. As such, we handle common power-of-two cases here to generate
- // better code. See PR2247.
- if (llvm::isPowerOf2_64(ElementSize)) {
- Value *ShAmt =
- llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
- return Builder.CreateAShr(BytesBetween, ShAmt, "sub.ptr.shr");
- }
-
- // Otherwise, do a full sdiv.
- Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize);
- return Builder.CreateSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
- }
-}
-
-Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
- // LLVM requires the LHS and RHS to be the same type: promote or truncate the
- // RHS to the same size as the LHS.
- Value *RHS = Ops.RHS;
- if (Ops.LHS->getType() != RHS->getType())
- RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
-
- return Builder.CreateShl(Ops.LHS, RHS, "shl");
-}
-
-Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
- // LLVM requires the LHS and RHS to be the same type: promote or truncate the
- // RHS to the same size as the LHS.
- Value *RHS = Ops.RHS;
- if (Ops.LHS->getType() != RHS->getType())
- RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
-
- if (Ops.Ty->isUnsignedIntegerType())
- return Builder.CreateLShr(Ops.LHS, RHS, "shr");
- return Builder.CreateAShr(Ops.LHS, RHS, "shr");
-}
-
-Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
- unsigned SICmpOpc, unsigned FCmpOpc) {
- Value *Result;
- QualType LHSTy = E->getLHS()->getType();
- if (!LHSTy->isAnyComplexType() && !LHSTy->isVectorType()) {
- Value *LHS = Visit(E->getLHS());
- Value *RHS = Visit(E->getRHS());
-
- if (LHS->getType()->isFloatingPoint()) {
- Result = Builder.CreateFCmp((llvm::CmpInst::Predicate)FCmpOpc,
- LHS, RHS, "cmp");
- } else if (LHSTy->isSignedIntegerType()) {
- Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
- LHS, RHS, "cmp");
- } else {
- // Unsigned integers and pointers.
- Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
- LHS, RHS, "cmp");
- }
- } else if (LHSTy->isVectorType()) {
- Value *LHS = Visit(E->getLHS());
- Value *RHS = Visit(E->getRHS());
-
- if (LHS->getType()->isFPOrFPVector()) {
- Result = Builder.CreateVFCmp((llvm::CmpInst::Predicate)FCmpOpc,
- LHS, RHS, "cmp");
- } else if (LHSTy->isUnsignedIntegerType()) {
- Result = Builder.CreateVICmp((llvm::CmpInst::Predicate)UICmpOpc,
- LHS, RHS, "cmp");
- } else {
- // Signed integers and pointers.
- Result = Builder.CreateVICmp((llvm::CmpInst::Predicate)SICmpOpc,
- LHS, RHS, "cmp");
- }
- return Result;
- } else {
- // Complex Comparison: can only be an equality comparison.
- CodeGenFunction::ComplexPairTy LHS = CGF.EmitComplexExpr(E->getLHS());
- CodeGenFunction::ComplexPairTy RHS = CGF.EmitComplexExpr(E->getRHS());
-
- QualType CETy = LHSTy->getAsComplexType()->getElementType();
-
- Value *ResultR, *ResultI;
- if (CETy->isRealFloatingType()) {
- ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
- LHS.first, RHS.first, "cmp.r");
- ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
- LHS.second, RHS.second, "cmp.i");
- } else {
- // Complex comparisons can only be equality comparisons. As such, signed
- // and unsigned opcodes are the same.
- ResultR = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
- LHS.first, RHS.first, "cmp.r");
- ResultI = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
- LHS.second, RHS.second, "cmp.i");
- }
-
- if (E->getOpcode() == BinaryOperator::EQ) {
- Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
- } else {
- assert(E->getOpcode() == BinaryOperator::NE &&
- "Complex comparison other than == or != ?");
- Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
- }
- }
-
- // ZExt result to int.
- return Builder.CreateZExt(Result, CGF.LLVMIntTy, "cmp.ext");
-}
-
-Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
- LValue LHS = EmitLValue(E->getLHS());
- Value *RHS = Visit(E->getRHS());
-
- // Store the value into the LHS.
- // FIXME: Volatility!
- CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType());
-
- // For bitfields, we need the value in the bitfield. Note that
- // property references do not reload their value (even though the
- // setter may have changed it).
- // FIXME: This adds an extra bitfield load
- if (LHS.isBitfield())
- return EmitLoadOfLValue(LHS, E->getLHS()->getType());
-
- // Return the RHS.
- return RHS;
-}
-
-Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
- Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
-
- llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("land_cont");
- llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("land_rhs");
-
- llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
- Builder.CreateCondBr(LHSCond, RHSBlock, ContBlock);
-
- CGF.EmitBlock(RHSBlock);
- Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
-
- // Reaquire the RHS block, as there may be subblocks inserted.
- RHSBlock = Builder.GetInsertBlock();
- CGF.EmitBlock(ContBlock);
-
- // Create a PHI node. If we just evaluted the LHS condition, the result is
- // false. If we evaluated both, the result is the RHS condition.
- llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "land");
- PN->reserveOperandSpace(2);
- PN->addIncoming(llvm::ConstantInt::getFalse(), OrigBlock);
- PN->addIncoming(RHSCond, RHSBlock);
-
- // ZExt result to int.
- return Builder.CreateZExt(PN, CGF.LLVMIntTy, "land.ext");
-}
-
-Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
- Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
-
- llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("lor_cont");
- llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("lor_rhs");
-
- llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
- Builder.CreateCondBr(LHSCond, ContBlock, RHSBlock);
-
- CGF.EmitBlock(RHSBlock);
- Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
-
- // Reaquire the RHS block, as there may be subblocks inserted.
- RHSBlock = Builder.GetInsertBlock();
- CGF.EmitBlock(ContBlock);
-
- // Create a PHI node. If we just evaluted the LHS condition, the result is
- // true. If we evaluated both, the result is the RHS condition.
- llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "lor");
- PN->reserveOperandSpace(2);
- PN->addIncoming(llvm::ConstantInt::getTrue(), OrigBlock);
- PN->addIncoming(RHSCond, RHSBlock);
-
- // ZExt result to int.
- return Builder.CreateZExt(PN, CGF.LLVMIntTy, "lor.ext");
-}
-
-Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
- CGF.EmitStmt(E->getLHS());
- return Visit(E->getRHS());
-}
-
-//===----------------------------------------------------------------------===//
-// Other Operators
-//===----------------------------------------------------------------------===//
-
-Value *ScalarExprEmitter::
-VisitConditionalOperator(const ConditionalOperator *E) {
- llvm::BasicBlock *LHSBlock = llvm::BasicBlock::Create("cond.?");
- llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("cond.:");
- llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("cond.cont");
-
- // Evaluate the conditional, then convert it to bool. We do this explicitly
- // because we need the unconverted value if this is a GNU ?: expression with
- // missing middle value.
- Value *CondVal = CGF.EmitScalarExpr(E->getCond());
- Value *CondBoolVal =CGF.EmitScalarConversion(CondVal, E->getCond()->getType(),
- CGF.getContext().BoolTy);
- Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock);
-
- CGF.EmitBlock(LHSBlock);
-
- // Handle the GNU extension for missing LHS.
- Value *LHS;
- if (E->getLHS())
- LHS = Visit(E->getLHS());
- else // Perform promotions, to handle cases like "short ?: int"
- LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType());
-
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(RHSBlock);
-
- Value *RHS = Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(ContBlock);
-
- if (!LHS || !RHS) {
- assert(E->getType()->isVoidType() && "Non-void value should have a value");
- return 0;
- }
-
- // Create a PHI node for the real part.
- llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), "cond");
- PN->reserveOperandSpace(2);
- PN->addIncoming(LHS, LHSBlock);
- PN->addIncoming(RHS, RHSBlock);
- return PN;
-}
-
-Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
- // Emit the LHS or RHS as appropriate.
- return
- Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() : E->getRHS());
-}
-
-Value *ScalarExprEmitter::VisitOverloadExpr(OverloadExpr *E) {
- return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->arg_end(CGF.getContext())).getScalarVal();
-}
-
-Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
- llvm::Value *ArgValue = EmitLValue(VE->getSubExpr()).getAddress();
-
- llvm::Value *V = Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));
- return V;
-}
-
-Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
- std::string str;
- llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
- CGF.getContext().getObjCEncodingForType(E->getEncodedType(), str,
- EncodingRecordTypes);
-
- llvm::Constant *C = llvm::ConstantArray::get(str);
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &CGF.CGM.getModule());
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
- llvm::Constant *Zeros[] = { Zero, Zero };
- C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
-
- return C;
-}
-
-//===----------------------------------------------------------------------===//
-// Entry Point into this File
-//===----------------------------------------------------------------------===//
-
-/// EmitComplexExpr - Emit the computation of the specified expression of
-/// complex type, ignoring the result.
-Value *CodeGenFunction::EmitScalarExpr(const Expr *E) {
- assert(E && !hasAggregateLLVMType(E->getType()) &&
- "Invalid scalar expression to emit");
-
- return ScalarExprEmitter(*this).Visit(const_cast<Expr*>(E));
-}
-
-/// EmitScalarConversion - Emit a conversion from the specified type to the
-/// specified destination type, both of which are LLVM scalar types.
-Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
- QualType DstTy) {
- assert(!hasAggregateLLVMType(SrcTy) && !hasAggregateLLVMType(DstTy) &&
- "Invalid scalar expression to emit");
- return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy);
-}
-
-/// EmitComplexToScalarConversion - Emit a conversion from the specified
-/// complex type to the specified destination type, where the destination
-/// type is an LLVM scalar type.
-Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
- QualType SrcTy,
- QualType DstTy) {
- assert(SrcTy->isAnyComplexType() && !hasAggregateLLVMType(DstTy) &&
- "Invalid complex -> scalar conversion");
- return ScalarExprEmitter(*this).EmitComplexToScalarConversion(Src, SrcTy,
- DstTy);
-}
-
-Value *CodeGenFunction::EmitShuffleVector(Value* V1, Value *V2, ...) {
- assert(V1->getType() == V2->getType() &&
- "Vector operands must be of the same type");
- unsigned NumElements =
- cast<llvm::VectorType>(V1->getType())->getNumElements();
-
- va_list va;
- va_start(va, V2);
-
- llvm::SmallVector<llvm::Constant*, 16> Args;
- for (unsigned i = 0; i < NumElements; i++) {
- int n = va_arg(va, int);
- assert(n >= 0 && n < (int)NumElements * 2 &&
- "Vector shuffle index out of bounds!");
- Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, n));
- }
-
- const char *Name = va_arg(va, const char *);
- va_end(va);
-
- llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
-
- return Builder.CreateShuffleVector(V1, V2, Mask, Name);
-}
-
-llvm::Value *CodeGenFunction::EmitVector(llvm::Value * const *Vals,
- unsigned NumVals, bool isSplat) {
- llvm::Value *Vec
- = llvm::UndefValue::get(llvm::VectorType::get(Vals[0]->getType(), NumVals));
-
- for (unsigned i = 0, e = NumVals; i != e; ++i) {
- llvm::Value *Val = isSplat ? Vals[0] : Vals[i];
- llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Vec = Builder.CreateInsertElement(Vec, Val, Idx, "tmp");
- }
-
- return Vec;
-}
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
deleted file mode 100644
index 9849fb61b6b5..000000000000
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
-//
-// 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 emit Objective-C code as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGObjCRuntime.h"
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Target/TargetData.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-/// Emits an instance of NSConstantString representing the object.
-llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) {
- std::string String(E->getString()->getStrData(), E->getString()->getByteLength());
- llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(String);
- // FIXME: This bitcast should just be made an invariant on the Runtime.
- return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
-}
-
-/// Emit a selector.
-llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
- // Untyped selector.
- // Note that this implementation allows for non-constant strings to be passed
- // as arguments to @selector(). Currently, the only thing preventing this
- // behaviour is the type checking in the front end.
- return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
-}
-
-llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
- // FIXME: This should pass the Decl not the name.
- return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
-}
-
-
-RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
- // Only the lookup mechanism and first two arguments of the method
- // implementation vary between runtimes. We can get the receiver and
- // arguments in generic code.
-
- CGObjCRuntime &Runtime = CGM.getObjCRuntime();
- const Expr *ReceiverExpr = E->getReceiver();
- bool isSuperMessage = false;
- bool isClassMessage = false;
- // Find the receiver
- llvm::Value *Receiver;
- if (!ReceiverExpr) {
- const ObjCInterfaceDecl *OID = E->getClassInfo().first;
-
- // Very special case, super send in class method. The receiver is
- // self (the class object) and the send uses super semantics.
- if (!OID) {
- assert(!strcmp(E->getClassName()->getName(), "super") &&
- "Unexpected missing class interface in message send.");
- isSuperMessage = true;
- Receiver = LoadObjCSelf();
- } else {
- Receiver = Runtime.GetClass(Builder, OID);
- }
-
- isClassMessage = true;
- } else if (const PredefinedExpr *PDE =
- dyn_cast<PredefinedExpr>(E->getReceiver())) {
- assert(PDE->getIdentType() == PredefinedExpr::ObjCSuper);
- isSuperMessage = true;
- Receiver = LoadObjCSelf();
- } else {
- Receiver = EmitScalarExpr(E->getReceiver());
- }
-
- CallArgList Args;
- for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
- i != e; ++i)
- Args.push_back(std::make_pair(EmitAnyExprToTemp(*i), (*i)->getType()));
-
- if (isSuperMessage) {
- // super is only valid in an Objective-C method
- const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
- return Runtime.GenerateMessageSendSuper(*this, E->getType(),
- E->getSelector(),
- OMD->getClassInterface(),
- Receiver,
- isClassMessage,
- Args);
- }
- return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
- Receiver, isClassMessage, Args);
-}
-
-/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
-/// the LLVM function and sets the other context used by
-/// CodeGenFunction.
-void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) {
- FunctionArgList Args;
- llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD);
-
- CGM.SetMethodAttributes(OMD, Fn);
-
- Args.push_back(std::make_pair(OMD->getSelfDecl(),
- OMD->getSelfDecl()->getType()));
- Args.push_back(std::make_pair(OMD->getCmdDecl(),
- OMD->getCmdDecl()->getType()));
-
- for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i) {
- ParmVarDecl *IPD = OMD->getParamDecl(i);
- Args.push_back(std::make_pair(IPD, IPD->getType()));
- }
-
- StartFunction(OMD, OMD->getResultType(), Fn, Args);
-}
-
-/// Generate an Objective-C method. An Objective-C method is a C function with
-/// its pointer, name, and types registered in the class struture.
-void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
- StartObjCMethod(OMD);
- EmitStmt(OMD->getBody());
-
- const CompoundStmt *S = dyn_cast<CompoundStmt>(OMD->getBody());
- if (S) {
- FinishFunction(S->getRBracLoc());
- } else {
- FinishFunction();
- }
-}
-
-// FIXME: I wasn't sure about the synthesis approach. If we end up
-// generating an AST for the whole body we can just fall back to
-// having a GenerateFunction which takes the body Stmt.
-
-/// GenerateObjCGetter - Generate an Objective-C property getter
-/// function. The given Decl must be either an ObjCCategoryImplDecl
-/// or an ObjCImplementationDecl.
-void CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) {
- ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
- const ObjCPropertyDecl *PD = PID->getPropertyDecl();
- ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
- assert(OMD && "Invalid call to generate getter (empty method)");
- // FIXME: This is rather murky, we create this here since they will
- // not have been created by Sema for us.
- OMD->createImplicitParams(getContext());
- StartObjCMethod(OMD);
-
- // Determine if we should use an objc_getProperty call for
- // this. Non-atomic and properties with assign semantics are
- // directly evaluated, and in gc-only mode we don't need it at all.
- if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
- PD->getSetterKind() != ObjCPropertyDecl::Assign &&
- !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)) {
- llvm::Value *GetPropertyFn =
- CGM.getObjCRuntime().GetPropertyGetFunction();
-
- if (!GetPropertyFn) {
- CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
- FinishFunction();
- return;
- }
-
- // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
- // FIXME: Can't this be simpler? This might even be worse than the
- // corresponding gcc code.
- CodeGenTypes &Types = CGM.getTypes();
- ValueDecl *Cmd = OMD->getCmdDecl();
- llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
- QualType IdTy = getContext().getObjCIdType();
- llvm::Value *SelfAsId =
- Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
- llvm::Value *Offset = EmitIvarOffset(OMD->getClassInterface(), Ivar);
- llvm::Value *True =
- llvm::ConstantInt::get(Types.ConvertTypeForMem(getContext().BoolTy), 1);
- CallArgList Args;
- Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
- Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
- Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
- Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
- RValue RV = EmitCall(GetPropertyFn, PD->getType(), Args);
- // We need to fix the type here. Ivars with copy & retain are
- // always objects so we don't need to worry about complex or
- // aggregates.
- RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
- Types.ConvertType(PD->getType())));
- EmitReturnOfRValue(RV, PD->getType());
- } else {
- EmitReturnOfRValue(EmitLoadOfLValue(EmitLValueForIvar(LoadObjCSelf(),
- Ivar, 0),
- Ivar->getType()),
- PD->getType());
- }
-
- FinishFunction();
-}
-
-/// GenerateObjCSetter - Generate an Objective-C property setter
-/// function. The given Decl must be either an ObjCCategoryImplDecl
-/// or an ObjCImplementationDecl.
-void CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) {
- ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
- const ObjCPropertyDecl *PD = PID->getPropertyDecl();
- ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
- assert(OMD && "Invalid call to generate setter (empty method)");
- // FIXME: This is rather murky, we create this here since they will
- // not have been created by Sema for us.
- OMD->createImplicitParams(getContext());
- StartObjCMethod(OMD);
-
- bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
- bool IsAtomic =
- !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
-
- // Determine if we should use an objc_setProperty call for
- // this. Properties with 'copy' semantics always use it, as do
- // non-atomic properties with 'release' semantics as long as we are
- // not in gc-only mode.
- if (IsCopy ||
- (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
- PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
- llvm::Value *SetPropertyFn =
- CGM.getObjCRuntime().GetPropertySetFunction();
-
- if (!SetPropertyFn) {
- CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
- FinishFunction();
- return;
- }
-
- // Emit objc_setProperty((id) self, _cmd, offset, arg,
- // <is-atomic>, <is-copy>).
- // FIXME: Can't this be simpler? This might even be worse than the
- // corresponding gcc code.
- CodeGenTypes &Types = CGM.getTypes();
- ValueDecl *Cmd = OMD->getCmdDecl();
- llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
- QualType IdTy = getContext().getObjCIdType();
- llvm::Value *SelfAsId =
- Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
- llvm::Value *Offset = EmitIvarOffset(OMD->getClassInterface(), Ivar);
- llvm::Value *Arg = LocalDeclMap[OMD->getParamDecl(0)];
- llvm::Value *ArgAsId =
- Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
- Types.ConvertType(IdTy));
- llvm::Value *True =
- llvm::ConstantInt::get(Types.ConvertTypeForMem(getContext().BoolTy), 1);
- llvm::Value *False =
- llvm::ConstantInt::get(Types.ConvertTypeForMem(getContext().BoolTy), 0);
- CallArgList Args;
- Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
- Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
- Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
- Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy));
- Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False),
- getContext().BoolTy));
- Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False),
- getContext().BoolTy));
- EmitCall(SetPropertyFn, PD->getType(), Args);
- } else {
- SourceLocation Loc = PD->getLocation();
- ValueDecl *Self = OMD->getSelfDecl();
- ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
- DeclRefExpr Base(Self, Self->getType(), Loc);
- ParmVarDecl *ArgDecl = OMD->getParamDecl(0);
- DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
- ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
- true, true);
- BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
- Ivar->getType(), Loc);
- EmitStmt(&Assign);
- }
-
- FinishFunction();
-}
-
-llvm::Value *CodeGenFunction::LoadObjCSelf() {
- const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
- return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
-}
-
-RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) {
- // Determine getter selector.
- Selector S;
- if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
- S = E->getGetterMethod()->getSelector();
- } else {
- S = E->getProperty()->getGetterName();
- }
-
- return CGM.getObjCRuntime().
- GenerateMessageSend(*this, E->getType(), S,
- EmitScalarExpr(E->getBase()),
- false, CallArgList());
-}
-
-void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E,
- RValue Src) {
- Selector S;
- if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
- ObjCMethodDecl *Setter = E->getSetterMethod();
-
- if (Setter) {
- S = Setter->getSelector();
- } else {
- // FIXME: This should be diagnosed by sema.
- SourceRange Range = E->getSourceRange();
- CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()),
- diag::err_typecheck_assign_const, 0, 0,
- &Range, 1);
- return;
- }
- } else {
- S = E->getProperty()->getSetterName();
- }
-
- CallArgList Args;
- Args.push_back(std::make_pair(Src, E->getType()));
- CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
- EmitScalarExpr(E->getBase()),
- false, Args);
-}
-
-void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
-{
- llvm::Function *EnumerationMutationFn =
- CGM.getObjCRuntime().EnumerationMutationFunction();
- llvm::Value *DeclAddress;
- QualType ElementTy;
-
- if (!EnumerationMutationFn) {
- CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
- return;
- }
-
- if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
- EmitStmt(SD);
- const ScopedDecl* D = SD->getSolitaryDecl();
- ElementTy = cast<ValueDecl>(D)->getType();
- DeclAddress = LocalDeclMap[D];
- } else {
- ElementTy = cast<Expr>(S.getElement())->getType();
- DeclAddress = 0;
- }
-
- // Fast enumeration state.
- QualType StateTy = getContext().getObjCFastEnumerationStateType();
- llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy),
- "state.ptr");
- StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3);
- EmitMemSetToZero(StatePtr, StateTy);
-
- // Number of elements in the items array.
- static const unsigned NumItems = 16;
-
- // Get selector
- llvm::SmallVector<IdentifierInfo*, 3> II;
- II.push_back(&CGM.getContext().Idents.get("countByEnumeratingWithState"));
- II.push_back(&CGM.getContext().Idents.get("objects"));
- II.push_back(&CGM.getContext().Idents.get("count"));
- Selector FastEnumSel = CGM.getContext().Selectors.getSelector(II.size(),
- &II[0]);
-
- QualType ItemsTy =
- getContext().getConstantArrayType(getContext().getObjCIdType(),
- llvm::APInt(32, NumItems),
- ArrayType::Normal, 0);
- llvm::Value *ItemsPtr = CreateTempAlloca(ConvertType(ItemsTy), "items.ptr");
-
- llvm::Value *Collection = EmitScalarExpr(S.getCollection());
-
- CallArgList Args;
- Args.push_back(std::make_pair(RValue::get(StatePtr),
- getContext().getPointerType(StateTy)));
-
- Args.push_back(std::make_pair(RValue::get(ItemsPtr),
- getContext().getPointerType(ItemsTy)));
-
- const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
- llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
- Args.push_back(std::make_pair(RValue::get(Count),
- getContext().UnsignedLongTy));
-
- RValue CountRV =
- CGM.getObjCRuntime().GenerateMessageSend(*this,
- getContext().UnsignedLongTy,
- FastEnumSel,
- Collection, false, Args);
-
- llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr");
- Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
-
- llvm::BasicBlock *NoElements = llvm::BasicBlock::Create("noelements");
- llvm::BasicBlock *SetStartMutations =
- llvm::BasicBlock::Create("setstartmutations");
-
- llvm::Value *Limit = Builder.CreateLoad(LimitPtr);
- llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy);
-
- llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
- Builder.CreateCondBr(IsZero, NoElements, SetStartMutations);
-
- EmitBlock(SetStartMutations);
-
- llvm::Value *StartMutationsPtr =
- CreateTempAlloca(UnsignedLongLTy);
-
- llvm::Value *StateMutationsPtrPtr =
- Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
- llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
- "mutationsptr");
-
- llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr,
- "mutations");
-
- Builder.CreateStore(StateMutations, StartMutationsPtr);
-
- llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart");
- EmitBlock(LoopStart);
-
- llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr");
- Builder.CreateStore(Zero, CounterPtr);
-
- llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody");
- EmitBlock(LoopBody);
-
- StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
- StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations");
-
- llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr,
- "mutations");
- llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations,
- StartMutations,
- "tobool");
-
-
- llvm::BasicBlock *WasMutated = llvm::BasicBlock::Create("wasmutated");
- llvm::BasicBlock *WasNotMutated = llvm::BasicBlock::Create("wasnotmutated");
-
- Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated);
-
- EmitBlock(WasMutated);
- llvm::Value *V =
- Builder.CreateBitCast(Collection,
- ConvertType(getContext().getObjCIdType()),
- "tmp");
- Builder.CreateCall(EnumerationMutationFn, V);
-
- EmitBlock(WasNotMutated);
-
- llvm::Value *StateItemsPtr =
- Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
-
- llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter");
-
- llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr,
- "stateitems");
-
- llvm::Value *CurrentItemPtr =
- Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr");
-
- llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem");
-
- // Cast the item to the right type.
- CurrentItem = Builder.CreateBitCast(CurrentItem,
- ConvertType(ElementTy), "tmp");
-
- if (!DeclAddress) {
- LValue LV = EmitLValue(cast<Expr>(S.getElement()));
-
- // Set the value to null.
- Builder.CreateStore(CurrentItem, LV.getAddress());
- } else
- Builder.CreateStore(CurrentItem, DeclAddress);
-
- // Increment the counter.
- Counter = Builder.CreateAdd(Counter,
- llvm::ConstantInt::get(UnsignedLongLTy, 1));
- Builder.CreateStore(Counter, CounterPtr);
-
- llvm::BasicBlock *LoopEnd = llvm::BasicBlock::Create("loopend");
- llvm::BasicBlock *AfterBody = llvm::BasicBlock::Create("afterbody");
-
- BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
-
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- EmitBlock(AfterBody);
-
- llvm::BasicBlock *FetchMore = llvm::BasicBlock::Create("fetchmore");
-
- llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless");
- Builder.CreateCondBr(IsLess, LoopBody, FetchMore);
-
- // Fetch more elements.
- EmitBlock(FetchMore);
-
- CountRV =
- CGM.getObjCRuntime().GenerateMessageSend(*this,
- getContext().UnsignedLongTy,
- FastEnumSel,
- Collection, false, Args);
- Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
- Limit = Builder.CreateLoad(LimitPtr);
-
- IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
- Builder.CreateCondBr(IsZero, NoElements, LoopStart);
-
- // No more elements.
- EmitBlock(NoElements);
-
- if (!DeclAddress) {
- // If the element was not a declaration, set it to be null.
-
- LValue LV = EmitLValue(cast<Expr>(S.getElement()));
-
- // Set the value to null.
- Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)),
- LV.getAddress());
- }
-
- EmitBlock(LoopEnd);
-}
-
-void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
-{
- CGM.getObjCRuntime().EmitTryStmt(*this, S);
-}
-
-void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
-{
- CGM.getObjCRuntime().EmitThrowStmt(*this, S);
-}
-
-CGObjCRuntime::~CGObjCRuntime() {}
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
deleted file mode 100644
index 7d98ecff9586..000000000000
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ /dev/null
@@ -1,969 +0,0 @@
-//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides Objective-C code generation targetting the GNU runtime. The
-// class in this file generates structures used by the GNU Objective-C runtime
-// library. These structures are defined in objc/objc.h and objc/objc-api.h in
-// the GNU runtime distribution.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGObjCRuntime.h"
-#include "CodeGenModule.h"
-#include "CodeGenFunction.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Module.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Target/TargetData.h"
-#include <map>
-using namespace clang;
-using namespace CodeGen;
-using llvm::dyn_cast;
-
-// The version of the runtime that this class targets. Must match the version
-// in the runtime.
-static const int RuntimeVersion = 8;
-static const int ProtocolVersion = 2;
-
-namespace {
-class CGObjCGNU : public CodeGen::CGObjCRuntime {
-private:
- CodeGen::CodeGenModule &CGM;
- llvm::Module &TheModule;
- const llvm::StructType *SelStructTy;
- const llvm::Type *SelectorTy;
- const llvm::Type *PtrToInt8Ty;
- const llvm::Type *IMPTy;
- const llvm::Type *IdTy;
- const llvm::Type *IntTy;
- const llvm::Type *PtrTy;
- const llvm::Type *LongTy;
- const llvm::Type *PtrToIntTy;
- std::vector<llvm::Constant*> Classes;
- std::vector<llvm::Constant*> Categories;
- std::vector<llvm::Constant*> ConstantStrings;
- llvm::Function *LoadFunction;
- llvm::StringMap<llvm::Constant*> ExistingProtocols;
- typedef std::pair<std::string, std::string> TypedSelector;
- std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
- llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
- // Some zeros used for GEPs in lots of places.
- llvm::Constant *Zeros[2];
- llvm::Constant *NULLPtr;
-private:
- llvm::Constant *GenerateIvarList(
- const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
- const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
- const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets);
- llvm::Constant *GenerateMethodList(const std::string &ClassName,
- const std::string &CategoryName,
- const llvm::SmallVectorImpl<Selector> &MethodSels,
- const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
- bool isClassMethodList);
- llvm::Constant *GenerateProtocolList(
- const llvm::SmallVectorImpl<std::string> &Protocols);
- llvm::Constant *GenerateClassStructure(
- llvm::Constant *MetaClass,
- llvm::Constant *SuperClass,
- unsigned info,
- const char *Name,
- llvm::Constant *Version,
- llvm::Constant *InstanceSize,
- llvm::Constant *IVars,
- llvm::Constant *Methods,
- llvm::Constant *Protocols);
- llvm::Constant *GenerateProtocolMethodList(
- const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames,
- const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes);
- llvm::Constant *MakeConstantString(const std::string &Str, const std::string
- &Name="");
- llvm::Constant *MakeGlobal(const llvm::StructType *Ty,
- std::vector<llvm::Constant*> &V, const std::string &Name="");
- llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
- std::vector<llvm::Constant*> &V, const std::string &Name="");
-public:
- CGObjCGNU(CodeGen::CodeGenModule &cgm);
- virtual llvm::Constant *GenerateConstantString(const std::string &String);
- virtual CodeGen::RValue
- GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs);
- virtual CodeGen::RValue
- GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- const ObjCInterfaceDecl *Class,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs);
- virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
- const ObjCInterfaceDecl *OID);
- virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
-
- virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
- virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
- virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
- virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
- const ObjCProtocolDecl *PD);
- virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
- virtual llvm::Function *ModuleInitFunction();
- virtual llvm::Function *GetPropertyGetFunction();
- virtual llvm::Function *GetPropertySetFunction();
- virtual llvm::Function *EnumerationMutationFunction();
-
- virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtTryStmt &S);
- virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtThrowStmt &S);
-};
-} // end anonymous namespace
-
-
-
-static std::string SymbolNameForClass(const std::string &ClassName) {
- return ".objc_class_" + ClassName;
-}
-
-static std::string SymbolNameForMethod(const std::string &ClassName, const
- std::string &CategoryName, const std::string &MethodName, bool isClassMethod)
-{
- return "._objc_method_" + ClassName +"("+CategoryName+")"+
- (isClassMethod ? "+" : "-") + MethodName;
-}
-
-CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
- : CGM(cgm), TheModule(CGM.getModule()) {
- IntTy = CGM.getTypes().ConvertType(CGM.getContext().IntTy);
- LongTy = CGM.getTypes().ConvertType(CGM.getContext().LongTy);
-
- Zeros[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- Zeros[1] = Zeros[0];
- NULLPtr = llvm::ConstantPointerNull::get(
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty));
- // C string type. Used in lots of places.
- PtrToInt8Ty =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- // Get the selector Type.
- SelStructTy = llvm::StructType::get(
- PtrToInt8Ty,
- PtrToInt8Ty,
- NULL);
- SelectorTy = llvm::PointerType::getUnqual(SelStructTy);
- PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
- PtrTy = PtrToInt8Ty;
-
- // Object type
- llvm::PATypeHolder OpaqueObjTy = llvm::OpaqueType::get();
- llvm::Type *OpaqueIdTy = llvm::PointerType::getUnqual(OpaqueObjTy);
- IdTy = llvm::StructType::get(OpaqueIdTy, NULL);
- llvm::cast<llvm::OpaqueType>(OpaqueObjTy.get())->refineAbstractTypeTo(IdTy);
- IdTy = llvm::cast<llvm::StructType>(OpaqueObjTy.get());
- IdTy = llvm::PointerType::getUnqual(IdTy);
-
- // IMP type
- std::vector<const llvm::Type*> IMPArgs;
- IMPArgs.push_back(IdTy);
- IMPArgs.push_back(SelectorTy);
- IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
-}
-// This has to perform the lookup every time, since posing and related
-// techniques can modify the name -> class mapping.
-llvm::Value *CGObjCGNU::GetClass(llvm::IRBuilder<> &Builder,
- const ObjCInterfaceDecl *OID) {
- llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getName());
- ClassName = Builder.CreateStructGEP(ClassName, 0);
-
- llvm::Constant *ClassLookupFn =
- TheModule.getOrInsertFunction("objc_lookup_class", IdTy, PtrToInt8Ty,
- NULL);
- return Builder.CreateCall(ClassLookupFn, ClassName);
-}
-
-/// GetSelector - Return the pointer to the unique'd string for this selector.
-llvm::Value *CGObjCGNU::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
- // FIXME: uniquing on the string is wasteful, unique on Sel instead!
- llvm::GlobalAlias *&US = UntypedSelectors[Sel.getName()];
- if (US == 0)
- US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
- llvm::GlobalValue::InternalLinkage,
- ".objc_untyped_selector_alias",
- NULL, &TheModule);
-
- return Builder.CreateLoad(US);
-
-}
-
-llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
- const std::string &Name) {
- llvm::Constant * ConstStr = llvm::ConstantArray::get(Str);
- ConstStr = new llvm::GlobalVariable(ConstStr->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- ConstStr, Name, &TheModule);
- return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
-}
-llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
- std::vector<llvm::Constant*> &V, const std::string &Name) {
- llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
- return new llvm::GlobalVariable(Ty, false,
- llvm::GlobalValue::InternalLinkage, C, Name, &TheModule);
-}
-llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
- std::vector<llvm::Constant*> &V, const std::string &Name) {
- llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
- return new llvm::GlobalVariable(Ty, false,
- llvm::GlobalValue::InternalLinkage, C, Name, &TheModule);
-}
-
-/// Generate an NSConstantString object.
-//TODO: In case there are any crazy people still using the GNU runtime without
-//an OpenStep implementation, this should let them select their own class for
-//constant strings.
-llvm::Constant *CGObjCGNU::GenerateConstantString(const std::string &Str) {
- std::vector<llvm::Constant*> Ivars;
- Ivars.push_back(NULLPtr);
- Ivars.push_back(MakeConstantString(Str));
- Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
- llvm::Constant *ObjCStr = MakeGlobal(
- llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
- Ivars, ".objc_str");
- ConstantStrings.push_back(
- llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty));
- return ObjCStr;
-}
-
-///Generates a message send where the super is the receiver. This is a message
-///send to self with special delivery semantics indicating which class's method
-///should be called.
-CodeGen::RValue
-CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- const ObjCInterfaceDecl *Class,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs) {
- const ObjCInterfaceDecl *SuperClass = Class->getSuperClass();
- const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType);
- // TODO: This should be cached, not looked up every time.
- llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass);
- llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
- std::vector<const llvm::Type*> impArgTypes;
- impArgTypes.push_back(Receiver->getType());
- impArgTypes.push_back(SelectorTy);
-
- // Avoid an explicit cast on the IMP by getting a version that has the right
- // return type.
- llvm::FunctionType *impType = llvm::FunctionType::get(ReturnTy, impArgTypes,
- true);
- // Construct the structure used to look up the IMP
- llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(),
- IdTy, NULL);
- llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy);
- // FIXME: volatility
- CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
- CGF.Builder.CreateStore(ReceiverClass, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
-
- // Get the IMP
- llvm::Constant *lookupFunction =
- TheModule.getOrInsertFunction("objc_msg_lookup_super",
- llvm::PointerType::getUnqual(impType),
- llvm::PointerType::getUnqual(ObjCSuperTy),
- SelectorTy, NULL);
- llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
- llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
- lookupArgs+2);
-
- // Call the method
- CallArgList ActualArgs;
- ActualArgs.push_back(std::make_pair(RValue::get(Receiver),
- CGF.getContext().getObjCIdType()));
- ActualArgs.push_back(std::make_pair(RValue::get(cmd),
- CGF.getContext().getObjCSelType()));
- ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
- return CGF.EmitCall(imp, ResultType, ActualArgs);
-}
-
-/// Generate code for a message send expression.
-CodeGen::RValue
-CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs) {
- const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType);
- llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
-
- // Look up the method implementation.
- std::vector<const llvm::Type*> impArgTypes;
- const llvm::Type *RetTy;
- //TODO: Revisit this when LLVM supports aggregate return types.
- if (ReturnTy->isSingleValueType() && ReturnTy != llvm::Type::VoidTy) {
- RetTy = ReturnTy;
- } else {
- // For struct returns allocate the space in the caller and pass it up to
- // the sender.
- RetTy = llvm::Type::VoidTy;
- impArgTypes.push_back(llvm::PointerType::getUnqual(ReturnTy));
- }
- impArgTypes.push_back(Receiver->getType());
- impArgTypes.push_back(SelectorTy);
-
- // Avoid an explicit cast on the IMP by getting a version that has the right
- // return type.
- llvm::FunctionType *impType = llvm::FunctionType::get(RetTy, impArgTypes,
- true);
-
- llvm::Constant *lookupFunction =
- TheModule.getOrInsertFunction("objc_msg_lookup",
- llvm::PointerType::getUnqual(impType),
- Receiver->getType(), SelectorTy, NULL);
- llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
-
- // Call the method.
- CallArgList ActualArgs;
- ActualArgs.push_back(std::make_pair(RValue::get(Receiver),
- CGF.getContext().getObjCIdType()));
- ActualArgs.push_back(std::make_pair(RValue::get(cmd),
- CGF.getContext().getObjCSelType()));
- ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
- return CGF.EmitCall(imp, ResultType, ActualArgs);
-}
-
-/// Generates a MethodList. Used in construction of a objc_class and
-/// objc_category structures.
-llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
- const std::string &CategoryName,
- const llvm::SmallVectorImpl<Selector> &MethodSels,
- const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
- bool isClassMethodList) {
- // Get the method structure type.
- llvm::StructType *ObjCMethodTy = llvm::StructType::get(
- PtrToInt8Ty, // Really a selector, but the runtime creates it us.
- PtrToInt8Ty, // Method types
- llvm::PointerType::getUnqual(IMPTy), //Method pointer
- NULL);
- std::vector<llvm::Constant*> Methods;
- std::vector<llvm::Constant*> Elements;
- for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
- Elements.clear();
- llvm::Constant *C = CGM.GetAddrOfConstantCString(MethodSels[i].getName());
- Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2));
- Elements.push_back(
- llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
- llvm::Constant *Method =
- TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
- MethodSels[i].getName(),
- isClassMethodList));
- Method = llvm::ConstantExpr::getBitCast(Method,
- llvm::PointerType::getUnqual(IMPTy));
- Elements.push_back(Method);
- Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
- }
-
- // Array of method structures
- llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
- MethodSels.size());
- llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
- Methods);
-
- // Structure containing list pointer, array and array count
- llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields;
- llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get();
- llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy);
- llvm::StructType *ObjCMethodListTy = llvm::StructType::get(NextPtrTy,
- IntTy,
- ObjCMethodArrayTy,
- NULL);
- // Refine next pointer type to concrete type
- llvm::cast<llvm::OpaqueType>(
- OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy);
- ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get());
-
- Methods.clear();
- Methods.push_back(llvm::ConstantPointerNull::get(
- llvm::PointerType::getUnqual(ObjCMethodListTy)));
- Methods.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty,
- MethodTypes.size()));
- Methods.push_back(MethodArray);
-
- // Create an instance of the structure
- return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list");
-}
-
-/// Generates an IvarList. Used in construction of a objc_class.
-llvm::Constant *CGObjCGNU::GenerateIvarList(
- const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
- const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
- const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets) {
- // Get the method structure type.
- llvm::StructType *ObjCIvarTy = llvm::StructType::get(
- PtrToInt8Ty,
- PtrToInt8Ty,
- IntTy,
- NULL);
- std::vector<llvm::Constant*> Ivars;
- std::vector<llvm::Constant*> Elements;
- for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
- Elements.clear();
- Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarNames[i],
- Zeros, 2));
- Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarTypes[i],
- Zeros, 2));
- Elements.push_back(IvarOffsets[i]);
- Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
- }
-
- // Array of method structures
- llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
- IvarNames.size());
-
-
- Elements.clear();
- Elements.push_back(llvm::ConstantInt::get(
- llvm::cast<llvm::IntegerType>(IntTy), (int)IvarNames.size()));
- Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
- // Structure containing array and array count
- llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
- ObjCIvarArrayTy,
- NULL);
-
- // Create an instance of the structure
- return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
-}
-
-/// Generate a class structure
-llvm::Constant *CGObjCGNU::GenerateClassStructure(
- llvm::Constant *MetaClass,
- llvm::Constant *SuperClass,
- unsigned info,
- const char *Name,
- llvm::Constant *Version,
- llvm::Constant *InstanceSize,
- llvm::Constant *IVars,
- llvm::Constant *Methods,
- llvm::Constant *Protocols) {
- // Set up the class structure
- // Note: Several of these are char*s when they should be ids. This is
- // because the runtime performs this translation on load.
- llvm::StructType *ClassTy = llvm::StructType::get(
- PtrToInt8Ty, // class_pointer
- PtrToInt8Ty, // super_class
- PtrToInt8Ty, // name
- LongTy, // version
- LongTy, // info
- LongTy, // instance_size
- IVars->getType(), // ivars
- Methods->getType(), // methods
- // These are all filled in by the runtime, so we pretend
- PtrTy, // dtable
- PtrTy, // subclass_list
- PtrTy, // sibling_class
- PtrTy, // protocols
- PtrTy, // gc_object_type
- NULL);
- llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
- llvm::Constant *NullP =
- llvm::ConstantPointerNull::get(llvm::cast<llvm::PointerType>(PtrTy));
- // Fill in the structure
- std::vector<llvm::Constant*> Elements;
- Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
- Elements.push_back(SuperClass);
- Elements.push_back(MakeConstantString(Name, ".class_name"));
- Elements.push_back(Zero);
- Elements.push_back(llvm::ConstantInt::get(LongTy, info));
- Elements.push_back(InstanceSize);
- Elements.push_back(IVars);
- Elements.push_back(Methods);
- Elements.push_back(NullP);
- Elements.push_back(NullP);
- Elements.push_back(NullP);
- Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
- Elements.push_back(NullP);
- // Create an instance of the structure
- return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name));
-}
-
-llvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
- const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames,
- const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes) {
- // Get the method structure type.
- llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
- PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
- PtrToInt8Ty,
- NULL);
- std::vector<llvm::Constant*> Methods;
- std::vector<llvm::Constant*> Elements;
- for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
- Elements.clear();
- Elements.push_back( llvm::ConstantExpr::getGetElementPtr(MethodNames[i],
- Zeros, 2));
- Elements.push_back(
- llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
- Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
- }
- llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
- MethodNames.size());
- llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy, Methods);
- llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
- IntTy, ObjCMethodArrayTy, NULL);
- Methods.clear();
- Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
- Methods.push_back(Array);
- return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list");
-}
-// Create the protocol list structure used in classes, categories and so on
-llvm::Constant *CGObjCGNU::GenerateProtocolList(
- const llvm::SmallVectorImpl<std::string> &Protocols) {
- llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
- Protocols.size());
- llvm::StructType *ProtocolListTy = llvm::StructType::get(
- PtrTy, //Should be a recurisve pointer, but it's always NULL here.
- LongTy,//FIXME: Should be size_t
- ProtocolArrayTy,
- NULL);
- std::vector<llvm::Constant*> Elements;
- for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
- iter != endIter ; iter++) {
- llvm::Constant *Ptr =
- llvm::ConstantExpr::getBitCast(ExistingProtocols[*iter], PtrToInt8Ty);
- Elements.push_back(Ptr);
- }
- llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
- Elements);
- Elements.clear();
- Elements.push_back(NULLPtr);
- Elements.push_back(llvm::ConstantInt::get(
- llvm::cast<llvm::IntegerType>(LongTy), Protocols.size()));
- Elements.push_back(ProtocolArray);
- return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
-}
-
-llvm::Value *CGObjCGNU::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
- const ObjCProtocolDecl *PD) {
- return ExistingProtocols[PD->getName()];
-}
-
-void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
- ASTContext &Context = CGM.getContext();
- const char *ProtocolName = PD->getName();
- llvm::SmallVector<std::string, 16> Protocols;
- for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
- E = PD->protocol_end(); PI != E; ++PI)
- Protocols.push_back((*PI)->getName());
- llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
- llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
- for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
- E = PD->instmeth_end(); iter != E; iter++) {
- std::string TypeStr;
- Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
- InstanceMethodNames.push_back(
- CGM.GetAddrOfConstantCString((*iter)->getSelector().getName()));
- InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- }
- // Collect information about class methods:
- llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
- llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
- for (ObjCProtocolDecl::classmeth_iterator iter = PD->classmeth_begin(),
- endIter = PD->classmeth_end() ; iter != endIter ; iter++) {
- std::string TypeStr;
- Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
- ClassMethodNames.push_back(
- CGM.GetAddrOfConstantCString((*iter)->getSelector().getName()));
- ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- }
-
- llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
- llvm::Constant *InstanceMethodList =
- GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
- llvm::Constant *ClassMethodList =
- GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
- // Protocols are objects containing lists of the methods implemented and
- // protocols adopted.
- llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
- PtrToInt8Ty,
- ProtocolList->getType(),
- InstanceMethodList->getType(),
- ClassMethodList->getType(),
- NULL);
- std::vector<llvm::Constant*> Elements;
- // The isa pointer must be set to a magic number so the runtime knows it's
- // the correct layout.
- Elements.push_back(llvm::ConstantExpr::getIntToPtr(
- llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy));
- Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
- Elements.push_back(ProtocolList);
- Elements.push_back(InstanceMethodList);
- Elements.push_back(ClassMethodList);
- ExistingProtocols[ProtocolName] =
- llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
- ".objc_protocol"), IdTy);
-}
-
-void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
- const char *ClassName = OCD->getClassInterface()->getName();
- const char *CategoryName = OCD->getName();
- // Collect information about instance methods
- llvm::SmallVector<Selector, 16> InstanceMethodSels;
- llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
- for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(),
- endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
- InstanceMethodSels.push_back((*iter)->getSelector());
- std::string TypeStr;
- CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
- InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- }
-
- // Collect information about class methods
- llvm::SmallVector<Selector, 16> ClassMethodSels;
- llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
- for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(),
- endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
- ClassMethodSels.push_back((*iter)->getSelector());
- std::string TypeStr;
- CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
- ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- }
-
- // Collect the names of referenced protocols
- llvm::SmallVector<std::string, 16> Protocols;
- const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface();
- const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
- E = Protos.end(); I != E; ++I)
- Protocols.push_back((*I)->getName());
-
- std::vector<llvm::Constant*> Elements;
- Elements.push_back(MakeConstantString(CategoryName));
- Elements.push_back(MakeConstantString(ClassName));
- // Instance method list
- Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
- ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
- false), PtrTy));
- // Class method list
- Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
- ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
- PtrTy));
- // Protocol list
- Elements.push_back(llvm::ConstantExpr::getBitCast(
- GenerateProtocolList(Protocols), PtrTy));
- Categories.push_back(llvm::ConstantExpr::getBitCast(
- MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, PtrTy,
- PtrTy, PtrTy, NULL), Elements), PtrTy));
-}
-
-void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
- ASTContext &Context = CGM.getContext();
-
- // Get the superclass name.
- const ObjCInterfaceDecl * SuperClassDecl =
- OID->getClassInterface()->getSuperClass();
- const char * SuperClassName = NULL;
- if (SuperClassDecl) {
- SuperClassName = SuperClassDecl->getName();
- }
-
- // Get the class name
- ObjCInterfaceDecl * ClassDecl = (ObjCInterfaceDecl*)OID->getClassInterface();
- const char * ClassName = ClassDecl->getName();
-
- // Get the size of instances. For runtimes that support late-bound instances
- // this should probably be something different (size just of instance
- // varaibles in this class, not superclasses?).
- int instanceSize = 0;
- const llvm::Type *ObjTy = 0;
- if (!LateBoundIVars()) {
- ObjTy = CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl));
- instanceSize = CGM.getTargetData().getABITypeSize(ObjTy);
- } else {
- // This is required by newer ObjC runtimes.
- assert(0 && "Late-bound instance variables not yet supported");
- }
-
- // Collect information about instance variables.
- llvm::SmallVector<llvm::Constant*, 16> IvarNames;
- llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
- llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
- const llvm::StructLayout *Layout =
- CGM.getTargetData().getStructLayout(cast<llvm::StructType>(ObjTy));
- ObjTy = llvm::PointerType::getUnqual(ObjTy);
- for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
- endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
- // Store the name
- IvarNames.push_back(CGM.GetAddrOfConstantCString((*iter)->getName()));
- // Get the type encoding for this ivar
- std::string TypeStr;
- llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
- Context.getObjCEncodingForType((*iter)->getType(), TypeStr,
- EncodingRecordTypes);
- IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- // Get the offset
- int offset =
- (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(*iter));
- IvarOffsets.push_back(
- llvm::ConstantInt::get(llvm::Type::Int32Ty, offset));
- }
-
- // Collect information about instance methods
- llvm::SmallVector<Selector, 16> InstanceMethodSels;
- llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
- for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(),
- endIter = OID->instmeth_end() ; iter != endIter ; iter++) {
- InstanceMethodSels.push_back((*iter)->getSelector());
- std::string TypeStr;
- Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
- InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- }
-
- // Collect information about class methods
- llvm::SmallVector<Selector, 16> ClassMethodSels;
- llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
- for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(),
- endIter = OID->classmeth_end() ; iter != endIter ; iter++) {
- ClassMethodSels.push_back((*iter)->getSelector());
- std::string TypeStr;
- Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
- ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
- }
- // Collect the names of referenced protocols
- llvm::SmallVector<std::string, 16> Protocols;
- const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
- E = Protos.end(); I != E; ++I)
- Protocols.push_back((*I)->getName());
-
-
-
- // Get the superclass pointer.
- llvm::Constant *SuperClass;
- if (SuperClassName) {
- SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
- } else {
- SuperClass = llvm::ConstantPointerNull::get(
- llvm::cast<llvm::PointerType>(PtrToInt8Ty));
- }
- // Empty vector used to construct empty method lists
- llvm::SmallVector<llvm::Constant*, 1> empty;
- // Generate the method and instance variable lists
- llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
- InstanceMethodSels, InstanceMethodTypes, false);
- llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
- ClassMethodSels, ClassMethodTypes, true);
- llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
- IvarOffsets);
- //Generate metaclass for class methods
- llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
- NULLPtr, 0x2L, /*name*/"", 0, Zeros[0], GenerateIvarList(
- empty, empty, empty), ClassMethodList, NULLPtr);
- // Generate the class structure
- llvm::Constant *ClassStruct = GenerateClassStructure(MetaClassStruct,
- SuperClass, 0x1L, ClassName, 0,
- llvm::ConstantInt::get(llvm::Type::Int32Ty, instanceSize), IvarList,
- MethodList, GenerateProtocolList(Protocols));
- // Add class structure to list to be added to the symtab later
- ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
- Classes.push_back(ClassStruct);
-}
-
-llvm::Function *CGObjCGNU::ModuleInitFunction() {
- // Only emit an ObjC load function if no Objective-C stuff has been called
- if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
- ExistingProtocols.empty() && TypedSelectors.empty() &&
- UntypedSelectors.empty())
- return NULL;
-
- // Name the ObjC types to make the IR a bit easier to read
- TheModule.addTypeName(".objc_selector", SelectorTy);
- TheModule.addTypeName(".objc_id", IdTy);
- TheModule.addTypeName(".objc_imp", IMPTy);
-
- std::vector<llvm::Constant*> Elements;
- // Generate statics list:
- llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
- ConstantStrings.size() + 1);
- ConstantStrings.push_back(NULLPtr);
- Elements.push_back(MakeConstantString("NSConstantString",
- ".objc_static_class_name"));
- Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, ConstantStrings));
- llvm::StructType *StaticsListTy =
- llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL);
- llvm::Type *StaticsListPtrTy = llvm::PointerType::getUnqual(StaticsListTy);
- llvm::Constant *Statics =
- MakeGlobal(StaticsListTy, Elements, ".objc_statics");
- llvm::ArrayType *StaticsListArrayTy =
- llvm::ArrayType::get(StaticsListPtrTy, 2);
- Elements.clear();
- Elements.push_back(Statics);
- Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
- Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
- Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
- // Array of classes, categories, and constant objects
- llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
- Classes.size() + Categories.size() + 2);
- llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelectorTy,
- llvm::Type::Int16Ty,
- llvm::Type::Int16Ty,
- ClassListTy, NULL);
-
- Elements.clear();
- // Pointer to an array of selectors used in this module.
- std::vector<llvm::Constant*> Selectors;
- for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
- iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end();
- iter != iterEnd ; ++iter) {
- Elements.push_back(MakeConstantString(iter->first.first, ".objc_sel_name"));
- Elements.push_back(MakeConstantString(iter->first.second,
- ".objc_sel_types"));
- Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
- Elements.clear();
- }
- for (llvm::StringMap<llvm::GlobalAlias*>::iterator
- iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
- iter != iterEnd; ++iter) {
- Elements.push_back(
- MakeConstantString(iter->getKeyData(), ".objc_sel_name"));
- Elements.push_back(NULLPtr);
- Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
- Elements.clear();
- }
- Elements.push_back(NULLPtr);
- Elements.push_back(NULLPtr);
- Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
- Elements.clear();
- // Number of static selectors
- Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() ));
- llvm::Constant *SelectorList = MakeGlobal(
- llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors,
- ".objc_selector_list");
- Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, SelectorTy));
-
- // Now that all of the static selectors exist, create pointers to them.
- int index = 0;
- for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
- iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end();
- iter != iterEnd; ++iter) {
- llvm::Constant *Idxs[] = {Zeros[0],
- llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]};
- llvm::GlobalVariable *SelPtr = new llvm::GlobalVariable(SelectorTy, true,
- llvm::GlobalValue::InternalLinkage,
- llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
- ".objc_sel_ptr", &TheModule);
- (*iter).second->setAliasee(SelPtr);
- }
- for (llvm::StringMap<llvm::GlobalAlias*>::iterator
- iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
- iter != iterEnd; iter++) {
- llvm::Constant *Idxs[] = {Zeros[0],
- llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]};
- llvm::GlobalVariable *SelPtr = new llvm::GlobalVariable(SelectorTy, true,
- llvm::GlobalValue::InternalLinkage,
- llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
- ".objc_sel_ptr", &TheModule);
- (*iter).second->setAliasee(SelPtr);
- }
- // Number of classes defined.
- Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty,
- Classes.size()));
- // Number of categories defined
- Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty,
- Categories.size()));
- // Create an array of classes, then categories, then static object instances
- Classes.insert(Classes.end(), Categories.begin(), Categories.end());
- // NULL-terminated list of static object instances (mainly constant strings)
- Classes.push_back(Statics);
- Classes.push_back(NULLPtr);
- llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
- Elements.push_back(ClassList);
- // Construct the symbol table
- llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
-
- // The symbol table is contained in a module which has some version-checking
- // constants
- llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
- PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL);
- Elements.clear();
- // Runtime version used for compatibility checking.
- Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
- //FIXME: Should be sizeof(ModuleTy)
- Elements.push_back(llvm::ConstantInt::get(LongTy, 16));
- //FIXME: Should be the path to the file where this module was declared
- Elements.push_back(NULLPtr);
- Elements.push_back(SymTab);
- llvm::Value *Module = MakeGlobal(ModuleTy, Elements);
-
- // Create the load function calling the runtime entry point with the module
- // structure
- std::vector<const llvm::Type*> VoidArgs;
- llvm::Function * LoadFunction = llvm::Function::Create(
- llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false),
- llvm::GlobalValue::InternalLinkage, ".objc_load_function",
- &TheModule);
- llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction);
- llvm::IRBuilder<> Builder;
- Builder.SetInsertPoint(EntryBB);
- llvm::Value *Register = TheModule.getOrInsertFunction("__objc_exec_class",
- llvm::Type::VoidTy, llvm::PointerType::getUnqual(ModuleTy), NULL);
- Builder.CreateCall(Register, Module);
- Builder.CreateRetVoid();
- return LoadFunction;
-}
-
-llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD) {
- const ObjCCategoryImplDecl *OCD =
- dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext());
- const std::string &CategoryName = OCD ? OCD->getName() : "";
- const std::string &ClassName = OMD->getClassInterface()->getName();
- const std::string &MethodName = OMD->getSelector().getName();
- bool isClassMethod = !OMD->isInstance();
-
- const llvm::FunctionType *MethodTy =
- CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
- std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
- MethodName, isClassMethod);
-
- llvm::Function *Method = llvm::Function::Create(MethodTy,
- llvm::GlobalValue::InternalLinkage,
- FunctionName,
- &TheModule);
- return Method;
-}
-
-llvm::Function *CGObjCGNU::GetPropertyGetFunction() {
- return 0;
-}
-
-llvm::Function *CGObjCGNU::GetPropertySetFunction() {
- return 0;
-}
-
-llvm::Function *CGObjCGNU::EnumerationMutationFunction() {
- return 0;
-}
-
-void CGObjCGNU::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtTryStmt &S) {
- CGF.ErrorUnsupported(&S, "@try statement");
-}
-
-void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtThrowStmt &S) {
- CGF.ErrorUnsupported(&S, "@throw statement");
-}
-
-CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){
- return new CGObjCGNU(CGM);
-}
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
deleted file mode 100644
index 0f760eebed6b..000000000000
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ /dev/null
@@ -1,2357 +0,0 @@
-//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides Objective-C code generation targetting the Apple runtime.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGObjCRuntime.h"
-
-#include "CodeGenModule.h"
-#include "CodeGenFunction.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/LangOptions.h"
-
-#include "llvm/Module.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Target/TargetData.h"
-#include <sstream>
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-
- typedef std::vector<llvm::Constant*> ConstantVector;
-
- // FIXME: We should find a nicer way to make the labels for
- // metadata, string concatenation is lame.
-
-/// ObjCTypesHelper - Helper class that encapsulates lazy
-/// construction of varies types used during ObjC generation.
-class ObjCTypesHelper {
-private:
- CodeGen::CodeGenModule &CGM;
-
- llvm::Function *MessageSendFn, *MessageSendStretFn;
- llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
-
-public:
- const llvm::Type *ShortTy, *IntTy, *LongTy;
- const llvm::Type *Int8PtrTy;
-
- /// ObjectPtrTy - LLVM type for object handles (typeof(id))
- const llvm::Type *ObjectPtrTy;
- /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
- const llvm::Type *SelectorPtrTy;
- /// ProtocolPtrTy - LLVM type for external protocol handles
- /// (typeof(Protocol))
- const llvm::Type *ExternalProtocolPtrTy;
-
- // SuperCTy - clang type for struct objc_super.
- QualType SuperCTy;
- // SuperPtrCTy - clang type for struct objc_super *.
- QualType SuperPtrCTy;
-
- /// SuperTy - LLVM type for struct objc_super.
- const llvm::StructType *SuperTy;
- /// SuperPtrTy - LLVM type for struct objc_super *.
- const llvm::Type *SuperPtrTy;
-
- /// SymtabTy - LLVM type for struct objc_symtab.
- const llvm::StructType *SymtabTy;
- /// SymtabPtrTy - LLVM type for struct objc_symtab *.
- const llvm::Type *SymtabPtrTy;
- /// ModuleTy - LLVM type for struct objc_module.
- const llvm::StructType *ModuleTy;
-
- /// ProtocolTy - LLVM type for struct objc_protocol.
- const llvm::StructType *ProtocolTy;
- /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
- const llvm::Type *ProtocolPtrTy;
- /// ProtocolExtensionTy - LLVM type for struct
- /// objc_protocol_extension.
- const llvm::StructType *ProtocolExtensionTy;
- /// ProtocolExtensionTy - LLVM type for struct
- /// objc_protocol_extension *.
- const llvm::Type *ProtocolExtensionPtrTy;
- /// MethodDescriptionTy - LLVM type for struct
- /// objc_method_description.
- const llvm::StructType *MethodDescriptionTy;
- /// MethodDescriptionListTy - LLVM type for struct
- /// objc_method_description_list.
- const llvm::StructType *MethodDescriptionListTy;
- /// MethodDescriptionListPtrTy - LLVM type for struct
- /// objc_method_description_list *.
- const llvm::Type *MethodDescriptionListPtrTy;
- /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
- /// in GCC parlance).
- const llvm::StructType *PropertyTy;
- /// PropertyListTy - LLVM type for struct objc_property_list
- /// (_prop_list_t in GCC parlance).
- const llvm::StructType *PropertyListTy;
- /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
- const llvm::Type *PropertyListPtrTy;
- /// ProtocolListTy - LLVM type for struct objc_property_list.
- const llvm::Type *ProtocolListTy;
- /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
- const llvm::Type *ProtocolListPtrTy;
- /// CategoryTy - LLVM type for struct objc_category.
- const llvm::StructType *CategoryTy;
- /// ClassTy - LLVM type for struct objc_class.
- const llvm::StructType *ClassTy;
- /// ClassPtrTy - LLVM type for struct objc_class *.
- const llvm::Type *ClassPtrTy;
- /// ClassExtensionTy - LLVM type for struct objc_class_ext.
- const llvm::StructType *ClassExtensionTy;
- /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
- const llvm::Type *ClassExtensionPtrTy;
- /// CacheTy - LLVM type for struct objc_cache.
- const llvm::Type *CacheTy;
- /// CachePtrTy - LLVM type for struct objc_cache *.
- const llvm::Type *CachePtrTy;
- // IvarTy - LLVM type for struct objc_ivar.
- const llvm::StructType *IvarTy;
- /// IvarListTy - LLVM type for struct objc_ivar_list.
- const llvm::Type *IvarListTy;
- /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
- const llvm::Type *IvarListPtrTy;
- // MethodTy - LLVM type for struct objc_method.
- const llvm::StructType *MethodTy;
- /// MethodListTy - LLVM type for struct objc_method_list.
- const llvm::Type *MethodListTy;
- /// MethodListPtrTy - LLVM type for struct objc_method_list *.
- const llvm::Type *MethodListPtrTy;
-
- llvm::Function *GetPropertyFn, *SetPropertyFn;
- llvm::Function *EnumerationMutationFn;
-
- /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
- const llvm::Type *ExceptionDataTy;
-
- /// ExceptionThrowFn - LLVM objc_exception_throw function.
- llvm::Function *ExceptionThrowFn;
-
- /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
- llvm::Function *ExceptionTryEnterFn;
-
- /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
- llvm::Function *ExceptionTryExitFn;
-
- /// ExceptionExtractFn - LLVM objc_exception_extract function.
- llvm::Function *ExceptionExtractFn;
-
- /// ExceptionMatchFn - LLVM objc_exception_match function.
- llvm::Function *ExceptionMatchFn;
-
- /// SetJmpFn - LLVM _setjmp function.
- llvm::Function *SetJmpFn;
-
-public:
- ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
- ~ObjCTypesHelper();
-
- llvm::Constant *getMessageSendFn(bool IsSuper, bool isStret);
-};
-
-class CGObjCMac : public CodeGen::CGObjCRuntime {
-private:
- CodeGen::CodeGenModule &CGM;
- ObjCTypesHelper ObjCTypes;
- /// ObjCABI - FIXME: Not sure yet.
- unsigned ObjCABI;
-
- /// LazySymbols - Symbols to generate a lazy reference for. See
- /// DefinedSymbols and FinishModule().
- std::set<IdentifierInfo*> LazySymbols;
-
- /// DefinedSymbols - External symbols which are defined by this
- /// module. The symbols in this list and LazySymbols are used to add
- /// special linker symbols which ensure that Objective-C modules are
- /// linked properly.
- std::set<IdentifierInfo*> DefinedSymbols;
-
- /// ClassNames - uniqued class names.
- llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
-
- /// MethodVarNames - uniqued method variable names.
- llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
-
- /// MethodVarTypes - uniqued method type signatures. We have to use
- /// a StringMap here because have no other unique reference.
- llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
-
- /// MethodDefinitions - map of methods which have been defined in
- /// this translation unit.
- llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
-
- /// PropertyNames - uniqued method variable names.
- llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
-
- /// ClassReferences - uniqued class references.
- llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
-
- /// SelectorReferences - uniqued selector references.
- llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
-
- /// Protocols - Protocols for which an objc_protocol structure has
- /// been emitted. Forward declarations are handled by creating an
- /// empty structure whose initializer is filled in when/if defined.
- llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
-
- /// DefinedClasses - List of defined classes.
- std::vector<llvm::GlobalValue*> DefinedClasses;
-
- /// DefinedCategories - List of defined categories.
- std::vector<llvm::GlobalValue*> DefinedCategories;
-
- /// UsedGlobals - List of globals to pack into the llvm.used metadata
- /// to prevent them from being clobbered.
- std::vector<llvm::GlobalVariable*> UsedGlobals;
-
- /// EmitImageInfo - Emit the image info marker used to encode some module
- /// level information.
- void EmitImageInfo();
-
- /// EmitModuleInfo - Another marker encoding module level
- /// information.
- void EmitModuleInfo();
-
- /// EmitModuleSymols - Emit module symbols, the list of defined
- /// classes and categories. The result has type SymtabPtrTy.
- llvm::Constant *EmitModuleSymbols();
-
- /// FinishModule - Write out global data structures at the end of
- /// processing a translation unit.
- void FinishModule();
-
- /// EmitClassExtension - Generate the class extension structure used
- /// to store the weak ivar layout and properties. The return value
- /// has type ClassExtensionPtrTy.
- llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
-
- /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
- /// for the given class.
- llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
- const ObjCInterfaceDecl *ID);
-
- CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Arg0,
- QualType Arg0Ty,
- bool IsSuper,
- const CallArgList &CallArgs);
-
- /// EmitIvarList - Emit the ivar list for the given
- /// implementation. If ForClass is true the list of class ivars
- /// (i.e. metaclass ivars) is emitted, otherwise the list of
- /// interface ivars will be emitted. The return value has type
- /// IvarListPtrTy.
- llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
- bool ForClass,
- const llvm::Type *InterfaceTy);
-
- /// EmitMetaClass - Emit a forward reference to the class structure
- /// for the metaclass of the given interface. The return value has
- /// type ClassPtrTy.
- llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
-
- /// EmitMetaClass - Emit a class structure for the metaclass of the
- /// given implementation. The return value has type ClassPtrTy.
- llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
- llvm::Constant *Protocols,
- const llvm::Type *InterfaceTy,
- const ConstantVector &Methods);
-
- llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
-
- llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
-
- /// EmitMethodList - Emit the method list for the given
- /// implementation. The return value has type MethodListPtrTy.
- llvm::Constant *EmitMethodList(const std::string &Name,
- const char *Section,
- const ConstantVector &Methods);
-
- /// EmitMethodDescList - Emit a method description list for a list of
- /// method declarations.
- /// - TypeName: The name for the type containing the methods.
- /// - IsProtocol: True iff these methods are for a protocol.
- /// - ClassMethds: True iff these are class methods.
- /// - Required: When true, only "required" methods are
- /// listed. Similarly, when false only "optional" methods are
- /// listed. For classes this should always be true.
- /// - begin, end: The method list to output.
- ///
- /// The return value has type MethodDescriptionListPtrTy.
- llvm::Constant *EmitMethodDescList(const std::string &Name,
- const char *Section,
- const ConstantVector &Methods);
-
- /// EmitPropertyList - Emit the given property list. The return
- /// value has type PropertyListPtrTy.
- llvm::Constant *EmitPropertyList(const std::string &Name,
- const Decl *Container,
- ObjCPropertyDecl * const *begin,
- ObjCPropertyDecl * const *end);
-
- /// EmitProtocolExtension - Generate the protocol extension
- /// structure used to store optional instance and class methods, and
- /// protocol properties. The return value has type
- /// ProtocolExtensionPtrTy.
- llvm::Constant *
- EmitProtocolExtension(const ObjCProtocolDecl *PD,
- const ConstantVector &OptInstanceMethods,
- const ConstantVector &OptClassMethods);
-
- /// EmitProtocolList - Generate the list of referenced
- /// protocols. The return value has type ProtocolListPtrTy.
- llvm::Constant *EmitProtocolList(const std::string &Name,
- ObjCProtocolDecl::protocol_iterator begin,
- ObjCProtocolDecl::protocol_iterator end);
-
- /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
- /// for the given selector.
- llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
-
- /// GetProtocolRef - Return a reference to the internal protocol
- /// description, creating an empty one if it has not been
- /// defined. The return value has type pointer-to ProtocolTy.
- llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
-
- /// GetClassName - Return a unique constant for the given selector's
- /// name. The return value has type char *.
- llvm::Constant *GetClassName(IdentifierInfo *Ident);
-
- /// GetMethodVarName - Return a unique constant for the given
- /// selector's name. The return value has type char *.
- llvm::Constant *GetMethodVarName(Selector Sel);
- llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
- llvm::Constant *GetMethodVarName(const std::string &Name);
-
- /// GetMethodVarType - Return a unique constant for the given
- /// selector's name. The return value has type char *.
-
- // FIXME: This is a horrible name.
- llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
- llvm::Constant *GetMethodVarType(const std::string &Name);
-
- /// GetPropertyName - Return a unique constant for the given
- /// name. The return value has type char *.
- llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
-
- // FIXME: This can be dropped once string functions are unified.
- llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
- const Decl *Container);
-
- /// GetNameForMethod - Return a name for the given method.
- /// \param[out] NameOut - The return value.
- void GetNameForMethod(const ObjCMethodDecl *OMD,
- std::string &NameOut);
-
-public:
- CGObjCMac(CodeGen::CodeGenModule &cgm);
- virtual llvm::Constant *GenerateConstantString(const std::string &String);
-
- virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs);
-
- virtual CodeGen::RValue
- GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- const ObjCInterfaceDecl *Class,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs);
-
- virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
- const ObjCInterfaceDecl *ID);
-
- virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
-
- virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
-
- virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
-
- virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
-
- virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
- const ObjCProtocolDecl *PD);
-
- virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
-
- virtual llvm::Function *ModuleInitFunction();
- virtual llvm::Function *GetPropertyGetFunction();
- virtual llvm::Function *GetPropertySetFunction();
- virtual llvm::Function *EnumerationMutationFunction();
-
- virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtTryStmt &S);
- virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtThrowStmt &S);
-
-};
-} // end anonymous namespace
-
-/* *** Helper Functions *** */
-
-/// getConstantGEP() - Help routine to construct simple GEPs.
-static llvm::Constant *getConstantGEP(llvm::Constant *C,
- unsigned idx0,
- unsigned idx1) {
- llvm::Value *Idxs[] = {
- llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
- };
- return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
-}
-
-/* *** CGObjCMac Public Interface *** */
-
-CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
- : CGM(cgm),
- ObjCTypes(cgm),
- ObjCABI(1)
-{
- // FIXME: How does this get set in GCC? And what does it even mean?
- if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
- ObjCABI = 2;
-
- EmitImageInfo();
-}
-
-/// GetClass - Return a reference to the class for the given interface
-/// decl.
-llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
- const ObjCInterfaceDecl *ID) {
- return EmitClassRef(Builder, ID);
-}
-
-/// GetSelector - Return the pointer to the unique'd string for this selector.
-llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
- return EmitSelector(Builder, Sel);
-}
-
-/// Generate a constant CFString object.
-/*
- struct __builtin_CFString {
- const int *isa; // point to __CFConstantStringClassReference
- int flags;
- const char *str;
- long length;
- };
-*/
-
-llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
- return CGM.GetAddrOfConstantCFString(String);
-}
-
-/// Generates a message send where the super is the receiver. This is
-/// a message send to self with special delivery semantics indicating
-/// which class's method should be called.
-CodeGen::RValue
-CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- const ObjCInterfaceDecl *Class,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CodeGen::CallArgList &CallArgs) {
- // Create and init a super structure; this is a (receiver, class)
- // pair we will pass to objc_msgSendSuper.
- llvm::Value *ObjCSuper =
- CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
- llvm::Value *ReceiverAsObject =
- CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
- CGF.Builder.CreateStore(ReceiverAsObject,
- CGF.Builder.CreateStructGEP(ObjCSuper, 0));
-
- // If this is a class message the metaclass is passed as the target.
- llvm::Value *Target;
- if (IsClassMessage) {
- llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
- llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
- llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
- Target = Super;
- } else {
- Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
- }
- // FIXME: We shouldn't need to do this cast, rectify the ASTContext
- // and ObjCTypes types.
- const llvm::Type *ClassTy =
- CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
- Target = CGF.Builder.CreateBitCast(Target, ClassTy);
- CGF.Builder.CreateStore(Target,
- CGF.Builder.CreateStructGEP(ObjCSuper, 1));
-
- return EmitMessageSend(CGF, ResultType, Sel,
- ObjCSuper, ObjCTypes.SuperPtrCTy,
- true, CallArgs);
-}
-
-/// Generate code for a message send expression.
-CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs) {
- llvm::Value *Arg0 =
- CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
- return EmitMessageSend(CGF, ResultType, Sel,
- Arg0, CGF.getContext().getObjCIdType(),
- false, CallArgs);
-}
-
-CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Arg0,
- QualType Arg0Ty,
- bool IsSuper,
- const CallArgList &CallArgs) {
- CallArgList ActualArgs;
- ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
- ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder,
- Sel)),
- CGF.getContext().getObjCSelType()));
- ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
-
- const llvm::FunctionType *FTy =
- CGM.getTypes().GetFunctionType(CGCallInfo(ResultType, ActualArgs),
- false);
- llvm::Constant *Fn =
- ObjCTypes.getMessageSendFn(IsSuper, CGM.ReturnTypeUsesSret(ResultType));
- Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
- return CGF.EmitCall(Fn, ResultType, ActualArgs);
-}
-
-llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
- const ObjCProtocolDecl *PD) {
- // FIXME: I don't understand why gcc generates this, or where it is
- // resolved. Investigate. Its also wasteful to look this up over and
- // over.
- LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
-
- return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
- ObjCTypes.ExternalProtocolPtrTy);
-}
-
-/*
- // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
- struct _objc_protocol {
- struct _objc_protocol_extension *isa;
- char *protocol_name;
- struct _objc_protocol_list *protocol_list;
- struct _objc__method_prototype_list *instance_methods;
- struct _objc__method_prototype_list *class_methods
- };
-
- See EmitProtocolExtension().
-*/
-void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
- // FIXME: I don't understand why gcc generates this, or where it is
- // resolved. Investigate. Its also wasteful to look this up over and
- // over.
- LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
-
- const char *ProtocolName = PD->getName();
-
- // Construct method lists.
- std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
- std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
- for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
- e = PD->instmeth_end(); i != e; ++i) {
- ObjCMethodDecl *MD = *i;
- llvm::Constant *C = GetMethodDescriptionConstant(MD);
- if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
- OptInstanceMethods.push_back(C);
- } else {
- InstanceMethods.push_back(C);
- }
- }
-
- for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
- e = PD->classmeth_end(); i != e; ++i) {
- ObjCMethodDecl *MD = *i;
- llvm::Constant *C = GetMethodDescriptionConstant(MD);
- if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
- OptClassMethods.push_back(C);
- } else {
- ClassMethods.push_back(C);
- }
- }
-
- std::vector<llvm::Constant*> Values(5);
- Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
- Values[1] = GetClassName(PD->getIdentifier());
- Values[2] =
- EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
- PD->protocol_begin(),
- PD->protocol_end());
- Values[3] =
- EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_")
- + PD->getName(),
- "__OBJC,__cat_inst_meth,regular,no_dead_strip",
- InstanceMethods);
- Values[4] =
- EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_")
- + PD->getName(),
- "__OBJC,__cat_cls_meth,regular,no_dead_strip",
- ClassMethods);
- llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
- Values);
-
- llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
- if (Entry) {
- // Already created, just update the initializer
- Entry->setInitializer(Init);
- } else {
- Entry =
- new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
- &CGM.getModule());
- Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
- UsedGlobals.push_back(Entry);
- // FIXME: Is this necessary? Why only for protocol?
- Entry->setAlignment(4);
- }
-}
-
-llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
- llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
-
- if (!Entry) {
- std::vector<llvm::Constant*> Values(5);
- Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
- Values[1] = GetClassName(PD->getIdentifier());
- Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
- Values[3] = Values[4] =
- llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
- llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
- Values);
-
- Entry =
- new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
- &CGM.getModule());
- Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
- UsedGlobals.push_back(Entry);
- // FIXME: Is this necessary? Why only for protocol?
- Entry->setAlignment(4);
- }
-
- return Entry;
-}
-
-/*
- struct _objc_protocol_extension {
- uint32_t size;
- struct objc_method_description_list *optional_instance_methods;
- struct objc_method_description_list *optional_class_methods;
- struct objc_property_list *instance_properties;
- };
-*/
-llvm::Constant *
-CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
- const ConstantVector &OptInstanceMethods,
- const ConstantVector &OptClassMethods) {
- uint64_t Size =
- CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
- std::vector<llvm::Constant*> Values(4);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
- Values[1] =
- EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_")
- + PD->getName(),
- "__OBJC,__cat_inst_meth,regular,no_dead_strip",
- OptInstanceMethods);
- Values[2] =
- EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_")
- + PD->getName(),
- "__OBJC,__cat_cls_meth,regular,no_dead_strip",
- OptClassMethods);
- Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
- PD->getName(),
- 0,
- PD->classprop_begin(),
- PD->classprop_end());
-
- // Return null if no extension bits are used.
- if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
- Values[3]->isNullValue())
- return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
-
- llvm::Constant *Init =
- llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- (std::string("\01L_OBJC_PROTOCOLEXT_") +
- PD->getName()),
- &CGM.getModule());
- // No special section, but goes in llvm.used
- UsedGlobals.push_back(GV);
-
- return GV;
-}
-
-/*
- struct objc_protocol_list {
- struct objc_protocol_list *next;
- long count;
- Protocol *list[];
- };
-*/
-llvm::Constant *
-CGObjCMac::EmitProtocolList(const std::string &Name,
- ObjCProtocolDecl::protocol_iterator begin,
- ObjCProtocolDecl::protocol_iterator end) {
- std::vector<llvm::Constant*> ProtocolRefs;
-
- for (; begin != end; ++begin)
- ProtocolRefs.push_back(GetProtocolRef(*begin));
-
- // Just return null for empty protocol lists
- if (ProtocolRefs.empty())
- return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
-
- // This list is null terminated.
- ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
-
- std::vector<llvm::Constant*> Values(3);
- // This field is only used by the runtime.
- Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
- Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
- Values[2] =
- llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
- ProtocolRefs.size()),
- ProtocolRefs);
-
- llvm::Constant *Init = llvm::ConstantStruct::get(Values);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- Name,
- &CGM.getModule());
- GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
- return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
-}
-
-/*
- struct _objc_property {
- const char * const name;
- const char * const attributes;
- };
-
- struct _objc_property_list {
- uint32_t entsize; // sizeof (struct _objc_property)
- uint32_t prop_count;
- struct _objc_property[prop_count];
- };
-*/
-llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
- const Decl *Container,
- ObjCPropertyDecl * const *begin,
- ObjCPropertyDecl * const *end) {
- std::vector<llvm::Constant*> Properties, Prop(2);
- for (; begin != end; ++begin) {
- const ObjCPropertyDecl *PD = *begin;
- Prop[0] = GetPropertyName(PD->getIdentifier());
- Prop[1] = GetPropertyTypeString(PD, Container);
- Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
- Prop));
- }
-
- // Return null for empty list.
- if (Properties.empty())
- return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
-
- unsigned PropertySize =
- CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
- std::vector<llvm::Constant*> Values(3);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
- Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
- llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
- Properties.size());
- Values[2] = llvm::ConstantArray::get(AT, Properties);
- llvm::Constant *Init = llvm::ConstantStruct::get(Values);
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- Name,
- &CGM.getModule());
- // No special section on property lists?
- UsedGlobals.push_back(GV);
- return llvm::ConstantExpr::getBitCast(GV,
- ObjCTypes.PropertyListPtrTy);
-
-}
-
-/*
- struct objc_method_description_list {
- int count;
- struct objc_method_description list[];
- };
-*/
-llvm::Constant *
-CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
- std::vector<llvm::Constant*> Desc(2);
- Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
- ObjCTypes.SelectorPtrTy);
- Desc[1] = GetMethodVarType(MD);
- return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
- Desc);
-}
-
-llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name,
- const char *Section,
- const ConstantVector &Methods) {
- // Return null for empty list.
- if (Methods.empty())
- return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
-
- std::vector<llvm::Constant*> Values(2);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
- llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
- Methods.size());
- Values[1] = llvm::ConstantArray::get(AT, Methods);
- llvm::Constant *Init = llvm::ConstantStruct::get(Values);
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init, Name, &CGM.getModule());
- GV->setSection(Section);
- UsedGlobals.push_back(GV);
- return llvm::ConstantExpr::getBitCast(GV,
- ObjCTypes.MethodDescriptionListPtrTy);
-}
-
-/*
- struct _objc_category {
- char *category_name;
- char *class_name;
- struct _objc_method_list *instance_methods;
- struct _objc_method_list *class_methods;
- struct _objc_protocol_list *protocols;
- uint32_t size; // <rdar://4585769>
- struct _objc_property_list *instance_properties;
- };
- */
-void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
- unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
-
- // FIXME: This is poor design, the OCD should have a pointer to the
- // category decl. Additionally, note that Category can be null for
- // the @implementation w/o an @interface case. Sema should just
- // create one for us as it does for @implementation so everyone else
- // can live life under a clear blue sky.
- const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
- const ObjCCategoryDecl *Category =
- Interface->FindCategoryDeclaration(OCD->getIdentifier());
- std::string ExtName(std::string(Interface->getName()) +
- "_" +
- OCD->getName());
-
- std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
- for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
- e = OCD->instmeth_end(); i != e; ++i) {
- // Instance methods should always be defined.
- InstanceMethods.push_back(GetMethodConstant(*i));
- }
- for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
- e = OCD->classmeth_end(); i != e; ++i) {
- // Class methods should always be defined.
- ClassMethods.push_back(GetMethodConstant(*i));
- }
-
- std::vector<llvm::Constant*> Values(7);
- Values[0] = GetClassName(OCD->getIdentifier());
- Values[1] = GetClassName(Interface->getIdentifier());
- Values[2] =
- EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
- ExtName,
- "__OBJC,__cat_inst_meth,regular,no_dead_strip",
- InstanceMethods);
- Values[3] =
- EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
- "__OBJC,__cat_class_meth,regular,no_dead_strip",
- ClassMethods);
- if (Category) {
- Values[4] =
- EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
- Category->protocol_begin(),
- Category->protocol_end());
- } else {
- Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
- }
- Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
-
- // If there is no category @interface then there can be no properties.
- if (Category) {
- Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
- OCD,
- Category->classprop_begin(),
- Category->classprop_end());
- } else {
- Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
- }
-
- llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
- Values);
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- std::string("\01L_OBJC_CATEGORY_")+ExtName,
- &CGM.getModule());
- GV->setSection("__OBJC,__category,regular,no_dead_strip");
- UsedGlobals.push_back(GV);
- DefinedCategories.push_back(GV);
-}
-
-// FIXME: Get from somewhere?
-enum ClassFlags {
- eClassFlags_Factory = 0x00001,
- eClassFlags_Meta = 0x00002,
- // <rdr://5142207>
- eClassFlags_HasCXXStructors = 0x02000,
- eClassFlags_Hidden = 0x20000,
- eClassFlags_ABI2_Hidden = 0x00010,
- eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
-};
-
-// <rdr://5142207&4705298&4843145>
-static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
- if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
- // FIXME: Support -fvisibility
- switch (attr->getVisibility()) {
- default:
- assert(0 && "Unknown visibility");
- return false;
- case VisibilityAttr::DefaultVisibility:
- case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
- return false;
- case VisibilityAttr::HiddenVisibility:
- return true;
- }
- } else {
- return false; // FIXME: Support -fvisibility
- }
-}
-
-/*
- struct _objc_class {
- Class isa;
- Class super_class;
- const char *name;
- long version;
- long info;
- long instance_size;
- struct _objc_ivar_list *ivars;
- struct _objc_method_list *methods;
- struct _objc_cache *cache;
- struct _objc_protocol_list *protocols;
- // Objective-C 1.0 extensions (<rdr://4585769>)
- const char *ivar_layout;
- struct _objc_class_ext *ext;
- };
-
- See EmitClassExtension();
- */
-void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
- DefinedSymbols.insert(ID->getIdentifier());
-
- const char *ClassName = ID->getName();
- // FIXME: Gross
- ObjCInterfaceDecl *Interface =
- const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
- llvm::Constant *Protocols =
- EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
- Interface->protocol_begin(),
- Interface->protocol_end());
- const llvm::Type *InterfaceTy =
- CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
- unsigned Flags = eClassFlags_Factory;
- unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
-
- // FIXME: Set CXX-structors flag.
- if (IsClassHidden(ID->getClassInterface()))
- Flags |= eClassFlags_Hidden;
-
- std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
- for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
- e = ID->instmeth_end(); i != e; ++i) {
- // Instance methods should always be defined.
- InstanceMethods.push_back(GetMethodConstant(*i));
- }
- for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
- e = ID->classmeth_end(); i != e; ++i) {
- // Class methods should always be defined.
- ClassMethods.push_back(GetMethodConstant(*i));
- }
-
- for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
- e = ID->propimpl_end(); i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
-
- if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
- ObjCPropertyDecl *PD = PID->getPropertyDecl();
-
- if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
- if (llvm::Constant *C = GetMethodConstant(MD))
- InstanceMethods.push_back(C);
- if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
- if (llvm::Constant *C = GetMethodConstant(MD))
- InstanceMethods.push_back(C);
- }
- }
-
- std::vector<llvm::Constant*> Values(12);
- Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods);
- if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
- // Record a reference to the super class.
- LazySymbols.insert(Super->getIdentifier());
-
- Values[ 1] =
- llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
- ObjCTypes.ClassPtrTy);
- } else {
- Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
- }
- Values[ 2] = GetClassName(ID->getIdentifier());
- // Version is always 0.
- Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
- Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
- Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
- Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
- Values[ 7] =
- EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
- "__OBJC,__inst_meth,regular,no_dead_strip",
- InstanceMethods);
- // cache is always NULL.
- Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
- Values[ 9] = Protocols;
- // FIXME: Set ivar_layout
- Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
- Values[11] = EmitClassExtension(ID);
- llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
- Values);
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- std::string("\01L_OBJC_CLASS_")+ClassName,
- &CGM.getModule());
- GV->setSection("__OBJC,__class,regular,no_dead_strip");
- UsedGlobals.push_back(GV);
- // FIXME: Why?
- GV->setAlignment(32);
- DefinedClasses.push_back(GV);
-}
-
-llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
- llvm::Constant *Protocols,
- const llvm::Type *InterfaceTy,
- const ConstantVector &Methods) {
- const char *ClassName = ID->getName();
- unsigned Flags = eClassFlags_Meta;
- unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
-
- if (IsClassHidden(ID->getClassInterface()))
- Flags |= eClassFlags_Hidden;
-
- std::vector<llvm::Constant*> Values(12);
- // The isa for the metaclass is the root of the hierarchy.
- const ObjCInterfaceDecl *Root = ID->getClassInterface();
- while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
- Root = Super;
- Values[ 0] =
- llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
- ObjCTypes.ClassPtrTy);
- // The super class for the metaclass is emitted as the name of the
- // super class. The runtime fixes this up to point to the
- // *metaclass* for the super class.
- if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
- Values[ 1] =
- llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
- ObjCTypes.ClassPtrTy);
- } else {
- Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
- }
- Values[ 2] = GetClassName(ID->getIdentifier());
- // Version is always 0.
- Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
- Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
- Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
- Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
- Values[ 7] =
- EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
- "__OBJC,__inst_meth,regular,no_dead_strip",
- Methods);
- // cache is always NULL.
- Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
- Values[ 9] = Protocols;
- // ivar_layout for metaclass is always NULL.
- Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
- // The class extension is always unused for metaclasses.
- Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
- llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
- Values);
-
- std::string Name("\01L_OBJC_METACLASS_");
- Name += ClassName;
-
- // Check for a forward reference.
- llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
- if (GV) {
- assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
- "Forward metaclass reference has incorrect type.");
- GV->setLinkage(llvm::GlobalValue::InternalLinkage);
- GV->setInitializer(Init);
- } else {
- GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init, Name,
- &CGM.getModule());
- }
- GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
- UsedGlobals.push_back(GV);
- // FIXME: Why?
- GV->setAlignment(32);
-
- return GV;
-}
-
-llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
- std::string Name("\01L_OBJC_METACLASS_");
- Name += ID->getName();
-
- // FIXME: Should we look these up somewhere other than the
- // module. Its a bit silly since we only generate these while
- // processing an implementation, so exactly one pointer would work
- // if know when we entered/exitted an implementation block.
-
- // Check for an existing forward reference.
- if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
- assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
- "Forward metaclass reference has incorrect type.");
- return GV;
- } else {
- // Generate as an external reference to keep a consistent
- // module. This will be patched up when we emit the metaclass.
- return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
- llvm::GlobalValue::ExternalLinkage,
- 0,
- Name,
- &CGM.getModule());
- }
-}
-
-/*
- struct objc_class_ext {
- uint32_t size;
- const char *weak_ivar_layout;
- struct _objc_property_list *properties;
- };
-*/
-llvm::Constant *
-CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
- uint64_t Size =
- CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
-
- std::vector<llvm::Constant*> Values(3);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
- // FIXME: Output weak_ivar_layout string.
- Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
- Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
- ID->getName(),
- ID,
- ID->getClassInterface()->classprop_begin(),
- ID->getClassInterface()->classprop_end());
-
- // Return null if no extension bits are used.
- if (Values[1]->isNullValue() && Values[2]->isNullValue())
- return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
-
- llvm::Constant *Init =
- llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- (std::string("\01L_OBJC_CLASSEXT_") +
- ID->getName()),
- &CGM.getModule());
- // No special section, but goes in llvm.used
- UsedGlobals.push_back(GV);
-
- return GV;
-}
-
-/*
- struct objc_ivar {
- char *ivar_name;
- char *ivar_type;
- int ivar_offset;
- };
-
- struct objc_ivar_list {
- int ivar_count;
- struct objc_ivar list[count];
- };
- */
-llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
- bool ForClass,
- const llvm::Type *InterfaceTy) {
- std::vector<llvm::Constant*> Ivars, Ivar(3);
-
- // When emitting the root class GCC emits ivar entries for the
- // actual class structure. It is not clear if we need to follow this
- // behavior; for now lets try and get away with not doing it. If so,
- // the cleanest solution would be to make up an ObjCInterfaceDecl
- // for the class.
- if (ForClass)
- return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
-
- const llvm::StructLayout *Layout =
- CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
- for (ObjCInterfaceDecl::ivar_iterator
- i = ID->getClassInterface()->ivar_begin(),
- e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
- ObjCIvarDecl *V = *i;
- unsigned Offset =
- Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
- std::string TypeStr;
- llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
- Ivar[0] = GetMethodVarName(V->getIdentifier());
- CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
- EncodingRecordTypes);
- Ivar[1] = GetMethodVarType(TypeStr);
- Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
- Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
- Ivar));
- }
-
- // Return null for empty list.
- if (Ivars.empty())
- return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
-
- std::vector<llvm::Constant*> Values(2);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
- llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
- Ivars.size());
- Values[1] = llvm::ConstantArray::get(AT, Ivars);
- llvm::Constant *Init = llvm::ConstantStruct::get(Values);
-
- const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
- "\01L_OBJC_INSTANCE_VARIABLES_");
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- std::string(Prefix) + ID->getName(),
- &CGM.getModule());
- if (ForClass) {
- GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
- // FIXME: Why is this only here?
- GV->setAlignment(32);
- } else {
- GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
- }
- UsedGlobals.push_back(GV);
- return llvm::ConstantExpr::getBitCast(GV,
- ObjCTypes.IvarListPtrTy);
-}
-
-/*
- struct objc_method {
- SEL method_name;
- char *method_types;
- void *method;
- };
-
- struct objc_method_list {
- struct objc_method_list *obsolete;
- int count;
- struct objc_method methods_list[count];
- };
-*/
-
-/// GetMethodConstant - Return a struct objc_method constant for the
-/// given method if it has been defined. The result is null if the
-/// method has not been defined. The return value has type MethodPtrTy.
-llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
- // FIXME: Use DenseMap::lookup
- llvm::Function *Fn = MethodDefinitions[MD];
- if (!Fn)
- return 0;
-
- std::vector<llvm::Constant*> Method(3);
- Method[0] =
- llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
- ObjCTypes.SelectorPtrTy);
- Method[1] = GetMethodVarType(MD);
- Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
- return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
-}
-
-llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
- const char *Section,
- const ConstantVector &Methods) {
- // Return null for empty list.
- if (Methods.empty())
- return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
-
- std::vector<llvm::Constant*> Values(3);
- Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
- Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
- llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
- Methods.size());
- Values[2] = llvm::ConstantArray::get(AT, Methods);
- llvm::Constant *Init = llvm::ConstantStruct::get(Values);
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- Name,
- &CGM.getModule());
- GV->setSection(Section);
- UsedGlobals.push_back(GV);
- return llvm::ConstantExpr::getBitCast(GV,
- ObjCTypes.MethodListPtrTy);
-}
-
-llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
- std::string Name;
- GetNameForMethod(OMD, Name);
-
- const llvm::FunctionType *MethodTy =
- CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
- llvm::Function *Method =
- llvm::Function::Create(MethodTy,
- llvm::GlobalValue::InternalLinkage,
- Name,
- &CGM.getModule());
- MethodDefinitions.insert(std::make_pair(OMD, Method));
-
- return Method;
-}
-
-llvm::Function *CGObjCMac::ModuleInitFunction() {
- // Abuse this interface function as a place to finalize.
- FinishModule();
-
- return NULL;
-}
-
-llvm::Function *CGObjCMac::GetPropertyGetFunction() {
- return ObjCTypes.GetPropertyFn;
-}
-
-llvm::Function *CGObjCMac::GetPropertySetFunction() {
- return ObjCTypes.SetPropertyFn;
-}
-
-llvm::Function *CGObjCMac::EnumerationMutationFunction()
-{
- return ObjCTypes.EnumerationMutationFn;
-}
-
-/*
-
-Objective-C setjmp-longjmp (sjlj) Exception Handling
---
-
-The basic framework for a @try-catch-finally is as follows:
-{
- objc_exception_data d;
- id _rethrow = null;
-
- objc_exception_try_enter(&d);
- if (!setjmp(d.jmp_buf)) {
- ... try body ...
- } else {
- // exception path
- id _caught = objc_exception_extract(&d);
-
- // enter new try scope for handlers
- if (!setjmp(d.jmp_buf)) {
- ... match exception and execute catch blocks ...
-
- // fell off end, rethrow.
- _rethrow = _caught;
- ... jump-through-finally to finally_rethrow ...
- } else {
- // exception in catch block
- _rethrow = objc_exception_extract(&d);
- ... jump-through-finally_no_exit to finally_rethrow ...
- }
- }
- ... jump-through-finally to finally_end ...
-
-finally:
- // match either the initial try_enter or the catch try_enter,
- // depending on the path followed.
- objc_exception_try_exit(&d);
-finally_no_exit:
- ... finally block ....
- ... dispatch to finally destination ...
-
-finally_rethrow:
- objc_exception_throw(_rethrow);
-
-finally_end:
-}
-
-This framework differs slightly from the one gcc uses, in that gcc
-uses _rethrow to determine if objc_exception_try_exit should be called
-and if the object should be rethrown. This breaks in the face of
-throwing nil and introduces unnecessary branches.
-
-We specialize this framework for a few particular circumstances:
-
- - If there are no catch blocks, then we avoid emitting the second
- exception handling context.
-
- - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
- e)) we avoid emitting the code to rethrow an uncaught exception.
-
- - FIXME: If there is no @finally block we can do a few more
- simplifications.
-
-Rethrows and Jumps-Through-Finally
---
-
-Support for implicit rethrows and jumping through the finally block is
-handled by storing the current exception-handling context in
-ObjCEHStack.
-
-In order to implement proper @finally semantics, we support one basic
-mechanism for jumping through the finally block to an arbitrary
-destination. Constructs which generate exits from a @try or @catch
-block use this mechanism to implement the proper semantics by chaining
-jumps, as necessary.
-
-This mechanism works like the one used for indirect goto: we
-arbitrarily assign an ID to each destination and store the ID for the
-destination in a variable prior to entering the finally block. At the
-end of the finally block we simply create a switch to the proper
-destination.
-
-*/
-
-void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtTryStmt &S) {
- // Create various blocks we refer to for handling @finally.
- llvm::BasicBlock *FinallyBlock = llvm::BasicBlock::Create("finally");
- llvm::BasicBlock *FinallyNoExit = llvm::BasicBlock::Create("finally.noexit");
- llvm::BasicBlock *FinallyRethrow = llvm::BasicBlock::Create("finally.throw");
- llvm::BasicBlock *FinallyEnd = llvm::BasicBlock::Create("finally.end");
- llvm::Value *DestCode =
- CGF.CreateTempAlloca(llvm::Type::Int32Ty, "finally.dst");
-
- // Generate jump code. Done here so we can directly add things to
- // the switch instruction.
- llvm::BasicBlock *FinallyJump = llvm::BasicBlock::Create("finally.jump");
- llvm::SwitchInst *FinallySwitch =
- llvm::SwitchInst::Create(new llvm::LoadInst(DestCode, "", FinallyJump),
- FinallyEnd, 10, FinallyJump);
-
- // Push an EH context entry, used for handling rethrows and jumps
- // through finally.
- CodeGenFunction::ObjCEHEntry EHEntry(FinallyBlock, FinallyNoExit,
- FinallySwitch, DestCode);
- CGF.ObjCEHStack.push_back(&EHEntry);
-
- // Allocate memory for the exception data and rethrow pointer.
- llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
- "exceptiondata.ptr");
- llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, "_rethrow");
-
- // Enter a new try block and call setjmp.
- CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
- llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0,
- "jmpbufarray");
- JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
- llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
- JmpBufPtr, "result");
-
- llvm::BasicBlock *TryBlock = llvm::BasicBlock::Create("try");
- llvm::BasicBlock *TryHandler = llvm::BasicBlock::Create("try.handler");
- CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"),
- TryHandler, TryBlock);
-
- // Emit the @try block.
- CGF.EmitBlock(TryBlock);
- CGF.EmitStmt(S.getTryBody());
- CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
-
- // Emit the "exception in @try" block.
- CGF.EmitBlock(TryHandler);
-
- // Retrieve the exception object. We may emit multiple blocks but
- // nothing can cross this so the value is already in SSA form.
- llvm::Value *Caught = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
- ExceptionData,
- "caught");
- EHEntry.Exception = Caught;
- if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) {
- // Enter a new exception try block (in case a @catch block throws
- // an exception).
- CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
-
- llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
- JmpBufPtr, "result");
- llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw");
-
- llvm::BasicBlock *CatchBlock = llvm::BasicBlock::Create("catch");
- llvm::BasicBlock *CatchHandler = llvm::BasicBlock::Create("catch.handler");
- CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
-
- CGF.EmitBlock(CatchBlock);
-
- // Handle catch list. As a special case we check if everything is
- // matched and avoid generating code for falling off the end if
- // so.
- bool AllMatched = false;
- for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
- llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("catch");
-
- const DeclStmt *CatchParam =
- cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt());
- const VarDecl *VD = 0;
- const PointerType *PT = 0;
-
- // catch(...) always matches.
- if (!CatchParam) {
- AllMatched = true;
- } else {
- VD = cast<VarDecl>(CatchParam->getSolitaryDecl());
- PT = VD->getType()->getAsPointerType();
-
- // catch(id e) always matches.
- // FIXME: For the time being we also match id<X>; this should
- // be rejected by Sema instead.
- if ((PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) ||
- VD->getType()->isObjCQualifiedIdType())
- AllMatched = true;
- }
-
- if (AllMatched) {
- if (CatchParam) {
- CGF.EmitStmt(CatchParam);
- CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD));
- }
-
- CGF.EmitStmt(CatchStmt->getCatchBody());
- CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
- break;
- }
-
- assert(PT && "Unexpected non-pointer type in @catch");
- QualType T = PT->getPointeeType();
- const ObjCInterfaceType *ObjCType = T->getAsObjCInterfaceType();
- assert(ObjCType && "Catch parameter must have Objective-C type!");
-
- // Check if the @catch block matches the exception object.
- llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
-
- llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn,
- Class, Caught, "match");
-
- llvm::BasicBlock *MatchedBlock = llvm::BasicBlock::Create("matched");
-
- CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
- MatchedBlock, NextCatchBlock);
-
- // Emit the @catch block.
- CGF.EmitBlock(MatchedBlock);
- CGF.EmitStmt(CatchParam);
-
- llvm::Value *Tmp =
- CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()),
- "tmp");
- CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(VD));
-
- CGF.EmitStmt(CatchStmt->getCatchBody());
- CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
-
- CGF.EmitBlock(NextCatchBlock);
- }
-
- if (!AllMatched) {
- // None of the handlers caught the exception, so store it to be
- // rethrown at the end of the @finally block.
- CGF.Builder.CreateStore(Caught, RethrowPtr);
- CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow);
- }
-
- // Emit the exception handler for the @catch blocks.
- CGF.EmitBlock(CatchHandler);
- CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
- ExceptionData),
- RethrowPtr);
- CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);
- } else {
- CGF.Builder.CreateStore(Caught, RethrowPtr);
- CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);
- }
-
- // Pop the exception-handling stack entry. It is important to do
- // this now, because the code in the @finally block is not in this
- // context.
- CGF.ObjCEHStack.pop_back();
-
- // Emit the @finally block.
- CGF.EmitBlock(FinallyBlock);
- CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
-
- CGF.EmitBlock(FinallyNoExit);
- if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt())
- CGF.EmitStmt(FinallyStmt->getFinallyBody());
-
- CGF.EmitBlock(FinallyJump);
-
- CGF.EmitBlock(FinallyRethrow);
- CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn,
- CGF.Builder.CreateLoad(RethrowPtr));
- CGF.Builder.CreateUnreachable();
-
- CGF.EmitBlock(FinallyEnd);
-}
-
-void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtThrowStmt &S) {
- llvm::Value *ExceptionAsObject;
-
- if (const Expr *ThrowExpr = S.getThrowExpr()) {
- llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
- ExceptionAsObject =
- CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
- } else {
- assert((!CGF.ObjCEHStack.empty() && CGF.ObjCEHStack.back()->Exception) &&
- "Unexpected rethrow outside @catch block.");
- ExceptionAsObject = CGF.ObjCEHStack.back()->Exception;
- }
-
- CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, ExceptionAsObject);
- CGF.Builder.CreateUnreachable();
- CGF.EmitBlock(llvm::BasicBlock::Create("bb"));
-}
-
-void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E,
- llvm::BasicBlock *Dst,
- bool ExecuteTryExit) {
- llvm::BasicBlock *Src = Builder.GetInsertBlock();
-
- if (isDummyBlock(Src))
- return;
-
- // Find the destination code for this block. We always use 0 for the
- // fallthrough block (default destination).
- llvm::SwitchInst *SI = E->FinallySwitch;
- llvm::ConstantInt *ID;
- if (Dst == SI->getDefaultDest()) {
- ID = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- } else {
- ID = SI->findCaseDest(Dst);
- if (!ID) {
- // No code found, get a new unique one by just using the number
- // of switch successors.
- ID = llvm::ConstantInt::get(llvm::Type::Int32Ty, SI->getNumSuccessors());
- SI->addCase(ID, Dst);
- }
- }
-
- // Set the destination code and branch.
- Builder.CreateStore(ID, E->DestCode);
- Builder.CreateBr(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit);
-}
-
-/* *** Private Interface *** */
-
-/// EmitImageInfo - Emit the image info marker used to encode some module
-/// level information.
-///
-/// See: <rdr://4810609&4810587&4810587>
-/// struct IMAGE_INFO {
-/// unsigned version;
-/// unsigned flags;
-/// };
-enum ImageInfoFlags {
- eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
- eImageInfo_GarbageCollected = (1 << 1),
- eImageInfo_GCOnly = (1 << 2)
-};
-
-void CGObjCMac::EmitImageInfo() {
- unsigned version = 0; // Version is unused?
- unsigned flags = 0;
-
- // FIXME: Fix and continue?
- if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
- flags |= eImageInfo_GarbageCollected;
- if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
- flags |= eImageInfo_GCOnly;
-
- // Emitted as int[2];
- llvm::Constant *values[2] = {
- llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
- };
- llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(AT, true,
- llvm::GlobalValue::InternalLinkage,
- llvm::ConstantArray::get(AT, values, 2),
- "\01L_OBJC_IMAGE_INFO",
- &CGM.getModule());
-
- if (ObjCABI == 1) {
- GV->setSection("__OBJC, __image_info,regular");
- } else {
- GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
- }
-
- UsedGlobals.push_back(GV);
-}
-
-
-// struct objc_module {
-// unsigned long version;
-// unsigned long size;
-// const char *name;
-// Symtab symtab;
-// };
-
-// FIXME: Get from somewhere
-static const int ModuleVersion = 7;
-
-void CGObjCMac::EmitModuleInfo() {
- uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
-
- std::vector<llvm::Constant*> Values(4);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
- Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
- // This used to be the filename, now it is unused. <rdr://4327263>
- Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
- Values[3] = EmitModuleSymbols();
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
- llvm::GlobalValue::InternalLinkage,
- llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
- Values),
- "\01L_OBJC_MODULES",
- &CGM.getModule());
- GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
- UsedGlobals.push_back(GV);
-}
-
-llvm::Constant *CGObjCMac::EmitModuleSymbols() {
- unsigned NumClasses = DefinedClasses.size();
- unsigned NumCategories = DefinedCategories.size();
-
- // Return null if no symbols were defined.
- if (!NumClasses && !NumCategories)
- return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
-
- std::vector<llvm::Constant*> Values(5);
- Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
- Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
- Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
- Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
-
- // The runtime expects exactly the list of defined classes followed
- // by the list of defined categories, in a single array.
- std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
- for (unsigned i=0; i<NumClasses; i++)
- Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
- ObjCTypes.Int8PtrTy);
- for (unsigned i=0; i<NumCategories; i++)
- Symbols[NumClasses + i] =
- llvm::ConstantExpr::getBitCast(DefinedCategories[i],
- ObjCTypes.Int8PtrTy);
-
- Values[4] =
- llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
- NumClasses + NumCategories),
- Symbols);
-
- llvm::Constant *Init = llvm::ConstantStruct::get(Values);
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Init->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- Init,
- "\01L_OBJC_SYMBOLS",
- &CGM.getModule());
- GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
- UsedGlobals.push_back(GV);
- return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
-}
-
-llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
- const ObjCInterfaceDecl *ID) {
- LazySymbols.insert(ID->getIdentifier());
-
- llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
-
- if (!Entry) {
- llvm::Constant *Casted =
- llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
- ObjCTypes.ClassPtrTy);
- Entry =
- new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
- llvm::GlobalValue::InternalLinkage,
- Casted, "\01L_OBJC_CLASS_REFERENCES_",
- &CGM.getModule());
- Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
- UsedGlobals.push_back(Entry);
- }
-
- return Builder.CreateLoad(Entry, false, "tmp");
-}
-
-llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
- llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
-
- if (!Entry) {
- llvm::Constant *Casted =
- llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
- ObjCTypes.SelectorPtrTy);
- Entry =
- new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
- llvm::GlobalValue::InternalLinkage,
- Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
- &CGM.getModule());
- Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
- UsedGlobals.push_back(Entry);
- }
-
- return Builder.CreateLoad(Entry, false, "tmp");
-}
-
-llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
- llvm::GlobalVariable *&Entry = ClassNames[Ident];
-
- if (!Entry) {
- llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
- Entry =
- new llvm::GlobalVariable(C->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- C, "\01L_OBJC_CLASS_NAME_",
- &CGM.getModule());
- Entry->setSection("__TEXT,__cstring,cstring_literals");
- UsedGlobals.push_back(Entry);
- }
-
- return getConstantGEP(Entry, 0, 0);
-}
-
-llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
- llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
-
- if (!Entry) {
- llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
- Entry =
- new llvm::GlobalVariable(C->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- C, "\01L_OBJC_METH_VAR_NAME_",
- &CGM.getModule());
- Entry->setSection("__TEXT,__cstring,cstring_literals");
- UsedGlobals.push_back(Entry);
- }
-
- return getConstantGEP(Entry, 0, 0);
-}
-
-// FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
- return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
-}
-
-// FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
- return GetMethodVarName(&CGM.getContext().Idents.get(Name));
-}
-
-llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
- llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
-
- if (!Entry) {
- llvm::Constant *C = llvm::ConstantArray::get(Name);
- Entry =
- new llvm::GlobalVariable(C->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- C, "\01L_OBJC_METH_VAR_TYPE_",
- &CGM.getModule());
- Entry->setSection("__TEXT,__cstring,cstring_literals");
- UsedGlobals.push_back(Entry);
- }
-
- return getConstantGEP(Entry, 0, 0);
-}
-
-// FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) {
- std::string TypeStr;
- CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
- TypeStr);
- return GetMethodVarType(TypeStr);
-}
-
-// FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
- llvm::GlobalVariable *&Entry = PropertyNames[Ident];
-
- if (!Entry) {
- llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
- Entry =
- new llvm::GlobalVariable(C->getType(), false,
- llvm::GlobalValue::InternalLinkage,
- C, "\01L_OBJC_PROP_NAME_ATTR_",
- &CGM.getModule());
- Entry->setSection("__TEXT,__cstring,cstring_literals");
- UsedGlobals.push_back(Entry);
- }
-
- return getConstantGEP(Entry, 0, 0);
-}
-
-// FIXME: Merge into a single cstring creation function.
-// FIXME: This Decl should be more precise.
-llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
- const Decl *Container) {
- std::string TypeStr;
- CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
- return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
-}
-
-void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
- std::string &NameOut) {
- // FIXME: Find the mangling GCC uses.
- std::stringstream s;
- s << (D->isInstance() ? "-" : "+");
- s << "[";
- s << D->getClassInterface()->getName();
- s << " ";
- s << D->getSelector().getName();
- s << "]";
- NameOut = s.str();
-}
-
-void CGObjCMac::FinishModule() {
- EmitModuleInfo();
-
- std::vector<llvm::Constant*> Used;
-
- for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
- e = UsedGlobals.end(); i != e; ++i) {
- Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
- }
-
- llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
- llvm::GlobalValue *GV =
- new llvm::GlobalVariable(AT, false,
- llvm::GlobalValue::AppendingLinkage,
- llvm::ConstantArray::get(AT, Used),
- "llvm.used",
- &CGM.getModule());
-
- GV->setSection("llvm.metadata");
-
- // Add assembler directives to add lazy undefined symbol references
- // for classes which are referenced but not defined. This is
- // important for correct linker interaction.
-
- // FIXME: Uh, this isn't particularly portable.
- std::stringstream s;
- for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
- e = LazySymbols.end(); i != e; ++i) {
- s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
- }
- for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
- e = DefinedSymbols.end(); i != e; ++i) {
- s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
- << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
- }
- CGM.getModule().appendModuleInlineAsm(s.str());
-}
-
-/* *** */
-
-ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
- : CGM(cgm)
-{
- CodeGen::CodeGenTypes &Types = CGM.getTypes();
- ASTContext &Ctx = CGM.getContext();
-
- ShortTy = Types.ConvertType(Ctx.ShortTy);
- IntTy = Types.ConvertType(Ctx.IntTy);
- LongTy = Types.ConvertType(Ctx.LongTy);
- Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-
- ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
- SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
-
- // FIXME: It would be nice to unify this with the opaque type, so
- // that the IR comes out a bit cleaner.
- const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
- ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
-
- MethodDescriptionTy =
- llvm::StructType::get(SelectorPtrTy,
- Int8PtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_method_description",
- MethodDescriptionTy);
-
- MethodDescriptionListTy =
- llvm::StructType::get(IntTy,
- llvm::ArrayType::get(MethodDescriptionTy, 0),
- NULL);
- CGM.getModule().addTypeName("struct._objc_method_description_list",
- MethodDescriptionListTy);
- MethodDescriptionListPtrTy =
- llvm::PointerType::getUnqual(MethodDescriptionListTy);
-
- PropertyTy = llvm::StructType::get(Int8PtrTy,
- Int8PtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_property",
- PropertyTy);
-
- PropertyListTy = llvm::StructType::get(IntTy,
- IntTy,
- llvm::ArrayType::get(PropertyTy, 0),
- NULL);
- CGM.getModule().addTypeName("struct._objc_property_list",
- PropertyListTy);
- PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
-
- // Protocol description structures
-
- ProtocolExtensionTy =
- llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
- llvm::PointerType::getUnqual(MethodDescriptionListTy),
- llvm::PointerType::getUnqual(MethodDescriptionListTy),
- PropertyListPtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_protocol_extension",
- ProtocolExtensionTy);
- ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
-
- // Handle recursive construction of Protocl and ProtocolList types
-
- llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
- llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
-
- T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
- LongTy,
- llvm::ArrayType::get(ProtocolTyHolder, 0),
- NULL);
- cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
-
- T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
- Int8PtrTy,
- llvm::PointerType::getUnqual(ProtocolListTyHolder),
- MethodDescriptionListPtrTy,
- MethodDescriptionListPtrTy,
- NULL);
- cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
-
- ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
- CGM.getModule().addTypeName("struct._objc_protocol_list",
- ProtocolListTy);
- ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
-
- ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
- CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
- ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
-
- // Class description structures
-
- IvarTy = llvm::StructType::get(Int8PtrTy,
- Int8PtrTy,
- IntTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
-
- IvarListTy = llvm::OpaqueType::get();
- CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
- IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
-
- MethodTy = llvm::StructType::get(SelectorPtrTy,
- Int8PtrTy,
- Int8PtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_method", MethodTy);
-
- MethodListTy = llvm::OpaqueType::get();
- CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
- MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
-
- CacheTy = llvm::OpaqueType::get();
- CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
- CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
-
- ClassExtensionTy =
- llvm::StructType::get(IntTy,
- Int8PtrTy,
- PropertyListPtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
- ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
-
- llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
-
- T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
- llvm::PointerType::getUnqual(ClassTyHolder),
- Int8PtrTy,
- LongTy,
- LongTy,
- LongTy,
- IvarListPtrTy,
- MethodListPtrTy,
- CachePtrTy,
- ProtocolListPtrTy,
- Int8PtrTy,
- ClassExtensionPtrTy,
- NULL);
- cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
-
- ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
- CGM.getModule().addTypeName("struct._objc_class", ClassTy);
- ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
-
- CategoryTy = llvm::StructType::get(Int8PtrTy,
- Int8PtrTy,
- MethodListPtrTy,
- MethodListPtrTy,
- ProtocolListPtrTy,
- IntTy,
- PropertyListPtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
-
- // I'm not sure I like this. The implicit coordination is a bit
- // gross. We should solve this in a reasonable fashion because this
- // is a pretty common task (match some runtime data structure with
- // an LLVM data structure).
-
- // FIXME: This is leaked.
- // FIXME: Merge with rewriter code?
- RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
- SourceLocation(),
- &Ctx.Idents.get("_objc_super"));
- FieldDecl *FieldDecls[2];
- FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0,
- Ctx.getObjCIdType());
- FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0,
- Ctx.getObjCClassType());
- RD->defineBody(Ctx, FieldDecls, 2);
-
- SuperCTy = Ctx.getTagDeclType(RD);
- SuperPtrCTy = Ctx.getPointerType(SuperCTy);
-
- SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
- SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
-
- // Global metadata structures
-
- SymtabTy = llvm::StructType::get(LongTy,
- SelectorPtrTy,
- ShortTy,
- ShortTy,
- llvm::ArrayType::get(Int8PtrTy, 0),
- NULL);
- CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
- SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
-
- ModuleTy =
- llvm::StructType::get(LongTy,
- LongTy,
- Int8PtrTy,
- SymtabPtrTy,
- NULL);
- CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
-
- // Message send functions.
-
- std::vector<const llvm::Type*> Params;
- Params.push_back(ObjectPtrTy);
- Params.push_back(SelectorPtrTy);
- MessageSendFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
- Params,
- true),
- "objc_msgSend");
-
- Params.clear();
- Params.push_back(Int8PtrTy);
- Params.push_back(ObjectPtrTy);
- Params.push_back(SelectorPtrTy);
- MessageSendStretFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- true),
- "objc_msgSend_stret");
-
- Params.clear();
- Params.push_back(SuperPtrTy);
- Params.push_back(SelectorPtrTy);
- MessageSendSuperFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
- Params,
- true),
- "objc_msgSendSuper");
-
- Params.clear();
- Params.push_back(Int8PtrTy);
- Params.push_back(SuperPtrTy);
- Params.push_back(SelectorPtrTy);
- MessageSendSuperStretFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- true),
- "objc_msgSendSuper_stret");
-
- // Property manipulation functions.
-
- Params.clear();
- Params.push_back(ObjectPtrTy);
- Params.push_back(SelectorPtrTy);
- Params.push_back(LongTy);
- Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
- GetPropertyFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
- Params,
- false),
- "objc_getProperty");
-
- Params.clear();
- Params.push_back(ObjectPtrTy);
- Params.push_back(SelectorPtrTy);
- Params.push_back(LongTy);
- Params.push_back(ObjectPtrTy);
- Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
- Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
- SetPropertyFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- false),
- "objc_setProperty");
-
- // Enumeration mutation.
-
- Params.clear();
- Params.push_back(ObjectPtrTy);
- EnumerationMutationFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- false),
- "objc_enumerationMutation");
-
- // FIXME: This is the size of the setjmp buffer and should be
- // target specific. 18 is what's used on 32-bit X86.
- uint64_t SetJmpBufferSize = 18;
-
- // Exceptions
- const llvm::Type *StackPtrTy =
- llvm::ArrayType::get(llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 4);
-
- ExceptionDataTy =
- llvm::StructType::get(llvm::ArrayType::get(llvm::Type::Int32Ty,
- SetJmpBufferSize),
- StackPtrTy, NULL);
- CGM.getModule().addTypeName("struct._objc_exception_data",
- ExceptionDataTy);
-
- Params.clear();
- Params.push_back(ObjectPtrTy);
- ExceptionThrowFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- false),
- "objc_exception_throw");
-
- Params.clear();
- Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
- ExceptionTryEnterFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- false),
- "objc_exception_try_enter");
- ExceptionTryExitFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params,
- false),
- "objc_exception_try_exit");
- ExceptionExtractFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
- Params,
- false),
- "objc_exception_extract");
-
- Params.clear();
- Params.push_back(ClassPtrTy);
- Params.push_back(ObjectPtrTy);
- ExceptionMatchFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
- Params,
- false),
- "objc_exception_match");
-
- Params.clear();
- Params.push_back(llvm::PointerType::getUnqual(llvm::Type::Int32Ty));
- SetJmpFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
- Params,
- false),
- "_setjmp");
-}
-
-ObjCTypesHelper::~ObjCTypesHelper() {
-}
-
-llvm::Constant *ObjCTypesHelper::getMessageSendFn(bool IsSuper, bool IsStret) {
- if (IsStret) {
- return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
- } else { // FIXME: floating point?
- return IsSuper ? MessageSendSuperFn : MessageSendFn;
- }
-}
-
-/* *** */
-
-CodeGen::CGObjCRuntime *
-CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
- return new CGObjCMac(CGM);
-}
diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h
deleted file mode 100644
index fe3032193d33..000000000000
--- a/clang/lib/CodeGen/CGObjCRuntime.h
+++ /dev/null
@@ -1,154 +0,0 @@
-//===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides an abstract class for Objective-C code generation. Concrete
-// subclasses of this implement code generation for specific Objective-C
-// runtime libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_OBCJRUNTIME_H
-#define CLANG_CODEGEN_OBCJRUNTIME_H
-#include "clang/Basic/IdentifierTable.h" // Selector
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/IRBuilder.h"
-#include <string>
-
-#include "CGValue.h"
-#include "CGCall.h"
-
-namespace llvm {
- class Constant;
- class Type;
- class Value;
- class Module;
- class Function;
-}
-
-namespace clang {
-namespace CodeGen {
- class CodeGenFunction;
-}
-
- class ObjCAtTryStmt;
- class ObjCAtThrowStmt;
- class ObjCCategoryImplDecl;
- class ObjCImplementationDecl;
- class ObjCInterfaceDecl;
- class ObjCMessageExpr;
- class ObjCMethodDecl;
- class ObjCProtocolDecl;
- class Selector;
-
-namespace CodeGen {
- class CodeGenModule;
-
-//FIXME Several methods should be pure virtual but aren't to avoid the
-//partially-implemented subclass breaking.
-
-/// Implements runtime-specific code generation functions.
-class CGObjCRuntime {
- typedef llvm::IRBuilder<> BuilderType;
-
-public:
- virtual ~CGObjCRuntime();
-
- /// Generate the function required to register all Objective-C components in
- /// this compilation unit with the runtime library.
- virtual llvm::Function *ModuleInitFunction() = 0;
-
- /// Get a selector for the specified name and type values. The
- /// return value should have the LLVM type for pointer-to
- /// ASTContext::getObjCSelType().
- virtual llvm::Value *GetSelector(BuilderType &Builder,
- Selector Sel) = 0;
-
- /// Generate a constant string object.
- virtual llvm::Constant *GenerateConstantString(const std::string &String) = 0;
-
- /// Generate a category. A category contains a list of methods (and
- /// accompanying metadata) and a list of protocols.
- virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
-
- /// Generate a class stucture for this class.
- virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
-
- /// Generate an Objective-C message send operation.
- virtual CodeGen::RValue
- GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- llvm::Value *Receiver,
- bool IsClassMessage,
- const CallArgList &CallArgs) = 0;
-
- /// Generate an Objective-C message send operation to the super
- /// class initiated in a method for Class and with the given Self
- /// object.
- virtual CodeGen::RValue
- GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
- QualType ResultType,
- Selector Sel,
- const ObjCInterfaceDecl *Class,
- llvm::Value *Self,
- bool IsClassMessage,
- const CallArgList &CallArgs) = 0;
-
- /// Emit the code to return the named protocol as an object, as in a
- /// @protocol expression.
- virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<true> &Builder,
- const ObjCProtocolDecl *OPD) = 0;
-
- /// Generate the named protocol. Protocols contain method metadata but no
- /// implementations.
- virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
-
- /// Generate a function preamble for a method with the specified
- /// types.
-
- // FIXME: Current this just generates the Function definition, but
- // really this should also be generating the loads of the
- // parameters, as the runtime should have full control over how
- // parameters are passed.
- virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD) = 0;
-
- /// Return the runtime function for getting properties.
- virtual llvm::Function *GetPropertyGetFunction() = 0;
-
- /// Return the runtime function for setting properties.
- virtual llvm::Function *GetPropertySetFunction() = 0;
-
- /// GetClass - Return a reference to the class for the given
- /// interface decl.
- virtual llvm::Value *GetClass(BuilderType &Builder,
- const ObjCInterfaceDecl *OID) = 0;
-
- /// EnumerationMutationFunction - Return the function that's called by the
- /// compiler when a mutation is detected during foreach iteration.
- virtual llvm::Function *EnumerationMutationFunction() = 0;
-
- /// If instance variable addresses are determined at runtime then this should
- /// return true, otherwise instance variables will be accessed directly from
- /// the structure. If this returns true then @defs is invalid for this
- /// runtime and a warning should be generated.
- virtual bool LateBoundIVars() const { return false; }
-
- virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtTryStmt &S) = 0;
- virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
- const ObjCAtThrowStmt &S) = 0;
-};
-
-/// Creates an instance of an Objective-C runtime class.
-//TODO: This should include some way of selecting which runtime to target.
-CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
-CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
-}
-}
-#endif
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
deleted file mode 100644
index 024fb0a6599d..000000000000
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ /dev/null
@@ -1,892 +0,0 @@
-//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
-//
-// 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 emit Stmt nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGDebugInfo.h"
-#include "CodeGenModule.h"
-#include "CodeGenFunction.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/ADT/StringExtras.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===----------------------------------------------------------------------===//
-// Statement Emission
-//===----------------------------------------------------------------------===//
-
-void CodeGenFunction::EmitStmt(const Stmt *S) {
- assert(S && "Null statement?");
-
- // Generate stoppoints if we are emitting debug info.
- // Beginning of a Compound Statement (e.g. an opening '{') does not produce
- // executable code. So do not generate a stoppoint for that.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) {
- if (S->getLocStart().isValid()) {
- DI->setLocation(S->getLocStart());
- }
-
- DI->EmitStopPoint(CurFn, Builder);
- }
-
- switch (S->getStmtClass()) {
- default:
- // Must be an expression in a stmt context. Emit the value (to get
- // side-effects) and ignore the result.
- if (const Expr *E = dyn_cast<Expr>(S)) {
- if (!hasAggregateLLVMType(E->getType()))
- EmitScalarExpr(E);
- else if (E->getType()->isAnyComplexType())
- EmitComplexExpr(E);
- else
- EmitAggExpr(E, 0, false);
- } else {
- ErrorUnsupported(S, "statement");
- }
- break;
- case Stmt::NullStmtClass: break;
- case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
- case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
- case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
- case Stmt::IndirectGotoStmtClass:
- EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break;
-
- case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
- case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
- case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break;
- case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break;
-
- case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
- case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
-
- case Stmt::BreakStmtClass:
- // FIXME: Implement break in @try or @catch blocks.
- if (!ObjCEHStack.empty()) {
- CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block");
- return;
- }
- EmitBreakStmt();
- break;
-
- case Stmt::ContinueStmtClass:
- // FIXME: Implement continue in @try or @catch blocks.
- if (!ObjCEHStack.empty()) {
- CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block");
- return;
- }
- EmitContinueStmt();
- break;
-
- case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
- case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break;
- case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break;
- case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break;
-
- case Stmt::ObjCAtTryStmtClass:
- EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
- break;
- case Stmt::ObjCAtCatchStmtClass:
- assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt");
- break;
- case Stmt::ObjCAtFinallyStmtClass:
- assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt");
- break;
- case Stmt::ObjCAtThrowStmtClass:
- EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S));
- break;
- case Stmt::ObjCAtSynchronizedStmtClass:
- ErrorUnsupported(S, "@synchronized statement");
- break;
- case Stmt::ObjCForCollectionStmtClass:
- EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S));
- break;
- }
-}
-
-/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true,
-/// this captures the expression result of the last sub-statement and returns it
-/// (for use by the statement expression extension).
-RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
- llvm::Value *AggLoc, bool isAggVol) {
- // FIXME: handle vla's etc.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if (DI) {
- if (S.getLBracLoc().isValid())
- DI->setLocation(S.getLBracLoc());
- DI->EmitRegionStart(CurFn, Builder);
- }
-
- for (CompoundStmt::const_body_iterator I = S.body_begin(),
- E = S.body_end()-GetLast; I != E; ++I)
- EmitStmt(*I);
-
- if (DI) {
- if (S.getRBracLoc().isValid())
- DI->setLocation(S.getRBracLoc());
- DI->EmitRegionEnd(CurFn, Builder);
- }
-
- if (!GetLast)
- return RValue::get(0);
-
- // We have to special case labels here. They are statements, but when put at
- // the end of a statement expression, they yield the value of their
- // subexpression. Handle this by walking through all labels we encounter,
- // emitting them before we evaluate the subexpr.
- const Stmt *LastStmt = S.body_back();
- while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
- EmitLabel(*LS);
- LastStmt = LS->getSubStmt();
- }
-
- return EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
-}
-
-void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {
- // Emit a branch from this block to the next one if this was a real block. If
- // this was just a fall-through block after a terminator, don't emit it.
- llvm::BasicBlock *LastBB = Builder.GetInsertBlock();
-
- if (LastBB->getTerminator()) {
- // If the previous block is already terminated, don't touch it.
- } else if (LastBB->empty() && isDummyBlock(LastBB)) {
- // If the last block was an empty placeholder, remove it now.
- // TODO: cache and reuse these.
- LastBB->eraseFromParent();
- } else {
- // Otherwise, create a fall-through branch.
- Builder.CreateBr(BB);
- }
- CurFn->getBasicBlockList().push_back(BB);
- Builder.SetInsertPoint(BB);
-}
-
-void CodeGenFunction::EmitLabel(const LabelStmt &S) {
- llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
- EmitBlock(NextBB);
-}
-
-
-void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
- EmitLabel(S);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
- // FIXME: Implement goto out in @try or @catch blocks.
- if (!ObjCEHStack.empty()) {
- CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block");
- return;
- }
-
- Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
-
- // Emit a block after the branch so that dead code after a goto has some place
- // to go.
- Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn));
-}
-
-void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
- // FIXME: Implement indirect goto in @try or @catch blocks.
- if (!ObjCEHStack.empty()) {
- CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block");
- return;
- }
-
- // Emit initial switch which will be patched up later by
- // EmitIndirectSwitches(). We need a default dest, so we use the
- // current BB, but this is overwritten.
- llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()),
- llvm::Type::Int32Ty,
- "addr");
- llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock());
- IndirectSwitches.push_back(I);
-
- // Emit a block after the branch so that dead code after a goto has some place
- // to go.
- Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn));
-}
-
-void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
- // FIXME: It would probably be nice for us to skip emission of if
- // (0) code here.
-
- // C99 6.8.4.1: The first substatement is executed if the expression compares
- // unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("ifend");
- llvm::BasicBlock *ThenBlock = llvm::BasicBlock::Create("ifthen");
- llvm::BasicBlock *ElseBlock = ContBlock;
-
- if (S.getElse())
- ElseBlock = llvm::BasicBlock::Create("ifelse");
-
- // Insert the conditional branch.
- Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
-
- // Emit the 'then' code.
- EmitBlock(ThenBlock);
- EmitStmt(S.getThen());
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB)) {
- BB->eraseFromParent();
- Builder.SetInsertPoint(ThenBlock);
- } else {
- Builder.CreateBr(ContBlock);
- }
-
- // Emit the 'else' code if present.
- if (const Stmt *Else = S.getElse()) {
- EmitBlock(ElseBlock);
- EmitStmt(Else);
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB)) {
- BB->eraseFromParent();
- Builder.SetInsertPoint(ElseBlock);
- } else {
- Builder.CreateBr(ContBlock);
- }
- }
-
- // Emit the continuation block for code after the if.
- EmitBlock(ContBlock);
-}
-
-void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
- // Emit the header for the loop, insert it, which will create an uncond br to
- // it.
- llvm::BasicBlock *LoopHeader = llvm::BasicBlock::Create("whilecond");
- EmitBlock(LoopHeader);
-
- // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
- // of the controlling expression takes place before each execution of the loop
- // body.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- // while(1) is common, avoid extra exit blocks. Be sure
- // to correctly handle break/continue though.
- bool EmitBoolCondBranch = true;
- if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
- if (C->isOne())
- EmitBoolCondBranch = false;
-
- // Create an exit block for when the condition fails, create a block for the
- // body of the loop.
- llvm::BasicBlock *ExitBlock = llvm::BasicBlock::Create("whileexit");
- llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("whilebody");
-
- // As long as the condition is true, go to the loop body.
- if (EmitBoolCondBranch)
- Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
-
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
-
- // Emit the loop body.
- EmitBlock(LoopBody);
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- // Cycle to the condition.
- Builder.CreateBr(LoopHeader);
-
- // Emit the exit block.
- EmitBlock(ExitBlock);
-
- // If LoopHeader is a simple forwarding block then eliminate it.
- if (!EmitBoolCondBranch
- && &LoopHeader->front() == LoopHeader->getTerminator()) {
- LoopHeader->replaceAllUsesWith(LoopBody);
- LoopHeader->getTerminator()->eraseFromParent();
- LoopHeader->eraseFromParent();
- }
-}
-
-void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
- // Emit the body for the loop, insert it, which will create an uncond br to
- // it.
- llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("dobody");
- llvm::BasicBlock *AfterDo = llvm::BasicBlock::Create("afterdo");
- EmitBlock(LoopBody);
-
- llvm::BasicBlock *DoCond = llvm::BasicBlock::Create("docond");
-
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
-
- // Emit the body of the loop into the block.
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- EmitBlock(DoCond);
-
- // C99 6.8.5.2: "The evaluation of the controlling expression takes place
- // after each execution of the loop body."
-
- // Evaluate the conditional in the while header.
- // C99 6.8.5p2/p4: The first substatement is executed if the expression
- // compares unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- // "do {} while (0)" is common in macros, avoid extra blocks. Be sure
- // to correctly handle break/continue though.
- bool EmitBoolCondBranch = true;
- if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
- if (C->isZero())
- EmitBoolCondBranch = false;
-
- // As long as the condition is true, iterate the loop.
- if (EmitBoolCondBranch)
- Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
-
- // Emit the exit block.
- EmitBlock(AfterDo);
-
- // If DoCond is a simple forwarding block then eliminate it.
- if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) {
- DoCond->replaceAllUsesWith(AfterDo);
- DoCond->getTerminator()->eraseFromParent();
- DoCond->eraseFromParent();
- }
-}
-
-void CodeGenFunction::EmitForStmt(const ForStmt &S) {
- // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
- // which contains a continue/break?
- // TODO: We could keep track of whether the loop body contains any
- // break/continue statements and not create unnecessary blocks (like
- // "afterfor" for a condless loop) if it doesn't.
-
- // Evaluate the first part before the loop.
- if (S.getInit())
- EmitStmt(S.getInit());
-
- // Start the loop with a block that tests the condition.
- llvm::BasicBlock *CondBlock = llvm::BasicBlock::Create("forcond");
- llvm::BasicBlock *AfterFor = llvm::BasicBlock::Create("afterfor");
-
- EmitBlock(CondBlock);
-
- // Evaluate the condition if present. If not, treat it as a non-zero-constant
- // according to 6.8.5.3p2, aka, true.
- if (S.getCond()) {
- // C99 6.8.5p2/p4: The first substatement is executed if the expression
- // compares unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- // As long as the condition is true, iterate the loop.
- llvm::BasicBlock *ForBody = llvm::BasicBlock::Create("forbody");
- Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor);
- EmitBlock(ForBody);
- } else {
- // Treat it as a non-zero constant. Don't even create a new block for the
- // body, just fall into it.
- }
-
- // If the for loop doesn't have an increment we can just use the
- // condition as the continue block.
- llvm::BasicBlock *ContinueBlock;
- if (S.getInc())
- ContinueBlock = llvm::BasicBlock::Create("forinc");
- else
- ContinueBlock = CondBlock;
-
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));
-
- // If the condition is true, execute the body of the for stmt.
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- // If there is an increment, emit it next.
- if (S.getInc()) {
- EmitBlock(ContinueBlock);
- EmitStmt(S.getInc());
- }
-
- // Finally, branch back up to the condition for the next iteration.
- Builder.CreateBr(CondBlock);
-
- // Emit the fall-through block.
- EmitBlock(AfterFor);
-}
-
-void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
- if (RV.isScalar()) {
- Builder.CreateStore(RV.getScalarVal(), ReturnValue);
- } else if (RV.isAggregate()) {
- EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty);
- } else {
- StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false);
- }
- Builder.CreateBr(ReturnBlock);
-
- // Emit a block after the branch so that dead code after a return has some
- // place to go.
- EmitBlock(llvm::BasicBlock::Create());
-}
-
-/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
-/// if the function returns void, or may be missing one if the function returns
-/// non-void. Fun stuff :).
-void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
- // Emit the result value, even if unused, to evalute the side effects.
- const Expr *RV = S.getRetValue();
-
- // FIXME: Clean this up by using an LValue for ReturnTemp,
- // EmitStoreThroughLValue, and EmitAnyExpr.
- if (!ReturnValue) {
- // Make sure not to return anything, but evaluate the expression
- // for side effects.
- if (RV)
- EmitAnyExpr(RV);
- } else if (RV == 0) {
- // Do nothing (return value is left uninitialized)
- } else if (!hasAggregateLLVMType(RV->getType())) {
- Builder.CreateStore(EmitScalarExpr(RV), ReturnValue);
- } else if (RV->getType()->isAnyComplexType()) {
- EmitComplexExprIntoAddr(RV, ReturnValue, false);
- } else {
- EmitAggExpr(RV, ReturnValue, false);
- }
-
- if (!ObjCEHStack.empty()) {
- for (ObjCEHStackType::reverse_iterator i = ObjCEHStack.rbegin(),
- e = ObjCEHStack.rend(); i != e; ++i) {
- llvm::BasicBlock *ReturnPad = llvm::BasicBlock::Create("return.pad");
- EmitJumpThroughFinally(*i, ReturnPad);
- EmitBlock(ReturnPad);
- }
- }
-
- Builder.CreateBr(ReturnBlock);
-
- // Emit a block after the branch so that dead code after a return has some
- // place to go.
- EmitBlock(llvm::BasicBlock::Create());
-}
-
-void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
- for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end();
- I != E; ++I)
- EmitDecl(**I);
-}
-
-void CodeGenFunction::EmitBreakStmt() {
- assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
-
- llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
- Builder.CreateBr(Block);
- EmitBlock(llvm::BasicBlock::Create());
-}
-
-void CodeGenFunction::EmitContinueStmt() {
- assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
-
- llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
- Builder.CreateBr(Block);
- EmitBlock(llvm::BasicBlock::Create());
-}
-
-/// EmitCaseStmtRange - If case statement range is not too big then
-/// add multiple cases to switch instruction, one for each value within
-/// the range. If range is too big then emit "if" condition check.
-void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) {
- assert(S.getRHS() && "Expected RHS value in CaseStmt");
-
- llvm::APSInt LHS = S.getLHS()->getIntegerConstantExprValue(getContext());
- llvm::APSInt RHS = S.getRHS()->getIntegerConstantExprValue(getContext());
-
- // Emit the code for this case. We do this first to make sure it is
- // properly chained from our predecessor before generating the
- // switch machinery to enter this block.
- StartBlock("sw.bb");
- llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
- EmitStmt(S.getSubStmt());
-
- // If range is empty, do nothing.
- if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
- return;
-
- llvm::APInt Range = RHS - LHS;
- // FIXME: parameters such as this should not be hardcoded.
- if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
- // Range is small enough to add multiple switch instruction cases.
- for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) {
- SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest);
- LHS++;
- }
- return;
- }
-
- // The range is too big. Emit "if" condition into a new block,
- // making sure to save and restore the current insertion point.
- llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock();
-
- // Push this test onto the chain of range checks (which terminates
- // in the default basic block). The switch's default will be changed
- // to the top of this chain after switch emission is complete.
- llvm::BasicBlock *FalseDest = CaseRangeBlock;
- CaseRangeBlock = llvm::BasicBlock::Create("sw.caserange");
-
- CurFn->getBasicBlockList().push_back(CaseRangeBlock);
- Builder.SetInsertPoint(CaseRangeBlock);
-
- // Emit range check.
- llvm::Value *Diff =
- Builder.CreateSub(SwitchInsn->getCondition(), llvm::ConstantInt::get(LHS),
- "tmp");
- llvm::Value *Cond =
- Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp");
- Builder.CreateCondBr(Cond, CaseDest, FalseDest);
-
- // Restore the appropriate insertion point.
- Builder.SetInsertPoint(RestoreBB);
-}
-
-void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
- if (S.getRHS()) {
- EmitCaseStmtRange(S);
- return;
- }
-
- StartBlock("sw.bb");
- llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
- llvm::APSInt CaseVal = S.getLHS()->getIntegerConstantExprValue(getContext());
- SwitchInsn->addCase(llvm::ConstantInt::get(CaseVal),
- CaseDest);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
- llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
- assert(DefaultBlock->empty() && "EmitDefaultStmt: Default block already defined?");
- EmitBlock(DefaultBlock);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
- llvm::Value *CondV = EmitScalarExpr(S.getCond());
-
- // Handle nested switch statements.
- llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
- llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
-
- // Create basic block to hold stuff that comes after switch
- // statement. We also need to create a default block now so that
- // explicit case ranges tests can have a place to jump to on
- // failure.
- llvm::BasicBlock *NextBlock = llvm::BasicBlock::Create("sw.epilog");
- llvm::BasicBlock *DefaultBlock = llvm::BasicBlock::Create("sw.default");
- SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
- CaseRangeBlock = DefaultBlock;
-
- // Create basic block for body of switch
- StartBlock("sw.body");
-
- // All break statements jump to NextBlock. If BreakContinueStack is non empty
- // then reuse last ContinueBlock.
- llvm::BasicBlock *ContinueBlock = NULL;
- if (!BreakContinueStack.empty())
- ContinueBlock = BreakContinueStack.back().ContinueBlock;
- BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
-
- // Emit switch body.
- EmitStmt(S.getBody());
- BreakContinueStack.pop_back();
-
- // Update the default block in case explicit case range tests have
- // been chained on top.
- SwitchInsn->setSuccessor(0, CaseRangeBlock);
-
- // If a default was never emitted then reroute any jumps to it and
- // discard.
- if (!DefaultBlock->getParent()) {
- DefaultBlock->replaceAllUsesWith(NextBlock);
- delete DefaultBlock;
- }
-
- // Emit continuation.
- EmitBlock(NextBlock);
-
- SwitchInsn = SavedSwitchInsn;
- CaseRangeBlock = SavedCRBlock;
-}
-
-static std::string ConvertAsmString(const char *Start, unsigned NumOperands,
- bool IsSimple) {
- static unsigned AsmCounter = 0;
- AsmCounter++;
- std::string Result;
- if (IsSimple) {
- while (*Start) {
- switch (*Start) {
- default:
- Result += *Start;
- break;
- case '$':
- Result += "$$";
- break;
- }
- Start++;
- }
-
- return Result;
- }
-
- while (*Start) {
- switch (*Start) {
- default:
- Result += *Start;
- break;
- case '$':
- Result += "$$";
- break;
- case '%':
- // Escaped character
- Start++;
- if (!*Start) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Trailing '%' in asm string.");
- }
-
- char EscapedChar = *Start;
- if (EscapedChar == '%') {
- // Escaped percentage sign.
- Result += '%';
- } else if (EscapedChar == '=') {
- // Generate an unique ID.
- Result += llvm::utostr(AsmCounter);
- } else if (isdigit(EscapedChar)) {
- // %n - Assembler operand n
- char *End;
- unsigned long n = strtoul(Start, &End, 10);
- if (Start == End) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Missing operand!");
- } else if (n >= NumOperands) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Operand number out of range!");
- }
-
- Result += '$' + llvm::utostr(n);
- Start = End - 1;
- } else if (isalpha(EscapedChar)) {
- char *End;
-
- unsigned long n = strtoul(Start + 1, &End, 10);
- if (Start == End) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Missing operand!");
- } else if (n >= NumOperands) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Operand number out of range!");
- }
-
- Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}';
- Start = End - 1;
- } else {
- assert(0 && "Unhandled asm escaped character!");
- }
- }
- Start++;
- }
-
- return Result;
-}
-
-static std::string SimplifyConstraint(const char* Constraint,
- TargetInfo &Target) {
- std::string Result;
-
- while (*Constraint) {
- switch (*Constraint) {
- default:
- Result += Target.convertConstraint(*Constraint);
- break;
- // Ignore these
- case '*':
- case '?':
- case '!':
- break;
- case 'g':
- Result += "imr";
- break;
- }
-
- Constraint++;
- }
-
- return Result;
-}
-
-void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
- std::string AsmString =
- ConvertAsmString(std::string(S.getAsmString()->getStrData(),
- S.getAsmString()->getByteLength()).c_str(),
- S.getNumOutputs() + S.getNumInputs(), S.isSimple());
-
- std::string Constraints;
-
- llvm::Value *ResultAddr = 0;
- const llvm::Type *ResultType = llvm::Type::VoidTy;
-
- std::vector<const llvm::Type*> ArgTypes;
- std::vector<llvm::Value*> Args;
-
- // Keep track of inout constraints.
- std::string InOutConstraints;
- std::vector<llvm::Value*> InOutArgs;
- std::vector<const llvm::Type*> InOutArgTypes;
-
- for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
- std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(),
- S.getOutputConstraint(i)->getByteLength());
-
- TargetInfo::ConstraintInfo Info;
- bool result = Target.validateOutputConstraint(OutputConstraint.c_str(),
- Info);
- assert(result && "Failed to parse output constraint");
-
- // Simplify the output constraint.
- OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target);
-
- LValue Dest = EmitLValue(S.getOutputExpr(i));
- const llvm::Type *DestValueType =
- cast<llvm::PointerType>(Dest.getAddress()->getType())->getElementType();
-
- // If the first output operand is not a memory dest, we'll
- // make it the return value.
- if (i == 0 && !(Info & TargetInfo::CI_AllowsMemory) &&
- DestValueType->isSingleValueType()) {
- ResultAddr = Dest.getAddress();
- ResultType = DestValueType;
- Constraints += "=" + OutputConstraint;
- } else {
- ArgTypes.push_back(Dest.getAddress()->getType());
- Args.push_back(Dest.getAddress());
- if (i != 0)
- Constraints += ',';
- Constraints += "=*";
- Constraints += OutputConstraint;
- }
-
- if (Info & TargetInfo::CI_ReadWrite) {
- // FIXME: This code should be shared with the code that handles inputs.
- InOutConstraints += ',';
-
- const Expr *InputExpr = S.getOutputExpr(i);
- llvm::Value *Arg;
- if ((Info & TargetInfo::CI_AllowsRegister) ||
- !(Info & TargetInfo::CI_AllowsMemory)) {
- if (ConvertType(InputExpr->getType())->isSingleValueType()) {
- Arg = EmitScalarExpr(InputExpr);
- } else {
- ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs");
- }
- } else {
- LValue Dest = EmitLValue(InputExpr);
- Arg = Dest.getAddress();
- InOutConstraints += '*';
- }
-
- InOutArgTypes.push_back(Arg->getType());
- InOutArgs.push_back(Arg);
- InOutConstraints += OutputConstraint;
- }
- }
-
- unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs();
-
- for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
- const Expr *InputExpr = S.getInputExpr(i);
-
- std::string InputConstraint(S.getInputConstraint(i)->getStrData(),
- S.getInputConstraint(i)->getByteLength());
-
- TargetInfo::ConstraintInfo Info;
- bool result = Target.validateInputConstraint(InputConstraint.c_str(),
- NumConstraints,
- Info);
- assert(result && "Failed to parse input constraint");
-
- if (i != 0 || S.getNumOutputs() > 0)
- Constraints += ',';
-
- // Simplify the input constraint.
- InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target);
-
- llvm::Value *Arg;
-
- if ((Info & TargetInfo::CI_AllowsRegister) ||
- !(Info & TargetInfo::CI_AllowsMemory)) {
- if (ConvertType(InputExpr->getType())->isSingleValueType()) {
- Arg = EmitScalarExpr(InputExpr);
- } else {
- ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs");
- }
- } else {
- LValue Dest = EmitLValue(InputExpr);
- Arg = Dest.getAddress();
- Constraints += '*';
- }
-
- ArgTypes.push_back(Arg->getType());
- Args.push_back(Arg);
- Constraints += InputConstraint;
- }
-
- // Append the "input" part of inout constraints last.
- for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
- ArgTypes.push_back(InOutArgTypes[i]);
- Args.push_back(InOutArgs[i]);
- }
- Constraints += InOutConstraints;
-
- // Clobbers
- for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
- std::string Clobber(S.getClobber(i)->getStrData(),
- S.getClobber(i)->getByteLength());
-
- Clobber = Target.getNormalizedGCCRegisterName(Clobber.c_str());
-
- if (i != 0 || NumConstraints != 0)
- Constraints += ',';
-
- Constraints += "~{";
- Constraints += Clobber;
- Constraints += '}';
- }
-
- // Add machine specific clobbers
- if (const char *C = Target.getClobbers()) {
- if (!Constraints.empty())
- Constraints += ',';
- Constraints += C;
- }
-
- const llvm::FunctionType *FTy =
- llvm::FunctionType::get(ResultType, ArgTypes, false);
-
- llvm::InlineAsm *IA =
- llvm::InlineAsm::get(FTy, AsmString, Constraints,
- S.isVolatile() || S.getNumOutputs() == 0);
- llvm::Value *Result = Builder.CreateCall(IA, Args.begin(), Args.end(), "");
- if (ResultAddr) // FIXME: volatility
- Builder.CreateStore(Result, ResultAddr);
-}
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
deleted file mode 100644
index fae473f8666f..000000000000
--- a/clang/lib/CodeGen/CGValue.h
+++ /dev/null
@@ -1,235 +0,0 @@
-//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// These classes implement wrappers around llvm::Value in order to
-// fully represent the range of values for C L- and R- values.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CGVALUE_H
-#define CLANG_CODEGEN_CGVALUE_H
-
-#include "clang/AST/Type.h"
-
-namespace llvm {
- class Constant;
- class Value;
-}
-
-namespace clang {
- class ObjCPropertyRefExpr;
-
-namespace CodeGen {
-
-/// RValue - This trivial value class is used to represent the result of an
-/// expression that is evaluated. It can be one of three things: either a
-/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
-/// address of an aggregate value in memory.
-class RValue {
- llvm::Value *V1, *V2;
- // TODO: Encode this into the low bit of pointer for more efficient
- // return-by-value.
- enum { Scalar, Complex, Aggregate } Flavor;
-
- // FIXME: Aggregate rvalues need to retain information about whether they are
- // volatile or not.
-public:
-
- bool isScalar() const { return Flavor == Scalar; }
- bool isComplex() const { return Flavor == Complex; }
- bool isAggregate() const { return Flavor == Aggregate; }
-
- /// getScalar() - Return the Value* of this scalar value.
- llvm::Value *getScalarVal() const {
- assert(isScalar() && "Not a scalar!");
- return V1;
- }
-
- /// getComplexVal - Return the real/imag components of this complex value.
- ///
- std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
- return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
- }
-
- /// getAggregateAddr() - Return the Value* of the address of the aggregate.
- llvm::Value *getAggregateAddr() const {
- assert(isAggregate() && "Not an aggregate!");
- return V1;
- }
-
- static RValue get(llvm::Value *V) {
- RValue ER;
- ER.V1 = V;
- ER.Flavor = Scalar;
- return ER;
- }
- static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
- RValue ER;
- ER.V1 = V1;
- ER.V2 = V2;
- ER.Flavor = Complex;
- return ER;
- }
- static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
- RValue ER;
- ER.V1 = C.first;
- ER.V2 = C.second;
- ER.Flavor = Complex;
- return ER;
- }
- static RValue getAggregate(llvm::Value *V) {
- RValue ER;
- ER.V1 = V;
- ER.Flavor = Aggregate;
- return ER;
- }
-};
-
-
-/// LValue - This represents an lvalue references. Because C/C++ allow
-/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
-/// bitrange.
-class LValue {
- // FIXME: alignment?
-
- enum {
- Simple, // This is a normal l-value, use getAddress().
- VectorElt, // This is a vector element l-value (V[i]), use getVector*
- BitField, // This is a bitfield l-value, use getBitfield*.
- ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
- PropertyRef // This is an Objective-C property reference, use
- // getPropertyRefExpr
- } LVType;
-
- llvm::Value *V;
-
- union {
- // Index into a vector subscript: V[i]
- llvm::Value *VectorIdx;
-
- // ExtVector element subset: V.xyx
- llvm::Constant *VectorElts;
-
- // BitField start bit and size
- struct {
- unsigned short StartBit;
- unsigned short Size;
- bool IsSigned;
- } BitfieldData;
-
- // Obj-C property reference expression
- const ObjCPropertyRefExpr *PropertyRefExpr;
- };
-
- bool Volatile:1;
- // FIXME: set but never used, what effect should it have?
- bool Restrict:1;
-
-private:
- static void SetQualifiers(unsigned Qualifiers, LValue& R) {
- R.Volatile = (Qualifiers&QualType::Volatile)!=0;
- R.Restrict = (Qualifiers&QualType::Restrict)!=0;
- }
-
-public:
- bool isSimple() const { return LVType == Simple; }
- bool isVectorElt() const { return LVType == VectorElt; }
- bool isBitfield() const { return LVType == BitField; }
- bool isExtVectorElt() const { return LVType == ExtVectorElt; }
- bool isPropertyRef() const { return LVType == PropertyRef; }
-
- bool isVolatileQualified() const { return Volatile; }
- bool isRestrictQualified() const { return Restrict; }
-
- // simple lvalue
- llvm::Value *getAddress() const { assert(isSimple()); return V; }
- // vector elt lvalue
- llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
- llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
- // extended vector elements.
- llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
- llvm::Constant *getExtVectorElts() const {
- assert(isExtVectorElt());
- return VectorElts;
- }
- // bitfield lvalue
- llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
- unsigned short getBitfieldStartBit() const {
- assert(isBitfield());
- return BitfieldData.StartBit;
- }
- unsigned short getBitfieldSize() const {
- assert(isBitfield());
- return BitfieldData.Size;
- }
- bool isBitfieldSigned() const {
- assert(isBitfield());
- return BitfieldData.IsSigned;
- }
- // property ref lvalue
- const ObjCPropertyRefExpr *getPropertyRefExpr() const {
- assert(isPropertyRef());
- return PropertyRefExpr;
- }
-
- static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers) {
- LValue R;
- R.LVType = Simple;
- R.V = V;
- SetQualifiers(Qualifiers,R);
- return R;
- }
-
- static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
- unsigned Qualifiers) {
- LValue R;
- R.LVType = VectorElt;
- R.V = Vec;
- R.VectorIdx = Idx;
- SetQualifiers(Qualifiers,R);
- return R;
- }
-
- static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
- unsigned Qualifiers) {
- LValue R;
- R.LVType = ExtVectorElt;
- R.V = Vec;
- R.VectorElts = Elts;
- SetQualifiers(Qualifiers,R);
- return R;
- }
-
- static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
- unsigned short Size, bool IsSigned,
- unsigned Qualifiers) {
- LValue R;
- R.LVType = BitField;
- R.V = V;
- R.BitfieldData.StartBit = StartBit;
- R.BitfieldData.Size = Size;
- R.BitfieldData.IsSigned = IsSigned;
- SetQualifiers(Qualifiers,R);
- return R;
- }
-
- static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
- unsigned Qualifiers) {
- LValue R;
- R.LVType = PropertyRef;
- R.PropertyRefExpr = E;
- SetQualifiers(Qualifiers,R);
- return R;
- }
-};
-
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
deleted file mode 100644
index b182ecf055f8..000000000000
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This coordinates the per-function state used while generating code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "CGDebugInfo.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Support/CFG.h"
-using namespace clang;
-using namespace CodeGen;
-
-CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
- : CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
- CaseRangeBlock(NULL) {
- LLVMIntTy = ConvertType(getContext().IntTy);
- LLVMPointerWidth = Target.getPointerWidth(0);
-}
-
-ASTContext &CodeGenFunction::getContext() const {
- return CGM.getContext();
-}
-
-
-llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
- llvm::BasicBlock *&BB = LabelMap[S];
- if (BB) return BB;
-
- // Create, but don't insert, the new block.
- return BB = llvm::BasicBlock::Create(S->getName());
-}
-
-llvm::Constant *
-CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
- return cast<llvm::Constant>(LocalDeclMap[BVD]);
-}
-
-llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD)
-{
- return LocalDeclMap[VD];
-}
-
-const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
- return CGM.getTypes().ConvertType(T);
-}
-
-bool CodeGenFunction::isObjCPointerType(QualType T) {
- // All Objective-C types are pointers.
- return T->isObjCInterfaceType() ||
- T->isObjCQualifiedInterfaceType() || T->isObjCQualifiedIdType();
-}
-
-bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
- return !isObjCPointerType(T) &&!T->isRealType() && !T->isPointerLikeType() &&
- !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
-}
-
-void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
- // Finish emission of indirect switches.
- EmitIndirectSwitches();
-
- // Emit debug descriptor for function end.
- if (CGDebugInfo *DI = CGM.getDebugInfo()) {
- if (EndLoc.isValid()) {
- DI->setLocation(EndLoc);
- }
- DI->EmitRegionEnd(CurFn, Builder);
- }
-
- assert(BreakContinueStack.empty() &&
- "mismatched push/pop in break/continue stack!");
-
- // Emit function epilog (to return). This has the nice side effect
- // of also automatically handling code that falls off the end.
- EmitBlock(ReturnBlock);
- EmitFunctionEpilog(FnRetTy, ReturnValue);
-
- // Remove the AllocaInsertPt instruction, which is just a convenience for us.
- AllocaInsertPt->eraseFromParent();
- AllocaInsertPt = 0;
-
- // Verify that the function is well formed.
- if (verifyFunction(*CurFn, llvm::PrintMessageAction)) {
- CurFn->dump();
- assert(0 && "Function failed verification!");
- }
-}
-
-void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy,
- llvm::Function *Fn,
- const FunctionArgList &Args) {
- CurFuncDecl = D;
- FnRetTy = RetTy;
- CurFn = Fn;
- assert(CurFn->isDeclaration() && "Function already has body?");
-
- llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
-
- // Create a marker to make it easy to insert allocas into the entryblock
- // later. Don't create this with the builder, because we don't want it
- // folded.
- llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
- AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
- EntryBB);
-
- ReturnBlock = llvm::BasicBlock::Create("return");
- ReturnValue = 0;
- if (!RetTy->isVoidType())
- ReturnValue = CreateTempAlloca(ConvertType(RetTy), "retval");
-
- Builder.SetInsertPoint(EntryBB);
-
- // Emit subprogram debug descriptor.
- // FIXME: The cast here is a huge hack.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (CGDebugInfo *DI = CGM.getDebugInfo()) {
- CompoundStmt* body = dyn_cast<CompoundStmt>(FD->getBody());
- if (body && body->getLBracLoc().isValid()) {
- DI->setLocation(body->getLBracLoc());
- }
- DI->EmitFunctionStart(FD, CurFn, Builder);
- }
- }
-
- EmitFunctionProlog(CurFn, FnRetTy, Args);
-}
-
-void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
- llvm::Function *Fn) {
- FunctionArgList Args;
- if (FD->getNumParams()) {
- const FunctionTypeProto* FProto = FD->getType()->getAsFunctionTypeProto();
- assert(FProto && "Function def must have prototype!");
-
- for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
- Args.push_back(std::make_pair(FD->getParamDecl(i),
- FProto->getArgType(i)));
- }
-
- StartFunction(FD, FD->getResultType(), Fn, Args);
-
- EmitStmt(FD->getBody());
-
- const CompoundStmt *S = dyn_cast<CompoundStmt>(FD->getBody());
- if (S) {
- FinishFunction(S->getRBracLoc());
- } else {
- FinishFunction();
- }
-}
-
-/// isDummyBlock - Return true if BB is an empty basic block
-/// with no predecessors.
-bool CodeGenFunction::isDummyBlock(const llvm::BasicBlock *BB) {
- if (BB->empty() && pred_begin(BB) == pred_end(BB) && !BB->hasName())
- return true;
- return false;
-}
-
-/// StartBlock - Start new block named N. If insert block is a dummy block
-/// then reuse it.
-void CodeGenFunction::StartBlock(const char *N) {
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (!isDummyBlock(BB))
- EmitBlock(llvm::BasicBlock::Create(N));
- else
- BB->setName(N);
-}
-
-/// getCGRecordLayout - Return record layout info.
-const CGRecordLayout *CodeGenFunction::getCGRecordLayout(CodeGenTypes &CGT,
- QualType Ty) {
- const RecordType *RTy = Ty->getAsRecordType();
- assert (RTy && "Unexpected type. RecordType expected here.");
-
- return CGT.getCGRecordLayout(RTy->getDecl());
-}
-
-/// ErrorUnsupported - Print out an error that codegen doesn't support the
-/// specified stmt yet.
-void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
- bool OmitOnError) {
- CGM.ErrorUnsupported(S, Type, OmitOnError);
-}
-
-unsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) {
- // Use LabelIDs.size() as the new ID if one hasn't been assigned.
- return LabelIDs.insert(std::make_pair(L, LabelIDs.size())).first->second;
-}
-
-void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty)
-{
- const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- if (DestPtr->getType() != BP)
- DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
-
- // Get size and alignment info for this aggregate.
- std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
-
- Builder.CreateCall4(CGM.getMemSetFn(), DestPtr,
- llvm::ConstantInt::getNullValue(llvm::Type::Int8Ty),
- // TypeInfo.first describes size in bits.
- llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
- llvm::ConstantInt::get(llvm::Type::Int32Ty,
- TypeInfo.second/8));
-}
-
-void CodeGenFunction::EmitIndirectSwitches() {
- llvm::BasicBlock *Default;
-
- if (IndirectSwitches.empty())
- return;
-
- if (!LabelIDs.empty()) {
- Default = getBasicBlockForLabel(LabelIDs.begin()->first);
- } else {
- // No possible targets for indirect goto, just emit an infinite
- // loop.
- Default = llvm::BasicBlock::Create("indirectgoto.loop", CurFn);
- llvm::BranchInst::Create(Default, Default);
- }
-
- for (std::vector<llvm::SwitchInst*>::iterator i = IndirectSwitches.begin(),
- e = IndirectSwitches.end(); i != e; ++i) {
- llvm::SwitchInst *I = *i;
-
- I->setSuccessor(0, Default);
- for (std::map<const LabelStmt*,unsigned>::iterator LI = LabelIDs.begin(),
- LE = LabelIDs.end(); LI != LE; ++LI) {
- I->addCase(llvm::ConstantInt::get(llvm::Type::Int32Ty,
- LI->second),
- getBasicBlockForLabel(LI->first));
- }
- }
-}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
deleted file mode 100644
index 8058c342e7a4..000000000000
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ /dev/null
@@ -1,518 +0,0 @@
-//===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the internal per-function state used for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENFUNCTION_H
-#define CLANG_CODEGEN_CODEGENFUNCTION_H
-
-#include "clang/AST/Type.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/IRBuilder.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-
-#include <vector>
-#include <map>
-
-#include "CGCall.h"
-#include "CGValue.h"
-
-namespace llvm {
- class BasicBlock;
- class Module;
- class SwitchInst;
-}
-
-namespace clang {
- class ASTContext;
- class Decl;
- class EnumConstantDecl;
- class FunctionDecl;
- class FunctionTypeProto;
- class LabelStmt;
- class ObjCInterfaceDecl;
- class ObjCIvarDecl;
- class ObjCMethodDecl;
- class ObjCPropertyImplDecl;
- class TargetInfo;
- class VarDecl;
-
-namespace CodeGen {
- class CodeGenModule;
- class CodeGenTypes;
- class CGRecordLayout;
-
-/// CodeGenFunction - This class organizes the per-function state that is used
-/// while generating LLVM code.
-class CodeGenFunction {
-public:
- CodeGenModule &CGM; // Per-module state.
- TargetInfo &Target;
-
- typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
- llvm::IRBuilder<> Builder;
-
- // Holds the Decl for the current function or method
- const Decl *CurFuncDecl;
- QualType FnRetTy;
- llvm::Function *CurFn;
-
- /// ReturnBlock - Unified return block.
- llvm::BasicBlock *ReturnBlock;
- /// ReturnValue - The temporary alloca to hold the return value. This
- /// is null iff the function has no return value.
- llvm::Instruction *ReturnValue;
-
- /// AllocaInsertPoint - This is an instruction in the entry block before which
- /// we prefer to insert allocas.
- llvm::Instruction *AllocaInsertPt;
-
- const llvm::Type *LLVMIntTy;
- uint32_t LLVMPointerWidth;
-
-public:
- // FIXME: The following should be private once EH code is moved out
- // of NeXT runtime.
-
- // ObjCEHStack - This keeps track of which object to rethrow from
- // inside @catch blocks and which @finally block exits from an EH
- // scope should be chained through.
- struct ObjCEHEntry {
- ObjCEHEntry(llvm::BasicBlock *fb, llvm::BasicBlock *fne,
- llvm::SwitchInst *fs, llvm::Value *dc)
- : FinallyBlock(fb), FinallyNoExit(fne), FinallySwitch(fs),
- DestCode(dc), Exception(0) {}
-
- /// Entry point to the finally block.
- llvm::BasicBlock *FinallyBlock;
-
- /// Entry point to the finally block which skips execution of the
- /// try_exit runtime function.
- llvm::BasicBlock *FinallyNoExit;
-
- /// Switch instruction which runs at the end of the finally block
- /// to forward jumps through the finally block.
- llvm::SwitchInst *FinallySwitch;
-
- /// Variable holding the code for the destination of a jump
- /// through the @finally block.
- llvm::Value *DestCode;
-
- /// The exception object being handled, during IR generation for a
- /// @catch block.
- llvm::Value *Exception;
- };
-
- typedef llvm::SmallVector<ObjCEHEntry*, 8> ObjCEHStackType;
- ObjCEHStackType ObjCEHStack;
-
- /// EmitJumpThroughFinally - Emit a branch from the current insert
- /// point through the finally handling code for \arg Entry and then
- /// on to \arg Dest.
- ///
- /// \param ExecuteTryExit - When true, the try_exit runtime function
- /// should be called prior to executing the finally code.
- void EmitJumpThroughFinally(ObjCEHEntry *Entry, llvm::BasicBlock *Dest,
- bool ExecuteTryExit=true);
-
-private:
- /// LabelIDs - Track arbitrary ids assigned to labels for use in
- /// implementing the GCC address-of-label extension and indirect
- /// goto. IDs are assigned to labels inside getIDForAddrOfLabel().
- std::map<const LabelStmt*, unsigned> LabelIDs;
-
- /// IndirectSwitches - Record the list of switches for indirect
- /// gotos. Emission of the actual switching code needs to be delayed
- /// until all AddrLabelExprs have been seen.
- std::vector<llvm::SwitchInst*> IndirectSwitches;
-
- /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
- /// decls.
- llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
-
- /// LabelMap - This keeps track of the LLVM basic block for each C label.
- llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
-
- // BreakContinueStack - This keeps track of where break and continue
- // statements should jump to.
- struct BreakContinue {
- BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb)
- : BreakBlock(bb), ContinueBlock(cb) {}
-
- llvm::BasicBlock *BreakBlock;
- llvm::BasicBlock *ContinueBlock;
- };
- llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
-
- /// SwitchInsn - This is nearest current switch instruction. It is null if
- /// if current context is not in a switch.
- llvm::SwitchInst *SwitchInsn;
-
- /// CaseRangeBlock - This block holds if condition check for last case
- /// statement range in current switch instruction.
- llvm::BasicBlock *CaseRangeBlock;
-
-public:
- CodeGenFunction(CodeGenModule &cgm);
-
- ASTContext &getContext() const;
-
- void GenerateObjCMethod(const ObjCMethodDecl *OMD);
-
- void StartObjCMethod(const ObjCMethodDecl *MD);
-
- /// GenerateObjCGetter - Synthesize an Objective-C property getter
- /// function.
- void GenerateObjCGetter(const ObjCPropertyImplDecl *PID);
-
- /// GenerateObjCSetter - Synthesize an Objective-C property setter
- /// function for the given property.
- void GenerateObjCSetter(const ObjCPropertyImplDecl *PID);
-
- void GenerateCode(const FunctionDecl *FD,
- llvm::Function *Fn);
- void StartFunction(const Decl *D, QualType RetTy,
- llvm::Function *Fn,
- const FunctionArgList &Args);
- void FinishFunction(SourceLocation EndLoc=SourceLocation());
-
- /// EmitFunctionProlog - Emit the target specific LLVM code to load
- /// the arguments for the given function. This is also responsible
- /// for naming the LLVM function arguments.
- void EmitFunctionProlog(llvm::Function *Fn, QualType RetTy,
- const FunctionArgList &Args);
-
- /// EmitFunctionEpilog - Emit the target specific LLVM code to
- /// return the given temporary.
- void EmitFunctionEpilog(QualType RetTy,
- llvm::Value *ReturnValue);
-
- const llvm::Type *ConvertType(QualType T);
-
- /// LoadObjCSelf - Load the value of self. This function is only
- /// valid while generating code for an Objective-C method.
- llvm::Value *LoadObjCSelf();
-
- /// isObjCPointerType - Return true if the specificed AST type will map onto
- /// some Objective-C pointer type.
- static bool isObjCPointerType(QualType T);
-
- /// hasAggregateLLVMType - Return true if the specified AST type will map into
- /// an aggregate LLVM type or is void.
- static bool hasAggregateLLVMType(QualType T);
-
- /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
- /// label maps to.
- llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
-
-
- void EmitBlock(llvm::BasicBlock *BB);
-
- /// ErrorUnsupported - Print out an error that codegen doesn't support the
- /// specified stmt yet.
- void ErrorUnsupported(const Stmt *S, const char *Type,
- bool OmitOnError=false);
-
- //===--------------------------------------------------------------------===//
- // Helpers
- //===--------------------------------------------------------------------===//
-
- /// CreateTempAlloca - This creates a alloca and inserts it into the entry
- /// block.
- llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty,
- const char *Name = "tmp");
-
- /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
- /// expression and compare the result against zero, returning an Int1Ty value.
- llvm::Value *EvaluateExprAsBool(const Expr *E);
-
- /// EmitAnyExpr - Emit code to compute the specified expression which can have
- /// any type. The result is returned as an RValue struct. If this is an
- /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
- /// the result should be returned.
- RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0,
- bool isAggLocVolatile = false);
-
- /// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result
- /// will always be accessible even if no aggregate location is
- /// provided.
- RValue EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc = 0,
- bool isAggLocVolatile = false);
-
- void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
- QualType EltTy);
-
- void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
-
- /// isDummyBlock - Return true if BB is an empty basic block
- /// with no predecessors.
- static bool isDummyBlock(const llvm::BasicBlock *BB);
-
- /// StartBlock - Start new block named N. If insert block is a dummy block
- /// then reuse it.
- void StartBlock(const char *N);
-
- /// getCGRecordLayout - Return record layout info.
- const CGRecordLayout *getCGRecordLayout(CodeGenTypes &CGT, QualType RTy);
-
- /// GetAddrOfStaticLocalVar - Return the address of a static local variable.
- llvm::Constant *GetAddrOfStaticLocalVar(const VarDecl *BVD);
-
- /// GetAddrOfLocalVar - Return the address of a local variable.
- llvm::Value *GetAddrOfLocalVar(const VarDecl *VD);
-
- /// getAccessedFieldNo - Given an encoded value and a result number, return
- /// the input field number being accessed.
- static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
-
- unsigned GetIDForAddrOfLabel(const LabelStmt *L);
-
- /// EmitMemSetToZero - Generate code to memset a value of the given type to 0;
- void EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty);
-
- //===--------------------------------------------------------------------===//
- // Declaration Emission
- //===--------------------------------------------------------------------===//
-
- void EmitDecl(const Decl &D);
- void EmitBlockVarDecl(const VarDecl &D);
- void EmitLocalBlockVarDecl(const VarDecl &D);
- void EmitStaticBlockVarDecl(const VarDecl &D);
-
- /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
- void EmitParmDecl(const VarDecl &D, llvm::Value *Arg);
-
- //===--------------------------------------------------------------------===//
- // Statement Emission
- //===--------------------------------------------------------------------===//
-
- void EmitStmt(const Stmt *S);
- RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
- llvm::Value *AggLoc = 0, bool isAggVol = false);
- void EmitLabel(const LabelStmt &S); // helper for EmitLabelStmt.
- void EmitLabelStmt(const LabelStmt &S);
- void EmitGotoStmt(const GotoStmt &S);
- void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
- void EmitIfStmt(const IfStmt &S);
- void EmitWhileStmt(const WhileStmt &S);
- void EmitDoStmt(const DoStmt &S);
- void EmitForStmt(const ForStmt &S);
- void EmitReturnStmt(const ReturnStmt &S);
- void EmitDeclStmt(const DeclStmt &S);
- void EmitBreakStmt();
- void EmitContinueStmt();
- void EmitSwitchStmt(const SwitchStmt &S);
- void EmitDefaultStmt(const DefaultStmt &S);
- void EmitCaseStmt(const CaseStmt &S);
- void EmitCaseStmtRange(const CaseStmt &S);
- void EmitAsmStmt(const AsmStmt &S);
-
- void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
- void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);
- void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
-
- //===--------------------------------------------------------------------===//
- // LValue Expression Emission
- //===--------------------------------------------------------------------===//
-
- /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E
- /// and issue an ErrorUnsupported style diagnostic (using the
- /// provided Name).
- LValue EmitUnsupportedLValue(const Expr *E,
- const char *Name);
-
- /// EmitLValue - Emit code to compute a designator that specifies the location
- /// of the expression.
- ///
- /// This can return one of two things: a simple address or a bitfield
- /// reference. In either case, the LLVM Value* in the LValue structure is
- /// guaranteed to be an LLVM pointer type.
- ///
- /// If this returns a bitfield reference, nothing about the pointee type of
- /// the LLVM value is known: For example, it may not be a pointer to an
- /// integer.
- ///
- /// If this returns a normal address, and if the lvalue's C type is fixed
- /// size, this method guarantees that the returned pointer type will point to
- /// an LLVM type of the same size of the lvalue's type. If the lvalue has a
- /// variable length type, this is not possible.
- ///
- LValue EmitLValue(const Expr *E);
-
- /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
- /// this method emits the address of the lvalue, then loads the result as an
- /// rvalue, returning the rvalue.
- RValue EmitLoadOfLValue(LValue V, QualType LVType);
- RValue EmitLoadOfExtVectorElementLValue(LValue V, QualType LVType);
- RValue EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType);
- RValue EmitLoadOfPropertyRefLValue(LValue LV, QualType ExprType);
-
-
- /// EmitStoreThroughLValue - Store the specified rvalue into the specified
- /// lvalue, where both are guaranteed to the have the same type, and that type
- /// is 'Ty'.
- void EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty);
- void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst,
- QualType Ty);
- void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty);
- void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst, QualType Ty);
-
- // Note: only availabe for agg return types
- LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
- // Note: only availabe for agg return types
- LValue EmitCallExprLValue(const CallExpr *E);
-
- LValue EmitDeclRefLValue(const DeclRefExpr *E);
- LValue EmitStringLiteralLValue(const StringLiteral *E);
- LValue EmitPredefinedLValue(const PredefinedExpr *E);
- LValue EmitUnaryOpLValue(const UnaryOperator *E);
- LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E);
- LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E);
- LValue EmitMemberExpr(const MemberExpr *E);
- LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
-
- llvm::Value *EmitIvarOffset(ObjCInterfaceDecl *Interface,
- const ObjCIvarDecl *Ivar);
- LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field,
- bool isUnion, unsigned CVRQualifiers);
- LValue EmitLValueForIvar(llvm::Value* Base, const ObjCIvarDecl *Ivar,
- unsigned CVRQualifiers);
-
- LValue EmitCXXConditionDeclLValue(const CXXConditionDeclExpr *E);
-
- LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
- LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
- LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E);
-
- //===--------------------------------------------------------------------===//
- // Scalar Expression Emission
- //===--------------------------------------------------------------------===//
-
- /// EmitCall - Generate a call of the given function, expecting the
- /// given result type, and using the given argument list which
- /// specifies both the LLVM arguments and the types they were
- /// derived from.
- RValue EmitCall(llvm::Value *Callee,
- QualType ResultType,
- const CallArgList &Args);
-
- RValue EmitCallExpr(const CallExpr *E);
-
- RValue EmitCallExpr(Expr *FnExpr, CallExpr::const_arg_iterator ArgBeg,
- CallExpr::const_arg_iterator ArgEnd);
-
- RValue EmitCallExpr(llvm::Value *Callee, QualType FnType,
- CallExpr::const_arg_iterator ArgBeg,
- CallExpr::const_arg_iterator ArgEnd);
-
- RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
-
- llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
- llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
-
- llvm::Value *EmitShuffleVector(llvm::Value* V1, llvm::Value *V2, ...);
- llvm::Value *EmitVector(llvm::Value * const *Vals, unsigned NumVals,
- bool isSplat = false);
-
- llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
- llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
- llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
- RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
- RValue EmitObjCPropertyGet(const ObjCPropertyRefExpr *E);
- void EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src);
-
-
- //===--------------------------------------------------------------------===//
- // Expression Emission
- //===--------------------------------------------------------------------===//
-
- // Expressions are broken into three classes: scalar, complex, aggregate.
-
- /// EmitScalarExpr - Emit the computation of the specified expression of
- /// LLVM scalar type, returning the result.
- llvm::Value *EmitScalarExpr(const Expr *E);
-
- /// EmitScalarConversion - Emit a conversion from the specified type to the
- /// specified destination type, both of which are LLVM scalar types.
- llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
- QualType DstTy);
-
- /// EmitComplexToScalarConversion - Emit a conversion from the specified
- /// complex type to the specified destination type, where the destination
- /// type is an LLVM scalar type.
- llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
- QualType DstTy);
-
-
- /// EmitAggExpr - Emit the computation of the specified expression of
- /// aggregate type. The result is computed into DestPtr. Note that if
- /// DestPtr is null, the value of the aggregate expression is not needed.
- void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest);
-
- /// EmitComplexExpr - Emit the computation of the specified expression of
- /// complex type, returning the result.
- ComplexPairTy EmitComplexExpr(const Expr *E);
-
- /// EmitComplexExprIntoAddr - Emit the computation of the specified expression
- /// of complex type, storing into the specified Value*.
- void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr,
- bool DestIsVolatile);
-
- /// StoreComplexToAddr - Store a complex number into the specified address.
- void StoreComplexToAddr(ComplexPairTy V, llvm::Value *DestAddr,
- bool DestIsVolatile);
- /// LoadComplexFromAddr - Load a complex number from the specified address.
- ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile);
-
- /// GenerateStaticBlockVarDecl - return the the static
- /// declaration of local variable.
- llvm::GlobalValue *GenerateStaticBlockVarDecl(const VarDecl &D,
- bool NoInit,
- const char *Separator);
-
- // GenerateStaticBlockVarDecl - return the static declaration of
- // a local variable. Performs initialization of the variable if necessary.
- llvm::GlobalValue *GenerateStaticCXXBlockVarDecl(const VarDecl &D);
-
- //===--------------------------------------------------------------------===//
- // Internal Helpers
- //===--------------------------------------------------------------------===//
-
-private:
- /// EmitIndirectSwitches - Emit code for all of the switch
- /// instructions in IndirectSwitches.
- void EmitIndirectSwitches();
-
- void EmitReturnOfRValue(RValue RV, QualType Ty);
-
- /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
- /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
- ///
- /// \param AI - The first function argument of the expansion.
- /// \return The argument following the last expanded function
- /// argument.
- llvm::Function::arg_iterator
- ExpandTypeFromArgs(QualType Ty, LValue Dst,
- llvm::Function::arg_iterator AI);
-
- /// ExpandTypeToArgs - Expand an RValue \arg Src, with the LLVM type
- /// for \arg Ty, into individual arguments on the provided vector
- /// \arg Args. See ABIArgInfo::Expand.
- void ExpandTypeToArgs(QualType Ty, RValue Src,
- llvm::SmallVector<llvm::Value*, 16> &Args);
-};
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
deleted file mode 100644
index a74f0578a5b9..000000000000
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ /dev/null
@@ -1,1044 +0,0 @@
-//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This coordinates the per-module state used while generating code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGDebugInfo.h"
-#include "CodeGenModule.h"
-#include "CodeGenFunction.h"
-#include "CGCall.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Module.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Analysis/Verifier.h"
-using namespace clang;
-using namespace CodeGen;
-
-
-CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
- llvm::Module &M, const llvm::TargetData &TD,
- Diagnostic &diags, bool GenerateDebugInfo)
- : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
- Types(C, M, TD), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0),
- CFConstantStringClassRef(0) {
-
- if (Features.ObjC1) {
- if (Features.NeXTRuntime) {
- Runtime = CreateMacObjCRuntime(*this);
- } else {
- Runtime = CreateGNUObjCRuntime(*this);
- }
- }
-
- // If debug info generation is enabled, create the CGDebugInfo object.
- DebugInfo = GenerateDebugInfo ? new CGDebugInfo(this) : 0;
-}
-
-CodeGenModule::~CodeGenModule() {
- delete Runtime;
- delete DebugInfo;
-}
-
-void CodeGenModule::Release() {
- EmitStatics();
- EmitAliases();
- if (Runtime)
- if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
- AddGlobalCtor(ObjCInitFunction);
- EmitCtorList(GlobalCtors, "llvm.global_ctors");
- EmitCtorList(GlobalDtors, "llvm.global_dtors");
- EmitAnnotations();
- BindRuntimeFunctions();
- // Run the verifier to check that the generated code is consistent.
- if (verifyModule(TheModule, llvm::PrintMessageAction)) {
- TheModule.dump();
- assert(0 && "Module failed verification!");
- }
-}
-
-void CodeGenModule::BindRuntimeFunctions() {
- // Deal with protecting runtime function names.
- for (unsigned i = 0, e = RuntimeFunctions.size(); i < e; ++i) {
- llvm::Function *Fn = RuntimeFunctions[i].first;
- const std::string &Name = RuntimeFunctions[i].second;
-
- // See if there is a conflict against a function.
- llvm::Function *Conflict = TheModule.getFunction(Name);
- if (Conflict) {
- // Decide which version to take. If the conflict is a definition
- // we are forced to take that, otherwise assume the runtime
- // knows best.
- if (!Conflict->isDeclaration()) {
- llvm::Value *Casted =
- llvm::ConstantExpr::getBitCast(Conflict, Fn->getType());
- Fn->replaceAllUsesWith(Casted);
- Fn->eraseFromParent();
- } else {
- Fn->takeName(Conflict);
- llvm::Value *Casted =
- llvm::ConstantExpr::getBitCast(Fn, Conflict->getType());
- Conflict->replaceAllUsesWith(Casted);
- Conflict->eraseFromParent();
- }
- } else {
- // FIXME: There still may be conflicts with aliases and
- // variables.
- Fn->setName(Name);
- }
- }
-}
-
-/// ErrorUnsupported - Print out an error that codegen doesn't support the
-/// specified stmt yet.
-void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
- bool OmitOnError) {
- if (OmitOnError && getDiags().hasErrorOccurred())
- return;
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
- "cannot codegen this %0 yet");
- SourceRange Range = S->getSourceRange();
- std::string Msg = Type;
- getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID,
- &Msg, 1, &Range, 1);
-}
-
-/// ErrorUnsupported - Print out an error that codegen doesn't support the
-/// specified decl yet.
-void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
- bool OmitOnError) {
- if (OmitOnError && getDiags().hasErrorOccurred())
- return;
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
- "cannot codegen this %0 yet");
- std::string Msg = Type;
- getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID,
- &Msg, 1);
-}
-
-/// setGlobalVisibility - Set the visibility for the given LLVM
-/// GlobalValue according to the given clang AST visibility value.
-static void setGlobalVisibility(llvm::GlobalValue *GV,
- VisibilityAttr::VisibilityTypes Vis) {
- switch (Vis) {
- default: assert(0 && "Unknown visibility!");
- case VisibilityAttr::DefaultVisibility:
- GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
- break;
- case VisibilityAttr::HiddenVisibility:
- GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
- break;
- case VisibilityAttr::ProtectedVisibility:
- GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
- break;
- }
-}
-
-/// AddGlobalCtor - Add a function to the list that will be called before
-/// main() runs.
-void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor, int Priority) {
- // TODO: Type coercion of void()* types.
- GlobalCtors.push_back(std::make_pair(Ctor, Priority));
-}
-
-/// AddGlobalDtor - Add a function to the list that will be called
-/// when the module is unloaded.
-void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) {
- // TODO: Type coercion of void()* types.
- GlobalDtors.push_back(std::make_pair(Dtor, Priority));
-}
-
-void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
- // Ctor function type is void()*.
- llvm::FunctionType* CtorFTy =
- llvm::FunctionType::get(llvm::Type::VoidTy,
- std::vector<const llvm::Type*>(),
- false);
- llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
-
- // Get the type of a ctor entry, { i32, void ()* }.
- llvm::StructType* CtorStructTy =
- llvm::StructType::get(llvm::Type::Int32Ty,
- llvm::PointerType::getUnqual(CtorFTy), NULL);
-
- // Construct the constructor and destructor arrays.
- std::vector<llvm::Constant*> Ctors;
- for (CtorList::const_iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
- std::vector<llvm::Constant*> S;
- S.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, I->second, false));
- S.push_back(llvm::ConstantExpr::getBitCast(I->first, CtorPFTy));
- Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S));
- }
-
- if (!Ctors.empty()) {
- llvm::ArrayType *AT = llvm::ArrayType::get(CtorStructTy, Ctors.size());
- new llvm::GlobalVariable(AT, false,
- llvm::GlobalValue::AppendingLinkage,
- llvm::ConstantArray::get(AT, Ctors),
- GlobalName,
- &TheModule);
- }
-}
-
-void CodeGenModule::EmitAnnotations() {
- if (Annotations.empty())
- return;
-
- // Create a new global variable for the ConstantStruct in the Module.
- llvm::Constant *Array =
- llvm::ConstantArray::get(llvm::ArrayType::get(Annotations[0]->getType(),
- Annotations.size()),
- Annotations);
- llvm::GlobalValue *gv =
- new llvm::GlobalVariable(Array->getType(), false,
- llvm::GlobalValue::AppendingLinkage, Array,
- "llvm.global.annotations", &TheModule);
- gv->setSection("llvm.metadata");
-}
-
-static void SetGlobalValueAttributes(const Decl *D,
- bool IsInternal,
- bool IsInline,
- llvm::GlobalValue *GV,
- bool ForDefinition) {
- // TODO: Set up linkage and many other things. Note, this is a simple
- // approximation of what we really want.
- if (!ForDefinition) {
- // Only a few attributes are set on declarations.
- if (D->getAttr<DLLImportAttr>())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- } else {
- if (IsInternal) {
- GV->setLinkage(llvm::Function::InternalLinkage);
- } else {
- if (D->getAttr<DLLImportAttr>())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- else if (D->getAttr<DLLExportAttr>())
- GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->getAttr<WeakAttr>() || IsInline)
- GV->setLinkage(llvm::Function::WeakLinkage);
- }
- }
-
- if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
- setGlobalVisibility(GV, attr->getVisibility());
- // FIXME: else handle -fvisibility
-
- if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
- // Prefaced with special LLVM marker to indicate that the name
- // should not be munged.
- GV->setName("\01" + ALA->getLabel());
- }
-}
-
-void CodeGenModule::SetFunctionAttributes(const Decl *D,
- const CGFunctionInfo &Info,
- llvm::Function *F) {
- AttributeListType AttributeList;
- ConstructAttributeList(D, Info.argtypes_begin(), Info.argtypes_end(),
- AttributeList);
-
- F->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(),
- AttributeList.size()));
-
- // Set the appropriate calling convention for the Function.
- if (D->getAttr<FastCallAttr>())
- F->setCallingConv(llvm::CallingConv::Fast);
-}
-
-/// SetFunctionAttributesForDefinition - Set function attributes
-/// specific to a function definition.
-void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D,
- llvm::Function *F) {
- if (isa<ObjCMethodDecl>(D)) {
- SetGlobalValueAttributes(D, true, false, F, true);
- } else {
- const FunctionDecl *FD = cast<FunctionDecl>(D);
- SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
- FD->isInline(), F, true);
- }
-
- if (!Features.Exceptions)
- F->addFnAttr(llvm::Attribute::NoUnwind);
-}
-
-void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD,
- llvm::Function *F) {
- SetFunctionAttributes(MD, CGFunctionInfo(MD, Context), F);
-
- SetFunctionAttributesForDefinition(MD, F);
-}
-
-void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
- llvm::Function *F) {
- SetFunctionAttributes(FD, CGFunctionInfo(FD), F);
-
- SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
- FD->isInline(), F, false);
-}
-
-
-void CodeGenModule::EmitAliases() {
- for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
- const FunctionDecl *D = Aliases[i];
- const AliasAttr *AA = D->getAttr<AliasAttr>();
-
- // This is something of a hack, if the FunctionDecl got overridden
- // then its attributes will be moved to the new declaration. In
- // this case the current decl has no alias attribute, but we will
- // eventually see it.
- if (!AA)
- continue;
-
- const std::string& aliaseeName = AA->getAliasee();
- llvm::Function *aliasee = getModule().getFunction(aliaseeName);
- if (!aliasee) {
- // FIXME: This isn't unsupported, this is just an error, which
- // sema should catch, but...
- ErrorUnsupported(D, "alias referencing a missing function");
- continue;
- }
-
- llvm::GlobalValue *GA =
- new llvm::GlobalAlias(aliasee->getType(),
- llvm::Function::ExternalLinkage,
- D->getName(),
- aliasee,
- &getModule());
-
- llvm::GlobalValue *&Entry = GlobalDeclMap[D->getIdentifier()];
- if (Entry) {
- // If we created a dummy function for this then replace it.
- GA->takeName(Entry);
-
- llvm::Value *Casted =
- llvm::ConstantExpr::getBitCast(GA, Entry->getType());
- Entry->replaceAllUsesWith(Casted);
- Entry->eraseFromParent();
-
- Entry = GA;
- }
-
- // Alias should never be internal or inline.
- SetGlobalValueAttributes(D, false, false, GA, true);
- }
-}
-
-void CodeGenModule::EmitStatics() {
- // Emit code for each used static decl encountered. Since a previously unused
- // static decl may become used during the generation of code for a static
- // function, iterate until no changes are made.
- bool Changed;
- do {
- Changed = false;
- for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
- const ValueDecl *D = StaticDecls[i];
-
- // Check if we have used a decl with the same name
- // FIXME: The AST should have some sort of aggregate decls or
- // global symbol map.
- // FIXME: This is missing some important cases. For example, we
- // need to check for uses in an alias and in a constructor.
- if (!GlobalDeclMap.count(D->getIdentifier()))
- continue;
-
- // Emit the definition.
- EmitGlobalDefinition(D);
-
- // Erase the used decl from the list.
- StaticDecls[i] = StaticDecls.back();
- StaticDecls.pop_back();
- --i;
- --e;
-
- // Remember that we made a change.
- Changed = true;
- }
- } while (Changed);
-}
-
-/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
-/// annotation information for a given GlobalValue. The annotation struct is
-/// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
-/// GlobalValue being annotated. The second field is the constant string
-/// created from the AnnotateAttr's annotation. The third field is a constant
-/// string containing the name of the translation unit. The fourth field is
-/// the line number in the file of the annotated value declaration.
-///
-/// FIXME: this does not unique the annotation string constants, as llvm-gcc
-/// appears to.
-///
-llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
- const AnnotateAttr *AA,
- unsigned LineNo) {
- llvm::Module *M = &getModule();
-
- // get [N x i8] constants for the annotation string, and the filename string
- // which are the 2nd and 3rd elements of the global annotation structure.
- const llvm::Type *SBP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- llvm::Constant *anno = llvm::ConstantArray::get(AA->getAnnotation(), true);
- llvm::Constant *unit = llvm::ConstantArray::get(M->getModuleIdentifier(),
- true);
-
- // Get the two global values corresponding to the ConstantArrays we just
- // created to hold the bytes of the strings.
- llvm::GlobalValue *annoGV =
- new llvm::GlobalVariable(anno->getType(), false,
- llvm::GlobalValue::InternalLinkage, anno,
- GV->getName() + ".str", M);
- // translation unit name string, emitted into the llvm.metadata section.
- llvm::GlobalValue *unitGV =
- new llvm::GlobalVariable(unit->getType(), false,
- llvm::GlobalValue::InternalLinkage, unit, ".str", M);
-
- // Create the ConstantStruct that is the global annotion.
- llvm::Constant *Fields[4] = {
- llvm::ConstantExpr::getBitCast(GV, SBP),
- llvm::ConstantExpr::getBitCast(annoGV, SBP),
- llvm::ConstantExpr::getBitCast(unitGV, SBP),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo)
- };
- return llvm::ConstantStruct::get(Fields, 4, false);
-}
-
-void CodeGenModule::EmitGlobal(const ValueDecl *Global) {
- bool isDef, isStatic;
-
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
- // Aliases are deferred until code for everything else has been
- // emitted.
- if (FD->getAttr<AliasAttr>()) {
- assert(!FD->isThisDeclarationADefinition() &&
- "Function alias cannot have a definition!");
- Aliases.push_back(FD);
- return;
- }
-
- isDef = FD->isThisDeclarationADefinition();
- isStatic = FD->getStorageClass() == FunctionDecl::Static;
- } else if (const VarDecl *VD = cast<VarDecl>(Global)) {
- assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
-
- isDef = !(VD->getStorageClass() == VarDecl::Extern && VD->getInit() == 0);
- isStatic = VD->getStorageClass() == VarDecl::Static;
- } else {
- assert(0 && "Invalid argument to EmitGlobal");
- return;
- }
-
- // Forward declarations are emitted lazily on first use.
- if (!isDef)
- return;
-
- // If the global is a static, defer code generation until later so
- // we can easily omit unused statics.
- if (isStatic) {
- StaticDecls.push_back(Global);
- return;
- }
-
- // Otherwise emit the definition.
- EmitGlobalDefinition(Global);
-}
-
-void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- EmitGlobalFunctionDefinition(FD);
- } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- EmitGlobalVarDefinition(VD);
- } else {
- assert(0 && "Invalid argument to EmitGlobalDefinition()");
- }
-}
-
- llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D) {
- assert(D->hasGlobalStorage() && "Not a global variable");
-
- QualType ASTTy = D->getType();
- const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
- const llvm::Type *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
-
- // Lookup the entry, lazily creating it if necessary.
- llvm::GlobalValue *&Entry = GlobalDeclMap[D->getIdentifier()];
- if (!Entry)
- Entry = new llvm::GlobalVariable(Ty, false,
- llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
-
- // Make sure the result is of the correct type.
- return llvm::ConstantExpr::getBitCast(Entry, PTy);
-}
-
-void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
- llvm::Constant *Init = 0;
- QualType ASTTy = D->getType();
- const llvm::Type *VarTy = getTypes().ConvertTypeForMem(ASTTy);
-
- if (D->getInit() == 0) {
- // This is a tentative definition; tentative definitions are
- // implicitly initialized with { 0 }
- const llvm::Type* InitTy;
- if (ASTTy->isIncompleteArrayType()) {
- // An incomplete array is normally [ TYPE x 0 ], but we need
- // to fix it to [ TYPE x 1 ].
- const llvm::ArrayType* ATy = cast<llvm::ArrayType>(VarTy);
- InitTy = llvm::ArrayType::get(ATy->getElementType(), 1);
- } else {
- InitTy = VarTy;
- }
- Init = llvm::Constant::getNullValue(InitTy);
- } else {
- Init = EmitConstantExpr(D->getInit());
- }
- const llvm::Type* InitType = Init->getType();
-
- llvm::GlobalValue *&Entry = GlobalDeclMap[D->getIdentifier()];
- llvm::GlobalVariable *GV = cast_or_null<llvm::GlobalVariable>(Entry);
-
- if (!GV) {
- GV = new llvm::GlobalVariable(InitType, false,
- llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
- } else if (GV->getType() !=
- llvm::PointerType::get(InitType, ASTTy.getAddressSpace())) {
- // We have a definition after a prototype with the wrong type.
- // We must make a new GlobalVariable* and update everything that used OldGV
- // (a declaration or tentative definition) with the new GlobalVariable*
- // (which will be a definition).
- //
- // This happens if there is a prototype for a global (e.g. "extern int x[];")
- // and then a definition of a different type (e.g. "int x[10];"). This also
- // happens when an initializer has a different type from the type of the
- // global (this happens with unions).
- //
- // FIXME: This also ends up happening if there's a definition followed by
- // a tentative definition! (Although Sema rejects that construct
- // at the moment.)
-
- // Save the old global
- llvm::GlobalVariable *OldGV = GV;
-
- // Make a new global with the correct type
- GV = new llvm::GlobalVariable(InitType, false,
- llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
- // Steal the name of the old global
- GV->takeName(OldGV);
-
- // Replace all uses of the old global with the new global
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
- OldGV->replaceAllUsesWith(NewPtrForOldDecl);
-
- // Erase the old global, since it is no longer used.
- OldGV->eraseFromParent();
- }
-
- Entry = GV;
-
- if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
- SourceManager &SM = Context.getSourceManager();
- AddAnnotation(EmitAnnotateAttr(GV, AA,
- SM.getLogicalLineNumber(D->getLocation())));
- }
-
- GV->setInitializer(Init);
- GV->setConstant(D->getType().isConstant(Context));
-
- // FIXME: This is silly; getTypeAlign should just work for incomplete arrays
- unsigned Align;
- if (const IncompleteArrayType* IAT =
- Context.getAsIncompleteArrayType(D->getType()))
- Align = Context.getTypeAlign(IAT->getElementType());
- else
- Align = Context.getTypeAlign(D->getType());
- if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) {
- Align = std::max(Align, AA->getAlignment());
- }
- GV->setAlignment(Align / 8);
-
- if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
- setGlobalVisibility(GV, attr->getVisibility());
- // FIXME: else handle -fvisibility
-
- if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
- // Prefaced with special LLVM marker to indicate that the name
- // should not be munged.
- GV->setName("\01" + ALA->getLabel());
- }
-
- // Set the llvm linkage type as appropriate.
- if (D->getStorageClass() == VarDecl::Static)
- GV->setLinkage(llvm::Function::InternalLinkage);
- else if (D->getAttr<DLLImportAttr>())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- else if (D->getAttr<DLLExportAttr>())
- GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->getAttr<WeakAttr>())
- GV->setLinkage(llvm::GlobalVariable::WeakLinkage);
- else {
- // FIXME: This isn't right. This should handle common linkage and other
- // stuff.
- switch (D->getStorageClass()) {
- case VarDecl::Static: assert(0 && "This case handled above");
- case VarDecl::Auto:
- case VarDecl::Register:
- assert(0 && "Can't have auto or register globals");
- case VarDecl::None:
- if (!D->getInit())
- GV->setLinkage(llvm::GlobalVariable::CommonLinkage);
- break;
- case VarDecl::Extern:
- case VarDecl::PrivateExtern:
- // todo: common
- break;
- }
- }
-
- // Emit global variable debug information.
- CGDebugInfo *DI = getDebugInfo();
- if(DI) {
- if(D->getLocation().isValid())
- DI->setLocation(D->getLocation());
- DI->EmitGlobalVariable(GV, D);
- }
-}
-
-llvm::GlobalValue *
-CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) {
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
- llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
- llvm::Function::ExternalLinkage,
- D->getName(), &getModule());
- SetFunctionAttributes(D, F);
- return F;
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D) {
- QualType ASTTy = D->getType();
- const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
- const llvm::Type *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
-
- // Lookup the entry, lazily creating it if necessary.
- llvm::GlobalValue *&Entry = GlobalDeclMap[D->getIdentifier()];
- if (!Entry)
- Entry = EmitForwardFunctionDefinition(D);
-
- return llvm::ConstantExpr::getBitCast(Entry, PTy);
-}
-
-void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
- llvm::GlobalValue *&Entry = GlobalDeclMap[D->getIdentifier()];
- if (!Entry) {
- Entry = EmitForwardFunctionDefinition(D);
- } else {
- // If the types mismatch then we have to rewrite the definition.
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
- if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
- // Otherwise, we have a definition after a prototype with the wrong type.
- // F is the Function* for the one with the wrong type, we must make a new
- // Function* and update everything that used F (a declaration) with the new
- // Function* (which will be a definition).
- //
- // This happens if there is a prototype for a function (e.g. "int f()") and
- // then a definition of a different type (e.g. "int f(int x)"). Start by
- // making a new function of the correct type, RAUW, then steal the name.
- llvm::GlobalValue *NewFn = EmitForwardFunctionDefinition(D);
- NewFn->takeName(Entry);
-
- // Replace uses of F with the Function we will endow with a body.
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
- Entry->replaceAllUsesWith(NewPtrForOldDecl);
-
- // Ok, delete the old function now, which is dead.
- assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
- Entry->eraseFromParent();
-
- Entry = NewFn;
- }
- }
-
- llvm::Function *Fn = cast<llvm::Function>(Entry);
- CodeGenFunction(*this).GenerateCode(D, Fn);
-
- SetFunctionAttributesForDefinition(D, Fn);
-
- if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) {
- AddGlobalCtor(Fn, CA->getPriority());
- } else if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) {
- AddGlobalDtor(Fn, DA->getPriority());
- }
-}
-
-llvm::Function *
-CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
- const std::string &Name) {
- llvm::Function *Fn = llvm::Function::Create(FTy,
- llvm::Function::ExternalLinkage,
- "", &TheModule);
- RuntimeFunctions.push_back(std::make_pair(Fn, Name));
- return Fn;
-}
-
-void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
- // Make sure that this type is translated.
- Types.UpdateCompletedType(TD);
-}
-
-
-/// getBuiltinLibFunction
-llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
- if (BuiltinID > BuiltinFunctions.size())
- BuiltinFunctions.resize(BuiltinID);
-
- // Cache looked up functions. Since builtin id #0 is invalid we don't reserve
- // a slot for it.
- assert(BuiltinID && "Invalid Builtin ID");
- llvm::Function *&FunctionSlot = BuiltinFunctions[BuiltinID-1];
- if (FunctionSlot)
- return FunctionSlot;
-
- assert(Context.BuiltinInfo.isLibFunction(BuiltinID) && "isn't a lib fn");
-
- // Get the name, skip over the __builtin_ prefix.
- const char *Name = Context.BuiltinInfo.GetName(BuiltinID)+10;
-
- // Get the type for the builtin.
- QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context);
- const llvm::FunctionType *Ty =
- cast<llvm::FunctionType>(getTypes().ConvertType(Type));
-
- // FIXME: This has a serious problem with code like this:
- // void abs() {}
- // ... __builtin_abs(x);
- // The two versions of abs will collide. The fix is for the builtin to win,
- // and for the existing one to be turned into a constantexpr cast of the
- // builtin. In the case where the existing one is a static function, it
- // should just be renamed.
- if (llvm::Function *Existing = getModule().getFunction(Name)) {
- if (Existing->getFunctionType() == Ty && Existing->hasExternalLinkage())
- return FunctionSlot = Existing;
- assert(Existing == 0 && "FIXME: Name collision");
- }
-
- // FIXME: param attributes for sext/zext etc.
- return FunctionSlot =
- llvm::Function::Create(Ty, llvm::Function::ExternalLinkage, Name,
- &getModule());
-}
-
-llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
- unsigned NumTys) {
- return llvm::Intrinsic::getDeclaration(&getModule(),
- (llvm::Intrinsic::ID)IID, Tys, NumTys);
-}
-
-llvm::Function *CodeGenModule::getMemCpyFn() {
- if (MemCpyFn) return MemCpyFn;
- llvm::Intrinsic::ID IID;
- switch (Context.Target.getPointerWidth(0)) {
- default: assert(0 && "Unknown ptr width");
- case 32: IID = llvm::Intrinsic::memcpy_i32; break;
- case 64: IID = llvm::Intrinsic::memcpy_i64; break;
- }
- return MemCpyFn = getIntrinsic(IID);
-}
-
-llvm::Function *CodeGenModule::getMemMoveFn() {
- if (MemMoveFn) return MemMoveFn;
- llvm::Intrinsic::ID IID;
- switch (Context.Target.getPointerWidth(0)) {
- default: assert(0 && "Unknown ptr width");
- case 32: IID = llvm::Intrinsic::memmove_i32; break;
- case 64: IID = llvm::Intrinsic::memmove_i64; break;
- }
- return MemMoveFn = getIntrinsic(IID);
-}
-
-llvm::Function *CodeGenModule::getMemSetFn() {
- if (MemSetFn) return MemSetFn;
- llvm::Intrinsic::ID IID;
- switch (Context.Target.getPointerWidth(0)) {
- default: assert(0 && "Unknown ptr width");
- case 32: IID = llvm::Intrinsic::memset_i32; break;
- case 64: IID = llvm::Intrinsic::memset_i64; break;
- }
- return MemSetFn = getIntrinsic(IID);
-}
-
-// We still need to work out the details of handling UTF-16.
-// See: <rdr://2996215>
-llvm::Constant *CodeGenModule::
-GetAddrOfConstantCFString(const std::string &str) {
- llvm::StringMapEntry<llvm::Constant *> &Entry =
- CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
-
- if (Entry.getValue())
- return Entry.getValue();
-
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
- llvm::Constant *Zeros[] = { Zero, Zero };
-
- if (!CFConstantStringClassRef) {
- const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
- Ty = llvm::ArrayType::get(Ty, 0);
-
- // FIXME: This is fairly broken if
- // __CFConstantStringClassReference is already defined, in that it
- // will get renamed and the user will most likely see an opaque
- // error message. This is a general issue with relying on
- // particular names.
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Ty, false,
- llvm::GlobalVariable::ExternalLinkage, 0,
- "__CFConstantStringClassReference",
- &getModule());
-
- // Decay array -> ptr
- CFConstantStringClassRef =
- llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
- }
-
- std::vector<llvm::Constant*> Fields(4);
-
- // Class pointer.
- Fields[0] = CFConstantStringClassRef;
-
- // Flags.
- const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
- Fields[1] = llvm::ConstantInt::get(Ty, 0x07C8);
-
- // String pointer.
- llvm::Constant *C = llvm::ConstantArray::get(str);
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &getModule());
- Fields[2] = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
-
- // String length.
- Ty = getTypes().ConvertType(getContext().LongTy);
- Fields[3] = llvm::ConstantInt::get(Ty, str.length());
-
- // The struct.
- Ty = getTypes().ConvertType(getContext().getCFConstantStringType());
- C = llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Fields);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalVariable::InternalLinkage,
- C, "", &getModule());
-
- GV->setSection("__DATA,__cfstring");
- Entry.setValue(GV);
-
- return GV;
-}
-
-/// GetStringForStringLiteral - Return the appropriate bytes for a
-/// string literal, properly padded to match the literal type.
-std::string CodeGenModule::GetStringForStringLiteral(const StringLiteral *E) {
- if (E->isWide()) {
- ErrorUnsupported(E, "wide string");
- return "FIXME";
- }
-
- const char *StrData = E->getStrData();
- unsigned Len = E->getByteLength();
-
- const ConstantArrayType *CAT =
- getContext().getAsConstantArrayType(E->getType());
- assert(CAT && "String isn't pointer or array!");
-
- // Resize the string to the right size
- // FIXME: What about wchar_t strings?
- std::string Str(StrData, StrData+Len);
- uint64_t RealLen = CAT->getSize().getZExtValue();
- Str.resize(RealLen, '\0');
-
- return Str;
-}
-
-/// GetAddrOfConstantStringFromLiteral - Return a pointer to a
-/// constant array for the given string literal.
-llvm::Constant *
-CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
- // FIXME: This can be more efficient.
- return GetAddrOfConstantString(GetStringForStringLiteral(S));
-}
-
-/// GenerateWritableString -- Creates storage for a string literal.
-static llvm::Constant *GenerateStringLiteral(const std::string &str,
- bool constant,
- CodeGenModule &CGM) {
- // Create Constant for this string literal. Don't add a '\0'.
- llvm::Constant *C = llvm::ConstantArray::get(str, false);
-
- // Create a global variable for this string
- C = new llvm::GlobalVariable(C->getType(), constant,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &CGM.getModule());
-
- return C;
-}
-
-/// GetAddrOfConstantString - Returns a pointer to a character array
-/// containing the literal. This contents are exactly that of the
-/// given string, i.e. it will not be null terminated automatically;
-/// see GetAddrOfConstantCString. Note that whether the result is
-/// actually a pointer to an LLVM constant depends on
-/// Feature.WriteableStrings.
-///
-/// The result has pointer to array type.
-llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) {
- // Don't share any string literals if writable-strings is turned on.
- if (Features.WritableStrings)
- return GenerateStringLiteral(str, false, *this);
-
- llvm::StringMapEntry<llvm::Constant *> &Entry =
- ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
-
- if (Entry.getValue())
- return Entry.getValue();
-
- // Create a global variable for this.
- llvm::Constant *C = GenerateStringLiteral(str, true, *this);
- Entry.setValue(C);
- return C;
-}
-
-/// GetAddrOfConstantCString - Returns a pointer to a character
-/// array containing the literal and a terminating '\-'
-/// character. The result has pointer to array type.
-llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str) {
- return GetAddrOfConstantString(str + "\0");
-}
-
-/// EmitObjCPropertyImplementations - Emit information for synthesized
-/// properties for an implementation.
-void CodeGenModule::EmitObjCPropertyImplementations(const
- ObjCImplementationDecl *D) {
- for (ObjCImplementationDecl::propimpl_iterator i = D->propimpl_begin(),
- e = D->propimpl_end(); i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
-
- // Dynamic is just for type-checking.
- if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
- ObjCPropertyDecl *PD = PID->getPropertyDecl();
-
- // Determine which methods need to be implemented, some may have
- // been overridden. Note that ::isSynthesized is not the method
- // we want, that just indicates if the decl came from a
- // property. What we want to know is if the method is defined in
- // this implementation.
- if (!D->getInstanceMethod(PD->getGetterName()))
- CodeGenFunction(*this).GenerateObjCGetter(PID);
- if (!PD->isReadOnly() &&
- !D->getInstanceMethod(PD->getSetterName()))
- CodeGenFunction(*this).GenerateObjCSetter(PID);
- }
- }
-}
-
-/// EmitTopLevelDecl - Emit code for a single top level declaration.
-void CodeGenModule::EmitTopLevelDecl(Decl *D) {
- // If an error has occurred, stop code generation, but continue
- // parsing and semantic analysis (to ensure all warnings and errors
- // are emitted).
- if (Diags.hasErrorOccurred())
- return;
-
- switch (D->getKind()) {
- case Decl::Function:
- case Decl::Var:
- EmitGlobal(cast<ValueDecl>(D));
- break;
-
- case Decl::Namespace:
- ErrorUnsupported(D, "namespace");
- break;
-
- // Objective-C Decls
-
- // Forward declarations, no (immediate) code generation.
- case Decl::ObjCClass:
- case Decl::ObjCCategory:
- case Decl::ObjCForwardProtocol:
- case Decl::ObjCInterface:
- break;
-
- case Decl::ObjCProtocol:
- Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
- break;
-
- case Decl::ObjCCategoryImpl:
- // Categories have properties but don't support synthesize so we
- // can ignore them here.
-
- Runtime->GenerateCategory(cast<ObjCCategoryImplDecl>(D));
- break;
-
- case Decl::ObjCImplementation: {
- ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
- EmitObjCPropertyImplementations(OMD);
- Runtime->GenerateClass(OMD);
- break;
- }
- case Decl::ObjCMethod: {
- ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
- // If this is not a prototype, emit the body.
- if (OMD->getBody())
- CodeGenFunction(*this).GenerateObjCMethod(OMD);
- break;
- }
- case Decl::ObjCCompatibleAlias:
- ErrorUnsupported(D, "Objective-C compatible alias");
- break;
-
- case Decl::LinkageSpec: {
- LinkageSpecDecl *LSD = cast<LinkageSpecDecl>(D);
- if (LSD->getLanguage() == LinkageSpecDecl::lang_cxx)
- ErrorUnsupported(LSD, "linkage spec");
- // FIXME: implement C++ linkage, C linkage works mostly by C
- // language reuse already.
- break;
- }
-
- case Decl::FileScopeAsm: {
- FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
- std::string AsmString(AD->getAsmString()->getStrData(),
- AD->getAsmString()->getByteLength());
-
- const std::string &S = getModule().getModuleInlineAsm();
- if (S.empty())
- getModule().setModuleInlineAsm(AsmString);
- else
- getModule().setModuleInlineAsm(S + '\n' + AsmString);
- break;
- }
-
- default:
- // Make sure we handled everything we should, every other kind is
- // a non-top-level decl. FIXME: Would be nice to have an
- // isTopLevelDeclKind function. Need to recode Decl::Kind to do
- // that easily.
- assert(isa<TypeDecl>(D) && "Unsupported decl kind");
- }
-}
-
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
deleted file mode 100644
index 6a201be37608..000000000000
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ /dev/null
@@ -1,283 +0,0 @@
-//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the internal per-translation-unit state used for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENMODULE_H
-#define CLANG_CODEGEN_CODEGENMODULE_H
-
-#include "CodeGenTypes.h"
-#include "clang/AST/Attr.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringMap.h"
-
-#include "CGCall.h"
-
-namespace llvm {
- class Module;
- class Constant;
- class Function;
- class GlobalValue;
- class TargetData;
- class FunctionType;
-}
-
-namespace clang {
- class ASTContext;
- class FunctionDecl;
- class IdentifierInfo;
- class ObjCMethodDecl;
- class ObjCImplementationDecl;
- class ObjCCategoryImplDecl;
- class ObjCProtocolDecl;
- class Decl;
- class Expr;
- class Stmt;
- class StringLiteral;
- class NamedDecl;
- class ValueDecl;
- class VarDecl;
- struct LangOptions;
- class Diagnostic;
- class AnnotateAttr;
-
-namespace CodeGen {
-
- class CodeGenFunction;
- class CGDebugInfo;
- class CGObjCRuntime;
-
-/// CodeGenModule - This class organizes the cross-function state that
-/// is used while generating LLVM code.
-class CodeGenModule {
- typedef std::vector< std::pair<llvm::Constant*, int> > CtorList;
-
- ASTContext &Context;
- const LangOptions &Features;
- llvm::Module &TheModule;
- const llvm::TargetData &TheTargetData;
- Diagnostic &Diags;
- CodeGenTypes Types;
- CGObjCRuntime* Runtime;
- CGDebugInfo* DebugInfo;
-
- llvm::Function *MemCpyFn;
- llvm::Function *MemMoveFn;
- llvm::Function *MemSetFn;
-
- /// RuntimeFunctions - List of runtime functions whose names must be
- /// protected from introducing conflicts. These functions should be
- /// created unnamed, we will name them and patch up conflicts when
- /// we release the module.
- std::vector< std::pair<llvm::Function*, std::string> > RuntimeFunctions;
-
- /// GlobalDeclMap - Mapping of decl names global variables we have
- /// already emitted. Note that the entries in this map are the
- /// actual globals and therefore may not be of the same type as the
- /// decl, they should be bitcasted on retrieval. Also note that the
- /// globals are keyed on their source name, not the global name
- /// (which may change with attributes such as asm-labels).
- llvm::DenseMap<IdentifierInfo*, llvm::GlobalValue*> GlobalDeclMap;
-
- /// Aliases - List of aliases in module. These cannot be emitted
- /// until all the code has been seen, as they reference things by
- /// name instead of directly and may reference forward.
- std::vector<const FunctionDecl*> Aliases;
-
- /// StaticDecls - List of static global for which code generation is
- /// delayed. When the translation unit has been fully processed we
- /// will lazily emit definitions for only the decls that were
- /// actually used. This should contain only Function and Var decls,
- /// and only those which actually define something.
- std::vector<const ValueDecl*> StaticDecls;
-
- /// GlobalCtors - Store the list of global constructors and their
- /// respective priorities to be emitted when the translation unit is
- /// complete.
- CtorList GlobalCtors;
-
- /// GlobalDtors - Store the list of global destructors and their
- /// respective priorities to be emitted when the translation unit is
- /// complete.
- CtorList GlobalDtors;
-
- std::vector<llvm::Constant*> Annotations;
-
- llvm::StringMap<llvm::Constant*> CFConstantStringMap;
- llvm::StringMap<llvm::Constant*> ConstantStringMap;
-
- /// CFConstantStringClassRef - Cached reference to the class for
- /// constant strings. This value has type int * but is actually an
- /// Obj-C class pointer.
- llvm::Constant *CFConstantStringClassRef;
-
- std::vector<llvm::Function *> BuiltinFunctions;
-public:
- CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M,
- const llvm::TargetData &TD, Diagnostic &Diags,
- bool GenerateDebugInfo);
-
- ~CodeGenModule();
-
- /// Release - Finalize LLVM code generation.
- void Release();
-
- /// getObjCRuntime() - Return a reference to the configured
- /// Objective-C runtime.
- CGObjCRuntime &getObjCRuntime() {
- assert(Runtime && "No Objective-C runtime has been configured.");
- return *Runtime;
- }
-
- /// hasObjCRuntime() - Return true iff an Objective-C runtime has
- /// been configured.
- bool hasObjCRuntime() { return !!Runtime; }
-
- CGDebugInfo *getDebugInfo() { return DebugInfo; }
- ASTContext &getContext() const { return Context; }
- const LangOptions &getLangOptions() const { return Features; }
- llvm::Module &getModule() const { return TheModule; }
- CodeGenTypes &getTypes() { return Types; }
- Diagnostic &getDiags() const { return Diags; }
- const llvm::TargetData &getTargetData() const { return TheTargetData; }
-
- /// GetAddrOfGlobalVar - Return the llvm::Constant for the address
- /// of the given global variable.
- llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D);
-
- /// GetAddrOfFunction - Return the llvm::Constant for the address
- /// of the given function.
- llvm::Constant *GetAddrOfFunction(const FunctionDecl *D);
-
- /// GetStringForStringLiteral - Return the appropriate bytes for a
- /// string literal, properly padded to match the literal type. If
- /// only the address of a constant is needed consider using
- /// GetAddrOfConstantStringLiteral.
- std::string GetStringForStringLiteral(const StringLiteral *E);
-
- /// GetAddrOfConstantCFString - Return a pointer to a
- /// constant CFString object for the given string.
- llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
-
- /// GetAddrOfConstantStringFromLiteral - Return a pointer to a
- /// constant array for the given string literal.
- llvm::Constant *GetAddrOfConstantStringFromLiteral(const StringLiteral *S);
-
- /// GetAddrOfConstantString - Returns a pointer to a character array
- /// containing the literal. This contents are exactly that of the
- /// given string, i.e. it will not be null terminated automatically;
- /// see GetAddrOfConstantCString. Note that whether the result is
- /// actually a pointer to an LLVM constant depends on
- /// Feature.WriteableStrings.
- ///
- /// The result has pointer to array type.
- llvm::Constant *GetAddrOfConstantString(const std::string& str);
-
- /// GetAddrOfConstantCString - Returns a pointer to a character
- /// array containing the literal and a terminating '\-'
- /// character. The result has pointer to array type.
- llvm::Constant *GetAddrOfConstantCString(const std::string &str);
-
- /// getBuiltinLibFunction - Given a builtin id for a function like
- /// "__builtin_fabsf", return a Function* for "fabsf".
- llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
-
- llvm::Function *getMemCpyFn();
- llvm::Function *getMemMoveFn();
- llvm::Function *getMemSetFn();
- llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
- unsigned NumTys = 0);
-
- /// EmitTopLevelDecl - Emit code for a single top level declaration.
- void EmitTopLevelDecl(Decl *D);
-
- void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
-
- /// CreateRuntimeFunction - Create a new runtime function whose name
- /// must be protected from collisions.
- llvm::Function *CreateRuntimeFunction(const llvm::FunctionType *Ty,
- const std::string &Name);
-
- void UpdateCompletedType(const TagDecl *D);
- llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
- llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
- const AnnotateAttr *AA, unsigned LineNo);
-
- /// ErrorUnsupported - Print out an error that codegen doesn't support the
- /// specified stmt yet.
- /// \param OmitOnError - If true, then this error should only be
- /// emitted if no other errors have been reported.
- void ErrorUnsupported(const Stmt *S, const char *Type,
- bool OmitOnError=false);
-
- /// ErrorUnsupported - Print out an error that codegen doesn't support the
- /// specified decl yet.
- /// \param OmitOnError - If true, then this error should only be
- /// emitted if no other errors have been reported.
- void ErrorUnsupported(const Decl *D, const char *Type,
- bool OmitOnError=false);
-
- void SetMethodAttributes(const ObjCMethodDecl *MD,
- llvm::Function *F);
-
- void SetFunctionAttributes(const Decl *D,
- const CGFunctionInfo &Info,
- llvm::Function *F);
-
- /// ReturnTypeUsesSret - Return true iff the given type uses 'sret'
- /// when used as a return type.
- bool ReturnTypeUsesSret(QualType RetTy);
-
- void ConstructAttributeList(const Decl *TargetDecl,
- const ArgTypeIterator begin,
- const ArgTypeIterator end,
- AttributeListType &PAL);
-
-private:
- /// SetFunctionAttributesForDefinition - Set function attributes
- /// specific to a function definition.
- /// \param D - The ObjCMethodDecl or FunctionDecl defining \arg F.
- void SetFunctionAttributesForDefinition(const Decl *D,
- llvm::Function *F);
-
- void SetFunctionAttributes(const FunctionDecl *FD,
- llvm::Function *F);
-
- /// EmitGlobal - Emit code for a singal global function or var
- /// decl. Forward declarations are emitted lazily.
- void EmitGlobal(const ValueDecl *D);
-
- void EmitGlobalDefinition(const ValueDecl *D);
- llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D);
- void EmitGlobalFunctionDefinition(const FunctionDecl *D);
- void EmitGlobalVarDefinition(const VarDecl *D);
- void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
-
- // FIXME: Hardcoding priority here is gross.
- void AddGlobalCtor(llvm::Function * Ctor, int Priority=65535);
- void AddGlobalDtor(llvm::Function * Dtor, int Priority=65535);
-
- /// EmitCtorList - Generates a global array of functions and
- /// priorities using the given list and name. This array will have
- /// appending linkage and is suitable for use as a LLVM constructor
- /// or destructor array.
- void EmitCtorList(const CtorList &Fns, const char *GlobalName);
-
- void EmitAliases(void);
- void EmitAnnotations(void);
- void EmitStatics(void);
-
- void BindRuntimeFunctions();
-};
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
deleted file mode 100644
index c156f7f7a9b2..000000000000
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the code that handles AST -> LLVM type lowering.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenTypes.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.h"
-
-#include "CGCall.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
- /// RecordOrganizer - This helper class, used by CGRecordLayout, layouts
- /// structs and unions. It manages transient information used during layout.
- /// FIXME : Handle field aligments. Handle packed structs.
- class RecordOrganizer {
- public:
- explicit RecordOrganizer(CodeGenTypes &Types, const RecordDecl& Record) :
- CGT(Types), RD(Record), STy(NULL) {}
-
- /// layoutStructFields - Do the actual work and lay out all fields. Create
- /// corresponding llvm struct type. This should be invoked only after
- /// all fields are added.
- void layoutStructFields(const ASTRecordLayout &RL);
-
- /// layoutUnionFields - Do the actual work and lay out all fields. Create
- /// corresponding llvm struct type. This should be invoked only after
- /// all fields are added.
- void layoutUnionFields(const ASTRecordLayout &RL);
-
- /// getLLVMType - Return associated llvm struct type. This may be NULL
- /// if fields are not laid out.
- llvm::Type *getLLVMType() const {
- return STy;
- }
-
- llvm::SmallSet<unsigned, 8> &getPaddingFields() {
- return PaddingFields;
- }
-
- private:
- CodeGenTypes &CGT;
- const RecordDecl& RD;
- llvm::Type *STy;
- llvm::SmallSet<unsigned, 8> PaddingFields;
- };
-}
-
-CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
- const llvm::TargetData &TD)
- : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD) {
-}
-
-CodeGenTypes::~CodeGenTypes() {
- for(llvm::DenseMap<const Type *, CGRecordLayout *>::iterator
- I = CGRecordLayouts.begin(), E = CGRecordLayouts.end();
- I != E; ++I)
- delete I->second;
- CGRecordLayouts.clear();
-}
-
-/// ConvertType - Convert the specified type to its LLVM form.
-const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
- llvm::PATypeHolder Result = ConvertTypeRecursive(T);
-
- // Any pointers that were converted defered evaluation of their pointee type,
- // creating an opaque type instead. This is in order to avoid problems with
- // circular types. Loop through all these defered pointees, if any, and
- // resolve them now.
- while (!PointersToResolve.empty()) {
- std::pair<const PointerLikeType *, llvm::OpaqueType*> P =
- PointersToResolve.back();
- PointersToResolve.pop_back();
- // We can handle bare pointers here because we know that the only pointers
- // to the Opaque type are P.second and from other types. Refining the
- // opqaue type away will invalidate P.second, but we don't mind :).
- const llvm::Type *NT = ConvertTypeRecursive(P.first->getPointeeType());
- P.second->refineAbstractTypeTo(NT);
- }
-
- return Result;
-}
-
-const llvm::Type *CodeGenTypes::ConvertTypeRecursive(QualType T) {
- T = Context.getCanonicalType(T);;
-
- // See if type is already cached.
- llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator
- I = TypeCache.find(T.getTypePtr());
- // If type is found in map and this is not a definition for a opaque
- // place holder type then use it. Otherwise, convert type T.
- if (I != TypeCache.end())
- return I->second.get();
-
- const llvm::Type *ResultType = ConvertNewType(T);
- TypeCache.insert(std::make_pair(T.getTypePtr(),
- llvm::PATypeHolder(ResultType)));
- return ResultType;
-}
-
-/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
-/// ConvertType in that it is used to convert to the memory representation for
-/// a type. For example, the scalar representation for _Bool is i1, but the
-/// memory representation is usually i8 or i32, depending on the target.
-const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
- const llvm::Type *R = ConvertType(T);
-
- // If this is a non-bool type, don't map it.
- if (R != llvm::Type::Int1Ty)
- return R;
-
- // Otherwise, return an integer of the target-specified size.
- return llvm::IntegerType::get((unsigned)Context.getTypeSize(T));
-
-}
-
-/// UpdateCompletedType - When we find the full definition for a TagDecl,
-/// replace the 'opaque' type we previously made for it if applicable.
-void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
- const Type *Key =
- Context.getTagDeclType(const_cast<TagDecl*>(TD)).getTypePtr();
- llvm::DenseMap<const Type*, llvm::PATypeHolder>::iterator TDTI =
- TagDeclTypes.find(Key);
- if (TDTI == TagDeclTypes.end()) return;
-
- // Remember the opaque LLVM type for this tagdecl.
- llvm::PATypeHolder OpaqueHolder = TDTI->second;
- assert(isa<llvm::OpaqueType>(OpaqueHolder.get()) &&
- "Updating compilation of an already non-opaque type?");
-
- // Remove it from TagDeclTypes so that it will be regenerated.
- TagDeclTypes.erase(TDTI);
-
- // Generate the new type.
- const llvm::Type *NT = ConvertTagDeclType(TD);
-
- // Refine the old opaque type to its new definition.
- cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT);
-}
-
-/// Produces a vector containing the all of the instance variables in an
-/// Objective-C object, in the order that they appear. Used to create LLVM
-/// structures corresponding to Objective-C objects.
-void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
- std::vector<const llvm::Type*> &IvarTypes) {
- ObjCInterfaceDecl *SuperClass = ObjCClass->getSuperClass();
- if (SuperClass)
- CollectObjCIvarTypes(SuperClass, IvarTypes);
- for (ObjCInterfaceDecl::ivar_iterator I = ObjCClass->ivar_begin(),
- E = ObjCClass->ivar_end(); I != E; ++I) {
- IvarTypes.push_back(ConvertType((*I)->getType()));
- ObjCIvarInfo[*I] = IvarTypes.size() - 1;
- }
-}
-
-static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) {
- if (&format == &llvm::APFloat::IEEEsingle)
- return llvm::Type::FloatTy;
- if (&format == &llvm::APFloat::IEEEdouble)
- return llvm::Type::DoubleTy;
- if (&format == &llvm::APFloat::IEEEquad)
- return llvm::Type::FP128Ty;
- if (&format == &llvm::APFloat::PPCDoubleDouble)
- return llvm::Type::PPC_FP128Ty;
- if (&format == &llvm::APFloat::x87DoubleExtended)
- return llvm::Type::X86_FP80Ty;
- assert(0 && "Unknown float format!");
- return 0;
-}
-
-const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
- const clang::Type &Ty = *Context.getCanonicalType(T);
-
- switch (Ty.getTypeClass()) {
- case Type::TypeName: // typedef isn't canonical.
- case Type::TypeOfExp: // typeof isn't canonical.
- case Type::TypeOfTyp: // typeof isn't canonical.
- assert(0 && "Non-canonical type, shouldn't happen");
- case Type::Builtin: {
- switch (cast<BuiltinType>(Ty).getKind()) {
- default: assert(0 && "Unknown builtin type!");
- case BuiltinType::Void:
- // LLVM void type can only be used as the result of a function call. Just
- // map to the same as char.
- return llvm::IntegerType::get(8);
-
- case BuiltinType::Bool:
- // Note that we always return bool as i1 for use as a scalar type.
- return llvm::Type::Int1Ty;
-
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- case BuiltinType::Short:
- case BuiltinType::UShort:
- case BuiltinType::Int:
- case BuiltinType::UInt:
- case BuiltinType::Long:
- case BuiltinType::ULong:
- case BuiltinType::LongLong:
- case BuiltinType::ULongLong:
- case BuiltinType::WChar:
- return llvm::IntegerType::get(
- static_cast<unsigned>(Context.getTypeSize(T)));
-
- case BuiltinType::Float:
- case BuiltinType::Double:
- case BuiltinType::LongDouble:
- return getTypeForFormat(Context.getFloatTypeSemantics(T));
- }
- break;
- }
- case Type::Complex: {
- const llvm::Type *EltTy =
- ConvertTypeRecursive(cast<ComplexType>(Ty).getElementType());
- return llvm::StructType::get(EltTy, EltTy, NULL);
- }
- case Type::Reference:
- case Type::Pointer: {
- const PointerLikeType &PTy = cast<PointerLikeType>(Ty);
- QualType ETy = PTy.getPointeeType();
- llvm::OpaqueType *PointeeType = llvm::OpaqueType::get();
- PointersToResolve.push_back(std::make_pair(&PTy, PointeeType));
- return llvm::PointerType::get(PointeeType, ETy.getAddressSpace());
- }
-
- case Type::VariableArray: {
- const VariableArrayType &A = cast<VariableArrayType>(Ty);
- assert(A.getIndexTypeQualifier() == 0 &&
- "FIXME: We only handle trivial array types so far!");
- // VLAs resolve to the innermost element type; this matches
- // the return of alloca, and there isn't any obviously better choice.
- return ConvertTypeRecursive(A.getElementType());
- }
- case Type::IncompleteArray: {
- const IncompleteArrayType &A = cast<IncompleteArrayType>(Ty);
- assert(A.getIndexTypeQualifier() == 0 &&
- "FIXME: We only handle trivial array types so far!");
- // int X[] -> [0 x int]
- return llvm::ArrayType::get(ConvertTypeRecursive(A.getElementType()), 0);
- }
- case Type::ConstantArray: {
- const ConstantArrayType &A = cast<ConstantArrayType>(Ty);
- const llvm::Type *EltTy = ConvertTypeRecursive(A.getElementType());
- return llvm::ArrayType::get(EltTy, A.getSize().getZExtValue());
- }
- case Type::ExtVector:
- case Type::Vector: {
- const VectorType &VT = cast<VectorType>(Ty);
- return llvm::VectorType::get(ConvertTypeRecursive(VT.getElementType()),
- VT.getNumElements());
- }
- case Type::FunctionNoProto:
- return GetFunctionType(CGFunctionInfo(cast<FunctionTypeNoProto>(&Ty)));
- case Type::FunctionProto:
- return GetFunctionType(CGFunctionInfo(cast<FunctionTypeProto>(&Ty)));
-
- case Type::ASQual:
- return
- ConvertTypeRecursive(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
-
- case Type::ObjCInterface: {
- // FIXME: This comment is broken. Either the code should check for
- // the flag it is referring to or it should do the right thing in
- // the presence of it.
-
- // Warning: Use of this is strongly discouraged. Late binding of instance
- // variables is supported on some runtimes and so using static binding can
- // break code when libraries are updated. Only use this if you have
- // previously checked that the ObjCRuntime subclass in use does not support
- // late-bound ivars.
- ObjCInterfaceType OIT = cast<ObjCInterfaceType>(Ty);
- std::vector<const llvm::Type*> IvarTypes;
- CollectObjCIvarTypes(OIT.getDecl(), IvarTypes);
- llvm::Type *T = llvm::StructType::get(IvarTypes);
- TheModule.addTypeName(std::string("struct.") + OIT.getDecl()->getName(), T);
- return T;
- }
-
- case Type::ObjCQualifiedInterface: {
- ObjCQualifiedInterfaceType QIT = cast<ObjCQualifiedInterfaceType>(Ty);
-
- return ConvertTypeRecursive(Context.getObjCInterfaceType(QIT.getDecl()));
- }
-
- case Type::ObjCQualifiedId:
- // Protocols don't influence the LLVM type.
- return ConvertTypeRecursive(Context.getObjCIdType());
-
- case Type::Tagged: {
- const TagDecl *TD = cast<TagType>(Ty).getDecl();
- const llvm::Type *Res = ConvertTagDeclType(TD);
-
- std::string TypeName(TD->getKindName());
- TypeName += '.';
-
- // Name the codegen type after the typedef name
- // if there is no tag type name available
- if (TD->getIdentifier())
- TypeName += TD->getName();
- else if (const TypedefType *TdT = dyn_cast<TypedefType>(T))
- TypeName += TdT->getDecl()->getName();
- else
- TypeName += "anon";
-
- TheModule.addTypeName(TypeName, Res);
- return Res;
- }
-
- case Type::BlockPointer: {
- assert(0 && "FIXME: Cannot get type of block pointer.");
- }
- }
-
- // FIXME: implement.
- return llvm::OpaqueType::get();
-}
-
-/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
-/// enum.
-const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
- // TagDecl's are not necessarily unique, instead use the (clang)
- // type connected to the decl.
- const Type *Key =
- Context.getTagDeclType(const_cast<TagDecl*>(TD)).getTypePtr();
- llvm::DenseMap<const Type*, llvm::PATypeHolder>::iterator TDTI =
- TagDeclTypes.find(Key);
-
- // If we've already compiled this tag type, use the previous definition.
- if (TDTI != TagDeclTypes.end())
- return TDTI->second;
-
- // If this is still a forward definition, just define an opaque type to use
- // for this tagged decl.
- if (!TD->isDefinition()) {
- llvm::Type *ResultType = llvm::OpaqueType::get();
- TagDeclTypes.insert(std::make_pair(Key, ResultType));
- return ResultType;
- }
-
- // Okay, this is a definition of a type. Compile the implementation now.
-
- if (TD->isEnum()) {
- // Don't bother storing enums in TagDeclTypes.
- return ConvertTypeRecursive(cast<EnumDecl>(TD)->getIntegerType());
- }
-
- // This decl could well be recursive. In this case, insert an opaque
- // definition of this type, which the recursive uses will get. We will then
- // refine this opaque version later.
-
- // Create new OpaqueType now for later use in case this is a recursive
- // type. This will later be refined to the actual type.
- llvm::PATypeHolder ResultHolder = llvm::OpaqueType::get();
- TagDeclTypes.insert(std::make_pair(Key, ResultHolder));
-
- const llvm::Type *ResultType;
- const RecordDecl *RD = cast<const RecordDecl>(TD);
- if (TD->isStruct() || TD->isClass()) {
- // Layout fields.
- RecordOrganizer RO(*this, *RD);
-
- RO.layoutStructFields(Context.getASTRecordLayout(RD));
-
- // Get llvm::StructType.
- const Type *Key =
- Context.getTagDeclType(const_cast<TagDecl*>(TD)).getTypePtr();
- CGRecordLayouts[Key] = new CGRecordLayout(RO.getLLVMType(),
- RO.getPaddingFields());
- ResultType = RO.getLLVMType();
-
- } else if (TD->isUnion()) {
- // Just use the largest element of the union, breaking ties with the
- // highest aligned member.
- if (RD->getNumMembers() != 0) {
- RecordOrganizer RO(*this, *RD);
-
- RO.layoutUnionFields(Context.getASTRecordLayout(RD));
-
- // Get llvm::StructType.
- const Type *Key =
- Context.getTagDeclType(const_cast<TagDecl*>(TD)).getTypePtr();
- CGRecordLayouts[Key] = new CGRecordLayout(RO.getLLVMType(),
- RO.getPaddingFields());
- ResultType = RO.getLLVMType();
- } else {
- ResultType = llvm::StructType::get(std::vector<const llvm::Type*>());
- }
- } else {
- assert(0 && "FIXME: Unknown tag decl kind!");
- }
-
- // Refine our Opaque type to ResultType. This can invalidate ResultType, so
- // make sure to read the result out of the holder.
- cast<llvm::OpaqueType>(ResultHolder.get())
- ->refineAbstractTypeTo(ResultType);
-
- return ResultHolder.get();
-}
-
-/// getLLVMFieldNo - Return llvm::StructType element number
-/// that corresponds to the field FD.
-unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
- llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD);
- assert (I != FieldInfo.end() && "Unable to find field info");
- return I->second;
-}
-
-unsigned CodeGenTypes::getLLVMFieldNo(const ObjCIvarDecl *OID) {
- llvm::DenseMap<const ObjCIvarDecl*, unsigned>::iterator
- I = ObjCIvarInfo.find(OID);
- assert(I != ObjCIvarInfo.end() && "Unable to find field info");
- return I->second;
-}
-
-/// addFieldInfo - Assign field number to field FD.
-void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) {
- FieldInfo[FD] = No;
-}
-
-/// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field FD.
-CodeGenTypes::BitFieldInfo CodeGenTypes::getBitFieldInfo(const FieldDecl *FD) {
- llvm::DenseMap<const FieldDecl *, BitFieldInfo>::iterator
- I = BitFields.find(FD);
- assert (I != BitFields.end() && "Unable to find bitfield info");
- return I->second;
-}
-
-/// addBitFieldInfo - Assign a start bit and a size to field FD.
-void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned Begin,
- unsigned Size) {
- BitFields.insert(std::make_pair(FD, BitFieldInfo(Begin, Size)));
-}
-
-/// getCGRecordLayout - Return record layout info for the given llvm::Type.
-const CGRecordLayout *
-CodeGenTypes::getCGRecordLayout(const TagDecl *TD) const {
- const Type *Key =
- Context.getTagDeclType(const_cast<TagDecl*>(TD)).getTypePtr();
- llvm::DenseMap<const Type*, CGRecordLayout *>::iterator I
- = CGRecordLayouts.find(Key);
- assert (I != CGRecordLayouts.end()
- && "Unable to find record layout information for type");
- return I->second;
-}
-
-/// layoutStructFields - Do the actual work and lay out all fields. Create
-/// corresponding llvm struct type.
-/// Note that this doesn't actually try to do struct layout; it depends on
-/// the layout built by the AST. (We have to do struct layout to do Sema,
-/// and there's no point to duplicating the work.)
-void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
- // FIXME: This code currently always generates packed structures.
- // Unpacked structures are more readable, and sometimes more efficient!
- // (But note that any changes here are likely to impact CGExprConstant,
- // which makes some messy assumptions.)
- uint64_t llvmSize = 0;
- // FIXME: Make this a SmallVector
- std::vector<const llvm::Type*> LLVMFields;
- int NumMembers = RD.getNumMembers();
-
- for (int curField = 0; curField < NumMembers; curField++) {
- const FieldDecl *FD = RD.getMember(curField);
- uint64_t offset = RL.getFieldOffset(curField);
- const llvm::Type *Ty = CGT.ConvertTypeRecursive(FD->getType());
- uint64_t size = CGT.getTargetData().getABITypeSizeInBits(Ty);
-
- if (FD->isBitField()) {
- Expr *BitWidth = FD->getBitWidth();
- llvm::APSInt FieldSize(32);
- bool isBitField =
- BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
- assert (isBitField && "Invalid BitField size expression");
- uint64_t BitFieldSize = FieldSize.getZExtValue();
-
- // Bitfield field info is different from other field info;
- // it actually ignores the underlying LLVM struct because
- // there isn't any convenient mapping.
- CGT.addFieldInfo(FD, offset / size);
- CGT.addBitFieldInfo(FD, offset % size, BitFieldSize);
- } else {
- // Put the element into the struct. This would be simpler
- // if we didn't bother, but it seems a bit too strange to
- // allocate all structs as i8 arrays.
- while (llvmSize < offset) {
- LLVMFields.push_back(llvm::Type::Int8Ty);
- llvmSize += 8;
- }
-
- llvmSize += size;
- CGT.addFieldInfo(FD, LLVMFields.size());
- LLVMFields.push_back(Ty);
- }
- }
-
- while (llvmSize < RL.getSize()) {
- LLVMFields.push_back(llvm::Type::Int8Ty);
- llvmSize += 8;
- }
-
- STy = llvm::StructType::get(LLVMFields, true);
- assert(CGT.getTargetData().getABITypeSizeInBits(STy) == RL.getSize());
-}
-
-/// layoutUnionFields - Do the actual work and lay out all fields. Create
-/// corresponding llvm struct type. This should be invoked only after
-/// all fields are added.
-void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
- for (int curField = 0; curField < RD.getNumMembers(); curField++) {
- const FieldDecl *FD = RD.getMember(curField);
- // The offset should usually be zero, but bitfields could be strange
- uint64_t offset = RL.getFieldOffset(curField);
-
- if (FD->isBitField()) {
- Expr *BitWidth = FD->getBitWidth();
- uint64_t BitFieldSize =
- BitWidth->getIntegerConstantExprValue(CGT.getContext()).getZExtValue();
-
- CGT.addFieldInfo(FD, 0);
- CGT.addBitFieldInfo(FD, offset, BitFieldSize);
- } else {
- CGT.addFieldInfo(FD, 0);
- }
- }
-
- // This looks stupid, but it is correct in the sense that
- // it works no matter how complicated the sizes and alignments
- // of the union elements are. The natural alignment
- // of the result doesn't matter because anyone allocating
- // structures should be aligning them appropriately anyway.
- // FIXME: We can be a bit more intuitive in a lot of cases.
- STy = llvm::ArrayType::get(llvm::Type::Int8Ty, RL.getSize() / 8);
- assert(CGT.getTargetData().getABITypeSizeInBits(STy) == RL.getSize());
-}
diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h
deleted file mode 100644
index 0c9ab7ef63d2..000000000000
--- a/clang/lib/CodeGen/CodeGenTypes.h
+++ /dev/null
@@ -1,200 +0,0 @@
-//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the code that handles AST -> LLVM type lowering.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENTYPES_H
-#define CLANG_CODEGEN_CODEGENTYPES_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include <vector>
-
-#include "CGCall.h"
-
-namespace llvm {
- class FunctionType;
- class Module;
- class OpaqueType;
- class PATypeHolder;
- class TargetData;
- class Type;
-}
-
-namespace clang {
- class ASTContext;
- class FieldDecl;
- class FunctionTypeProto;
- class ObjCInterfaceDecl;
- class ObjCIvarDecl;
- class PointerLikeType;
- class PointerType;
- class QualType;
- class RecordDecl;
- class TagDecl;
- class TargetInfo;
- class Type;
-
-namespace CodeGen {
- class CodeGenTypes;
-
- /// CGRecordLayout - This class handles struct and union layout info while
- /// lowering AST types to LLVM types.
- class CGRecordLayout {
- CGRecordLayout(); // DO NOT IMPLEMENT
- public:
- CGRecordLayout(llvm::Type *T, llvm::SmallSet<unsigned, 8> &PF)
- : STy(T), PaddingFields(PF) {
- // FIXME : Collect info about fields that requires adjustments
- // (i.e. fields that do not directly map to llvm struct fields.)
- }
-
- /// getLLVMType - Return llvm type associated with this record.
- llvm::Type *getLLVMType() const {
- return STy;
- }
-
- bool isPaddingField(unsigned No) const {
- return PaddingFields.count(No) != 0;
- }
-
- unsigned getNumPaddingFields() {
- return PaddingFields.size();
- }
-
- private:
- llvm::Type *STy;
- llvm::SmallSet<unsigned, 8> PaddingFields;
- };
-
-/// CodeGenTypes - This class organizes the cross-module state that is used
-/// while lowering AST types to LLVM types.
-class CodeGenTypes {
- ASTContext &Context;
- TargetInfo &Target;
- llvm::Module& TheModule;
- const llvm::TargetData& TheTargetData;
-
-
- llvm::SmallVector<std::pair<const PointerLikeType *,
- llvm::OpaqueType *>, 8> PointersToResolve;
-
- llvm::DenseMap<const Type*, llvm::PATypeHolder> TagDeclTypes;
-
- /// CGRecordLayouts - This maps llvm struct type with corresponding
- /// record layout info.
- /// FIXME : If CGRecordLayout is less than 16 bytes then use
- /// inline it in the map.
- llvm::DenseMap<const Type*, CGRecordLayout *> CGRecordLayouts;
-
- /// FieldInfo - This maps struct field with corresponding llvm struct type
- /// field no. This info is populated by record organizer.
- llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
- llvm::DenseMap<const ObjCIvarDecl *, unsigned> ObjCIvarInfo;
-
-public:
- class BitFieldInfo {
- public:
- explicit BitFieldInfo(unsigned short B, unsigned short S)
- : Begin(B), Size(S) {}
-
- unsigned short Begin;
- unsigned short Size;
- };
-
-private:
- llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields;
-
- /// TypeCache - This map keeps cache of llvm::Types (through PATypeHolder)
- /// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is
- /// used instead of llvm::Type because it allows us to bypass potential
- /// dangling type pointers due to type refinement on llvm side.
- llvm::DenseMap<Type *, llvm::PATypeHolder> TypeCache;
-
- /// ConvertNewType - Convert type T into a llvm::Type. Do not use this
- /// method directly because it does not do any type caching. This method
- /// is available only for ConvertType(). CovertType() is preferred
- /// interface to convert type T into a llvm::Type.
- const llvm::Type *ConvertNewType(QualType T);
-public:
- CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD);
- ~CodeGenTypes();
-
- const llvm::TargetData &getTargetData() const { return TheTargetData; }
- TargetInfo &getTarget() const { return Target; }
- ASTContext &getContext() const { return Context; }
-
- /// ConvertType - Convert type T into a llvm::Type.
- const llvm::Type *ConvertType(QualType T);
- const llvm::Type *ConvertTypeRecursive(QualType T);
-
- /// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
- /// ConvertType in that it is used to convert to the memory representation for
- /// a type. For example, the scalar representation for _Bool is i1, but the
- /// memory representation is usually i8 or i32, depending on the target.
- const llvm::Type *ConvertTypeForMem(QualType T);
-
- /// GetFunctionType - Get the LLVM function type from Info.
- const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);
- /// GetFunctionType - Get the LLVM function type from Info.
- /// \param IsVariadic Should the resulting type be variadic?
- const llvm::FunctionType *GetFunctionType(const CGCallInfo &Info,
- bool IsVariadic);
-
- /// GetFunctionType - Get the LLVM function type for the given types
- /// and variadicness.
- // FIXME: Do we even need IsVariadic here?
- const llvm::FunctionType *GetFunctionType(ArgTypeIterator begin,
- ArgTypeIterator end,
- bool IsVariadic);
-
- void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
- std::vector<const llvm::Type*> &IvarTypes);
-
- const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
- /// Returns a StructType representing an Objective-C object
- const llvm::Type *ConvertObjCInterfaceToStruct(const ObjCInterfaceDecl *OID);
-
- /// getLLVMFieldNo - Return llvm::StructType element number
- /// that corresponds to the field FD.
- unsigned getLLVMFieldNo(const FieldDecl *FD);
- unsigned getLLVMFieldNo(const ObjCIvarDecl *OID);
-
-
- /// UpdateCompletedType - When we find the full definition for a TagDecl,
- /// replace the 'opaque' type we previously made for it if applicable.
- void UpdateCompletedType(const TagDecl *TD);
-
-public: // These are internal details of CGT that shouldn't be used externally.
- /// addFieldInfo - Assign field number to field FD.
- void addFieldInfo(const FieldDecl *FD, unsigned No);
-
- /// addBitFieldInfo - Assign a start bit and a size to field FD.
- void addBitFieldInfo(const FieldDecl *FD, unsigned Begin, unsigned Size);
-
- /// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field
- /// FD.
- BitFieldInfo getBitFieldInfo(const FieldDecl *FD);
-
- /// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
- /// enum.
- const llvm::Type *ConvertTagDeclType(const TagDecl *TD);
-
- /// GetExpandedTypes - Expand the type \arg Ty into the LLVM
- /// argument types it would be passed as on the provided vector \arg
- /// ArgTys. See ABIArgInfo::Expand.
- void GetExpandedTypes(QualType Ty, std::vector<const llvm::Type*> &ArgTys);
-};
-
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/CodeGen/Makefile b/clang/lib/CodeGen/Makefile
deleted file mode 100644
index 4d7828ef67a0..000000000000
--- a/clang/lib/CodeGen/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- clang/lib/CodeGen/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the AST -> LLVM code generation library for the
-# C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangCodeGen
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
deleted file mode 100644
index dafc0f5e2586..000000000000
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This builds an AST and converts it to LLVM Code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// LLVM Emitter
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/ADT/OwningPtr.h"
-
-
-namespace {
- class VISIBILITY_HIDDEN CodeGeneratorImpl : public CodeGenerator {
- Diagnostic &Diags;
- llvm::OwningPtr<const llvm::TargetData> TD;
- ASTContext *Ctx;
- const LangOptions &Features;
- bool GenerateDebugInfo;
- protected:
- llvm::OwningPtr<llvm::Module> M;
- llvm::OwningPtr<CodeGen::CodeGenModule> Builder;
- public:
- CodeGeneratorImpl(Diagnostic &diags, const LangOptions &LO,
- const std::string& ModuleName,
- bool DebugInfoFlag)
- : Diags(diags), Features(LO), GenerateDebugInfo(DebugInfoFlag),
- M(new llvm::Module(ModuleName)) {}
-
- virtual ~CodeGeneratorImpl() {}
-
- virtual llvm::Module* ReleaseModule() {
- return M.take();
- }
-
- virtual void Initialize(ASTContext &Context) {
- Ctx = &Context;
-
- M->setTargetTriple(Ctx->Target.getTargetTriple());
- M->setDataLayout(Ctx->Target.getTargetDescription());
- TD.reset(new llvm::TargetData(Ctx->Target.getTargetDescription()));
- Builder.reset(new CodeGen::CodeGenModule(Context, Features, *M, *TD,
- Diags, GenerateDebugInfo));
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- // Make sure to emit all elements of a ScopedDecl.
- if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
- for (; SD; SD = SD->getNextDeclarator())
- Builder->EmitTopLevelDecl(SD);
- } else {
- Builder->EmitTopLevelDecl(D);
- }
- }
-
- /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
- /// (e.g. struct, union, enum, class) is completed. This allows the client to
- /// hack on the type, which can occur at any point in the file (because these
- /// can be defined in declspecs).
- virtual void HandleTagDeclDefinition(TagDecl *D) {
- Builder->UpdateCompletedType(D);
- }
-
- virtual void HandleTranslationUnit(TranslationUnit& TU) {
- if (Diags.hasErrorOccurred()) {
- M.reset();
- return;
- }
-
- if (Builder)
- Builder->Release();
- };
- };
-}
-
-CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags,
- const LangOptions &Features,
- const std::string& ModuleName,
- bool GenerateDebugInfo) {
- return new CodeGeneratorImpl(Diags, Features, ModuleName, GenerateDebugInfo);
-}
diff --git a/clang/lib/Driver/HTMLDiagnostics.cpp b/clang/lib/Driver/HTMLDiagnostics.cpp
deleted file mode 100644
index 5a6987dbcbb5..000000000000
--- a/clang/lib/Driver/HTMLDiagnostics.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- 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 HTMLDiagnostics object.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/HTMLDiagnostics.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/Rewrite/HTMLRewrite.h"
-#include "clang/Lex/Lexer.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include <fstream>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Boilerplate.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN HTMLDiagnostics : public PathDiagnosticClient {
- llvm::sys::Path Directory, FilePrefix;
- bool createdDir, noDir;
- Preprocessor* PP;
- PreprocessorFactory* PPF;
- std::vector<const PathDiagnostic*> BatchedDiags;
-public:
- HTMLDiagnostics(const std::string& prefix, Preprocessor* pp,
- PreprocessorFactory* ppf);
-
- virtual ~HTMLDiagnostics();
-
- virtual void HandlePathDiagnostic(const PathDiagnostic* D);
-
- void HandlePiece(Rewriter& R, unsigned BugFileID,
- const PathDiagnosticPiece& P, unsigned num, unsigned max);
-
- void HighlightRange(Rewriter& R, unsigned BugFileID, SourceRange Range);
-
- void ReportDiag(const PathDiagnostic& D);
-};
-
-} // end anonymous namespace
-
-HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix, Preprocessor* pp,
- PreprocessorFactory* ppf)
- : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false),
- PP(pp), PPF(ppf) {
-
- // All html files begin with "report"
- FilePrefix.appendComponent("report");
-}
-
-PathDiagnosticClient*
-clang::CreateHTMLDiagnosticClient(const std::string& prefix, Preprocessor* PP,
- PreprocessorFactory* PPF) {
-
- return new HTMLDiagnostics(prefix, PP, PPF);
-}
-
-//===----------------------------------------------------------------------===//
-// Report processing.
-//===----------------------------------------------------------------------===//
-
-void HTMLDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
- if (!D)
- return;
-
- if (D->empty()) {
- delete D;
- return;
- }
-
- BatchedDiags.push_back(D);
-}
-
-HTMLDiagnostics::~HTMLDiagnostics() {
-
- while (!BatchedDiags.empty()) {
- const PathDiagnostic* D = BatchedDiags.back();
- BatchedDiags.pop_back();
- ReportDiag(*D);
- delete D;
- }
-}
-
-void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
-
- // Create the HTML directory if it is missing.
-
- if (!createdDir) {
- createdDir = true;
- std::string ErrorMsg;
- Directory.createDirectoryOnDisk(true, &ErrorMsg);
-
- if (!Directory.isDirectory()) {
- llvm::cerr << "warning: could not create directory '"
- << Directory.toString() << "'\n"
- << "reason: " << ErrorMsg << '\n';
-
- noDir = true;
-
- return;
- }
- }
-
- if (noDir)
- return;
-
- SourceManager& SMgr = D.begin()->getLocation().getManager();
-
- unsigned FileID = 0;
- bool FileIDInitialized = false;
-
- // Verify that the entire path is from the same FileID.
- for (PathDiagnostic::const_iterator I=D.begin(), E=D.end(); I != E; ++I) {
-
- FullSourceLoc L = I->getLocation();
-
- if (!L.isFileID())
- return; // FIXME: Emit a warning?
-
- if (!FileIDInitialized) {
- FileID = L.getCanonicalFileID();
- FileIDInitialized = true;
- }
- else if (L.getCanonicalFileID() != FileID)
- return; // FIXME: Emit a warning?
-
- // Check the source ranges.
- for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
- RE=I->ranges_end(); RI!=RE; ++RI) {
-
- SourceLocation L = RI->getBegin();
-
- if (!L.isFileID())
- return; // FIXME: Emit a warning?
-
- if (SMgr.getCanonicalFileID(L) != FileID)
- return; // FIXME: Emit a warning?
-
- L = RI->getEnd();
-
- if (!L.isFileID())
- return; // FIXME: Emit a warning?
-
- if (SMgr.getCanonicalFileID(L) != FileID)
- return; // FIXME: Emit a warning?
- }
- }
-
- if (!FileIDInitialized)
- return; // FIXME: Emit a warning?
-
- // Create a new rewriter to generate HTML.
- Rewriter R(SMgr);
-
- // Process the path.
-
- unsigned n = D.size();
- unsigned max = n;
-
- for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
- I!=E; ++I, --n) {
-
- HandlePiece(R, FileID, *I, n, max);
- }
-
- // Add line numbers, header, footer, etc.
-
- // unsigned FileID = R.getSourceMgr().getMainFileID();
- html::EscapeText(R, FileID);
- html::AddLineNumbers(R, FileID);
-
- // If we have a preprocessor, relex the file and syntax highlight.
- // We might not have a preprocessor if we come from a deserialized AST file,
- // for example.
-
- if (PP) html::SyntaxHighlight(R, FileID, *PP);
-
- // FIXME: We eventually want to use PPF to create a fresh Preprocessor,
- // once we have worked out the bugs.
- //
- // if (PPF) html::HighlightMacros(R, FileID, *PPF);
- //
- if (PP) html::HighlightMacros(R, FileID, *PP);
-
- // Get the full directory name of the analyzed file.
-
- const FileEntry* Entry = SMgr.getFileEntryForID(FileID);
-
- // This is a cludge; basically we want to append either the full
- // working directory if we have no directory information. This is
- // a work in progress.
-
- std::string DirName = "";
-
- if (!llvm::sys::Path(Entry->getName()).isAbsolute()) {
- llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
- DirName = P.toString() + "/";
- }
-
- // Add the name of the file as an <h1> tag.
-
- {
- std::string s;
- llvm::raw_string_ostream os(s);
-
- os << "<!-- REPORTHEADER -->\n"
- << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n"
- "<tr><td class=\"rowname\">File:</td><td>"
- << html::EscapeText(DirName)
- << html::EscapeText(Entry->getName())
- << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
- "<a href=\"#EndPath\">line "
- << (*D.rbegin()).getLocation().getLogicalLineNumber()
- << ", column "
- << (*D.rbegin()).getLocation().getLogicalColumnNumber()
- << "</a></td></tr>\n"
- "<tr><td class=\"rowname\">Description:</td><td>"
- << D.getDescription() << "</td></tr>\n";
-
- // Output any other meta data.
-
- for (PathDiagnostic::meta_iterator I=D.meta_begin(), E=D.meta_end();
- I!=E; ++I) {
- os << "<tr><td></td><td>" << html::EscapeText(*I) << "</td></tr>\n";
- }
-
- os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
- "<h3>Annotated Source Code</h3>\n";
-
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- // Embed meta-data tags.
-
- const std::string& BugDesc = D.getDescription();
-
- if (!BugDesc.empty()) {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- const std::string& BugCategory = D.getCategory();
-
- if (!BugCategory.empty()) {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "\n<!-- BUGLINE " << D.back()->getLocation().getLogicalLineNumber()
- << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- {
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- // Add CSS, header, and footer.
-
- html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName());
-
- // Get the rewrite buffer.
- const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID);
-
- if (!Buf) {
- llvm::cerr << "warning: no diagnostics generated for main file.\n";
- return;
- }
-
- // Create the stream to write out the HTML.
- std::ofstream os;
-
- {
- // Create a path for the target HTML file.
- llvm::sys::Path F(FilePrefix);
- F.makeUnique(false, NULL);
-
- // Rename the file with an HTML extension.
- llvm::sys::Path H(F);
- H.appendSuffix("html");
- F.renamePathOnDisk(H, NULL);
-
- os.open(H.toString().c_str());
-
- if (!os) {
- llvm::cerr << "warning: could not create file '" << F.toString() << "'\n";
- return;
- }
- }
-
- // Emit the HTML to disk.
-
- for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
- os << *I;
-}
-
-void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID,
- const PathDiagnosticPiece& P,
- unsigned num, unsigned max) {
-
- // For now, just draw a box above the line in question, and emit the
- // warning.
-
- FullSourceLoc Pos = P.getLocation();
-
- if (!Pos.isValid())
- return;
-
- SourceManager& SM = R.getSourceMgr();
- FullSourceLoc LPos = Pos.getLogicalLoc();
- unsigned FileID = SM.getCanonicalFileID(LPos.getLocation());
-
- assert (&LPos.getManager() == &SM && "SourceManagers are different!");
-
- if (LPos.getCanonicalFileID() != BugFileID)
- return;
-
- const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID);
- const char* FileStart = Buf->getBufferStart();
-
- // Compute the column number. Rewind from the current position to the start
- // of the line.
-
- unsigned ColNo = LPos.getColumnNumber();
- const char *TokLogicalPtr = LPos.getCharacterData();
- const char *LineStart = TokLogicalPtr-ColNo;
-
- // Only compute LineEnd if we display below a line.
- const char *LineEnd = TokLogicalPtr;
-
- if (P.getDisplayHint() == PathDiagnosticPiece::Below) {
- const char* FileEnd = Buf->getBufferEnd();
-
- while (*LineEnd != '\n' && LineEnd != FileEnd)
- ++LineEnd;
- }
-
- // Compute the margin offset by counting tabs and non-tabs.
-
- unsigned PosNo = 0;
-
- for (const char* c = LineStart; c != TokLogicalPtr; ++c)
- PosNo += *c == '\t' ? 8 : 1;
-
- // Create the html for the message.
- {
- // Get the string and determining its maximum substring.
- const std::string& Msg = P.getString();
- unsigned max_token = 0;
- unsigned cnt = 0;
- unsigned len = Msg.size();
-
- for (std::string::const_iterator I=Msg.begin(), E=Msg.end(); I!=E; ++I)
- switch (*I) {
- default:
- ++cnt;
- continue;
- case ' ':
- case '\t':
- case '\n':
- if (cnt > max_token) max_token = cnt;
- cnt = 0;
- }
-
- if (cnt > max_token) max_token = cnt;
-
- // Next, determine the approximate size of the message bubble in em.
- unsigned em;
- const unsigned max_line = 80;
-
- if (max_token >= max_line)
- em = max_token / 2;
- else {
- unsigned characters = max_line;
- unsigned lines = len / max_line;
-
- if (lines > 0) {
- for (; characters > max_token; --characters)
- if (len / characters > lines) {
- ++characters;
- break;
- }
- }
-
- em = characters / 2;
- }
-
- // Now generate the message bubble.
- std::string s;
- llvm::raw_string_ostream os(s);
-
- os << "\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\"";
-
- if (num == max)
- os << "EndPath";
- else
- os << "Path" << num;
-
- os << "\" class=\"msg\" style=\"margin-left:" << PosNo << "ex";
- if (em < max_line/2) os << "; max-width:" << em << "em";
- os << "\">";
-
- if (max > 1)
- os << "<span class=\"PathIndex\">[" << num << "]</span> ";
-
- os << html::EscapeText(Msg) << "</div></td></tr>";
-
- // Insert the new html.
- unsigned DisplayPos = 0;
-
- switch (P.getDisplayHint()) {
- case PathDiagnosticPiece::Above:
- DisplayPos = LineStart - FileStart;
- break;
- case PathDiagnosticPiece::Below:
- DisplayPos = LineEnd - FileStart;
- break;
- default:
- assert (false && "Unhandled hint.");
- }
-
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, DisplayPos), os.str());
- }
-
- // Now highlight the ranges.
-
- for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
- I != E; ++I)
- HighlightRange(R, FileID, *I);
-}
-
-void HTMLDiagnostics::HighlightRange(Rewriter& R, unsigned BugFileID,
- SourceRange Range) {
-
- SourceManager& SM = R.getSourceMgr();
-
- SourceLocation LogicalStart = SM.getLogicalLoc(Range.getBegin());
- unsigned StartLineNo = SM.getLineNumber(LogicalStart);
-
- SourceLocation LogicalEnd = SM.getLogicalLoc(Range.getEnd());
- unsigned EndLineNo = SM.getLineNumber(LogicalEnd);
-
- if (EndLineNo < StartLineNo)
- return;
-
- if (SM.getCanonicalFileID(LogicalStart) != BugFileID ||
- SM.getCanonicalFileID(LogicalEnd) != BugFileID)
- return;
-
- // Compute the column number of the end.
- unsigned EndColNo = SM.getColumnNumber(LogicalEnd);
- unsigned OldEndColNo = EndColNo;
-
- if (EndColNo) {
- // Add in the length of the token, so that we cover multi-char tokens.
- EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SM) - 1;
- }
-
- // Highlight the range. Make the span tag the outermost tag for the
- // selected range.
-
- SourceLocation E = LogicalEnd.getFileLocWithOffset(EndColNo - OldEndColNo);
-
- html::HighlightRange(R, LogicalStart, E,
- "<span class=\"mrange\">", "</span>");
-}
diff --git a/clang/lib/Driver/InitHeaderSearch.cpp b/clang/lib/Driver/InitHeaderSearch.cpp
deleted file mode 100644
index a2fa826d0cbe..000000000000
--- a/clang/lib/Driver/InitHeaderSearch.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-//===--- InitHeaderSearch.cpp - Initialize header search paths ----------*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the InitHeaderSearch class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/InitHeaderSearch.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/LangOptions.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/System/Path.h"
-#include "llvm/Config/config.h"
-#include <vector>
-
-using namespace clang;
-
-void InitHeaderSearch::AddPath(const std::string &Path, IncludeDirGroup Group,
- bool isCXXAware, bool isUserSupplied,
- bool isFramework) {
- assert(!Path.empty() && "can't handle empty path here");
- FileManager &FM = Headers.getFileMgr();
-
- // Compute the actual path, taking into consideration -isysroot.
- llvm::SmallString<256> MappedPath;
-
- // Handle isysroot.
- if (Group == System) {
- // FIXME: Portability. This should be a sys::Path interface, this doesn't
- // handle things like C:\ right, nor win32 \\network\device\blah.
- if (isysroot.size() != 1 || isysroot[0] != '/') // Add isysroot if present.
- MappedPath.append(isysroot.begin(), isysroot.end());
- }
-
- MappedPath.append(Path.begin(), Path.end());
-
- // Compute the DirectoryLookup type.
- SrcMgr::Characteristic_t Type;
- if (Group == Quoted || Group == Angled)
- Type = SrcMgr::C_User;
- else if (isCXXAware)
- Type = SrcMgr::C_System;
- else
- Type = SrcMgr::C_ExternCSystem;
-
-
- // If the directory exists, add it.
- if (const DirectoryEntry *DE = FM.getDirectory(&MappedPath[0],
- &MappedPath[0]+
- MappedPath.size())) {
- IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied,
- isFramework));
- return;
- }
-
- // Check to see if this is an apple-style headermap (which are not allowed to
- // be frameworks).
- if (!isFramework) {
- if (const FileEntry *FE = FM.getFile(&MappedPath[0],
- &MappedPath[0]+MappedPath.size())) {
- if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
- // It is a headermap, add it to the search path.
- IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied));
- return;
- }
- }
- }
-
- if (Verbose)
- fprintf(stderr, "ignoring nonexistent directory \"%s\"\n", Path.c_str());
-}
-
-
-void InitHeaderSearch::AddEnvVarPaths(const char *Name) {
- const char* at = getenv(Name);
- if (!at || *at == 0) // Empty string should not add '.' path.
- return;
-
- const char* delim = strchr(at, llvm::sys::PathSeparator);
- while (delim != 0) {
- if (delim-at == 0)
- AddPath(".", Angled, false, true, false);
- else
- AddPath(std::string(at, std::string::size_type(delim-at)), Angled, false,
- true, false);
- at = delim + 1;
- delim = strchr(at, llvm::sys::PathSeparator);
- }
- if (*at == 0)
- AddPath(".", Angled, false, true, false);
- else
- AddPath(at, Angled, false, true, false);
-}
-
-
-void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang) {
- // FIXME: temporary hack: hard-coded paths.
- // FIXME: get these from the target?
-
-#ifdef LLVM_ON_WIN32
- if (Lang.CPlusPlus) {
- // Mingw32 GCC version 4
- AddPath("c:/mingw/lib/gcc/mingw32/4.3.0/include/c++", System, true, false, false);
- AddPath("c:/mingw/lib/gcc/mingw32/4.3.0/include/c++/mingw32", System, true, false, false);
- AddPath("c:/mingw/lib/gcc/mingw32/4.3.0/include/c++/backward", System, true, false, false);
- }
-
- // Mingw32 GCC version 4
- AddPath("C:/mingw/lib/gcc/mingw32/4.3.0/include", System, false, false, false);
- AddPath("C:/mingw/include", System, false, false, false);
-#else
-
- if (Lang.CPlusPlus) {
- AddPath("/usr/include/c++/4.2.1", System, true, false, false);
- AddPath("/usr/include/c++/4.2.1/i686-apple-darwin10", System, true, false,
- false);
- AddPath("/usr/include/c++/4.2.1/backward", System, true, false, false);
-
- AddPath("/usr/include/c++/4.0.0", System, true, false, false);
- AddPath("/usr/include/c++/4.0.0/i686-apple-darwin8", System, true, false,
- false);
- AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false);
-
- // Ubuntu 7.10 - Gutsy Gibbon
- AddPath("/usr/include/c++/4.1.3", System, true, false, false);
- AddPath("/usr/include/c++/4.1.3/i486-linux-gnu", System, true, false,
- false);
- AddPath("/usr/include/c++/4.1.3/backward", System, true, false, false);
-
- // Fedora 8
- AddPath("/usr/include/c++/4.1.2", System, true, false, false);
- AddPath("/usr/include/c++/4.1.2/i386-redhat-linux", System, true, false,
- false);
- AddPath("/usr/include/c++/4.1.2/backward", System, true, false, false);
-
- // Fedora 9
- AddPath("/usr/include/c++/4.3.0", System, true, false, false);
- AddPath("/usr/include/c++/4.3.0/i386-redhat-linux", System, true, false,
- false);
- AddPath("/usr/include/c++/4.3.0/backward", System, true, false, false);
-
- // Arch Linux 2008-06-24
- AddPath("/usr/include/c++/4.3.1", System, true, false, false);
- AddPath("/usr/include/c++/4.3.1/i686-pc-linux-gnu", System, true, false,
- false);
- AddPath("/usr/include/c++/4.3.1/backward", System, true, false, false);
- AddPath("/usr/include/c++/4.3.1/x86_64-unknown-linux-gnu", System, true,
- false, false);
-
- // DragonFly
- AddPath("/usr/include/c++/4.1", System, true, false, false);
- }
-
- AddPath("/usr/local/include", System, false, false, false);
-
- AddPath("/usr/lib/gcc/i686-apple-darwin10/4.2.1/include", System,
- false, false, false);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/include",
- System, false, false, false);
-
- // leopard
- AddPath("/usr/lib/gcc/i686-apple-darwin9/4.0.1/include", System,
- false, false, false);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin9/4.0.1/include",
- System, false, false, false);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin9/"
- "4.0.1/../../../../powerpc-apple-darwin0/include",
- System, false, false, false);
-
- // tiger
- AddPath("/usr/lib/gcc/i686-apple-darwin8/4.0.1/include", System,
- false, false, false);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include",
- System, false, false, false);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin8/"
- "4.0.1/../../../../powerpc-apple-darwin8/include",
- System, false, false, false);
-
- // Ubuntu 7.10 - Gutsy Gibbon
- AddPath("/usr/lib/gcc/i486-linux-gnu/4.1.3/include", System,
- false, false, false);
-
- // Fedora 8
- AddPath("/usr/lib/gcc/i386-redhat-linux/4.1.2/include", System,
- false, false, false);
-
- // Fedora 9
- AddPath("/usr/lib/gcc/i386-redhat-linux/4.3.0/include", System,
- false, false, false);
-
- //Debian testing/lenny x86
- AddPath("/usr/lib/gcc/i486-linux-gnu/4.2.3/include", System,
- false, false, false);
-
- //Debian testing/lenny amd64
- AddPath("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include", System,
- false, false, false);
-
- // Arch Linux 2008-06-24
- AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include", System,
- false, false, false);
- AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.3.1/include-fixed", System,
- false, false, false);
- AddPath("/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include", System,
- false, false, false);
- AddPath("/usr/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include-fixed",
- System, false, false, false);
-
- // Debian testing/lenny ppc32
- AddPath("/usr/lib/gcc/powerpc-linux-gnu/4.2.3/include", System,
- false, false, false);
-
- // Gentoo x86 stable
- AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include", System,
- false, false, false);
-
- // DragonFly
- AddPath("/usr/libdata/gcc41", System, true, false, false);
-
- AddPath("/usr/include", System, false, false, false);
- AddPath("/System/Library/Frameworks", System, true, false, true);
- AddPath("/Library/Frameworks", System, true, false, true);
-
-#endif
-}
-
-void InitHeaderSearch::AddDefaultEnvVarPaths(const LangOptions &Lang) {
- AddEnvVarPaths("CPATH");
- if (Lang.CPlusPlus && Lang.ObjC1)
- AddEnvVarPaths("OBJCPLUS_INCLUDE_PATH");
- else if (Lang.CPlusPlus)
- AddEnvVarPaths("CPLUS_INCLUDE_PATH");
- else if (Lang.ObjC1)
- AddEnvVarPaths("OBJC_INCLUDE_PATH");
- else
- AddEnvVarPaths("C_INCLUDE_PATH");
-}
-
-
-/// RemoveDuplicates - If there are duplicate directory entries in the specified
-/// search list, remove the later (dead) ones.
-static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList,
- bool Verbose) {
- llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenDirs;
- llvm::SmallPtrSet<const DirectoryEntry *, 8> SeenFrameworkDirs;
- llvm::SmallPtrSet<const HeaderMap *, 8> SeenHeaderMaps;
- for (unsigned i = 0; i != SearchList.size(); ++i) {
- unsigned DirToRemove = i;
-
- if (SearchList[i].isNormalDir()) {
- // If this isn't the first time we've seen this dir, remove it.
- if (SeenDirs.insert(SearchList[i].getDir()))
- continue;
-
- // If we have a normal #include dir that is shadowed later in the chain
- // by a system include dir, we actually want to ignore the user's request
- // and drop the user dir... keeping the system dir. This is weird, but
- // required to emulate GCC's search path correctly.
- //
- // Since dupes of system dirs are rare, just rescan to find the original
- // that we're nuking instead of using a DenseMap.
- if (SearchList[i].getDirCharacteristic() != SrcMgr::C_User) {
- // Find the dir that this is the same of.
- unsigned FirstDir;
- for (FirstDir = 0; ; ++FirstDir) {
- assert(FirstDir != i && "Didn't find dupe?");
- if (SearchList[FirstDir].getDir() == SearchList[i].getDir())
- break;
- }
-
- // If the first dir in the search path is a non-system dir, zap it
- // instead of the system one.
- if (SearchList[FirstDir].getDirCharacteristic() == SrcMgr::C_User)
- DirToRemove = FirstDir;
- }
-
- if (Verbose) {
- fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
- SearchList[i].getDir()->getName());
- if (DirToRemove != i)
- fprintf(stderr, " as it is a non-system directory that duplicates"
- " a system directory\n");
- }
- } else if (SearchList[i].isFramework()) {
- // If this isn't the first time we've seen this framework dir, remove it.
- if (SeenFrameworkDirs.insert(SearchList[i].getFrameworkDir()))
- continue;
-
- if (Verbose)
- fprintf(stderr, "ignoring duplicate framework \"%s\"\n",
- SearchList[i].getFrameworkDir()->getName());
-
- } else {
- assert(SearchList[i].isHeaderMap() && "Not a headermap or normal dir?");
- // If this isn't the first time we've seen this headermap, remove it.
- if (SeenHeaderMaps.insert(SearchList[i].getHeaderMap()))
- continue;
-
- if (Verbose)
- fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
- SearchList[i].getDir()->getName());
- }
-
- // This is reached if the current entry is a duplicate. Remove the
- // DirToRemove (usually the current dir).
- SearchList.erase(SearchList.begin()+DirToRemove);
- --i;
- }
-}
-
-
-void InitHeaderSearch::Realize() {
- // Concatenate ANGLE+SYSTEM+AFTER chains together into SearchList.
- std::vector<DirectoryLookup> SearchList;
- SearchList = IncludeGroup[Angled];
- SearchList.insert(SearchList.end(), IncludeGroup[System].begin(),
- IncludeGroup[System].end());
- SearchList.insert(SearchList.end(), IncludeGroup[After].begin(),
- IncludeGroup[After].end());
- RemoveDuplicates(SearchList, Verbose);
- RemoveDuplicates(IncludeGroup[Quoted], Verbose);
-
- // Prepend QUOTED list on the search list.
- SearchList.insert(SearchList.begin(), IncludeGroup[Quoted].begin(),
- IncludeGroup[Quoted].end());
-
-
- bool DontSearchCurDir = false; // TODO: set to true if -I- is set?
- Headers.SetSearchPaths(SearchList, IncludeGroup[Quoted].size(),
- DontSearchCurDir);
-
- // If verbose, print the list of directories that will be searched.
- if (Verbose) {
- fprintf(stderr, "#include \"...\" search starts here:\n");
- unsigned QuotedIdx = IncludeGroup[Quoted].size();
- for (unsigned i = 0, e = SearchList.size(); i != e; ++i) {
- if (i == QuotedIdx)
- fprintf(stderr, "#include <...> search starts here:\n");
- const char *Name = SearchList[i].getName();
- const char *Suffix;
- if (SearchList[i].isNormalDir())
- Suffix = "";
- else if (SearchList[i].isFramework())
- Suffix = " (framework directory)";
- else {
- assert(SearchList[i].isHeaderMap() && "Unknown DirectoryLookup");
- Suffix = " (headermap)";
- }
- fprintf(stderr, " %s%s\n", Name, Suffix);
- }
- fprintf(stderr, "End of search list.\n");
- }
-}
-
diff --git a/clang/lib/Driver/Makefile b/clang/lib/Driver/Makefile
deleted file mode 100644
index 01902fd88af2..000000000000
--- a/clang/lib/Driver/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- clang/lib/Analysis/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements analyses built on top of source-level CFGs.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangDriver
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Driver/TextDiagnosticBuffer.cpp b/clang/lib/Driver/TextDiagnosticBuffer.cpp
deleted file mode 100644
index 1df93750f0dc..000000000000
--- a/clang/lib/Driver/TextDiagnosticBuffer.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===--- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a concrete diagnostic client, which buffers the diagnostic messages.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/TextDiagnosticBuffer.h"
-using namespace clang;
-
-/// HandleDiagnostic - Store the errors & warnings that are reported.
-///
-void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level Level,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *,
- unsigned) {
- switch (Level) {
- default: assert(0 && "Diagnostic not handled during diagnostic buffering!");
- case Diagnostic::Note:
- Notes.push_back(std::make_pair(Pos.getLocation(),
- FormatDiagnostic(Diags, Level, ID,
- Strs, NumStrs)));
- break;
- case Diagnostic::Warning:
- Warnings.push_back(std::make_pair(Pos.getLocation(),
- FormatDiagnostic(Diags, Level, ID,
- Strs, NumStrs)));
- break;
- case Diagnostic::Error:
- Errors.push_back(std::make_pair(Pos.getLocation(),
- FormatDiagnostic(Diags, Level, ID,
- Strs, NumStrs)));
- break;
- }
-}
diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp
deleted file mode 100644
index e0faf478d1a5..000000000000
--- a/clang/lib/Driver/TextDiagnosticPrinter.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-//===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This diagnostic client prints out their diagnostic messages.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/TextDiagnosticPrinter.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Lexer.h"
-#include "llvm/Support/MemoryBuffer.h"
-using namespace clang;
-
-void TextDiagnosticPrinter::
-PrintIncludeStack(FullSourceLoc Pos) {
- if (Pos.isInvalid()) return;
-
- Pos = Pos.getLogicalLoc();
-
- // Print out the other include frames first.
- PrintIncludeStack(Pos.getIncludeLoc());
- unsigned LineNo = Pos.getLineNumber();
-
- OS << "In file included from " << Pos.getSourceName()
- << ":" << LineNo << ":\n";
-}
-
-/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
-/// any characters in LineNo that intersect the SourceRange.
-void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
- SourceManager& SourceMgr,
- unsigned LineNo, unsigned FileID,
- std::string &CaretLine,
- const std::string &SourceLine) {
- assert(CaretLine.size() == SourceLine.size() &&
- "Expect a correspondence between source and caret line!");
- if (!R.isValid()) return;
-
- SourceLocation LogicalStart = SourceMgr.getLogicalLoc(R.getBegin());
- unsigned StartLineNo = SourceMgr.getLineNumber(LogicalStart);
- if (StartLineNo > LineNo || LogicalStart.getFileID() != FileID)
- return; // No intersection.
-
- SourceLocation LogicalEnd = SourceMgr.getLogicalLoc(R.getEnd());
- unsigned EndLineNo = SourceMgr.getLineNumber(LogicalEnd);
- if (EndLineNo < LineNo || LogicalEnd.getFileID() != FileID)
- return; // No intersection.
-
- // Compute the column number of the start.
- unsigned StartColNo = 0;
- if (StartLineNo == LineNo) {
- StartColNo = SourceMgr.getLogicalColumnNumber(R.getBegin());
- if (StartColNo) --StartColNo; // Zero base the col #.
- }
-
- // Pick the first non-whitespace column.
- while (StartColNo < SourceLine.size() &&
- (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
- ++StartColNo;
-
- // Compute the column number of the end.
- unsigned EndColNo = CaretLine.size();
- if (EndLineNo == LineNo) {
- EndColNo = SourceMgr.getLogicalColumnNumber(R.getEnd());
- if (EndColNo) {
- --EndColNo; // Zero base the col #.
-
- // Add in the length of the token, so that we cover multi-char tokens.
- EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr);
- } else {
- EndColNo = CaretLine.size();
- }
- }
-
- // Pick the last non-whitespace column.
- if (EndColNo <= SourceLine.size())
- while (EndColNo-1 &&
- (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
- --EndColNo;
- else
- EndColNo = SourceLine.size();
-
- // Fill the range with ~'s.
- assert(StartColNo <= EndColNo && "Invalid range!");
- for (unsigned i = StartColNo; i < EndColNo; ++i)
- CaretLine[i] = '~';
-}
-
-void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags,
- Diagnostic::Level Level,
- FullSourceLoc Pos,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs,
- const SourceRange *Ranges,
- unsigned NumRanges) {
- unsigned LineNo = 0, ColNo = 0;
- unsigned FileID = 0;
- const char *LineStart = 0, *LineEnd = 0;
-
- if (Pos.isValid()) {
- FullSourceLoc LPos = Pos.getLogicalLoc();
- LineNo = LPos.getLineNumber();
- FileID = LPos.getLocation().getFileID();
-
- // First, if this diagnostic is not in the main file, print out the
- // "included from" lines.
- if (LastWarningLoc != LPos.getIncludeLoc()) {
- LastWarningLoc = LPos.getIncludeLoc();
- PrintIncludeStack(LastWarningLoc);
- }
-
- // Compute the column number. Rewind from the current position to the start
- // of the line.
- ColNo = LPos.getColumnNumber();
- const char *TokLogicalPtr = LPos.getCharacterData();
- LineStart = TokLogicalPtr-ColNo+1; // Column # is 1-based
-
- // Compute the line end. Scan forward from the error position to the end of
- // the line.
- const llvm::MemoryBuffer *Buffer = LPos.getBuffer();
- const char *BufEnd = Buffer->getBufferEnd();
- LineEnd = TokLogicalPtr;
- while (LineEnd != BufEnd &&
- *LineEnd != '\n' && *LineEnd != '\r')
- ++LineEnd;
-
- OS << Buffer->getBufferIdentifier() << ":" << LineNo << ":";
- if (ColNo && ShowColumn)
- OS << ColNo << ":";
- OS << " ";
- }
-
- switch (Level) {
- default: assert(0 && "Unknown diagnostic type!");
- case Diagnostic::Note: OS << "note: "; break;
- case Diagnostic::Warning: OS << "warning: "; break;
- case Diagnostic::Error: OS << "error: "; break;
- case Diagnostic::Fatal: OS << "fatal error: "; break;
- break;
- }
-
- OS << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";
-
- if (CaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) || Ranges)) {
- // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
- LastLoc = Pos;
-
- // Get the line of the source file.
- std::string SourceLine(LineStart, LineEnd);
-
- // Create a line for the caret that is filled with spaces that is the same
- // length as the line of source code.
- std::string CaretLine(LineEnd-LineStart, ' ');
-
- // Highlight all of the characters covered by Ranges with ~ characters.
- for (unsigned i = 0; i != NumRanges; ++i)
- HighlightRange(Ranges[i], Pos.getManager(), LineNo, FileID,
- CaretLine, SourceLine);
-
- // Next, insert the caret itself.
- if (ColNo-1 < CaretLine.size())
- CaretLine[ColNo-1] = '^';
- else
- CaretLine.push_back('^');
-
- // Scan the source line, looking for tabs. If we find any, manually expand
- // them to 8 characters and update the CaretLine to match.
- for (unsigned i = 0; i != SourceLine.size(); ++i) {
- if (SourceLine[i] != '\t') continue;
-
- // Replace this tab with at least one space.
- SourceLine[i] = ' ';
-
- // Compute the number of spaces we need to insert.
- unsigned NumSpaces = ((i+8)&~7) - (i+1);
- assert(NumSpaces < 8 && "Invalid computation of space amt");
-
- // Insert spaces into the SourceLine.
- SourceLine.insert(i+1, NumSpaces, ' ');
-
- // Insert spaces or ~'s into CaretLine.
- CaretLine.insert(i+1, NumSpaces, CaretLine[i] == '~' ? '~' : ' ');
- }
-
- // Finally, remove any blank spaces from the end of CaretLine.
- while (CaretLine[CaretLine.size()-1] == ' ')
- CaretLine.erase(CaretLine.end()-1);
-
- // Emit what we have computed.
- OS << SourceLine << "\n";
- OS << CaretLine << "\n";
- }
-}
diff --git a/clang/lib/Headers/Makefile b/clang/lib/Headers/Makefile
deleted file mode 100644
index 7af7f0f87004..000000000000
--- a/clang/lib/Headers/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-##===- clang/lib/Headers/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-include $(LEVEL)/Makefile.common
-
-HeaderDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/Headers
-
-HEADERS := $(notdir $(wildcard $(PROJ_SRC_DIR)/*.h))
-
-OBJHEADERS := $(addprefix $(HeaderDir)/, $(HEADERS))
-
-
-$(OBJHEADERS): $(HeaderDir)/%.h: $(PROJ_SRC_DIR)/%.h $(HeaderDir)/.dir
- $(Verb) cp $< $@
- @echo Copying $(notdir $<) to build dir
-
-printit:
- echo $(OBJHEADERS)
- echo $(PROJ_SRC_DIR)
-
-# Hook into the standard Makefile rules.
-all-local:: $(OBJHEADERS)
-
-PROJ_headers := $(DESTDIR)$(PROJ_prefix)/Headers
-
-INSTHEADERS := $(addprefix $(PROJ_headers)/, $(HEADERS))
-
-$(INSTHEADERS): $(PROJ_headers)/%.h: $(HeaderDir)/%.h $(PROJ_headers)/.dir
- $(Verb) $(DataInstall) $< $(PROJ_headers)
-
-install-local:: $(INSTHEADERS)
-
diff --git a/clang/lib/Headers/iso646.h b/clang/lib/Headers/iso646.h
deleted file mode 100644
index dca13c5babe5..000000000000
--- a/clang/lib/Headers/iso646.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*===---- iso646.h - Standard header for alternate spellings of operators---===
- *
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- *===-----------------------------------------------------------------------===
- */
-
-#ifndef __ISO646_H
-#define __ISO646_H
-
-#ifndef __cplusplus
-#define and &&
-#define and_eq &=
-#define bitand &
-#define bitor |
-#define compl ~
-#define not !
-#define not_eq !=
-#define or ||
-#define or_eq |=
-#define xor ^
-#define xor_eq ^=
-#endif
-
-#endif /* __ISO646_H */
diff --git a/clang/lib/Headers/mmintrin.h b/clang/lib/Headers/mmintrin.h
deleted file mode 100644
index 97b7b0d6aee3..000000000000
--- a/clang/lib/Headers/mmintrin.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*===---- mmintrin.h - MMX intrinsics --------------------------------------===
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- *===-----------------------------------------------------------------------===
- */
-
-#ifndef __MMINTRIN_H
-#define __MMINTRIN_H
-
-#ifndef __MMX__
-#error "MMX instruction set not enabled"
-#else
-
-typedef long long __m64 __attribute__((__vector_size__(8)));
-
-typedef int __v2si __attribute__((__vector_size__(8)));
-typedef short __v4hi __attribute__((__vector_size__(8)));
-typedef char __v8qi __attribute__((__vector_size__(8)));
-
-inline void __attribute__((__always_inline__)) _mm_empty()
-{
- __builtin_ia32_emms();
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cvtsi32_si64(int __i)
-{
- return (__m64)(__v2si){__i, 0};
-}
-
-inline int __attribute__((__always_inline__)) _mm_cvtsi64_si32(__m64 __m)
-{
- __v2si __mmx_var2 = (__v2si)__m;
- return __mmx_var2[0];
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cvtsi64_m64(long long __i)
-{
- return (__m64)__i;
-}
-
-inline long long __attribute__((__always_inline__)) _mm_cvtm64_si64(__m64 __m)
-{
- return (long long)__m;
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_packs_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_packsswb((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_packs_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_packssdw((__v2si)__m1, (__v2si)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_packs_pu16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_packuswb((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpackhi_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpackhi_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, 2, 4+2, 3, 4+3);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpackhi_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 1, 2+1);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpacklo_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpacklo_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, 0, 4+0, 1, 4+1);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpacklo_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 0, 2+0);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_add_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v8qi)__m1 + (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_add_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v4hi)__m1 + (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_add_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v2si)__m1 + (__v2si)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_adds_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_paddsb((__v8qi)__m1, (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_adds_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_paddsw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_adds_pu8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_paddusb((__v8qi)__m1, (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_adds_pu16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_paddusw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sub_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v8qi)__m1 - (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sub_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v4hi)__m1 - (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sub_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v2si)__m1 - (__v2si)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_subs_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_psubsb((__v8qi)__m1, (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_subs_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_psubsw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_subs_pu8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_psubusb((__v8qi)__m1, (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_subs_pu16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_psubusw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_madd_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pmaddwd((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_mulhi_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pmulhw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_mullo_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)((__v4hi)__m1 * (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sll_pi16(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_psllw((__v4hi)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_slli_pi16(__m64 __m, int __count)
-{
- return (__m64)__builtin_ia32_psllwi((__v4hi)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sll_pi32(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_pslld((__v2si)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_slli_pi32(__m64 __m, int __count)
-{
- return (__m64)__builtin_ia32_pslldi((__v2si)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sll_si64(__m64 __m, __m64 __count)
-{
- return __builtin_ia32_psllq(__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_slli_si64(__m64 __m, int __count)
-{
- return __builtin_ia32_psllqi(__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sra_pi16(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_psraw((__v4hi)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srai_pi16(__m64 __m, int __count)
-{
- return (__m64)__builtin_ia32_psrawi((__v4hi)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_sra_pi32(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_psrad((__v2si)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srai_pi32(__m64 __m, int __count)
-{
- return (__m64)__builtin_ia32_psradi((__v2si)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srl_pi16(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_psrlw((__v4hi)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srli_pi16(__m64 __m, int __count)
-{
- return (__m64)__builtin_ia32_psrlwi((__v4hi)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srl_pi32(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_psrld((__v2si)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srli_pi32(__m64 __m, int __count)
-{
- return (__m64)__builtin_ia32_psrldi((__v2si)__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srl_si64(__m64 __m, __m64 __count)
-{
- return (__m64)__builtin_ia32_psrlq(__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srli_si64(__m64 __m, int __count)
-{
- return __builtin_ia32_psrlqi(__m, __count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_and_si64(__m64 __m1, __m64 __m2)
-{
- return __m1 & __m2;
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_andnot_si64(__m64 __m1, __m64 __m2)
-{
- return ~__m1 & __m2;
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_or_si64(__m64 __m1, __m64 __m2)
-{
- return __m1 | __m2;
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_xor_si64(__m64 __m1, __m64 __m2)
-{
- return __m1 ^ __m2;
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pcmpeqb((__v8qi)__m1, (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pcmpeqw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pcmpeqd((__v2si)__m1, (__v2si)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pcmpgtb((__v8qi)__m1, (__v8qi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pcmpgtw((__v4hi)__m1, (__v4hi)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_cmpgt_pi32(__m64 __m1, __m64 __m2)
-{
- return (__m64)__builtin_ia32_pcmpgtd((__v2si)__m1, (__v2si)__m2);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_setzero_si64()
-{
- return (__m64){ 0LL };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_set_pi32(int __i1, int __i0)
-{
- return (__m64)(__v2si){ __i0, __i1 };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_set_pi16(short __s3, short __s2, short __s1, short __s0)
-{
- return (__m64)(__v4hi){ __s0, __s1, __s2, __s3 };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2, char __b1, char __b0)
-{
- return (__m64)(__v8qi){ __b0, __b1, __b2, __b3, __b4, __b5, __b6, __b7 };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_set1_pi32(int __i)
-{
- return (__m64)(__v2si){ __i, __i };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_set1_pi16(short __s)
-{
- return (__m64)(__v4hi){ __s };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_set1_pi8(char __b)
-{
- return (__m64)(__v8qi){ __b };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_setr_pi32(int __i1, int __i0)
-{
- return (__m64)(__v2si){ __i1, __i0 };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_setr_pi16(short __s3, short __s2, short __s1, short __s0)
-{
- return (__m64)(__v4hi){ __s3, __s2, __s1, __s0 };
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_setr_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2, char __b1, char __b0)
-{
- return (__m64)(__v8qi){ __b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0 };
-}
-
-#endif /* __MMX__ */
-
-#endif /* __MMINTRIN_H */
-
diff --git a/clang/lib/Headers/stdarg.h b/clang/lib/Headers/stdarg.h
deleted file mode 100644
index b73edb4699b7..000000000000
--- a/clang/lib/Headers/stdarg.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*===---- stdarg.h - Variable argument handling ----------------------------===
- *
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- *===-----------------------------------------------------------------------===
- */
-
-#ifndef __STDARG_H
-#define __STDARG_H
-
-typedef __builtin_va_list va_list;
-#define va_start(ap, param) __builtin_va_start(ap, param)
-#define va_end(ap) __builtin_va_end(ap)
-#define va_arg(ap, type) __builtin_va_arg(ap, type)
-#define va_copy(dest, src) __builtin_va_copy(dest, src)
-
-/* Hack required to make standard headers work, at least on Ubuntu */
-#define __GNUC_VA_LIST 1
-typedef __builtin_va_list __gnuc_va_list;
-
-#endif /* __STDARG_H */
diff --git a/clang/lib/Headers/stdbool.h b/clang/lib/Headers/stdbool.h
deleted file mode 100644
index e44a1f9a979f..000000000000
--- a/clang/lib/Headers/stdbool.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*===---- stdbool.h - Standard header for booleans -------------------------===
- *
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- *===-----------------------------------------------------------------------===
- */
-
-#ifndef __STDBOOL_H
-#define __STDBOOL_H
-
-/* Don't define bool, true, and false in C++ */
-#ifndef __cplusplus
-#define bool _Bool
-#define true 1
-#define false 0
-#endif
-
-#define __bool_true_false_are_defined 1
-
-#endif /* __STDBOOL_H */
diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h
deleted file mode 100644
index 3e7e4dda0d2e..000000000000
--- a/clang/lib/Headers/stddef.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*===---- stddef.h - Basic type definitions --------------------------------===
- *
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- *===-----------------------------------------------------------------------===
- */
-
-#ifndef __STDDEF_H
-#define __STDDEF_H
-
-typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t;
-typedef __typeof__(sizeof(int)) size_t;
-#ifndef __cplusplus
-typedef __typeof__(*L"") wchar_t;
-#endif
-
-#define NULL ((void*)0)
-#define offsetof(t, d) __builtin_offsetof(t, d)
-
-#endif /* __STDDEF_H */
diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp
deleted file mode 100644
index d058e1ece4b4..000000000000
--- a/clang/lib/Lex/HeaderMap.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-//===--- HeaderMap.cpp - A file that acts like dir of symlinks ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the HeaderMap interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/HeaderMap.h"
-#include "clang/Basic/FileManager.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/MemoryBuffer.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Data Structures and Manifest Constants
-//===----------------------------------------------------------------------===//
-
-enum {
- HMAP_HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p',
- HMAP_HeaderVersion = 1,
-
- HMAP_EmptyBucketKey = 0
-};
-
-namespace clang {
-struct HMapBucket {
- uint32_t Key; // Offset (into strings) of key.
-
- uint32_t Prefix; // Offset (into strings) of value prefix.
- uint32_t Suffix; // Offset (into strings) of value suffix.
-};
-
-struct HMapHeader {
- uint32_t Magic; // Magic word, also indicates byte order.
- uint16_t Version; // Version number -- currently 1.
- uint16_t Reserved; // Reserved for future use - zero for now.
- uint32_t StringsOffset; // Offset to start of string pool.
- uint32_t NumEntries; // Number of entries in the string table.
- uint32_t NumBuckets; // Number of buckets (always a power of 2).
- uint32_t MaxValueLength; // Length of longest result path (excluding nul).
- // An array of 'NumBuckets' HMapBucket objects follows this header.
- // Strings follow the buckets, at StringsOffset.
-};
-} // end namespace clang.
-
-/// HashHMapKey - This is the 'well known' hash function required by the file
-/// format, used to look up keys in the hash table. The hash table uses simple
-/// linear probing based on this function.
-static inline unsigned HashHMapKey(const char *S, const char *End) {
- unsigned Result = 0;
-
- for (; S != End; S++)
- Result += tolower(*S) * 13;
- return Result;
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// Verification and Construction
-//===----------------------------------------------------------------------===//
-
-/// HeaderMap::Create - This attempts to load the specified file as a header
-/// map. If it doesn't look like a HeaderMap, it gives up and returns null.
-/// If it looks like a HeaderMap but is obviously corrupted, it puts a reason
-/// into the string error argument and returns null.
-const HeaderMap *HeaderMap::Create(const FileEntry *FE) {
- // If the file is too small to be a header map, ignore it.
- unsigned FileSize = FE->getSize();
- if (FileSize <= sizeof(HMapHeader)) return 0;
-
- llvm::OwningPtr<const llvm::MemoryBuffer> FileBuffer(
- llvm::MemoryBuffer::getFile(FE->getName(), 0, FE->getSize()));
- if (FileBuffer == 0) return 0; // Unreadable file?
- const char *FileStart = FileBuffer->getBufferStart();
-
- // We know the file is at least as big as the header, check it now.
- const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart);
-
- // Sniff it to see if it's a headermap by checking the magic number and
- // version.
- bool NeedsByteSwap;
- if (Header->Magic == HMAP_HeaderMagicNumber &&
- Header->Version == HMAP_HeaderVersion)
- NeedsByteSwap = false;
- else if (Header->Magic == llvm::ByteSwap_32(HMAP_HeaderMagicNumber) &&
- Header->Version == llvm::ByteSwap_16(HMAP_HeaderVersion))
- NeedsByteSwap = true; // Mixed endianness headermap.
- else
- return 0; // Not a header map.
-
- if (Header->Reserved != 0) return 0;
-
- // Okay, everything looks good, create the header map.
- return new HeaderMap(FileBuffer.take(), NeedsByteSwap);
-}
-
-HeaderMap::~HeaderMap() {
- delete FileBuffer;
-}
-
-//===----------------------------------------------------------------------===//
-// Utility Methods
-//===----------------------------------------------------------------------===//
-
-
-/// getFileName - Return the filename of the headermap.
-const char *HeaderMap::getFileName() const {
- return FileBuffer->getBufferIdentifier();
-}
-
-unsigned HeaderMap::getEndianAdjustedWord(unsigned X) const {
- if (!NeedsBSwap) return X;
- return llvm::ByteSwap_32(X);
-}
-
-/// getHeader - Return a reference to the file header, in unbyte-swapped form.
-/// This method cannot fail.
-const HMapHeader &HeaderMap::getHeader() const {
- // We know the file is at least as big as the header. Return it.
- return *reinterpret_cast<const HMapHeader*>(FileBuffer->getBufferStart());
-}
-
-/// getBucket - Return the specified hash table bucket from the header map,
-/// bswap'ing its fields as appropriate. If the bucket number is not valid,
-/// this return a bucket with an empty key (0).
-HMapBucket HeaderMap::getBucket(unsigned BucketNo) const {
- HMapBucket Result;
- Result.Key = HMAP_EmptyBucketKey;
-
- const HMapBucket *BucketArray =
- reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() +
- sizeof(HMapHeader));
-
- const HMapBucket *BucketPtr = BucketArray+BucketNo;
- if ((char*)(BucketPtr+1) > FileBuffer->getBufferEnd())
- return Result; // Invalid buffer, corrupt hmap.
-
- // Otherwise, the bucket is valid. Load the values, bswapping as needed.
- Result.Key = getEndianAdjustedWord(BucketPtr->Key);
- Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix);
- Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix);
- return Result;
-}
-
-/// getString - Look up the specified string in the string table. If the string
-/// index is not valid, it returns an empty string.
-const char *HeaderMap::getString(unsigned StrTabIdx) const {
- // Add the start of the string table to the idx.
- StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);
-
- // Check for invalid index.
- if (StrTabIdx >= FileBuffer->getBufferSize())
- return 0;
-
- // Otherwise, we have a valid pointer into the file. Just return it. We know
- // that the "string" can not overrun the end of the file, because the buffer
- // is nul terminated by virtue of being a MemoryBuffer.
- return FileBuffer->getBufferStart()+StrTabIdx;
-}
-
-/// StringsEqualWithoutCase - Compare the specified two strings for case-
-/// insensitive equality, returning true if they are equal. Both strings are
-/// known to have the same length.
-static bool StringsEqualWithoutCase(const char *S1, const char *S2,
- unsigned Len) {
- for (; Len; ++S1, ++S2, --Len)
- if (tolower(*S1) != tolower(*S2))
- return false;
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// The Main Drivers
-//===----------------------------------------------------------------------===//
-
-/// dump - Print the contents of this headermap to stderr.
-void HeaderMap::dump() const {
- const HMapHeader &Hdr = getHeader();
- unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
-
- fprintf(stderr, "Header Map %s:\n %d buckets, %d entries\n",
- getFileName(), NumBuckets,
- getEndianAdjustedWord(Hdr.NumEntries));
-
- for (unsigned i = 0; i != NumBuckets; ++i) {
- HMapBucket B = getBucket(i);
- if (B.Key == HMAP_EmptyBucketKey) continue;
-
- const char *Key = getString(B.Key);
- const char *Prefix = getString(B.Prefix);
- const char *Suffix = getString(B.Suffix);
- fprintf(stderr, " %d. %s -> '%s' '%s'\n", i, Key, Prefix, Suffix);
- }
-}
-
-/// LookupFile - Check to see if the specified relative filename is located in
-/// this HeaderMap. If so, open it and return its FileEntry.
-const FileEntry *HeaderMap::LookupFile(const char *FilenameStart,
- const char *FilenameEnd,
- FileManager &FM) const {
- const HMapHeader &Hdr = getHeader();
- unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
-
- // If the number of buckets is not a power of two, the headermap is corrupt.
- // Don't probe infinitely.
- if (NumBuckets & (NumBuckets-1))
- return 0;
-
- // Linearly probe the hash table.
- for (unsigned Bucket = HashHMapKey(FilenameStart, FilenameEnd);; ++Bucket) {
- HMapBucket B = getBucket(Bucket & (NumBuckets-1));
- if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss.
-
- // See if the key matches. If not, probe on.
- const char *Key = getString(B.Key);
- unsigned BucketKeyLen = strlen(Key);
- if (BucketKeyLen != unsigned(FilenameEnd-FilenameStart))
- continue;
-
- // See if the actual strings equal.
- if (!StringsEqualWithoutCase(FilenameStart, Key, BucketKeyLen))
- continue;
-
- // If so, we have a match in the hash table. Construct the destination
- // path.
- llvm::SmallString<1024> DestPath;
- DestPath += getString(B.Prefix);
- DestPath += getString(B.Suffix);
- return FM.getFile(DestPath.begin(), DestPath.end());
- }
-}
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
deleted file mode 100644
index 44ae35c8b7e4..000000000000
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ /dev/null
@@ -1,425 +0,0 @@
-//===--- HeaderSearch.cpp - Resolve Header File Locations ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the DirectoryLookup and HeaderSearch interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/HeaderMap.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/System/Path.h"
-#include "llvm/ADT/SmallString.h"
-using namespace clang;
-
-HeaderSearch::HeaderSearch(FileManager &FM) : FileMgr(FM), FrameworkMap(64) {
- SystemDirIdx = 0;
- NoCurDirSearch = false;
-
- NumIncluded = 0;
- NumMultiIncludeFileOptzn = 0;
- NumFrameworkLookups = NumSubFrameworkLookups = 0;
-}
-
-HeaderSearch::~HeaderSearch() {
- // Delete headermaps.
- for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
- delete HeaderMaps[i].second;
-}
-
-void HeaderSearch::PrintStats() {
- fprintf(stderr, "\n*** HeaderSearch Stats:\n");
- fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
- unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
- for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
- NumOnceOnlyFiles += FileInfo[i].isImport;
- if (MaxNumIncludes < FileInfo[i].NumIncludes)
- MaxNumIncludes = FileInfo[i].NumIncludes;
- NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
- }
- fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles);
- fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles);
- fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes);
-
- fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded);
- fprintf(stderr, " %d #includes skipped due to"
- " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
-
- fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
- fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
-}
-
-/// CreateHeaderMap - This method returns a HeaderMap for the specified
-/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
-const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
- // We expect the number of headermaps to be small, and almost always empty.
- // If it ever grows, use of a linear search should be re-evaluated.
- if (!HeaderMaps.empty()) {
- for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
- // Pointer equality comparison of FileEntries works because they are
- // already uniqued by inode.
- if (HeaderMaps[i].first == FE)
- return HeaderMaps[i].second;
- }
-
- if (const HeaderMap *HM = HeaderMap::Create(FE)) {
- HeaderMaps.push_back(std::make_pair(FE, HM));
- return HM;
- }
-
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// File lookup within a DirectoryLookup scope
-//===----------------------------------------------------------------------===//
-
-/// getName - Return the directory or filename corresponding to this lookup
-/// object.
-const char *DirectoryLookup::getName() const {
- if (isNormalDir())
- return getDir()->getName();
- if (isFramework())
- return getFrameworkDir()->getName();
- assert(isHeaderMap() && "Unknown DirectoryLookup");
- return getHeaderMap()->getFileName();
-}
-
-
-/// LookupFile - Lookup the specified file in this search path, returning it
-/// if it exists or returning null if not.
-const FileEntry *DirectoryLookup::LookupFile(const char *FilenameStart,
- const char *FilenameEnd,
- HeaderSearch &HS) const {
- llvm::SmallString<1024> TmpDir;
- if (isNormalDir()) {
- // Concatenate the requested file onto the directory.
- // FIXME: Portability. Filename concatenation should be in sys::Path.
- TmpDir += getDir()->getName();
- TmpDir.push_back('/');
- TmpDir.append(FilenameStart, FilenameEnd);
- return HS.getFileMgr().getFile(TmpDir.begin(), TmpDir.end());
- }
-
- if (isFramework())
- return DoFrameworkLookup(FilenameStart, FilenameEnd, HS);
-
- assert(isHeaderMap() && "Unknown directory lookup");
- return getHeaderMap()->LookupFile(FilenameStart, FilenameEnd,HS.getFileMgr());
-}
-
-
-/// DoFrameworkLookup - Do a lookup of the specified file in the current
-/// DirectoryLookup, which is a framework directory.
-const FileEntry *DirectoryLookup::DoFrameworkLookup(const char *FilenameStart,
- const char *FilenameEnd,
- HeaderSearch &HS) const {
- FileManager &FileMgr = HS.getFileMgr();
-
- // Framework names must have a '/' in the filename.
- const char *SlashPos = std::find(FilenameStart, FilenameEnd, '/');
- if (SlashPos == FilenameEnd) return 0;
-
- // Find out if this is the home for the specified framework, by checking
- // HeaderSearch. Possible answer are yes/no and unknown.
- const DirectoryEntry *&FrameworkDirCache =
- HS.LookupFrameworkCache(FilenameStart, SlashPos);
-
- // If it is known and in some other directory, fail.
- if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir())
- return 0;
-
- // Otherwise, construct the path to this framework dir.
-
- // FrameworkName = "/System/Library/Frameworks/"
- llvm::SmallString<1024> FrameworkName;
- FrameworkName += getFrameworkDir()->getName();
- if (FrameworkName.empty() || FrameworkName.back() != '/')
- FrameworkName.push_back('/');
-
- // FrameworkName = "/System/Library/Frameworks/Cocoa"
- FrameworkName.append(FilenameStart, SlashPos);
-
- // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
- FrameworkName += ".framework/";
-
- // If the cache entry is still unresolved, query to see if the cache entry is
- // still unresolved. If so, check its existence now.
- if (FrameworkDirCache == 0) {
- HS.IncrementFrameworkLookupCount();
-
- // If the framework dir doesn't exist, we fail.
- // FIXME: It's probably more efficient to query this with FileMgr.getDir.
- if (!llvm::sys::Path(std::string(FrameworkName.begin(),
- FrameworkName.end())).exists())
- return 0;
-
- // Otherwise, if it does, remember that this is the right direntry for this
- // framework.
- FrameworkDirCache = getFrameworkDir();
- }
-
- // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
- unsigned OrigSize = FrameworkName.size();
-
- FrameworkName += "Headers/";
- FrameworkName.append(SlashPos+1, FilenameEnd);
- if (const FileEntry *FE = FileMgr.getFile(FrameworkName.begin(),
- FrameworkName.end())) {
- return FE;
- }
-
- // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
- const char *Private = "Private";
- FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
- Private+strlen(Private));
- return FileMgr.getFile(FrameworkName.begin(), FrameworkName.end());
-}
-
-
-//===----------------------------------------------------------------------===//
-// Header File Location.
-//===----------------------------------------------------------------------===//
-
-
-/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
-/// return null on failure. isAngled indicates whether the file reference is
-/// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if
-/// non-null, indicates where the #including file is, in case a relative search
-/// is needed.
-const FileEntry *HeaderSearch::LookupFile(const char *FilenameStart,
- const char *FilenameEnd,
- bool isAngled,
- const DirectoryLookup *FromDir,
- const DirectoryLookup *&CurDir,
- const FileEntry *CurFileEnt) {
- // If 'Filename' is absolute, check to see if it exists and no searching.
- // FIXME: Portability. This should be a sys::Path interface, this doesn't
- // handle things like C:\foo.txt right, nor win32 \\network\device\blah.
- if (FilenameStart[0] == '/') {
- CurDir = 0;
-
- // If this was an #include_next "/absolute/file", fail.
- if (FromDir) return 0;
-
- // Otherwise, just return the file.
- return FileMgr.getFile(FilenameStart, FilenameEnd);
- }
-
- // Step #0, unless disabled, check to see if the file is in the #includer's
- // directory. This has to be based on CurFileEnt, not CurDir, because
- // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
- // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
- // This search is not done for <> headers.
- if (CurFileEnt && !isAngled && !NoCurDirSearch) {
- llvm::SmallString<1024> TmpDir;
- // Concatenate the requested file onto the directory.
- // FIXME: Portability. Filename concatenation should be in sys::Path.
- TmpDir += CurFileEnt->getDir()->getName();
- TmpDir.push_back('/');
- TmpDir.append(FilenameStart, FilenameEnd);
- if (const FileEntry *FE = FileMgr.getFile(TmpDir.begin(), TmpDir.end())) {
- // Leave CurDir unset.
- // This file is a system header or C++ unfriendly if the old file is.
- //
- // Note that the temporary 'DirInfo' is required here, as either call to
- // getFileInfo could resize the vector and we don't want to rely on order
- // of evaluation.
- unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
- getFileInfo(FE).DirInfo = DirInfo;
- return FE;
- }
- }
-
- CurDir = 0;
-
- // If this is a system #include, ignore the user #include locs.
- unsigned i = isAngled ? SystemDirIdx : 0;
-
- // If this is a #include_next request, start searching after the directory the
- // file was found in.
- if (FromDir)
- i = FromDir-&SearchDirs[0];
-
- // Cache all of the lookups performed by this method. Many headers are
- // multiply included, and the "pragma once" optimization prevents them from
- // being relex/pp'd, but they would still have to search through a
- // (potentially huge) series of SearchDirs to find it.
- std::pair<unsigned, unsigned> &CacheLookup =
- LookupFileCache.GetOrCreateValue(FilenameStart, FilenameEnd).getValue();
-
- // If the entry has been previously looked up, the first value will be
- // non-zero. If the value is equal to i (the start point of our search), then
- // this is a matching hit.
- if (CacheLookup.first == i+1) {
- // Skip querying potentially lots of directories for this lookup.
- i = CacheLookup.second;
- } else {
- // Otherwise, this is the first query, or the previous query didn't match
- // our search start. We will fill in our found location below, so prime the
- // start point value.
- CacheLookup.first = i+1;
- }
-
- // Check each directory in sequence to see if it contains this file.
- for (; i != SearchDirs.size(); ++i) {
- const FileEntry *FE =
- SearchDirs[i].LookupFile(FilenameStart, FilenameEnd, *this);
- if (!FE) continue;
-
- CurDir = &SearchDirs[i];
-
- // This file is a system header or C++ unfriendly if the dir is.
- getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
-
- // Remember this location for the next lookup we do.
- CacheLookup.second = i;
- return FE;
- }
-
- // Otherwise, didn't find it. Remember we didn't find this.
- CacheLookup.second = SearchDirs.size();
- return 0;
-}
-
-/// LookupSubframeworkHeader - Look up a subframework for the specified
-/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
-/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
-/// is a subframework within Carbon.framework. If so, return the FileEntry
-/// for the designated file, otherwise return null.
-const FileEntry *HeaderSearch::
-LookupSubframeworkHeader(const char *FilenameStart,
- const char *FilenameEnd,
- const FileEntry *ContextFileEnt) {
- assert(ContextFileEnt && "No context file?");
-
- // Framework names must have a '/' in the filename. Find it.
- const char *SlashPos = std::find(FilenameStart, FilenameEnd, '/');
- if (SlashPos == FilenameEnd) return 0;
-
- // Look up the base framework name of the ContextFileEnt.
- const char *ContextName = ContextFileEnt->getName();
-
- // If the context info wasn't a framework, couldn't be a subframework.
- const char *FrameworkPos = strstr(ContextName, ".framework/");
- if (FrameworkPos == 0)
- return 0;
-
- llvm::SmallString<1024> FrameworkName(ContextName,
- FrameworkPos+strlen(".framework/"));
-
- // Append Frameworks/HIToolbox.framework/
- FrameworkName += "Frameworks/";
- FrameworkName.append(FilenameStart, SlashPos);
- FrameworkName += ".framework/";
-
- llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup =
- FrameworkMap.GetOrCreateValue(FilenameStart, SlashPos);
-
- // Some other location?
- if (CacheLookup.getValue() &&
- CacheLookup.getKeyLength() == FrameworkName.size() &&
- memcmp(CacheLookup.getKeyData(), &FrameworkName[0],
- CacheLookup.getKeyLength()) != 0)
- return 0;
-
- // Cache subframework.
- if (CacheLookup.getValue() == 0) {
- ++NumSubFrameworkLookups;
-
- // If the framework dir doesn't exist, we fail.
- const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.begin(),
- FrameworkName.end());
- if (Dir == 0) return 0;
-
- // Otherwise, if it does, remember that this is the right direntry for this
- // framework.
- CacheLookup.setValue(Dir);
- }
-
- const FileEntry *FE = 0;
-
- // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
- llvm::SmallString<1024> HeadersFilename(FrameworkName);
- HeadersFilename += "Headers/";
- HeadersFilename.append(SlashPos+1, FilenameEnd);
- if (!(FE = FileMgr.getFile(HeadersFilename.begin(),
- HeadersFilename.end()))) {
-
- // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
- HeadersFilename = FrameworkName;
- HeadersFilename += "PrivateHeaders/";
- HeadersFilename.append(SlashPos+1, FilenameEnd);
- if (!(FE = FileMgr.getFile(HeadersFilename.begin(), HeadersFilename.end())))
- return 0;
- }
-
- // This file is a system header or C++ unfriendly if the old file is.
- //
- // Note that the temporary 'DirInfo' is required here, as either call to
- // getFileInfo could resize the vector and we don't want to rely on order
- // of evaluation.
- unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
- getFileInfo(FE).DirInfo = DirInfo;
- return FE;
-}
-
-//===----------------------------------------------------------------------===//
-// File Info Management.
-//===----------------------------------------------------------------------===//
-
-
-/// getFileInfo - Return the PerFileInfo structure for the specified
-/// FileEntry.
-HeaderSearch::PerFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
- if (FE->getUID() >= FileInfo.size())
- FileInfo.resize(FE->getUID()+1);
- return FileInfo[FE->getUID()];
-}
-
-/// ShouldEnterIncludeFile - Mark the specified file as a target of of a
-/// #include, #include_next, or #import directive. Return false if #including
-/// the file will have no effect or true if we should include it.
-bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
- ++NumIncluded; // Count # of attempted #includes.
-
- // Get information about this file.
- PerFileInfo &FileInfo = getFileInfo(File);
-
- // If this is a #import directive, check that we have not already imported
- // this header.
- if (isImport) {
- // If this has already been imported, don't import it again.
- FileInfo.isImport = true;
-
- // Has this already been #import'ed or #include'd?
- if (FileInfo.NumIncludes) return false;
- } else {
- // Otherwise, if this is a #include of a file that was previously #import'd
- // or if this is the second #include of a #pragma once file, ignore it.
- if (FileInfo.isImport)
- return false;
- }
-
- // Next, check to see if the file is wrapped with #ifndef guards. If so, and
- // if the macro that guards it is defined, we know the #include has no effect.
- if (FileInfo.ControllingMacro &&
- FileInfo.ControllingMacro->hasMacroDefinition()) {
- ++NumMultiIncludeFileOptzn;
- return false;
- }
-
- // Increment the number of times this file has been included.
- ++FileInfo.NumIncludes;
-
- return true;
-}
-
-
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
deleted file mode 100644
index 8bce589f177f..000000000000
--- a/clang/lib/Lex/Lexer.cpp
+++ /dev/null
@@ -1,1656 +0,0 @@
-//===--- Lexer.cpp - C Language Family Lexer ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Lexer and Token interfaces.
-//
-//===----------------------------------------------------------------------===//
-//
-// TODO: GCC Diagnostics emitted by the lexer:
-// PEDWARN: (form feed|vertical tab) in preprocessing directive
-//
-// Universal characters, unicode, char mapping:
-// WARNING: `%.*s' is not in NFKC
-// WARNING: `%.*s' is not in NFC
-//
-// Other:
-// TODO: Options to support:
-// -fexec-charset,-fwide-exec-charset
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cctype>
-using namespace clang;
-
-static void InitCharacterInfo();
-
-//===----------------------------------------------------------------------===//
-// Token Class Implementation
-//===----------------------------------------------------------------------===//
-
-/// isObjCAtKeyword - Return true if we have an ObjC keyword identifier.
-bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const {
- return is(tok::identifier) &&
- getIdentifierInfo()->getObjCKeywordID() == objcKey;
-}
-
-/// getObjCKeywordID - Return the ObjC keyword kind.
-tok::ObjCKeywordKind Token::getObjCKeywordID() const {
- IdentifierInfo *specId = getIdentifierInfo();
- return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Lexer Class Implementation
-//===----------------------------------------------------------------------===//
-
-
-/// Lexer constructor - Create a new lexer object for the specified buffer
-/// with the specified preprocessor managing the lexing process. This lexer
-/// assumes that the associated file buffer and Preprocessor objects will
-/// outlive it, so it doesn't take ownership of either of them.
-Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp,
- const char *BufStart, const char *BufEnd)
- : FileLoc(fileloc), PP(&pp), Features(pp.getLangOptions()) {
-
- SourceManager &SourceMgr = PP->getSourceManager();
- unsigned InputFileID = SourceMgr.getPhysicalLoc(FileLoc).getFileID();
- const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(InputFileID);
-
- Is_PragmaLexer = false;
- InitCharacterInfo();
-
- // BufferStart must always be InputFile->getBufferStart().
- BufferStart = InputFile->getBufferStart();
-
- // BufferPtr and BufferEnd can start out somewhere inside the current buffer.
- // If unspecified, they starts at the start/end of the buffer.
- BufferPtr = BufStart ? BufStart : BufferStart;
- BufferEnd = BufEnd ? BufEnd : InputFile->getBufferEnd();
-
- assert(BufferEnd[0] == 0 &&
- "We assume that the input buffer has a null character at the end"
- " to simplify lexing!");
-
- // Start of the file is a start of line.
- IsAtStartOfLine = true;
-
- // We are not after parsing a #.
- ParsingPreprocessorDirective = false;
-
- // We are not after parsing #include.
- ParsingFilename = false;
-
- // We are not in raw mode. Raw mode disables diagnostics and interpretation
- // of tokens (e.g. identifiers, thus disabling macro expansion). It is used
- // to quickly lex the tokens of the buffer, e.g. when handling a "#if 0" block
- // or otherwise skipping over tokens.
- LexingRawMode = false;
-
- // Default to keeping comments if requested.
- KeepCommentMode = PP->getCommentRetentionState();
-}
-
-/// Lexer constructor - Create a new raw lexer object. This object is only
-/// suitable for calls to 'LexRawToken'. This lexer assumes that the
-/// associated file buffer will outlive it, so it doesn't take ownership of
-/// either of them.
-Lexer::Lexer(SourceLocation fileloc, const LangOptions &features,
- const char *BufStart, const char *BufEnd)
- : FileLoc(fileloc), PP(0), Features(features) {
- Is_PragmaLexer = false;
- InitCharacterInfo();
-
- BufferStart = BufStart;
- BufferPtr = BufStart;
- BufferEnd = BufEnd;
-
- assert(BufferEnd[0] == 0 &&
- "We assume that the input buffer has a null character at the end"
- " to simplify lexing!");
-
- // Start of the file is a start of line.
- IsAtStartOfLine = true;
-
- // We are not after parsing a #.
- ParsingPreprocessorDirective = false;
-
- // We are not after parsing #include.
- ParsingFilename = false;
-
- // We *are* in raw mode.
- LexingRawMode = true;
-
- // Never keep comments in raw mode.
- KeepCommentMode = false;
-}
-
-
-/// Stringify - Convert the specified string into a C string, with surrounding
-/// ""'s, and with escaped \ and " characters.
-std::string Lexer::Stringify(const std::string &Str, bool Charify) {
- std::string Result = Str;
- char Quote = Charify ? '\'' : '"';
- for (unsigned i = 0, e = Result.size(); i != e; ++i) {
- if (Result[i] == '\\' || Result[i] == Quote) {
- Result.insert(Result.begin()+i, '\\');
- ++i; ++e;
- }
- }
- return Result;
-}
-
-/// Stringify - Convert the specified string into a C string by escaping '\'
-/// and " characters. This does not add surrounding ""'s to the string.
-void Lexer::Stringify(llvm::SmallVectorImpl<char> &Str) {
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- if (Str[i] == '\\' || Str[i] == '"') {
- Str.insert(Str.begin()+i, '\\');
- ++i; ++e;
- }
- }
-}
-
-
-/// MeasureTokenLength - Relex the token at the specified location and return
-/// its length in bytes in the input file. If the token needs cleaning (e.g.
-/// includes a trigraph or an escaped newline) then this count includes bytes
-/// that are part of that.
-unsigned Lexer::MeasureTokenLength(SourceLocation Loc,
- const SourceManager &SM) {
- // If this comes from a macro expansion, we really do want the macro name, not
- // the token this macro expanded to.
- Loc = SM.getLogicalLoc(Loc);
-
- const char *StrData = SM.getCharacterData(Loc);
-
- // TODO: this could be special cased for common tokens like identifiers, ')',
- // etc to make this faster, if it mattered. Just look at StrData[0] to handle
- // all obviously single-char tokens. This could use
- // Lexer::isObviouslySimpleCharacter for example to handle identifiers or
- // something.
-
-
- const char *BufEnd = SM.getBufferData(Loc.getFileID()).second;
-
- // Create a langops struct and enable trigraphs. This is sufficient for
- // measuring tokens.
- LangOptions LangOpts;
- LangOpts.Trigraphs = true;
-
- // Create a lexer starting at the beginning of this token.
- Lexer TheLexer(Loc, LangOpts, StrData, BufEnd);
- Token TheTok;
- TheLexer.LexRawToken(TheTok);
- return TheTok.getLength();
-}
-
-//===----------------------------------------------------------------------===//
-// Character information.
-//===----------------------------------------------------------------------===//
-
-static unsigned char CharInfo[256];
-
-enum {
- CHAR_HORZ_WS = 0x01, // ' ', '\t', '\f', '\v'. Note, no '\0'
- CHAR_VERT_WS = 0x02, // '\r', '\n'
- CHAR_LETTER = 0x04, // a-z,A-Z
- CHAR_NUMBER = 0x08, // 0-9
- CHAR_UNDER = 0x10, // _
- CHAR_PERIOD = 0x20 // .
-};
-
-static void InitCharacterInfo() {
- static bool isInited = false;
- if (isInited) return;
- isInited = true;
-
- // Intiialize the CharInfo table.
- // TODO: statically initialize this.
- CharInfo[(int)' '] = CharInfo[(int)'\t'] =
- CharInfo[(int)'\f'] = CharInfo[(int)'\v'] = CHAR_HORZ_WS;
- CharInfo[(int)'\n'] = CharInfo[(int)'\r'] = CHAR_VERT_WS;
-
- CharInfo[(int)'_'] = CHAR_UNDER;
- CharInfo[(int)'.'] = CHAR_PERIOD;
- for (unsigned i = 'a'; i <= 'z'; ++i)
- CharInfo[i] = CharInfo[i+'A'-'a'] = CHAR_LETTER;
- for (unsigned i = '0'; i <= '9'; ++i)
- CharInfo[i] = CHAR_NUMBER;
-}
-
-/// isIdentifierBody - Return true if this is the body character of an
-/// identifier, which is [a-zA-Z0-9_].
-static inline bool isIdentifierBody(unsigned char c) {
- return (CharInfo[c] & (CHAR_LETTER|CHAR_NUMBER|CHAR_UNDER)) ? true : false;
-}
-
-/// isHorizontalWhitespace - Return true if this character is horizontal
-/// whitespace: ' ', '\t', '\f', '\v'. Note that this returns false for '\0'.
-static inline bool isHorizontalWhitespace(unsigned char c) {
- return (CharInfo[c] & CHAR_HORZ_WS) ? true : false;
-}
-
-/// isWhitespace - Return true if this character is horizontal or vertical
-/// whitespace: ' ', '\t', '\f', '\v', '\n', '\r'. Note that this returns false
-/// for '\0'.
-static inline bool isWhitespace(unsigned char c) {
- return (CharInfo[c] & (CHAR_HORZ_WS|CHAR_VERT_WS)) ? true : false;
-}
-
-/// isNumberBody - Return true if this is the body character of an
-/// preprocessing number, which is [a-zA-Z0-9_.].
-static inline bool isNumberBody(unsigned char c) {
- return (CharInfo[c] & (CHAR_LETTER|CHAR_NUMBER|CHAR_UNDER|CHAR_PERIOD)) ?
- true : false;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Diagnostics forwarding code.
-//===----------------------------------------------------------------------===//
-
-/// GetMappedTokenLoc - If lexing out of a 'mapped buffer', where we pretend the
-/// lexer buffer was all instantiated at a single point, perform the mapping.
-/// This is currently only used for _Pragma implementation, so it is the slow
-/// path of the hot getSourceLocation method. Do not allow it to be inlined.
-static SourceLocation GetMappedTokenLoc(Preprocessor &PP,
- SourceLocation FileLoc,
- unsigned CharNo) DISABLE_INLINE;
-static SourceLocation GetMappedTokenLoc(Preprocessor &PP,
- SourceLocation FileLoc,
- unsigned CharNo) {
- // Otherwise, we're lexing "mapped tokens". This is used for things like
- // _Pragma handling. Combine the instantiation location of FileLoc with the
- // physical location.
- SourceManager &SourceMgr = PP.getSourceManager();
-
- // Create a new SLoc which is expanded from logical(FileLoc) but whose
- // characters come from phys(FileLoc)+Offset.
- SourceLocation VirtLoc = SourceMgr.getLogicalLoc(FileLoc);
- SourceLocation PhysLoc = SourceMgr.getPhysicalLoc(FileLoc);
- PhysLoc = SourceLocation::getFileLoc(PhysLoc.getFileID(), CharNo);
- return SourceMgr.getInstantiationLoc(PhysLoc, VirtLoc);
-}
-
-/// getSourceLocation - Return a source location identifier for the specified
-/// offset in the current file.
-SourceLocation Lexer::getSourceLocation(const char *Loc) const {
- assert(Loc >= BufferStart && Loc <= BufferEnd &&
- "Location out of range for this buffer!");
-
- // In the normal case, we're just lexing from a simple file buffer, return
- // the file id from FileLoc with the offset specified.
- unsigned CharNo = Loc-BufferStart;
- if (FileLoc.isFileID())
- return SourceLocation::getFileLoc(FileLoc.getFileID(), CharNo);
-
- assert(PP && "This doesn't work on raw lexers");
- return GetMappedTokenLoc(*PP, FileLoc, CharNo);
-}
-
-/// Diag - Forwarding function for diagnostics. This translate a source
-/// position in the current buffer into a SourceLocation object for rendering.
-void Lexer::Diag(const char *Loc, unsigned DiagID,
- const std::string &Msg) const {
- if (LexingRawMode && Diagnostic::isBuiltinNoteWarningOrExtension(DiagID))
- return;
- PP->Diag(getSourceLocation(Loc), DiagID, Msg);
-}
-void Lexer::Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg) const {
- if (LexingRawMode && Diagnostic::isBuiltinNoteWarningOrExtension(DiagID))
- return;
- PP->Diag(Loc, DiagID, Msg);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Trigraph and Escaped Newline Handling Code.
-//===----------------------------------------------------------------------===//
-
-/// GetTrigraphCharForLetter - Given a character that occurs after a ?? pair,
-/// return the decoded trigraph letter it corresponds to, or '\0' if nothing.
-static char GetTrigraphCharForLetter(char Letter) {
- switch (Letter) {
- default: return 0;
- case '=': return '#';
- case ')': return ']';
- case '(': return '[';
- case '!': return '|';
- case '\'': return '^';
- case '>': return '}';
- case '/': return '\\';
- case '<': return '{';
- case '-': return '~';
- }
-}
-
-/// DecodeTrigraphChar - If the specified character is a legal trigraph when
-/// prefixed with ??, emit a trigraph warning. If trigraphs are enabled,
-/// return the result character. Finally, emit a warning about trigraph use
-/// whether trigraphs are enabled or not.
-static char DecodeTrigraphChar(const char *CP, Lexer *L) {
- char Res = GetTrigraphCharForLetter(*CP);
- if (Res && L) {
- if (!L->getFeatures().Trigraphs) {
- L->Diag(CP-2, diag::trigraph_ignored);
- return 0;
- } else {
- L->Diag(CP-2, diag::trigraph_converted, std::string()+Res);
- }
- }
- return Res;
-}
-
-/// getCharAndSizeSlow - Peek a single 'character' from the specified buffer,
-/// get its size, and return it. This is tricky in several cases:
-/// 1. If currently at the start of a trigraph, we warn about the trigraph,
-/// then either return the trigraph (skipping 3 chars) or the '?',
-/// depending on whether trigraphs are enabled or not.
-/// 2. If this is an escaped newline (potentially with whitespace between
-/// the backslash and newline), implicitly skip the newline and return
-/// the char after it.
-/// 3. If this is a UCN, return it. FIXME: C++ UCN's?
-///
-/// This handles the slow/uncommon case of the getCharAndSize method. Here we
-/// know that we can accumulate into Size, and that we have already incremented
-/// Ptr by Size bytes.
-///
-/// NOTE: When this method is updated, getCharAndSizeSlowNoWarn (below) should
-/// be updated to match.
-///
-char Lexer::getCharAndSizeSlow(const char *Ptr, unsigned &Size,
- Token *Tok) {
- // If we have a slash, look for an escaped newline.
- if (Ptr[0] == '\\') {
- ++Size;
- ++Ptr;
-Slash:
- // Common case, backslash-char where the char is not whitespace.
- if (!isWhitespace(Ptr[0])) return '\\';
-
- // See if we have optional whitespace characters followed by a newline.
- {
- unsigned SizeTmp = 0;
- do {
- ++SizeTmp;
- if (Ptr[SizeTmp-1] == '\n' || Ptr[SizeTmp-1] == '\r') {
- // Remember that this token needs to be cleaned.
- if (Tok) Tok->setFlag(Token::NeedsCleaning);
-
- // Warn if there was whitespace between the backslash and newline.
- if (SizeTmp != 1 && Tok)
- Diag(Ptr, diag::backslash_newline_space);
-
- // If this is a \r\n or \n\r, skip the newlines.
- if ((Ptr[SizeTmp] == '\r' || Ptr[SizeTmp] == '\n') &&
- Ptr[SizeTmp-1] != Ptr[SizeTmp])
- ++SizeTmp;
-
- // Found backslash<whitespace><newline>. Parse the char after it.
- Size += SizeTmp;
- Ptr += SizeTmp;
- // Use slow version to accumulate a correct size field.
- return getCharAndSizeSlow(Ptr, Size, Tok);
- }
- } while (isWhitespace(Ptr[SizeTmp]));
- }
-
- // Otherwise, this is not an escaped newline, just return the slash.
- return '\\';
- }
-
- // If this is a trigraph, process it.
- if (Ptr[0] == '?' && Ptr[1] == '?') {
- // If this is actually a legal trigraph (not something like "??x"), emit
- // a trigraph warning. If so, and if trigraphs are enabled, return it.
- if (char C = DecodeTrigraphChar(Ptr+2, Tok ? this : 0)) {
- // Remember that this token needs to be cleaned.
- if (Tok) Tok->setFlag(Token::NeedsCleaning);
-
- Ptr += 3;
- Size += 3;
- if (C == '\\') goto Slash;
- return C;
- }
- }
-
- // If this is neither, return a single character.
- ++Size;
- return *Ptr;
-}
-
-
-/// getCharAndSizeSlowNoWarn - Handle the slow/uncommon case of the
-/// getCharAndSizeNoWarn method. Here we know that we can accumulate into Size,
-/// and that we have already incremented Ptr by Size bytes.
-///
-/// NOTE: When this method is updated, getCharAndSizeSlow (above) should
-/// be updated to match.
-char Lexer::getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features) {
- // If we have a slash, look for an escaped newline.
- if (Ptr[0] == '\\') {
- ++Size;
- ++Ptr;
-Slash:
- // Common case, backslash-char where the char is not whitespace.
- if (!isWhitespace(Ptr[0])) return '\\';
-
- // See if we have optional whitespace characters followed by a newline.
- {
- unsigned SizeTmp = 0;
- do {
- ++SizeTmp;
- if (Ptr[SizeTmp-1] == '\n' || Ptr[SizeTmp-1] == '\r') {
-
- // If this is a \r\n or \n\r, skip the newlines.
- if ((Ptr[SizeTmp] == '\r' || Ptr[SizeTmp] == '\n') &&
- Ptr[SizeTmp-1] != Ptr[SizeTmp])
- ++SizeTmp;
-
- // Found backslash<whitespace><newline>. Parse the char after it.
- Size += SizeTmp;
- Ptr += SizeTmp;
-
- // Use slow version to accumulate a correct size field.
- return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
- }
- } while (isWhitespace(Ptr[SizeTmp]));
- }
-
- // Otherwise, this is not an escaped newline, just return the slash.
- return '\\';
- }
-
- // If this is a trigraph, process it.
- if (Features.Trigraphs && Ptr[0] == '?' && Ptr[1] == '?') {
- // If this is actually a legal trigraph (not something like "??x"), return
- // it.
- if (char C = GetTrigraphCharForLetter(Ptr[2])) {
- Ptr += 3;
- Size += 3;
- if (C == '\\') goto Slash;
- return C;
- }
- }
-
- // If this is neither, return a single character.
- ++Size;
- return *Ptr;
-}
-
-//===----------------------------------------------------------------------===//
-// Helper methods for lexing.
-//===----------------------------------------------------------------------===//
-
-void Lexer::LexIdentifier(Token &Result, const char *CurPtr) {
- // Match [_A-Za-z0-9]*, we have already matched [_A-Za-z$]
- unsigned Size;
- unsigned char C = *CurPtr++;
- while (isIdentifierBody(C)) {
- C = *CurPtr++;
- }
- --CurPtr; // Back up over the skipped character.
-
- // Fast path, no $,\,? in identifier found. '\' might be an escaped newline
- // or UCN, and ? might be a trigraph for '\', an escaped newline or UCN.
- // FIXME: UCNs.
- if (C != '\\' && C != '?' && (C != '$' || !Features.DollarIdents)) {
-FinishIdentifier:
- const char *IdStart = BufferPtr;
- FormTokenWithChars(Result, CurPtr);
- Result.setKind(tok::identifier);
-
- // If we are in raw mode, return this identifier raw. There is no need to
- // look up identifier information or attempt to macro expand it.
- if (LexingRawMode) return;
-
- // Fill in Result.IdentifierInfo, looking up the identifier in the
- // identifier table.
- PP->LookUpIdentifierInfo(Result, IdStart);
-
- // Finally, now that we know we have an identifier, pass this off to the
- // preprocessor, which may macro expand it or something.
- return PP->HandleIdentifier(Result);
- }
-
- // Otherwise, $,\,? in identifier found. Enter slower path.
-
- C = getCharAndSize(CurPtr, Size);
- while (1) {
- if (C == '$') {
- // If we hit a $ and they are not supported in identifiers, we are done.
- if (!Features.DollarIdents) goto FinishIdentifier;
-
- // Otherwise, emit a diagnostic and continue.
- Diag(CurPtr, diag::ext_dollar_in_identifier);
- CurPtr = ConsumeChar(CurPtr, Size, Result);
- C = getCharAndSize(CurPtr, Size);
- continue;
- } else if (!isIdentifierBody(C)) { // FIXME: UCNs.
- // Found end of identifier.
- goto FinishIdentifier;
- }
-
- // Otherwise, this character is good, consume it.
- CurPtr = ConsumeChar(CurPtr, Size, Result);
-
- C = getCharAndSize(CurPtr, Size);
- while (isIdentifierBody(C)) { // FIXME: UCNs.
- CurPtr = ConsumeChar(CurPtr, Size, Result);
- C = getCharAndSize(CurPtr, Size);
- }
- }
-}
-
-
-/// LexNumericConstant - Lex the remainder of a integer or floating point
-/// constant. From[-1] is the first character lexed. Return the end of the
-/// constant.
-void Lexer::LexNumericConstant(Token &Result, const char *CurPtr) {
- unsigned Size;
- char C = getCharAndSize(CurPtr, Size);
- char PrevCh = 0;
- while (isNumberBody(C)) { // FIXME: UCNs?
- CurPtr = ConsumeChar(CurPtr, Size, Result);
- PrevCh = C;
- C = getCharAndSize(CurPtr, Size);
- }
-
- // If we fell out, check for a sign, due to 1e+12. If we have one, continue.
- if ((C == '-' || C == '+') && (PrevCh == 'E' || PrevCh == 'e'))
- return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
-
- // If we have a hex FP constant, continue.
- if (Features.HexFloats &&
- (C == '-' || C == '+') && (PrevCh == 'P' || PrevCh == 'p'))
- return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
-
- Result.setKind(tok::numeric_constant);
-
- // Update the location of token as well as BufferPtr.
- FormTokenWithChars(Result, CurPtr);
-}
-
-/// LexStringLiteral - Lex the remainder of a string literal, after having lexed
-/// either " or L".
-void Lexer::LexStringLiteral(Token &Result, const char *CurPtr, bool Wide){
- const char *NulCharacter = 0; // Does this string contain the \0 character?
-
- char C = getAndAdvanceChar(CurPtr, Result);
- while (C != '"') {
- // Skip escaped characters.
- if (C == '\\') {
- // Skip the escaped character.
- C = getAndAdvanceChar(CurPtr, Result);
- } else if (C == '\n' || C == '\r' || // Newline.
- (C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!LexingRawMode) Diag(BufferPtr, diag::err_unterminated_string);
- Result.setKind(tok::unknown);
- FormTokenWithChars(Result, CurPtr-1);
- return;
- } else if (C == 0) {
- NulCharacter = CurPtr-1;
- }
- C = getAndAdvanceChar(CurPtr, Result);
- }
-
- // If a nul character existed in the string, warn about it.
- if (NulCharacter) Diag(NulCharacter, diag::null_in_string);
-
- Result.setKind(Wide ? tok::wide_string_literal : tok::string_literal);
-
- // Update the location of the token as well as the BufferPtr instance var.
- FormTokenWithChars(Result, CurPtr);
-}
-
-/// LexAngledStringLiteral - Lex the remainder of an angled string literal,
-/// after having lexed the '<' character. This is used for #include filenames.
-void Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
- const char *NulCharacter = 0; // Does this string contain the \0 character?
-
- char C = getAndAdvanceChar(CurPtr, Result);
- while (C != '>') {
- // Skip escaped characters.
- if (C == '\\') {
- // Skip the escaped character.
- C = getAndAdvanceChar(CurPtr, Result);
- } else if (C == '\n' || C == '\r' || // Newline.
- (C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!LexingRawMode) Diag(BufferPtr, diag::err_unterminated_string);
- Result.setKind(tok::unknown);
- FormTokenWithChars(Result, CurPtr-1);
- return;
- } else if (C == 0) {
- NulCharacter = CurPtr-1;
- }
- C = getAndAdvanceChar(CurPtr, Result);
- }
-
- // If a nul character existed in the string, warn about it.
- if (NulCharacter) Diag(NulCharacter, diag::null_in_string);
-
- Result.setKind(tok::angle_string_literal);
-
- // Update the location of token as well as BufferPtr.
- FormTokenWithChars(Result, CurPtr);
-}
-
-
-/// LexCharConstant - Lex the remainder of a character constant, after having
-/// lexed either ' or L'.
-void Lexer::LexCharConstant(Token &Result, const char *CurPtr) {
- const char *NulCharacter = 0; // Does this character contain the \0 character?
-
- // Handle the common case of 'x' and '\y' efficiently.
- char C = getAndAdvanceChar(CurPtr, Result);
- if (C == '\'') {
- if (!LexingRawMode) Diag(BufferPtr, diag::err_empty_character);
- Result.setKind(tok::unknown);
- FormTokenWithChars(Result, CurPtr);
- return;
- } else if (C == '\\') {
- // Skip the escaped character.
- // FIXME: UCN's.
- C = getAndAdvanceChar(CurPtr, Result);
- }
-
- if (C && C != '\n' && C != '\r' && CurPtr[0] == '\'') {
- ++CurPtr;
- } else {
- // Fall back on generic code for embedded nulls, newlines, wide chars.
- do {
- // Skip escaped characters.
- if (C == '\\') {
- // Skip the escaped character.
- C = getAndAdvanceChar(CurPtr, Result);
- } else if (C == '\n' || C == '\r' || // Newline.
- (C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!LexingRawMode) Diag(BufferPtr, diag::err_unterminated_char);
- Result.setKind(tok::unknown);
- FormTokenWithChars(Result, CurPtr-1);
- return;
- } else if (C == 0) {
- NulCharacter = CurPtr-1;
- }
- C = getAndAdvanceChar(CurPtr, Result);
- } while (C != '\'');
- }
-
- if (NulCharacter) Diag(NulCharacter, diag::null_in_char);
-
- Result.setKind(tok::char_constant);
-
- // Update the location of token as well as BufferPtr.
- FormTokenWithChars(Result, CurPtr);
-}
-
-/// SkipWhitespace - Efficiently skip over a series of whitespace characters.
-/// Update BufferPtr to point to the next non-whitespace character and return.
-void Lexer::SkipWhitespace(Token &Result, const char *CurPtr) {
- // Whitespace - Skip it, then return the token after the whitespace.
- unsigned char Char = *CurPtr; // Skip consequtive spaces efficiently.
- while (1) {
- // Skip horizontal whitespace very aggressively.
- while (isHorizontalWhitespace(Char))
- Char = *++CurPtr;
-
- // Otherwise if we something other than whitespace, we're done.
- if (Char != '\n' && Char != '\r')
- break;
-
- if (ParsingPreprocessorDirective) {
- // End of preprocessor directive line, let LexTokenInternal handle this.
- BufferPtr = CurPtr;
- return;
- }
-
- // ok, but handle newline.
- // The returned token is at the start of the line.
- Result.setFlag(Token::StartOfLine);
- // No leading whitespace seen so far.
- Result.clearFlag(Token::LeadingSpace);
- Char = *++CurPtr;
- }
-
- // If this isn't immediately after a newline, there is leading space.
- char PrevChar = CurPtr[-1];
- if (PrevChar != '\n' && PrevChar != '\r')
- Result.setFlag(Token::LeadingSpace);
-
- BufferPtr = CurPtr;
-}
-
-// SkipBCPLComment - We have just read the // characters from input. Skip until
-// we find the newline character thats terminate the comment. Then update
-/// BufferPtr and return.
-bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
- // If BCPL comments aren't explicitly enabled for this language, emit an
- // extension warning.
- if (!Features.BCPLComment) {
- Diag(BufferPtr, diag::ext_bcpl_comment);
-
- // Mark them enabled so we only emit one warning for this translation
- // unit.
- Features.BCPLComment = true;
- }
-
- // Scan over the body of the comment. The common case, when scanning, is that
- // the comment contains normal ascii characters with nothing interesting in
- // them. As such, optimize for this case with the inner loop.
- char C;
- do {
- C = *CurPtr;
- // FIXME: Speedup BCPL comment lexing. Just scan for a \n or \r character.
- // If we find a \n character, scan backwards, checking to see if it's an
- // escaped newline, like we do for block comments.
-
- // Skip over characters in the fast loop.
- while (C != 0 && // Potentially EOF.
- C != '\\' && // Potentially escaped newline.
- C != '?' && // Potentially trigraph.
- C != '\n' && C != '\r') // Newline or DOS-style newline.
- C = *++CurPtr;
-
- // If this is a newline, we're done.
- if (C == '\n' || C == '\r')
- break; // Found the newline? Break out!
-
- // Otherwise, this is a hard case. Fall back on getAndAdvanceChar to
- // properly decode the character.
- const char *OldPtr = CurPtr;
- C = getAndAdvanceChar(CurPtr, Result);
-
- // If we read multiple characters, and one of those characters was a \r or
- // \n, then we had an escaped newline within the comment. Emit diagnostic
- // unless the next line is also a // comment.
- if (CurPtr != OldPtr+1 && C != '/' && CurPtr[0] != '/') {
- for (; OldPtr != CurPtr; ++OldPtr)
- if (OldPtr[0] == '\n' || OldPtr[0] == '\r') {
- // Okay, we found a // comment that ends in a newline, if the next
- // line is also a // comment, but has spaces, don't emit a diagnostic.
- if (isspace(C)) {
- const char *ForwardPtr = CurPtr;
- while (isspace(*ForwardPtr)) // Skip whitespace.
- ++ForwardPtr;
- if (ForwardPtr[0] == '/' && ForwardPtr[1] == '/')
- break;
- }
-
- Diag(OldPtr-1, diag::ext_multi_line_bcpl_comment);
- break;
- }
- }
-
- if (CurPtr == BufferEnd+1) { --CurPtr; break; }
- } while (C != '\n' && C != '\r');
-
- // Found but did not consume the newline.
-
- // If we are returning comments as tokens, return this comment as a token.
- if (KeepCommentMode)
- return SaveBCPLComment(Result, CurPtr);
-
- // If we are inside a preprocessor directive and we see the end of line,
- // return immediately, so that the lexer can return this as an EOM token.
- if (ParsingPreprocessorDirective || CurPtr == BufferEnd) {
- BufferPtr = CurPtr;
- return true;
- }
-
- // Otherwise, eat the \n character. We don't care if this is a \n\r or
- // \r\n sequence.
- ++CurPtr;
-
- // The next returned token is at the start of the line.
- Result.setFlag(Token::StartOfLine);
- // No leading whitespace seen so far.
- Result.clearFlag(Token::LeadingSpace);
- BufferPtr = CurPtr;
- return true;
-}
-
-/// SaveBCPLComment - If in save-comment mode, package up this BCPL comment in
-/// an appropriate way and return it.
-bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) {
- Result.setKind(tok::comment);
- FormTokenWithChars(Result, CurPtr);
-
- // If this BCPL-style comment is in a macro definition, transmogrify it into
- // a C-style block comment.
- if (ParsingPreprocessorDirective) {
- std::string Spelling = PP->getSpelling(Result);
- assert(Spelling[0] == '/' && Spelling[1] == '/' && "Not bcpl comment?");
- Spelling[1] = '*'; // Change prefix to "/*".
- Spelling += "*/"; // add suffix.
-
- Result.setLocation(PP->CreateString(&Spelling[0], Spelling.size(),
- Result.getLocation()));
- Result.setLength(Spelling.size());
- }
- return false;
-}
-
-/// isBlockCommentEndOfEscapedNewLine - Return true if the specified newline
-/// character (either \n or \r) is part of an escaped newline sequence. Issue a
-/// diagnostic if so. We know that the is inside of a block comment.
-static bool isEndOfBlockCommentWithEscapedNewLine(const char *CurPtr,
- Lexer *L) {
- assert(CurPtr[0] == '\n' || CurPtr[0] == '\r');
-
- // Back up off the newline.
- --CurPtr;
-
- // If this is a two-character newline sequence, skip the other character.
- if (CurPtr[0] == '\n' || CurPtr[0] == '\r') {
- // \n\n or \r\r -> not escaped newline.
- if (CurPtr[0] == CurPtr[1])
- return false;
- // \n\r or \r\n -> skip the newline.
- --CurPtr;
- }
-
- // If we have horizontal whitespace, skip over it. We allow whitespace
- // between the slash and newline.
- bool HasSpace = false;
- while (isHorizontalWhitespace(*CurPtr) || *CurPtr == 0) {
- --CurPtr;
- HasSpace = true;
- }
-
- // If we have a slash, we know this is an escaped newline.
- if (*CurPtr == '\\') {
- if (CurPtr[-1] != '*') return false;
- } else {
- // It isn't a slash, is it the ?? / trigraph?
- if (CurPtr[0] != '/' || CurPtr[-1] != '?' || CurPtr[-2] != '?' ||
- CurPtr[-3] != '*')
- return false;
-
- // This is the trigraph ending the comment. Emit a stern warning!
- CurPtr -= 2;
-
- // If no trigraphs are enabled, warn that we ignored this trigraph and
- // ignore this * character.
- if (!L->getFeatures().Trigraphs) {
- L->Diag(CurPtr, diag::trigraph_ignored_block_comment);
- return false;
- }
- L->Diag(CurPtr, diag::trigraph_ends_block_comment);
- }
-
- // Warn about having an escaped newline between the */ characters.
- L->Diag(CurPtr, diag::escaped_newline_block_comment_end);
-
- // If there was space between the backslash and newline, warn about it.
- if (HasSpace) L->Diag(CurPtr, diag::backslash_newline_space);
-
- return true;
-}
-
-#ifdef __SSE2__
-#include <emmintrin.h>
-#elif __ALTIVEC__
-#include <altivec.h>
-#undef bool
-#endif
-
-/// SkipBlockComment - We have just read the /* characters from input. Read
-/// until we find the */ characters that terminate the comment. Note that we
-/// don't bother decoding trigraphs or escaped newlines in block comments,
-/// because they cannot cause the comment to end. The only thing that can
-/// happen is the comment could end with an escaped newline between the */ end
-/// of comment.
-bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
- // Scan one character past where we should, looking for a '/' character. Once
- // we find it, check to see if it was preceeded by a *. This common
- // optimization helps people who like to put a lot of * characters in their
- // comments.
-
- // The first character we get with newlines and trigraphs skipped to handle
- // the degenerate /*/ case below correctly if the * has an escaped newline
- // after it.
- unsigned CharSize;
- unsigned char C = getCharAndSize(CurPtr, CharSize);
- CurPtr += CharSize;
- if (C == 0 && CurPtr == BufferEnd+1) {
- Diag(BufferPtr, diag::err_unterminated_block_comment);
- BufferPtr = CurPtr-1;
- return true;
- }
-
- // Check to see if the first character after the '/*' is another /. If so,
- // then this slash does not end the block comment, it is part of it.
- if (C == '/')
- C = *CurPtr++;
-
- while (1) {
- // Skip over all non-interesting characters until we find end of buffer or a
- // (probably ending) '/' character.
- if (CurPtr + 24 < BufferEnd) {
- // While not aligned to a 16-byte boundary.
- while (C != '/' && ((intptr_t)CurPtr & 0x0F) != 0)
- C = *CurPtr++;
-
- if (C == '/') goto FoundSlash;
-
-#ifdef __SSE2__
- __m128i Slashes = _mm_set_epi8('/', '/', '/', '/', '/', '/', '/', '/',
- '/', '/', '/', '/', '/', '/', '/', '/');
- while (CurPtr+16 <= BufferEnd &&
- _mm_movemask_epi8(_mm_cmpeq_epi8(*(__m128i*)CurPtr, Slashes)) == 0)
- CurPtr += 16;
-#elif __ALTIVEC__
- __vector unsigned char Slashes = {
- '/', '/', '/', '/', '/', '/', '/', '/',
- '/', '/', '/', '/', '/', '/', '/', '/'
- };
- while (CurPtr+16 <= BufferEnd &&
- !vec_any_eq(*(vector unsigned char*)CurPtr, Slashes))
- CurPtr += 16;
-#else
- // Scan for '/' quickly. Many block comments are very large.
- while (CurPtr[0] != '/' &&
- CurPtr[1] != '/' &&
- CurPtr[2] != '/' &&
- CurPtr[3] != '/' &&
- CurPtr+4 < BufferEnd) {
- CurPtr += 4;
- }
-#endif
-
- // It has to be one of the bytes scanned, increment to it and read one.
- C = *CurPtr++;
- }
-
- // Loop to scan the remainder.
- while (C != '/' && C != '\0')
- C = *CurPtr++;
-
- FoundSlash:
- if (C == '/') {
- if (CurPtr[-2] == '*') // We found the final */. We're done!
- break;
-
- if ((CurPtr[-2] == '\n' || CurPtr[-2] == '\r')) {
- if (isEndOfBlockCommentWithEscapedNewLine(CurPtr-2, this)) {
- // We found the final */, though it had an escaped newline between the
- // * and /. We're done!
- break;
- }
- }
- if (CurPtr[0] == '*' && CurPtr[1] != '/') {
- // If this is a /* inside of the comment, emit a warning. Don't do this
- // if this is a /*/, which will end the comment. This misses cases with
- // embedded escaped newlines, but oh well.
- Diag(CurPtr-1, diag::nested_block_comment);
- }
- } else if (C == 0 && CurPtr == BufferEnd+1) {
- Diag(BufferPtr, diag::err_unterminated_block_comment);
- // Note: the user probably forgot a */. We could continue immediately
- // after the /*, but this would involve lexing a lot of what really is the
- // comment, which surely would confuse the parser.
- BufferPtr = CurPtr-1;
- return true;
- }
- C = *CurPtr++;
- }
-
- // If we are returning comments as tokens, return this comment as a token.
- if (KeepCommentMode) {
- Result.setKind(tok::comment);
- FormTokenWithChars(Result, CurPtr);
- return false;
- }
-
- // It is common for the tokens immediately after a /**/ comment to be
- // whitespace. Instead of going through the big switch, handle it
- // efficiently now.
- if (isHorizontalWhitespace(*CurPtr)) {
- Result.setFlag(Token::LeadingSpace);
- SkipWhitespace(Result, CurPtr+1);
- return true;
- }
-
- // Otherwise, just return so that the next character will be lexed as a token.
- BufferPtr = CurPtr;
- Result.setFlag(Token::LeadingSpace);
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Primary Lexing Entry Points
-//===----------------------------------------------------------------------===//
-
-/// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
-/// (potentially) macro expand the filename.
-void Lexer::LexIncludeFilename(Token &FilenameTok) {
- assert(ParsingPreprocessorDirective &&
- ParsingFilename == false &&
- "Must be in a preprocessing directive!");
-
- // We are now parsing a filename!
- ParsingFilename = true;
-
- // Lex the filename.
- Lex(FilenameTok);
-
- // We should have obtained the filename now.
- ParsingFilename = false;
-
- // No filename?
- if (FilenameTok.is(tok::eom))
- Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
-}
-
-/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
-/// uninterpreted string. This switches the lexer out of directive mode.
-std::string Lexer::ReadToEndOfLine() {
- assert(ParsingPreprocessorDirective && ParsingFilename == false &&
- "Must be in a preprocessing directive!");
- std::string Result;
- Token Tmp;
-
- // CurPtr - Cache BufferPtr in an automatic variable.
- const char *CurPtr = BufferPtr;
- while (1) {
- char Char = getAndAdvanceChar(CurPtr, Tmp);
- switch (Char) {
- default:
- Result += Char;
- break;
- case 0: // Null.
- // Found end of file?
- if (CurPtr-1 != BufferEnd) {
- // Nope, normal character, continue.
- Result += Char;
- break;
- }
- // FALL THROUGH.
- case '\r':
- case '\n':
- // Okay, we found the end of the line. First, back up past the \0, \r, \n.
- assert(CurPtr[-1] == Char && "Trigraphs for newline?");
- BufferPtr = CurPtr-1;
-
- // Next, lex the character, which should handle the EOM transition.
- Lex(Tmp);
- assert(Tmp.is(tok::eom) && "Unexpected token!");
-
- // Finally, we're done, return the string we found.
- return Result;
- }
- }
-}
-
-/// LexEndOfFile - CurPtr points to the end of this file. Handle this
-/// condition, reporting diagnostics and handling other edge cases as required.
-/// This returns true if Result contains a token, false if PP.Lex should be
-/// called again.
-bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
- // If we hit the end of the file while parsing a preprocessor directive,
- // end the preprocessor directive first. The next token returned will
- // then be the end of file.
- if (ParsingPreprocessorDirective) {
- // Done parsing the "line".
- ParsingPreprocessorDirective = false;
- Result.setKind(tok::eom);
- // Update the location of token as well as BufferPtr.
- FormTokenWithChars(Result, CurPtr);
-
- // Restore comment saving mode, in case it was disabled for directive.
- KeepCommentMode = PP->getCommentRetentionState();
- return true; // Have a token.
- }
-
- // If we are in raw mode, return this event as an EOF token. Let the caller
- // that put us in raw mode handle the event.
- if (LexingRawMode) {
- Result.startToken();
- BufferPtr = BufferEnd;
- FormTokenWithChars(Result, BufferEnd);
- Result.setKind(tok::eof);
- return true;
- }
-
- // Otherwise, issue diagnostics for unterminated #if and missing newline.
-
- // If we are in a #if directive, emit an error.
- while (!ConditionalStack.empty()) {
- Diag(ConditionalStack.back().IfLoc, diag::err_pp_unterminated_conditional);
- ConditionalStack.pop_back();
- }
-
- // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
- // a pedwarn.
- if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r'))
- Diag(BufferEnd, diag::ext_no_newline_eof);
-
- BufferPtr = CurPtr;
-
- // Finally, let the preprocessor handle this.
- return PP->HandleEndOfFile(Result);
-}
-
-/// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from
-/// the specified lexer will return a tok::l_paren token, 0 if it is something
-/// else and 2 if there are no more tokens in the buffer controlled by the
-/// lexer.
-unsigned Lexer::isNextPPTokenLParen() {
- assert(!LexingRawMode && "How can we expand a macro from a skipping buffer?");
-
- // Switch to 'skipping' mode. This will ensure that we can lex a token
- // without emitting diagnostics, disables macro expansion, and will cause EOF
- // to return an EOF token instead of popping the include stack.
- LexingRawMode = true;
-
- // Save state that can be changed while lexing so that we can restore it.
- const char *TmpBufferPtr = BufferPtr;
-
- Token Tok;
- Tok.startToken();
- LexTokenInternal(Tok);
-
- // Restore state that may have changed.
- BufferPtr = TmpBufferPtr;
-
- // Restore the lexer back to non-skipping mode.
- LexingRawMode = false;
-
- if (Tok.is(tok::eof))
- return 2;
- return Tok.is(tok::l_paren);
-}
-
-
-/// LexTokenInternal - This implements a simple C family lexer. It is an
-/// extremely performance critical piece of code. This assumes that the buffer
-/// has a null character at the end of the file. Return true if an error
-/// occurred and compilation should terminate, false if normal. This returns a
-/// preprocessing token, not a normal token, as such, it is an internal
-/// interface. It assumes that the Flags of result have been cleared before
-/// calling this.
-void Lexer::LexTokenInternal(Token &Result) {
-LexNextToken:
- // New token, can't need cleaning yet.
- Result.clearFlag(Token::NeedsCleaning);
- Result.setIdentifierInfo(0);
-
- // CurPtr - Cache BufferPtr in an automatic variable.
- const char *CurPtr = BufferPtr;
-
- // Small amounts of horizontal whitespace is very common between tokens.
- if ((*CurPtr == ' ') || (*CurPtr == '\t')) {
- ++CurPtr;
- while ((*CurPtr == ' ') || (*CurPtr == '\t'))
- ++CurPtr;
- BufferPtr = CurPtr;
- Result.setFlag(Token::LeadingSpace);
- }
-
- unsigned SizeTmp, SizeTmp2; // Temporaries for use in cases below.
-
- // Read a character, advancing over it.
- char Char = getAndAdvanceChar(CurPtr, Result);
- switch (Char) {
- case 0: // Null.
- // Found end of file?
- if (CurPtr-1 == BufferEnd) {
- // Read the PP instance variable into an automatic variable, because
- // LexEndOfFile will often delete 'this'.
- Preprocessor *PPCache = PP;
- if (LexEndOfFile(Result, CurPtr-1)) // Retreat back into the file.
- return; // Got a token to return.
- assert(PPCache && "Raw buffer::LexEndOfFile should return a token");
- return PPCache->Lex(Result);
- }
-
- Diag(CurPtr-1, diag::null_in_file);
- Result.setFlag(Token::LeadingSpace);
- SkipWhitespace(Result, CurPtr);
- goto LexNextToken; // GCC isn't tail call eliminating.
- case '\n':
- case '\r':
- // If we are inside a preprocessor directive and we see the end of line,
- // we know we are done with the directive, so return an EOM token.
- if (ParsingPreprocessorDirective) {
- // Done parsing the "line".
- ParsingPreprocessorDirective = false;
-
- // Restore comment saving mode, in case it was disabled for directive.
- KeepCommentMode = PP->getCommentRetentionState();
-
- // Since we consumed a newline, we are back at the start of a line.
- IsAtStartOfLine = true;
-
- Result.setKind(tok::eom);
- break;
- }
- // The returned token is at the start of the line.
- Result.setFlag(Token::StartOfLine);
- // No leading whitespace seen so far.
- Result.clearFlag(Token::LeadingSpace);
- SkipWhitespace(Result, CurPtr);
- goto LexNextToken; // GCC isn't tail call eliminating.
- case ' ':
- case '\t':
- case '\f':
- case '\v':
- SkipHorizontalWhitespace:
- Result.setFlag(Token::LeadingSpace);
- SkipWhitespace(Result, CurPtr);
-
- SkipIgnoredUnits:
- CurPtr = BufferPtr;
-
- // If the next token is obviously a // or /* */ comment, skip it efficiently
- // too (without going through the big switch stmt).
- if (CurPtr[0] == '/' && CurPtr[1] == '/' && !KeepCommentMode) {
- SkipBCPLComment(Result, CurPtr+2);
- goto SkipIgnoredUnits;
- } else if (CurPtr[0] == '/' && CurPtr[1] == '*' && !KeepCommentMode) {
- SkipBlockComment(Result, CurPtr+2);
- goto SkipIgnoredUnits;
- } else if (isHorizontalWhitespace(*CurPtr)) {
- goto SkipHorizontalWhitespace;
- }
- goto LexNextToken; // GCC isn't tail call eliminating.
-
- // C99 6.4.4.1: Integer Constants.
- // C99 6.4.4.2: Floating Constants.
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
- return LexNumericConstant(Result, CurPtr);
-
- case 'L': // Identifier (Loony) or wide literal (L'x' or L"xyz").
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
- Char = getCharAndSize(CurPtr, SizeTmp);
-
- // Wide string literal.
- if (Char == '"')
- return LexStringLiteral(Result, ConsumeChar(CurPtr, SizeTmp, Result),
- true);
-
- // Wide character constant.
- if (Char == '\'')
- return LexCharConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result));
- // FALL THROUGH, treating L like the start of an identifier.
-
- // C99 6.4.2: Identifiers.
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
- case 'H': case 'I': case 'J': case 'K': /*'L'*/case 'M': case 'N':
- case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
- case 'V': case 'W': case 'X': case 'Y': case 'Z':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
- case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
- case 'v': case 'w': case 'x': case 'y': case 'z':
- case '_':
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
- return LexIdentifier(Result, CurPtr);
-
- case '$': // $ in identifiers.
- if (Features.DollarIdents) {
- Diag(CurPtr-1, diag::ext_dollar_in_identifier);
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
- return LexIdentifier(Result, CurPtr);
- }
-
- Result.setKind(tok::unknown);
- break;
-
- // C99 6.4.4: Character Constants.
- case '\'':
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
- return LexCharConstant(Result, CurPtr);
-
- // C99 6.4.5: String Literals.
- case '"':
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
- return LexStringLiteral(Result, CurPtr, false);
-
- // C99 6.4.6: Punctuators.
- case '?':
- Result.setKind(tok::question);
- break;
- case '[':
- Result.setKind(tok::l_square);
- break;
- case ']':
- Result.setKind(tok::r_square);
- break;
- case '(':
- Result.setKind(tok::l_paren);
- break;
- case ')':
- Result.setKind(tok::r_paren);
- break;
- case '{':
- Result.setKind(tok::l_brace);
- break;
- case '}':
- Result.setKind(tok::r_brace);
- break;
- case '.':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char >= '0' && Char <= '9') {
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
-
- return LexNumericConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result));
- } else if (Features.CPlusPlus && Char == '*') {
- Result.setKind(tok::periodstar);
- CurPtr += SizeTmp;
- } else if (Char == '.' &&
- getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '.') {
- Result.setKind(tok::ellipsis);
- CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
- SizeTmp2, Result);
- } else {
- Result.setKind(tok::period);
- }
- break;
- case '&':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '&') {
- Result.setKind(tok::ampamp);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '=') {
- Result.setKind(tok::ampequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::amp);
- }
- break;
- case '*':
- if (getCharAndSize(CurPtr, SizeTmp) == '=') {
- Result.setKind(tok::starequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::star);
- }
- break;
- case '+':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '+') {
- Result.setKind(tok::plusplus);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '=') {
- Result.setKind(tok::plusequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::plus);
- }
- break;
- case '-':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '-') {
- Result.setKind(tok::minusminus);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '>' && Features.CPlusPlus &&
- getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '*') {
- Result.setKind(tok::arrowstar); // C++ ->*
- CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
- SizeTmp2, Result);
- } else if (Char == '>') {
- Result.setKind(tok::arrow);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '=') {
- Result.setKind(tok::minusequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::minus);
- }
- break;
- case '~':
- Result.setKind(tok::tilde);
- break;
- case '!':
- if (getCharAndSize(CurPtr, SizeTmp) == '=') {
- Result.setKind(tok::exclaimequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::exclaim);
- }
- break;
- case '/':
- // 6.4.9: Comments
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '/') { // BCPL comment.
- if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result))) {
- // It is common for the tokens immediately after a // comment to be
- // whitespace (indentation for the next line). Instead of going through
- // the big switch, handle it efficiently now.
- goto SkipIgnoredUnits;
- }
- return; // KeepCommentMode
- } else if (Char == '*') { // /**/ comment.
- if (SkipBlockComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
- goto LexNextToken; // GCC isn't tail call eliminating.
- return; // KeepCommentMode
- } else if (Char == '=') {
- Result.setKind(tok::slashequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::slash);
- }
- break;
- case '%':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '=') {
- Result.setKind(tok::percentequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.Digraphs && Char == '>') {
- Result.setKind(tok::r_brace); // '%>' -> '}'
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.Digraphs && Char == ':') {
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '%' && getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == ':') {
- Result.setKind(tok::hashhash); // '%:%:' -> '##'
- CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
- SizeTmp2, Result);
- } else if (Char == '@' && Features.Microsoft) { // %:@ -> #@ -> Charize
- Result.setKind(tok::hashat);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- Diag(BufferPtr, diag::charize_microsoft_ext);
- } else {
- Result.setKind(tok::hash); // '%:' -> '#'
-
- // We parsed a # character. If this occurs at the start of the line,
- // it's actually the start of a preprocessing directive. Callback to
- // the preprocessor to handle it.
- // FIXME: -fpreprocessed mode??
- if (Result.isAtStartOfLine() && !LexingRawMode) {
- BufferPtr = CurPtr;
- PP->HandleDirective(Result);
-
- // As an optimization, if the preprocessor didn't switch lexers, tail
- // recurse.
- if (PP->isCurrentLexer(this)) {
- // Start a new token. If this is a #include or something, the PP may
- // want us starting at the beginning of the line again. If so, set
- // the StartOfLine flag.
- if (IsAtStartOfLine) {
- Result.setFlag(Token::StartOfLine);
- IsAtStartOfLine = false;
- }
- goto LexNextToken; // GCC isn't tail call eliminating.
- }
-
- return PP->Lex(Result);
- }
- }
- } else {
- Result.setKind(tok::percent);
- }
- break;
- case '<':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (ParsingFilename) {
- return LexAngledStringLiteral(Result, CurPtr+SizeTmp);
- } else if (Char == '<' &&
- getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '=') {
- Result.setKind(tok::lesslessequal);
- CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
- SizeTmp2, Result);
- } else if (Char == '<') {
- Result.setKind(tok::lessless);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '=') {
- Result.setKind(tok::lessequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.Digraphs && Char == ':') {
- Result.setKind(tok::l_square); // '<:' -> '['
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.Digraphs && Char == '%') {
- Result.setKind(tok::l_brace); // '<%' -> '{'
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::less);
- }
- break;
- case '>':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '=') {
- Result.setKind(tok::greaterequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '>' &&
- getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '=') {
- Result.setKind(tok::greatergreaterequal);
- CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
- SizeTmp2, Result);
- } else if (Char == '>') {
- Result.setKind(tok::greatergreater);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::greater);
- }
- break;
- case '^':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '=') {
- Result.setKind(tok::caretequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::caret);
- }
- break;
- case '|':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '=') {
- Result.setKind(tok::pipeequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '|') {
- Result.setKind(tok::pipepipe);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::pipe);
- }
- break;
- case ':':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Features.Digraphs && Char == '>') {
- Result.setKind(tok::r_square); // ':>' -> ']'
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.CPlusPlus && Char == ':') {
- Result.setKind(tok::coloncolon);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::colon);
- }
- break;
- case ';':
- Result.setKind(tok::semi);
- break;
- case '=':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '=') {
- Result.setKind(tok::equalequal);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::equal);
- }
- break;
- case ',':
- Result.setKind(tok::comma);
- break;
- case '#':
- Char = getCharAndSize(CurPtr, SizeTmp);
- if (Char == '#') {
- Result.setKind(tok::hashhash);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '@' && Features.Microsoft) { // #@ -> Charize
- Result.setKind(tok::hashat);
- Diag(BufferPtr, diag::charize_microsoft_ext);
- CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else {
- Result.setKind(tok::hash);
- // We parsed a # character. If this occurs at the start of the line,
- // it's actually the start of a preprocessing directive. Callback to
- // the preprocessor to handle it.
- // FIXME: -fpreprocessed mode??
- if (Result.isAtStartOfLine() && !LexingRawMode) {
- BufferPtr = CurPtr;
- PP->HandleDirective(Result);
-
- // As an optimization, if the preprocessor didn't switch lexers, tail
- // recurse.
- if (PP->isCurrentLexer(this)) {
- // Start a new token. If this is a #include or something, the PP may
- // want us starting at the beginning of the line again. If so, set
- // the StartOfLine flag.
- if (IsAtStartOfLine) {
- Result.setFlag(Token::StartOfLine);
- IsAtStartOfLine = false;
- }
- goto LexNextToken; // GCC isn't tail call eliminating.
- }
- return PP->Lex(Result);
- }
- }
- break;
-
- case '@':
- // Objective C support.
- if (CurPtr[-1] == '@' && Features.ObjC1)
- Result.setKind(tok::at);
- else
- Result.setKind(tok::unknown);
- break;
-
- case '\\':
- // FIXME: UCN's.
- // FALL THROUGH.
- default:
- Result.setKind(tok::unknown);
- break;
- }
-
- // Notify MIOpt that we read a non-whitespace/non-comment token.
- MIOpt.ReadToken();
-
- // Update the location of token as well as BufferPtr.
- FormTokenWithChars(Result, CurPtr);
-}
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
deleted file mode 100644
index f63e6cfffc0d..000000000000
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-//===--- LiteralSupport.cpp - Code to parse and process literals ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the NumericLiteralParser, CharLiteralParser, and
-// StringLiteralParser interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/LiteralSupport.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/StringExtras.h"
-using namespace clang;
-
-/// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
-/// not valid.
-static int HexDigitValue(char C) {
- if (C >= '0' && C <= '9') return C-'0';
- if (C >= 'a' && C <= 'f') return C-'a'+10;
- if (C >= 'A' && C <= 'F') return C-'A'+10;
- return -1;
-}
-
-/// ProcessCharEscape - Parse a standard C escape sequence, which can occur in
-/// either a character or a string literal.
-static unsigned ProcessCharEscape(const char *&ThisTokBuf,
- const char *ThisTokEnd, bool &HadError,
- SourceLocation Loc, bool IsWide,
- Preprocessor &PP) {
- // Skip the '\' char.
- ++ThisTokBuf;
-
- // We know that this character can't be off the end of the buffer, because
- // that would have been \", which would not have been the end of string.
- unsigned ResultChar = *ThisTokBuf++;
- switch (ResultChar) {
- // These map to themselves.
- case '\\': case '\'': case '"': case '?': break;
-
- // These have fixed mappings.
- case 'a':
- // TODO: K&R: the meaning of '\\a' is different in traditional C
- ResultChar = 7;
- break;
- case 'b':
- ResultChar = 8;
- break;
- case 'e':
- PP.Diag(Loc, diag::ext_nonstandard_escape, "e");
- ResultChar = 27;
- break;
- case 'f':
- ResultChar = 12;
- break;
- case 'n':
- ResultChar = 10;
- break;
- case 'r':
- ResultChar = 13;
- break;
- case 't':
- ResultChar = 9;
- break;
- case 'v':
- ResultChar = 11;
- break;
-
- //case 'u': case 'U': // FIXME: UCNs.
- case 'x': { // Hex escape.
- ResultChar = 0;
- if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
- PP.Diag(Loc, diag::err_hex_escape_no_digits);
- HadError = 1;
- break;
- }
-
- // Hex escapes are a maximal series of hex digits.
- bool Overflow = false;
- for (; ThisTokBuf != ThisTokEnd; ++ThisTokBuf) {
- int CharVal = HexDigitValue(ThisTokBuf[0]);
- if (CharVal == -1) break;
- // About to shift out a digit?
- Overflow |= (ResultChar & 0xF0000000) ? true : false;
- ResultChar <<= 4;
- ResultChar |= CharVal;
- }
-
- // See if any bits will be truncated when evaluated as a character.
- unsigned CharWidth = PP.getTargetInfo().getCharWidth(IsWide);
-
- if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
- Overflow = true;
- ResultChar &= ~0U >> (32-CharWidth);
- }
-
- // Check for overflow.
- if (Overflow) // Too many digits to fit in
- PP.Diag(Loc, diag::warn_hex_escape_too_large);
- break;
- }
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7': {
- // Octal escapes.
- --ThisTokBuf;
- ResultChar = 0;
-
- // Octal escapes are a series of octal digits with maximum length 3.
- // "\0123" is a two digit sequence equal to "\012" "3".
- unsigned NumDigits = 0;
- do {
- ResultChar <<= 3;
- ResultChar |= *ThisTokBuf++ - '0';
- ++NumDigits;
- } while (ThisTokBuf != ThisTokEnd && NumDigits < 3 &&
- ThisTokBuf[0] >= '0' && ThisTokBuf[0] <= '7');
-
- // Check for overflow. Reject '\777', but not L'\777'.
- unsigned CharWidth = PP.getTargetInfo().getCharWidth(IsWide);
-
- if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
- PP.Diag(Loc, diag::warn_octal_escape_too_large);
- ResultChar &= ~0U >> (32-CharWidth);
- }
- break;
- }
-
- // Otherwise, these are not valid escapes.
- case '(': case '{': case '[': case '%':
- // GCC accepts these as extensions. We warn about them as such though.
- if (!PP.getLangOptions().NoExtensions) {
- PP.Diag(Loc, diag::ext_nonstandard_escape,
- std::string()+(char)ResultChar);
- break;
- }
- // FALL THROUGH.
- default:
- if (isgraph(ThisTokBuf[0])) {
- PP.Diag(Loc, diag::ext_unknown_escape, std::string()+(char)ResultChar);
- } else {
- PP.Diag(Loc, diag::ext_unknown_escape, "x"+llvm::utohexstr(ResultChar));
- }
- break;
- }
-
- return ResultChar;
-}
-
-
-
-
-/// integer-constant: [C99 6.4.4.1]
-/// decimal-constant integer-suffix
-/// octal-constant integer-suffix
-/// hexadecimal-constant integer-suffix
-/// decimal-constant:
-/// nonzero-digit
-/// decimal-constant digit
-/// octal-constant:
-/// 0
-/// octal-constant octal-digit
-/// hexadecimal-constant:
-/// hexadecimal-prefix hexadecimal-digit
-/// hexadecimal-constant hexadecimal-digit
-/// hexadecimal-prefix: one of
-/// 0x 0X
-/// integer-suffix:
-/// unsigned-suffix [long-suffix]
-/// unsigned-suffix [long-long-suffix]
-/// long-suffix [unsigned-suffix]
-/// long-long-suffix [unsigned-sufix]
-/// nonzero-digit:
-/// 1 2 3 4 5 6 7 8 9
-/// octal-digit:
-/// 0 1 2 3 4 5 6 7
-/// hexadecimal-digit:
-/// 0 1 2 3 4 5 6 7 8 9
-/// a b c d e f
-/// A B C D E F
-/// unsigned-suffix: one of
-/// u U
-/// long-suffix: one of
-/// l L
-/// long-long-suffix: one of
-/// ll LL
-///
-/// floating-constant: [C99 6.4.4.2]
-/// TODO: add rules...
-///
-NumericLiteralParser::
-NumericLiteralParser(const char *begin, const char *end,
- SourceLocation TokLoc, Preprocessor &pp)
- : PP(pp), ThisTokBegin(begin), ThisTokEnd(end) {
-
- // This routine assumes that the range begin/end matches the regex for integer
- // and FP constants (specifically, the 'pp-number' regex), and assumes that
- // the byte at "*end" is both valid and not part of the regex. Because of
- // this, it doesn't have to check for 'overscan' in various places.
- assert(!isalnum(*end) && *end != '.' && *end != '_' &&
- "Lexer didn't maximally munch?");
-
- s = DigitsBegin = begin;
- saw_exponent = false;
- saw_period = false;
- isLong = false;
- isUnsigned = false;
- isLongLong = false;
- isFloat = false;
- isImaginary = false;
- hadError = false;
-
- if (*s == '0') { // parse radix
- ParseNumberStartingWithZero(TokLoc);
- if (hadError)
- return;
- } else { // the first digit is non-zero
- radix = 10;
- s = SkipDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (isxdigit(*s) && !(*s == 'e' || *s == 'E')) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_invalid_decimal_digit, std::string(s, s+1));
- return;
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipDigits(s);
- }
- if ((*s == 'e' || *s == 'E')) { // exponent
- const char *Exponent = s;
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s);
- if (first_non_digit != s) {
- s = first_non_digit;
- } else {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-begin),
- diag::err_exponent_has_no_digits);
- return;
- }
- }
- }
-
- SuffixBegin = s;
-
- // Parse the suffix. At this point we can classify whether we have an FP or
- // integer constant.
- bool isFPConstant = isFloatingLiteral();
-
- // Loop over all of the characters of the suffix. If we see something bad,
- // we break out of the loop.
- for (; s != ThisTokEnd; ++s) {
- switch (*s) {
- case 'f': // FP Suffix for "float"
- case 'F':
- if (!isFPConstant) break; // Error for integer constant.
- if (isFloat || isLong) break; // FF, LF invalid.
- isFloat = true;
- continue; // Success.
- case 'u':
- case 'U':
- if (isFPConstant) break; // Error for floating constant.
- if (isUnsigned) break; // Cannot be repeated.
- isUnsigned = true;
- continue; // Success.
- case 'l':
- case 'L':
- if (isLong || isLongLong) break; // Cannot be repeated.
- if (isFloat) break; // LF invalid.
-
- // Check for long long. The L's need to be adjacent and the same case.
- if (s+1 != ThisTokEnd && s[1] == s[0]) {
- if (isFPConstant) break; // long long invalid for floats.
- isLongLong = true;
- ++s; // Eat both of them.
- } else {
- isLong = true;
- }
- continue; // Success.
- case 'i':
- if (PP.getLangOptions().Microsoft) {
- // Allow i8, i16, i32, i64, and i128.
- if (++s == ThisTokEnd) break;
- switch (*s) {
- case '8':
- s++; // i8 suffix
- break;
- case '1':
- if (++s == ThisTokEnd) break;
- if (*s == '6') s++; // i16 suffix
- else if (*s == '2') {
- if (++s == ThisTokEnd) break;
- if (*s == '8') s++; // i128 suffix
- }
- break;
- case '3':
- if (++s == ThisTokEnd) break;
- if (*s == '2') s++; // i32 suffix
- break;
- case '6':
- if (++s == ThisTokEnd) break;
- if (*s == '4') s++; // i64 suffix
- break;
- default:
- break;
- }
- break;
- }
- // fall through.
- case 'I':
- case 'j':
- case 'J':
- if (isImaginary) break; // Cannot be repeated.
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::ext_imaginary_constant);
- isImaginary = true;
- continue; // Success.
- }
- // If we reached here, there was an error.
- break;
- }
-
- // Report an error if there are any.
- if (s != ThisTokEnd) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- isFPConstant ? diag::err_invalid_suffix_float_constant :
- diag::err_invalid_suffix_integer_constant,
- std::string(SuffixBegin, ThisTokEnd));
- return;
- }
-}
-
-/// ParseNumberStartingWithZero - This method is called when the first character
-/// of the number is found to be a zero. This means it is either an octal
-/// number (like '04') or a hex number ('0x123a') a binary number ('0b1010') or
-/// a floating point number (01239.123e4). Eat the prefix, determining the
-/// radix etc.
-void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
- assert(s[0] == '0' && "Invalid method call");
- s++;
-
- // Handle a hex number like 0x1234.
- if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
- s++;
- radix = 16;
- DigitsBegin = s;
- s = SkipHexDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipHexDigits(s);
- }
- // A binary exponent can appear with or with a '.'. If dotted, the
- // binary exponent is required.
- if (*s == 'p' || *s == 'P') {
- const char *Exponent = s;
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s);
- if (first_non_digit == s) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
- diag::err_exponent_has_no_digits);
- return;
- }
- s = first_non_digit;
-
- if (!PP.getLangOptions().HexFloats)
- Diag(TokLoc, diag::ext_hexconstant_invalid);
- } else if (saw_period) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
- diag::err_hexconstant_requires_exponent);
- }
- return;
- }
-
- // Handle simple binary numbers 0b01010
- if (*s == 'b' || *s == 'B') {
- // 0b101010 is a GCC extension.
- PP.Diag(TokLoc, diag::ext_binary_literal);
- ++s;
- radix = 2;
- DigitsBegin = s;
- s = SkipBinaryDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (isxdigit(*s)) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
- diag::err_invalid_binary_digit, std::string(s, s+1));
- }
- // Other suffixes will be diagnosed by the caller.
- return;
- }
-
- // For now, the radix is set to 8. If we discover that we have a
- // floating point constant, the radix will change to 10. Octal floating
- // point constants are not permitted (only decimal and hexadecimal).
- radix = 8;
- DigitsBegin = s;
- s = SkipOctalDigits(s);
- if (s == ThisTokEnd)
- return; // Done, simple octal number like 01234
-
- // If we have some other non-octal digit that *is* a decimal digit, see if
- // this is part of a floating point number like 094.123 or 09e1.
- if (isdigit(*s)) {
- const char *EndDecimal = SkipDigits(s);
- if (EndDecimal[0] == '.' || EndDecimal[0] == 'e' || EndDecimal[0] == 'E') {
- s = EndDecimal;
- radix = 10;
- }
- }
-
- // If we have a hex digit other than 'e' (which denotes a FP exponent) then
- // the code is using an incorrect base.
- if (isxdigit(*s) && *s != 'e' && *s != 'E') {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
- diag::err_invalid_octal_digit, std::string(s, s+1));
- return;
- }
-
- if (*s == '.') {
- s++;
- radix = 10;
- saw_period = true;
- s = SkipDigits(s); // Skip suffix.
- }
- if (*s == 'e' || *s == 'E') { // exponent
- const char *Exponent = s;
- s++;
- radix = 10;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s);
- if (first_non_digit != s) {
- s = first_non_digit;
- } else {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
- diag::err_exponent_has_no_digits);
- return;
- }
- }
-}
-
-
-/// GetIntegerValue - Convert this numeric literal value to an APInt that
-/// matches Val's input width. If there is an overflow, set Val to the low bits
-/// of the result and return true. Otherwise, return false.
-bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) {
- Val = 0;
- s = DigitsBegin;
-
- llvm::APInt RadixVal(Val.getBitWidth(), radix);
- llvm::APInt CharVal(Val.getBitWidth(), 0);
- llvm::APInt OldVal = Val;
-
- bool OverflowOccurred = false;
- while (s < SuffixBegin) {
- unsigned C = HexDigitValue(*s++);
-
- // If this letter is out of bound for this radix, reject it.
- assert(C < radix && "NumericLiteralParser ctor should have rejected this");
-
- CharVal = C;
-
- // Add the digit to the value in the appropriate radix. If adding in digits
- // made the value smaller, then this overflowed.
- OldVal = Val;
-
- // Multiply by radix, did overflow occur on the multiply?
- Val *= RadixVal;
- OverflowOccurred |= Val.udiv(RadixVal) != OldVal;
-
- OldVal = Val;
- // Add value, did overflow occur on the value?
- Val += CharVal;
- OverflowOccurred |= Val.ult(OldVal);
- OverflowOccurred |= Val.ult(CharVal);
- }
- return OverflowOccurred;
-}
-
-llvm::APFloat NumericLiteralParser::
-GetFloatValue(const llvm::fltSemantics &Format, bool* isExact) {
- using llvm::APFloat;
-
- llvm::SmallVector<char,256> floatChars;
- for (unsigned i = 0, n = ThisTokEnd-ThisTokBegin; i != n; ++i)
- floatChars.push_back(ThisTokBegin[i]);
-
- floatChars.push_back('\0');
-
- APFloat V (Format, APFloat::fcZero, false);
- APFloat::opStatus status;
-
- status = V.convertFromString(&floatChars[0],APFloat::rmNearestTiesToEven);
-
- if (isExact)
- *isExact = status == APFloat::opOK;
-
- return V;
-}
-
-void NumericLiteralParser::Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &M) {
- PP.Diag(Loc, DiagID, M);
- hadError = true;
-}
-
-
-CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
- SourceLocation Loc, Preprocessor &PP) {
- // At this point we know that the character matches the regex "L?'.*'".
- HadError = false;
- Value = 0;
-
- // Determine if this is a wide character.
- IsWide = begin[0] == 'L';
- if (IsWide) ++begin;
-
- // Skip over the entry quote.
- assert(begin[0] == '\'' && "Invalid token lexed");
- ++begin;
-
- // FIXME: This assumes that 'int' is 32-bits in overflow calculation, and the
- // size of "value".
- assert(PP.getTargetInfo().getIntWidth() == 32 &&
- "Assumes sizeof(int) == 4 for now");
- // FIXME: This assumes that wchar_t is 32-bits for now.
- assert(PP.getTargetInfo().getWCharWidth() == 32 &&
- "Assumes sizeof(wchar_t) == 4 for now");
- // FIXME: This extensively assumes that 'char' is 8-bits.
- assert(PP.getTargetInfo().getCharWidth() == 8 &&
- "Assumes char is 8 bits");
-
- bool isFirstChar = true;
- bool isMultiChar = false;
- while (begin[0] != '\'') {
- unsigned ResultChar;
- if (begin[0] != '\\') // If this is a normal character, consume it.
- ResultChar = *begin++;
- else // Otherwise, this is an escape character.
- ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP);
-
- // If this is a multi-character constant (e.g. 'abc'), handle it. These are
- // implementation defined (C99 6.4.4.4p10).
- if (!isFirstChar) {
- // If this is the second character being processed, do special handling.
- if (!isMultiChar) {
- isMultiChar = true;
-
- // Warn about discarding the top bits for multi-char wide-character
- // constants (L'abcd').
- if (IsWide)
- PP.Diag(Loc, diag::warn_extraneous_wide_char_constant);
- }
-
- if (IsWide) {
- // Emulate GCC's (unintentional?) behavior: L'ab' -> L'b'.
- Value = 0;
- } else {
- // Narrow character literals act as though their value is concatenated
- // in this implementation.
- if (((Value << 8) >> 8) != Value)
- PP.Diag(Loc, diag::warn_char_constant_too_large);
- Value <<= 8;
- }
- }
-
- Value += ResultChar;
- isFirstChar = false;
- }
-
- // If this is a single narrow character, sign extend it (e.g. '\xFF' is "-1")
- // if 'char' is signed for this target (C99 6.4.4.4p10). Note that multiple
- // character constants are not sign extended in the this implementation:
- // '\xFF\xFF' = 65536 and '\x0\xFF' = 255, which matches GCC.
- if (!IsWide && !isMultiChar && (Value & 128) &&
- PP.getTargetInfo().isCharSigned())
- Value = (signed char)Value;
-}
-
-
-/// string-literal: [C99 6.4.5]
-/// " [s-char-sequence] "
-/// L" [s-char-sequence] "
-/// s-char-sequence:
-/// s-char
-/// s-char-sequence s-char
-/// s-char:
-/// any source character except the double quote ",
-/// backslash \, or newline character
-/// escape-character
-/// universal-character-name
-/// escape-character: [C99 6.4.4.4]
-/// \ escape-code
-/// universal-character-name
-/// escape-code:
-/// character-escape-code
-/// octal-escape-code
-/// hex-escape-code
-/// character-escape-code: one of
-/// n t b r f v a
-/// \ ' " ?
-/// octal-escape-code:
-/// octal-digit
-/// octal-digit octal-digit
-/// octal-digit octal-digit octal-digit
-/// hex-escape-code:
-/// x hex-digit
-/// hex-escape-code hex-digit
-/// universal-character-name:
-/// \u hex-quad
-/// \U hex-quad hex-quad
-/// hex-quad:
-/// hex-digit hex-digit hex-digit hex-digit
-///
-StringLiteralParser::
-StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
- Preprocessor &pp, TargetInfo &t)
- : PP(pp), Target(t) {
- // Scan all of the string portions, remember the max individual token length,
- // computing a bound on the concatenated string length, and see whether any
- // piece is a wide-string. If any of the string portions is a wide-string
- // literal, the result is a wide-string literal [C99 6.4.5p4].
- MaxTokenLength = StringToks[0].getLength();
- SizeBound = StringToks[0].getLength()-2; // -2 for "".
- AnyWide = StringToks[0].is(tok::wide_string_literal);
-
- hadError = false;
-
- // Implement Translation Phase #6: concatenation of string literals
- /// (C99 5.1.1.2p1). The common case is only one string fragment.
- for (unsigned i = 1; i != NumStringToks; ++i) {
- // The string could be shorter than this if it needs cleaning, but this is a
- // reasonable bound, which is all we need.
- SizeBound += StringToks[i].getLength()-2; // -2 for "".
-
- // Remember maximum string piece length.
- if (StringToks[i].getLength() > MaxTokenLength)
- MaxTokenLength = StringToks[i].getLength();
-
- // Remember if we see any wide strings.
- AnyWide |= StringToks[i].is(tok::wide_string_literal);
- }
-
-
- // Include space for the null terminator.
- ++SizeBound;
-
- // TODO: K&R warning: "traditional C rejects string constant concatenation"
-
- // Get the width in bytes of wchar_t. If no wchar_t strings are used, do not
- // query the target. As such, wchar_tByteWidth is only valid if AnyWide=true.
- wchar_tByteWidth = ~0U;
- if (AnyWide) {
- wchar_tByteWidth = Target.getWCharWidth();
- assert((wchar_tByteWidth & 7) == 0 && "Assumes wchar_t is byte multiple!");
- wchar_tByteWidth /= 8;
- }
-
- // The output buffer size needs to be large enough to hold wide characters.
- // This is a worst-case assumption which basically corresponds to L"" "long".
- if (AnyWide)
- SizeBound *= wchar_tByteWidth;
-
- // Size the temporary buffer to hold the result string data.
- ResultBuf.resize(SizeBound);
-
- // Likewise, but for each string piece.
- llvm::SmallString<512> TokenBuf;
- TokenBuf.resize(MaxTokenLength);
-
- // Loop over all the strings, getting their spelling, and expanding them to
- // wide strings as appropriate.
- ResultPtr = &ResultBuf[0]; // Next byte to fill in.
-
- Pascal = false;
-
- for (unsigned i = 0, e = NumStringToks; i != e; ++i) {
- const char *ThisTokBuf = &TokenBuf[0];
- // Get the spelling of the token, which eliminates trigraphs, etc. We know
- // that ThisTokBuf points to a buffer that is big enough for the whole token
- // and 'spelled' tokens can only shrink.
- unsigned ThisTokLen = PP.getSpelling(StringToks[i], ThisTokBuf);
- const char *ThisTokEnd = ThisTokBuf+ThisTokLen-1; // Skip end quote.
-
- // TODO: Input character set mapping support.
-
- // Skip L marker for wide strings.
- bool ThisIsWide = false;
- if (ThisTokBuf[0] == 'L') {
- ++ThisTokBuf;
- ThisIsWide = true;
- }
-
- assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
- ++ThisTokBuf;
-
- // Check if this is a pascal string
- if (pp.getLangOptions().PascalStrings && ThisTokBuf + 1 != ThisTokEnd &&
- ThisTokBuf[0] == '\\' && ThisTokBuf[1] == 'p') {
-
- // If the \p sequence is found in the first token, we have a pascal string
- // Otherwise, if we already have a pascal string, ignore the first \p
- if (i == 0) {
- ++ThisTokBuf;
- Pascal = true;
- } else if (Pascal)
- ThisTokBuf += 2;
- }
-
- while (ThisTokBuf != ThisTokEnd) {
- // Is this a span of non-escape characters?
- if (ThisTokBuf[0] != '\\') {
- const char *InStart = ThisTokBuf;
- do {
- ++ThisTokBuf;
- } while (ThisTokBuf != ThisTokEnd && ThisTokBuf[0] != '\\');
-
- // Copy the character span over.
- unsigned Len = ThisTokBuf-InStart;
- if (!AnyWide) {
- memcpy(ResultPtr, InStart, Len);
- ResultPtr += Len;
- } else {
- // Note: our internal rep of wide char tokens is always little-endian.
- for (; Len; --Len, ++InStart) {
- *ResultPtr++ = InStart[0];
- // Add zeros at the end.
- for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
- *ResultPtr++ = 0;
- }
- }
- continue;
- }
-
- // Otherwise, this is an escape character. Process it.
- unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
- StringToks[i].getLocation(),
- ThisIsWide, PP);
-
- // Note: our internal rep of wide char tokens is always little-endian.
- *ResultPtr++ = ResultChar & 0xFF;
-
- if (AnyWide) {
- for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
- *ResultPtr++ = ResultChar >> i*8;
- }
- }
- }
-
- // Add zero terminator.
- *ResultPtr = 0;
- if (AnyWide) {
- for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
- *ResultPtr++ = 0;
- }
-
- if (Pascal)
- ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
-}
diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp
deleted file mode 100644
index a26e50eb762f..000000000000
--- a/clang/lib/Lex/MacroArgs.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//===--- TokenLexer.cpp - Lex from a token stream -------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the TokenLexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MacroArgs.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-using namespace clang;
-
-/// MacroArgs ctor function - This destroys the vector passed in.
-MacroArgs *MacroArgs::create(const MacroInfo *MI,
- const Token *UnexpArgTokens,
- unsigned NumToks, bool VarargsElided) {
- assert(MI->isFunctionLike() &&
- "Can't have args for an object-like macro!");
-
- // Allocate memory for the MacroArgs object with the lexer tokens at the end.
- MacroArgs *Result = (MacroArgs*)malloc(sizeof(MacroArgs) +
- NumToks*sizeof(Token));
- // Construct the macroargs object.
- new (Result) MacroArgs(NumToks, VarargsElided);
-
- // Copy the actual unexpanded tokens to immediately after the result ptr.
- if (NumToks)
- memcpy(const_cast<Token*>(Result->getUnexpArgument(0)),
- UnexpArgTokens, NumToks*sizeof(Token));
-
- return Result;
-}
-
-/// destroy - Destroy and deallocate the memory for this object.
-///
-void MacroArgs::destroy() {
- // Run the dtor to deallocate the vectors.
- this->~MacroArgs();
- // Release the memory for the object.
- free(this);
-}
-
-
-/// getArgLength - Given a pointer to an expanded or unexpanded argument,
-/// return the number of tokens, not counting the EOF, that make up the
-/// argument.
-unsigned MacroArgs::getArgLength(const Token *ArgPtr) {
- unsigned NumArgTokens = 0;
- for (; ArgPtr->isNot(tok::eof); ++ArgPtr)
- ++NumArgTokens;
- return NumArgTokens;
-}
-
-
-/// getUnexpArgument - Return the unexpanded tokens for the specified formal.
-///
-const Token *MacroArgs::getUnexpArgument(unsigned Arg) const {
- // The unexpanded argument tokens start immediately after the MacroArgs object
- // in memory.
- const Token *Start = (const Token *)(this+1);
- const Token *Result = Start;
- // Scan to find Arg.
- for (; Arg; ++Result) {
- assert(Result < Start+NumUnexpArgTokens && "Invalid arg #");
- if (Result->is(tok::eof))
- --Arg;
- }
- return Result;
-}
-
-
-/// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
-/// by pre-expansion, return false. Otherwise, conservatively return true.
-bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok,
- Preprocessor &PP) const {
- // If there are no identifiers in the argument list, or if the identifiers are
- // known to not be macros, pre-expansion won't modify it.
- for (; ArgTok->isNot(tok::eof); ++ArgTok)
- if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) {
- if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled())
- // Return true even though the macro could be a function-like macro
- // without a following '(' token.
- return true;
- }
- return false;
-}
-
-/// getPreExpArgument - Return the pre-expanded form of the specified
-/// argument.
-const std::vector<Token> &
-MacroArgs::getPreExpArgument(unsigned Arg, Preprocessor &PP) {
- assert(Arg < NumUnexpArgTokens && "Invalid argument number!");
-
- // If we have already computed this, return it.
- if (PreExpArgTokens.empty())
- PreExpArgTokens.resize(NumUnexpArgTokens);
-
- std::vector<Token> &Result = PreExpArgTokens[Arg];
- if (!Result.empty()) return Result;
-
- const Token *AT = getUnexpArgument(Arg);
- unsigned NumToks = getArgLength(AT)+1; // Include the EOF.
-
- // Otherwise, we have to pre-expand this argument, populating Result. To do
- // this, we set up a fake TokenLexer to lex from the unexpanded argument
- // list. With this installed, we lex expanded tokens until we hit the EOF
- // token at the end of the unexp list.
- PP.EnterTokenStream(AT, NumToks, false /*disable expand*/,
- false /*owns tokens*/);
-
- // Lex all of the macro-expanded tokens into Result.
- do {
- Result.push_back(Token());
- PP.Lex(Result.back());
- } while (Result.back().isNot(tok::eof));
-
- // Pop the token stream off the top of the stack. We know that the internal
- // pointer inside of it is to the "end" of the token stream, but the stack
- // will not otherwise be popped until the next token is lexed. The problem is
- // that the token may be lexed sometime after the vector of tokens itself is
- // destroyed, which would be badness.
- PP.RemoveTopOfLexerStack();
- return Result;
-}
-
-
-/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
-/// tokens into the literal string token that should be produced by the C #
-/// preprocessor operator. If Charify is true, then it should be turned into
-/// a character literal for the Microsoft charize (#@) extension.
-///
-Token MacroArgs::StringifyArgument(const Token *ArgToks,
- Preprocessor &PP, bool Charify) {
- Token Tok;
- Tok.startToken();
- Tok.setKind(tok::string_literal);
-
- const Token *ArgTokStart = ArgToks;
-
- // Stringify all the tokens.
- std::string Result = "\"";
- // FIXME: Optimize this loop to not use std::strings.
- bool isFirst = true;
- for (; ArgToks->isNot(tok::eof); ++ArgToks) {
- const Token &Tok = *ArgToks;
- if (!isFirst && (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()))
- Result += ' ';
- isFirst = false;
-
- // If this is a string or character constant, escape the token as specified
- // by 6.10.3.2p2.
- if (Tok.is(tok::string_literal) || // "foo"
- Tok.is(tok::wide_string_literal) || // L"foo"
- Tok.is(tok::char_constant)) { // 'x' and L'x'.
- Result += Lexer::Stringify(PP.getSpelling(Tok));
- } else {
- // Otherwise, just append the token.
- Result += PP.getSpelling(Tok);
- }
- }
-
- // If the last character of the string is a \, and if it isn't escaped, this
- // is an invalid string literal, diagnose it as specified in C99.
- if (Result[Result.size()-1] == '\\') {
- // Count the number of consequtive \ characters. If even, then they are
- // just escaped backslashes, otherwise it's an error.
- unsigned FirstNonSlash = Result.size()-2;
- // Guaranteed to find the starting " if nothing else.
- while (Result[FirstNonSlash] == '\\')
- --FirstNonSlash;
- if ((Result.size()-1-FirstNonSlash) & 1) {
- // Diagnose errors for things like: #define F(X) #X / F(\)
- PP.Diag(ArgToks[-1], diag::pp_invalid_string_literal);
- Result.erase(Result.end()-1); // remove one of the \'s.
- }
- }
- Result += '"';
-
- // If this is the charify operation and the result is not a legal character
- // constant, diagnose it.
- if (Charify) {
- // First step, turn double quotes into single quotes:
- Result[0] = '\'';
- Result[Result.size()-1] = '\'';
-
- // Check for bogus character.
- bool isBad = false;
- if (Result.size() == 3) {
- isBad = Result[1] == '\''; // ''' is not legal. '\' already fixed above.
- } else {
- isBad = (Result.size() != 4 || Result[1] != '\\'); // Not '\x'
- }
-
- if (isBad) {
- PP.Diag(ArgTokStart[0], diag::err_invalid_character_to_charify);
- Result = "' '"; // Use something arbitrary, but legal.
- }
- }
-
- Tok.setLength(Result.size());
- Tok.setLocation(PP.CreateString(&Result[0], Result.size()));
- return Tok;
-}
-
-/// getStringifiedArgument - Compute, cache, and return the specified argument
-/// that has been 'stringified' as required by the # operator.
-const Token &MacroArgs::getStringifiedArgument(unsigned ArgNo,
- Preprocessor &PP) {
- assert(ArgNo < NumUnexpArgTokens && "Invalid argument number!");
- if (StringifiedArgs.empty()) {
- StringifiedArgs.resize(getNumArguments());
- memset(&StringifiedArgs[0], 0,
- sizeof(StringifiedArgs[0])*getNumArguments());
- }
- if (StringifiedArgs[ArgNo].isNot(tok::string_literal))
- StringifiedArgs[ArgNo] = StringifyArgument(getUnexpArgument(ArgNo), PP);
- return StringifiedArgs[ArgNo];
-}
diff --git a/clang/lib/Lex/MacroArgs.h b/clang/lib/Lex/MacroArgs.h
deleted file mode 100644
index 4b22fa18aa8b..000000000000
--- a/clang/lib/Lex/MacroArgs.h
+++ /dev/null
@@ -1,109 +0,0 @@
-//===--- MacroArgs.h - Formal argument info for Macros ----------*- 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 MacroArgs interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_MACROARGS_H
-#define LLVM_CLANG_MACROARGS_H
-
-#include <vector>
-
-namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
-
-/// MacroArgs - An instance of this class captures information about
-/// the formal arguments specified to a function-like macro invocation.
-class MacroArgs {
- /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
- /// arguments. All of the actual argument tokens are allocated immediately
- /// after the MacroArgs object in memory. This is all of the arguments
- /// concatenated together, with 'EOF' markers at the end of each argument.
- unsigned NumUnexpArgTokens;
-
- /// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty
- /// if not yet computed. This includes the EOF marker at the end of the
- /// stream.
- std::vector<std::vector<Token> > PreExpArgTokens;
-
- /// StringifiedArgs - This contains arguments in 'stringified' form. If the
- /// stringified form of an argument has not yet been computed, this is empty.
- std::vector<Token> StringifiedArgs;
-
- /// VarargsElided - True if this is a C99 style varargs macro invocation and
- /// there was no argument specified for the "..." argument. If the argument
- /// was specified (even empty) or this isn't a C99 style varargs function, or
- /// if in strict mode and the C99 varargs macro had only a ... argument, this
- /// is false.
- bool VarargsElided;
-
- MacroArgs(unsigned NumToks, bool varargsElided)
- : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided) {}
- ~MacroArgs() {}
-public:
- /// MacroArgs ctor function - Create a new MacroArgs object with the specified
- /// macro and argument info.
- static MacroArgs *create(const MacroInfo *MI,
- const Token *UnexpArgTokens,
- unsigned NumArgTokens, bool VarargsElided);
-
- /// destroy - Destroy and deallocate the memory for this object.
- ///
- void destroy();
-
- /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
- /// by pre-expansion, return false. Otherwise, conservatively return true.
- bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const;
-
- /// getUnexpArgument - Return a pointer to the first token of the unexpanded
- /// token list for the specified formal.
- ///
- const Token *getUnexpArgument(unsigned Arg) const;
-
- /// getArgLength - Given a pointer to an expanded or unexpanded argument,
- /// return the number of tokens, not counting the EOF, that make up the
- /// argument.
- static unsigned getArgLength(const Token *ArgPtr);
-
- /// getPreExpArgument - Return the pre-expanded form of the specified
- /// argument.
- const std::vector<Token> &
- getPreExpArgument(unsigned Arg, Preprocessor &PP);
-
- /// getStringifiedArgument - Compute, cache, and return the specified argument
- /// that has been 'stringified' as required by the # operator.
- const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP);
-
- /// getNumArguments - Return the number of arguments passed into this macro
- /// invocation.
- unsigned getNumArguments() const { return NumUnexpArgTokens; }
-
-
- /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
- /// invocation and there was no argument specified for the "..." argument. If
- /// the argument was specified (even empty) or this isn't a C99 style varargs
- /// function, or if in strict mode and the C99 varargs macro had only a ...
- /// argument, this returns false.
- bool isVarargsElidedUse() const { return VarargsElided; }
-
- /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
- /// tokens into the literal string token that should be produced by the C #
- /// preprocessor operator. If Charify is true, then it should be turned into
- /// a character literal for the Microsoft charize (#@) extension.
- ///
- static Token StringifyArgument(const Token *ArgToks,
- Preprocessor &PP, bool Charify = false);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp
deleted file mode 100644
index de19ff502a6a..000000000000
--- a/clang/lib/Lex/MacroInfo.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//===--- MacroInfo.cpp - Information about #defined identifiers -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MacroInfo interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/Preprocessor.h"
-using namespace clang;
-
-MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
- IsFunctionLike = false;
- IsC99Varargs = false;
- IsGNUVarargs = false;
- IsBuiltinMacro = false;
- IsDisabled = false;
- IsUsed = true;
-
- ArgumentList = 0;
- NumArguments = 0;
-}
-
-/// isIdenticalTo - Return true if the specified macro definition is equal to
-/// this macro in spelling, arguments, and whitespace. This is used to emit
-/// duplicate definition warnings. This implements the rules in C99 6.10.3.
-///
-bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const {
- // Check # tokens in replacement, number of args, and various flags all match.
- if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
- getNumArgs() != Other.getNumArgs() ||
- isFunctionLike() != Other.isFunctionLike() ||
- isC99Varargs() != Other.isC99Varargs() ||
- isGNUVarargs() != Other.isGNUVarargs())
- return false;
-
- // Check arguments.
- for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end();
- I != E; ++I, ++OI)
- if (*I != *OI) return false;
-
- // Check all the tokens.
- for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
- const Token &A = ReplacementTokens[i];
- const Token &B = Other.ReplacementTokens[i];
- if (A.getKind() != B.getKind() ||
- A.isAtStartOfLine() != B.isAtStartOfLine() ||
- A.hasLeadingSpace() != B.hasLeadingSpace())
- return false;
-
- // If this is an identifier, it is easy.
- if (A.getIdentifierInfo() || B.getIdentifierInfo()) {
- if (A.getIdentifierInfo() != B.getIdentifierInfo())
- return false;
- continue;
- }
-
- // Otherwise, check the spelling.
- if (PP.getSpelling(A) != PP.getSpelling(B))
- return false;
- }
-
- return true;
-}
diff --git a/clang/lib/Lex/Makefile b/clang/lib/Lex/Makefile
deleted file mode 100644
index 187448c99228..000000000000
--- a/clang/lib/Lex/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-##===- clang/lib/Lex/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the Lexer library for the C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-include $(LEVEL)/Makefile.config
-
-LIBRARYNAME := clangLex
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-ifeq ($(ARCH),PowerPC)
-CXXFLAGS += -maltivec
-endif
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Lex/PPCaching.cpp b/clang/lib/Lex/PPCaching.cpp
deleted file mode 100644
index 822b207cdcbe..000000000000
--- a/clang/lib/Lex/PPCaching.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-//===--- PPCaching.cpp - Handle caching lexed tokens ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements pieces of the Preprocessor interface that manage the
-// caching of lexed tokens.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-using namespace clang;
-
-/// EnableBacktrackAtThisPos - From the point that this method is called, and
-/// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
-/// keeps track of the lexed tokens so that a subsequent Backtrack() call will
-/// make the Preprocessor re-lex the same tokens.
-///
-/// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
-/// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
-/// be combined with the EnableBacktrackAtThisPos calls in reverse order.
-void Preprocessor::EnableBacktrackAtThisPos() {
- CacheTokens = true;
- BacktrackPositions.push_back(CachedLexPos);
- EnterCachingLexMode();
-}
-
-/// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
-void Preprocessor::CommitBacktrackedTokens() {
- assert(!BacktrackPositions.empty()
- && "EnableBacktrackAtThisPos was not called!");
- BacktrackPositions.pop_back();
- CacheTokens = !BacktrackPositions.empty();
-}
-
-/// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
-/// EnableBacktrackAtThisPos() was previously called.
-void Preprocessor::Backtrack() {
- assert(!BacktrackPositions.empty()
- && "EnableBacktrackAtThisPos was not called!");
- CachedLexPos = BacktrackPositions.back();
- BacktrackPositions.pop_back();
- CacheTokens = !BacktrackPositions.empty();
-}
-
-void Preprocessor::CachingLex(Token &Result) {
- if (CachedLexPos < CachedTokens.size()) {
- Result = CachedTokens[CachedLexPos++];
- return;
- }
-
- ExitCachingLexMode();
- Lex(Result);
-
- if (!CacheTokens) {
- // All cached tokens were consumed.
- CachedTokens.clear();
- CachedLexPos = 0;
- return;
- }
-
- // We should cache the lexed token.
-
- EnterCachingLexMode();
- if (Result.isNot(tok::eof)) {
- CachedTokens.push_back(Result);
- ++CachedLexPos;
- }
-}
-
-void Preprocessor::EnterCachingLexMode() {
- if (InCachingLexMode())
- return;
-
- IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
- CurTokenLexer));
- CurLexer = 0;
- CurTokenLexer = 0;
-}
-
-
-const Token &Preprocessor::PeekAhead(unsigned N) {
- assert(CachedLexPos + N > CachedTokens.size() && "Confused caching.");
- ExitCachingLexMode();
- for (unsigned C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
- CachedTokens.push_back(Token());
- Lex(CachedTokens.back());
- }
- EnterCachingLexMode();
- return CachedTokens.back();
-}
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
deleted file mode 100644
index a3aaabd298d7..000000000000
--- a/clang/lib/Lex/PPDirectives.cpp
+++ /dev/null
@@ -1,1161 +0,0 @@
-//===--- PPDirectives.cpp - Directive Handling for Preprocessor -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements # directive processing for the Preprocessor.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Utility Methods for Preprocessor Directive Handling.
-//===----------------------------------------------------------------------===//
-
-/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
-/// current line until the tok::eom token is found.
-void Preprocessor::DiscardUntilEndOfDirective() {
- Token Tmp;
- do {
- LexUnexpandedToken(Tmp);
- } while (Tmp.isNot(tok::eom));
-}
-
-/// isCXXNamedOperator - Returns "true" if the token is a named operator in C++.
-static bool isCXXNamedOperator(const std::string &Spelling) {
- return Spelling == "and" || Spelling == "bitand" || Spelling == "bitor" ||
- Spelling == "compl" || Spelling == "not" || Spelling == "not_eq" ||
- Spelling == "or" || Spelling == "xor";
-}
-
-/// ReadMacroName - Lex and validate a macro name, which occurs after a
-/// #define or #undef. This sets the token kind to eom and discards the rest
-/// of the macro line if the macro name is invalid. isDefineUndef is 1 if
-/// this is due to a a #define, 2 if #undef directive, 0 if it is something
-/// else (e.g. #ifdef).
-void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) {
- // Read the token, don't allow macro expansion on it.
- LexUnexpandedToken(MacroNameTok);
-
- // Missing macro name?
- if (MacroNameTok.is(tok::eom))
- return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
-
- IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
- if (II == 0) {
- std::string Spelling = getSpelling(MacroNameTok);
- if (isCXXNamedOperator(Spelling))
- // C++ 2.5p2: Alternative tokens behave the same as its primary token
- // except for their spellings.
- Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name, Spelling);
- else
- Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
- // Fall through on error.
- } else if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
- // Error if defining "defined": C99 6.10.8.4.
- Diag(MacroNameTok, diag::err_defined_macro_name);
- } else if (isDefineUndef && II->hasMacroDefinition() &&
- getMacroInfo(II)->isBuiltinMacro()) {
- // Error if defining "__LINE__" and other builtins: C99 6.10.8.4.
- if (isDefineUndef == 1)
- Diag(MacroNameTok, diag::pp_redef_builtin_macro);
- else
- Diag(MacroNameTok, diag::pp_undef_builtin_macro);
- } else {
- // Okay, we got a good identifier node. Return it.
- return;
- }
-
- // Invalid macro name, read and discard the rest of the line. Then set the
- // token kind to tok::eom.
- MacroNameTok.setKind(tok::eom);
- return DiscardUntilEndOfDirective();
-}
-
-/// CheckEndOfDirective - Ensure that the next token is a tok::eom token. If
-/// not, emit a diagnostic and consume up until the eom.
-void Preprocessor::CheckEndOfDirective(const char *DirType) {
- Token Tmp;
- // Lex unexpanded tokens: macros might expand to zero tokens, causing us to
- // miss diagnosing invalid lines.
- LexUnexpandedToken(Tmp);
-
- // There should be no tokens after the directive, but we allow them as an
- // extension.
- while (Tmp.is(tok::comment)) // Skip comments in -C mode.
- LexUnexpandedToken(Tmp);
-
- if (Tmp.isNot(tok::eom)) {
- Diag(Tmp, diag::ext_pp_extra_tokens_at_eol, DirType);
- DiscardUntilEndOfDirective();
- }
-}
-
-
-
-/// SkipExcludedConditionalBlock - We just read a #if or related directive and
-/// decided that the subsequent tokens are in the #if'd out portion of the
-/// file. Lex the rest of the file, until we see an #endif. If
-/// FoundNonSkipPortion is true, then we have already emitted code for part of
-/// this #if directive, so #else/#elif blocks should never be entered. If ElseOk
-/// is true, then #else directives are ok, if not, then we have already seen one
-/// so a #else directive is a duplicate. When this returns, the caller can lex
-/// the first valid token.
-void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
- bool FoundNonSkipPortion,
- bool FoundElse) {
- ++NumSkipped;
- assert(CurTokenLexer == 0 && CurLexer &&
- "Lexing a macro, not a file?");
-
- CurLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/false,
- FoundNonSkipPortion, FoundElse);
-
- // Enter raw mode to disable identifier lookup (and thus macro expansion),
- // disabling warnings, etc.
- CurLexer->LexingRawMode = true;
- Token Tok;
- while (1) {
- CurLexer->Lex(Tok);
-
- // If this is the end of the buffer, we have an error.
- if (Tok.is(tok::eof)) {
- // Emit errors for each unterminated conditional on the stack, including
- // the current one.
- while (!CurLexer->ConditionalStack.empty()) {
- Diag(CurLexer->ConditionalStack.back().IfLoc,
- diag::err_pp_unterminated_conditional);
- CurLexer->ConditionalStack.pop_back();
- }
-
- // Just return and let the caller lex after this #include.
- break;
- }
-
- // If this token is not a preprocessor directive, just skip it.
- if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine())
- continue;
-
- // We just parsed a # character at the start of a line, so we're in
- // directive mode. Tell the lexer this so any newlines we see will be
- // converted into an EOM token (this terminates the macro).
- CurLexer->ParsingPreprocessorDirective = true;
- CurLexer->KeepCommentMode = false;
-
-
- // Read the next token, the directive flavor.
- LexUnexpandedToken(Tok);
-
- // If this isn't an identifier directive (e.g. is "# 1\n" or "#\n", or
- // something bogus), skip it.
- if (Tok.isNot(tok::identifier)) {
- CurLexer->ParsingPreprocessorDirective = false;
- // Restore comment saving mode.
- CurLexer->KeepCommentMode = KeepComments;
- continue;
- }
-
- // If the first letter isn't i or e, it isn't intesting to us. We know that
- // this is safe in the face of spelling differences, because there is no way
- // to spell an i/e in a strange way that is another letter. Skipping this
- // allows us to avoid looking up the identifier info for #define/#undef and
- // other common directives.
- const char *RawCharData = SourceMgr.getCharacterData(Tok.getLocation());
- char FirstChar = RawCharData[0];
- if (FirstChar >= 'a' && FirstChar <= 'z' &&
- FirstChar != 'i' && FirstChar != 'e') {
- CurLexer->ParsingPreprocessorDirective = false;
- // Restore comment saving mode.
- CurLexer->KeepCommentMode = KeepComments;
- continue;
- }
-
- // Get the identifier name without trigraphs or embedded newlines. Note
- // that we can't use Tok.getIdentifierInfo() because its lookup is disabled
- // when skipping.
- // TODO: could do this with zero copies in the no-clean case by using
- // strncmp below.
- char Directive[20];
- unsigned IdLen;
- if (!Tok.needsCleaning() && Tok.getLength() < 20) {
- IdLen = Tok.getLength();
- memcpy(Directive, RawCharData, IdLen);
- Directive[IdLen] = 0;
- } else {
- std::string DirectiveStr = getSpelling(Tok);
- IdLen = DirectiveStr.size();
- if (IdLen >= 20) {
- CurLexer->ParsingPreprocessorDirective = false;
- // Restore comment saving mode.
- CurLexer->KeepCommentMode = KeepComments;
- continue;
- }
- memcpy(Directive, &DirectiveStr[0], IdLen);
- Directive[IdLen] = 0;
- }
-
- if (FirstChar == 'i' && Directive[1] == 'f') {
- if ((IdLen == 2) || // "if"
- (IdLen == 5 && !strcmp(Directive+2, "def")) || // "ifdef"
- (IdLen == 6 && !strcmp(Directive+2, "ndef"))) { // "ifndef"
- // We know the entire #if/#ifdef/#ifndef block will be skipped, don't
- // bother parsing the condition.
- DiscardUntilEndOfDirective();
- CurLexer->pushConditionalLevel(Tok.getLocation(), /*wasskipping*/true,
- /*foundnonskip*/false,
- /*fnddelse*/false);
- }
- } else if (FirstChar == 'e') {
- if (IdLen == 5 && !strcmp(Directive+1, "ndif")) { // "endif"
- CheckEndOfDirective("#endif");
- PPConditionalInfo CondInfo;
- CondInfo.WasSkipping = true; // Silence bogus warning.
- bool InCond = CurLexer->popConditionalLevel(CondInfo);
- InCond = InCond; // Silence warning in no-asserts mode.
- assert(!InCond && "Can't be skipping if not in a conditional!");
-
- // If we popped the outermost skipping block, we're done skipping!
- if (!CondInfo.WasSkipping)
- break;
- } else if (IdLen == 4 && !strcmp(Directive+1, "lse")) { // "else".
- // #else directive in a skipping conditional. If not in some other
- // skipping conditional, and if #else hasn't already been seen, enter it
- // as a non-skipping conditional.
- CheckEndOfDirective("#else");
- PPConditionalInfo &CondInfo = CurLexer->peekConditionalLevel();
-
- // If this is a #else with a #else before it, report the error.
- if (CondInfo.FoundElse) Diag(Tok, diag::pp_err_else_after_else);
-
- // Note that we've seen a #else in this conditional.
- CondInfo.FoundElse = true;
-
- // If the conditional is at the top level, and the #if block wasn't
- // entered, enter the #else block now.
- if (!CondInfo.WasSkipping && !CondInfo.FoundNonSkip) {
- CondInfo.FoundNonSkip = true;
- break;
- }
- } else if (IdLen == 4 && !strcmp(Directive+1, "lif")) { // "elif".
- PPConditionalInfo &CondInfo = CurLexer->peekConditionalLevel();
-
- bool ShouldEnter;
- // If this is in a skipping block or if we're already handled this #if
- // block, don't bother parsing the condition.
- if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
- DiscardUntilEndOfDirective();
- ShouldEnter = false;
- } else {
- // Restore the value of LexingRawMode so that identifiers are
- // looked up, etc, inside the #elif expression.
- assert(CurLexer->LexingRawMode && "We have to be skipping here!");
- CurLexer->LexingRawMode = false;
- IdentifierInfo *IfNDefMacro = 0;
- ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
- CurLexer->LexingRawMode = true;
- }
-
- // If this is a #elif with a #else before it, report the error.
- if (CondInfo.FoundElse) Diag(Tok, diag::pp_err_elif_after_else);
-
- // If this condition is true, enter it!
- if (ShouldEnter) {
- CondInfo.FoundNonSkip = true;
- break;
- }
- }
- }
-
- CurLexer->ParsingPreprocessorDirective = false;
- // Restore comment saving mode.
- CurLexer->KeepCommentMode = KeepComments;
- }
-
- // Finally, if we are out of the conditional (saw an #endif or ran off the end
- // of the file, just stop skipping and return to lexing whatever came after
- // the #if block.
- CurLexer->LexingRawMode = false;
-}
-
-/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
-/// return null on failure. isAngled indicates whether the file reference is
-/// for system #include's or not (i.e. using <> instead of "").
-const FileEntry *Preprocessor::LookupFile(const char *FilenameStart,
- const char *FilenameEnd,
- bool isAngled,
- const DirectoryLookup *FromDir,
- const DirectoryLookup *&CurDir) {
- // If the header lookup mechanism may be relative to the current file, pass in
- // info about where the current file is.
- const FileEntry *CurFileEnt = 0;
- if (!FromDir) {
- SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
- CurFileEnt = SourceMgr.getFileEntryForLoc(FileLoc);
- }
-
- // Do a standard file entry lookup.
- CurDir = CurDirLookup;
- const FileEntry *FE =
- HeaderInfo.LookupFile(FilenameStart, FilenameEnd,
- isAngled, FromDir, CurDir, CurFileEnt);
- if (FE) return FE;
-
- // Otherwise, see if this is a subframework header. If so, this is relative
- // to one of the headers on the #include stack. Walk the list of the current
- // headers on the #include stack and pass them to HeaderInfo.
- if (CurLexer && !CurLexer->Is_PragmaLexer) {
- if ((CurFileEnt = SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc())))
- if ((FE = HeaderInfo.LookupSubframeworkHeader(FilenameStart, FilenameEnd,
- CurFileEnt)))
- return FE;
- }
-
- for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
- IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
- if (ISEntry.TheLexer && !ISEntry.TheLexer->Is_PragmaLexer) {
- if ((CurFileEnt =
- SourceMgr.getFileEntryForLoc(ISEntry.TheLexer->getFileLoc())))
- if ((FE = HeaderInfo.LookupSubframeworkHeader(FilenameStart,
- FilenameEnd, CurFileEnt)))
- return FE;
- }
- }
-
- // Otherwise, we really couldn't find the file.
- return 0;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Directive Handling.
-//===----------------------------------------------------------------------===//
-
-/// HandleDirective - This callback is invoked when the lexer sees a # token
-/// at the start of a line. This consumes the directive, modifies the
-/// lexer/preprocessor state, and advances the lexer(s) so that the next token
-/// read is the correct one.
-void Preprocessor::HandleDirective(Token &Result) {
- // FIXME: Traditional: # with whitespace before it not recognized by K&R?
-
- // We just parsed a # character at the start of a line, so we're in directive
- // mode. Tell the lexer this so any newlines we see will be converted into an
- // EOM token (which terminates the directive).
- CurLexer->ParsingPreprocessorDirective = true;
-
- ++NumDirectives;
-
- // We are about to read a token. For the multiple-include optimization FA to
- // work, we have to remember if we had read any tokens *before* this
- // pp-directive.
- bool ReadAnyTokensBeforeDirective = CurLexer->MIOpt.getHasReadAnyTokensVal();
-
- // Read the next token, the directive flavor. This isn't expanded due to
- // C99 6.10.3p8.
- LexUnexpandedToken(Result);
-
- // C99 6.10.3p11: Is this preprocessor directive in macro invocation? e.g.:
- // #define A(x) #x
- // A(abc
- // #warning blah
- // def)
- // If so, the user is relying on non-portable behavior, emit a diagnostic.
- if (InMacroArgs)
- Diag(Result, diag::ext_embedded_directive);
-
-TryAgain:
- switch (Result.getKind()) {
- case tok::eom:
- return; // null directive.
- case tok::comment:
- // Handle stuff like "# /*foo*/ define X" in -E -C mode.
- LexUnexpandedToken(Result);
- goto TryAgain;
-
- case tok::numeric_constant:
- // FIXME: implement # 7 line numbers!
- DiscardUntilEndOfDirective();
- return;
- default:
- IdentifierInfo *II = Result.getIdentifierInfo();
- if (II == 0) break; // Not an identifier.
-
- // Ask what the preprocessor keyword ID is.
- switch (II->getPPKeywordID()) {
- default: break;
- // C99 6.10.1 - Conditional Inclusion.
- case tok::pp_if:
- return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
- case tok::pp_ifdef:
- return HandleIfdefDirective(Result, false, true/*not valid for miopt*/);
- case tok::pp_ifndef:
- return HandleIfdefDirective(Result, true, ReadAnyTokensBeforeDirective);
- case tok::pp_elif:
- return HandleElifDirective(Result);
- case tok::pp_else:
- return HandleElseDirective(Result);
- case tok::pp_endif:
- return HandleEndifDirective(Result);
-
- // C99 6.10.2 - Source File Inclusion.
- case tok::pp_include:
- return HandleIncludeDirective(Result); // Handle #include.
-
- // C99 6.10.3 - Macro Replacement.
- case tok::pp_define:
- return HandleDefineDirective(Result);
- case tok::pp_undef:
- return HandleUndefDirective(Result);
-
- // C99 6.10.4 - Line Control.
- case tok::pp_line:
- // FIXME: implement #line
- DiscardUntilEndOfDirective();
- return;
-
- // C99 6.10.5 - Error Directive.
- case tok::pp_error:
- return HandleUserDiagnosticDirective(Result, false);
-
- // C99 6.10.6 - Pragma Directive.
- case tok::pp_pragma:
- return HandlePragmaDirective();
-
- // GNU Extensions.
- case tok::pp_import:
- return HandleImportDirective(Result);
- case tok::pp_include_next:
- return HandleIncludeNextDirective(Result);
-
- case tok::pp_warning:
- Diag(Result, diag::ext_pp_warning_directive);
- return HandleUserDiagnosticDirective(Result, true);
- case tok::pp_ident:
- return HandleIdentSCCSDirective(Result);
- case tok::pp_sccs:
- return HandleIdentSCCSDirective(Result);
- case tok::pp_assert:
- //isExtension = true; // FIXME: implement #assert
- break;
- case tok::pp_unassert:
- //isExtension = true; // FIXME: implement #unassert
- break;
- }
- break;
- }
-
- // If we reached here, the preprocessing token is not valid!
- Diag(Result, diag::err_pp_invalid_directive);
-
- // Read the rest of the PP line.
- DiscardUntilEndOfDirective();
-
- // Okay, we're done parsing the directive.
-}
-
-void Preprocessor::HandleUserDiagnosticDirective(Token &Tok,
- bool isWarning) {
- // Read the rest of the line raw. We do this because we don't want macros
- // to be expanded and we don't require that the tokens be valid preprocessing
- // tokens. For example, this is allowed: "#warning ` 'foo". GCC does
- // collapse multiple consequtive white space between tokens, but this isn't
- // specified by the standard.
- std::string Message = CurLexer->ReadToEndOfLine();
-
- unsigned DiagID = isWarning ? diag::pp_hash_warning : diag::err_pp_hash_error;
- return Diag(Tok, DiagID, Message);
-}
-
-/// HandleIdentSCCSDirective - Handle a #ident/#sccs directive.
-///
-void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {
- // Yes, this directive is an extension.
- Diag(Tok, diag::ext_pp_ident_directive);
-
- // Read the string argument.
- Token StrTok;
- Lex(StrTok);
-
- // If the token kind isn't a string, it's a malformed directive.
- if (StrTok.isNot(tok::string_literal) &&
- StrTok.isNot(tok::wide_string_literal))
- return Diag(StrTok, diag::err_pp_malformed_ident);
-
- // Verify that there is nothing after the string, other than EOM.
- CheckEndOfDirective("#ident");
-
- if (Callbacks)
- Callbacks->Ident(Tok.getLocation(), getSpelling(StrTok));
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Include Directive Handling.
-//===----------------------------------------------------------------------===//
-
-/// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
-/// checked and spelled filename, e.g. as an operand of #include. This returns
-/// true if the input filename was in <>'s or false if it were in ""'s. The
-/// caller is expected to provide a buffer that is large enough to hold the
-/// spelling of the filename, but is also expected to handle the case when
-/// this method decides to use a different buffer.
-bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
- const char *&BufStart,
- const char *&BufEnd) {
- // Get the text form of the filename.
- assert(BufStart != BufEnd && "Can't have tokens with empty spellings!");
-
- // Make sure the filename is <x> or "x".
- bool isAngled;
- if (BufStart[0] == '<') {
- if (BufEnd[-1] != '>') {
- Diag(Loc, diag::err_pp_expects_filename);
- BufStart = 0;
- return true;
- }
- isAngled = true;
- } else if (BufStart[0] == '"') {
- if (BufEnd[-1] != '"') {
- Diag(Loc, diag::err_pp_expects_filename);
- BufStart = 0;
- return true;
- }
- isAngled = false;
- } else {
- Diag(Loc, diag::err_pp_expects_filename);
- BufStart = 0;
- return true;
- }
-
- // Diagnose #include "" as invalid.
- if (BufEnd-BufStart <= 2) {
- Diag(Loc, diag::err_pp_empty_filename);
- BufStart = 0;
- return "";
- }
-
- // Skip the brackets.
- ++BufStart;
- --BufEnd;
- return isAngled;
-}
-
-/// ConcatenateIncludeName - Handle cases where the #include name is expanded
-/// from a macro as multiple tokens, which need to be glued together. This
-/// occurs for code like:
-/// #define FOO <a/b.h>
-/// #include FOO
-/// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
-///
-/// This code concatenates and consumes tokens up to the '>' token. It returns
-/// false if the > was found, otherwise it returns true if it finds and consumes
-/// the EOM marker.
-static bool ConcatenateIncludeName(llvm::SmallVector<char, 128> &FilenameBuffer,
- Preprocessor &PP) {
- Token CurTok;
-
- PP.Lex(CurTok);
- while (CurTok.isNot(tok::eom)) {
- // Append the spelling of this token to the buffer. If there was a space
- // before it, add it now.
- if (CurTok.hasLeadingSpace())
- FilenameBuffer.push_back(' ');
-
- // Get the spelling of the token, directly into FilenameBuffer if possible.
- unsigned PreAppendSize = FilenameBuffer.size();
- FilenameBuffer.resize(PreAppendSize+CurTok.getLength());
-
- const char *BufPtr = &FilenameBuffer[PreAppendSize];
- unsigned ActualLen = PP.getSpelling(CurTok, BufPtr);
-
- // If the token was spelled somewhere else, copy it into FilenameBuffer.
- if (BufPtr != &FilenameBuffer[PreAppendSize])
- memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
-
- // Resize FilenameBuffer to the correct size.
- if (CurTok.getLength() != ActualLen)
- FilenameBuffer.resize(PreAppendSize+ActualLen);
-
- // If we found the '>' marker, return success.
- if (CurTok.is(tok::greater))
- return false;
-
- PP.Lex(CurTok);
- }
-
- // If we hit the eom marker, emit an error and return true so that the caller
- // knows the EOM has been read.
- PP.Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
- return true;
-}
-
-/// HandleIncludeDirective - The "#include" tokens have just been read, read the
-/// file to be included from the lexer, then include it! This is a common
-/// routine with functionality shared between #include, #include_next and
-/// #import. LookupFrom is set when this is a #include_next directive, it
-/// specifies the file to start searching from.
-void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
- const DirectoryLookup *LookupFrom,
- bool isImport) {
-
- Token FilenameTok;
- CurLexer->LexIncludeFilename(FilenameTok);
-
- // Reserve a buffer to get the spelling.
- llvm::SmallVector<char, 128> FilenameBuffer;
- const char *FilenameStart, *FilenameEnd;
-
- switch (FilenameTok.getKind()) {
- case tok::eom:
- // If the token kind is EOM, the error has already been diagnosed.
- return;
-
- case tok::angle_string_literal:
- case tok::string_literal: {
- FilenameBuffer.resize(FilenameTok.getLength());
- FilenameStart = &FilenameBuffer[0];
- unsigned Len = getSpelling(FilenameTok, FilenameStart);
- FilenameEnd = FilenameStart+Len;
- break;
- }
-
- case tok::less:
- // This could be a <foo/bar.h> file coming from a macro expansion. In this
- // case, glue the tokens together into FilenameBuffer and interpret those.
- FilenameBuffer.push_back('<');
- if (ConcatenateIncludeName(FilenameBuffer, *this))
- return; // Found <eom> but no ">"? Diagnostic already emitted.
- FilenameStart = &FilenameBuffer[0];
- FilenameEnd = &FilenameBuffer[FilenameBuffer.size()];
- break;
- default:
- Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
- DiscardUntilEndOfDirective();
- return;
- }
-
- bool isAngled = GetIncludeFilenameSpelling(FilenameTok.getLocation(),
- FilenameStart, FilenameEnd);
- // If GetIncludeFilenameSpelling set the start ptr to null, there was an
- // error.
- if (FilenameStart == 0) {
- DiscardUntilEndOfDirective();
- return;
- }
-
- // Verify that there is nothing after the filename, other than EOM. Use the
- // preprocessor to lex this in case lexing the filename entered a macro.
- CheckEndOfDirective("#include");
-
- // Check that we don't have infinite #include recursion.
- if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1)
- return Diag(FilenameTok, diag::err_pp_include_too_deep);
-
- // Search include directories.
- const DirectoryLookup *CurDir;
- const FileEntry *File = LookupFile(FilenameStart, FilenameEnd,
- isAngled, LookupFrom, CurDir);
- if (File == 0)
- return Diag(FilenameTok, diag::err_pp_file_not_found,
- std::string(FilenameStart, FilenameEnd));
-
- // Ask HeaderInfo if we should enter this #include file. If not, #including
- // this file will have no effect.
- if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport))
- return;
-
- // The #included file will be considered to be a system header if either it is
- // in a system include directory, or if the #includer is a system include
- // header.
- SrcMgr::Characteristic_t FileCharacter =
- std::max(HeaderInfo.getFileDirFlavor(File),
- SourceMgr.getFileCharacteristic(getCurrentFileLexer()->getFileLoc()));
-
- // Look up the file, create a File ID for it.
- unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
- FileCharacter);
- if (FileID == 0)
- return Diag(FilenameTok, diag::err_pp_file_not_found,
- std::string(FilenameStart, FilenameEnd));
-
- // Finally, if all is good, enter the new file!
- EnterSourceFile(FileID, CurDir);
-}
-
-/// HandleIncludeNextDirective - Implements #include_next.
-///
-void Preprocessor::HandleIncludeNextDirective(Token &IncludeNextTok) {
- Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
-
- // #include_next is like #include, except that we start searching after
- // the current found directory. If we can't do this, issue a
- // diagnostic.
- const DirectoryLookup *Lookup = CurDirLookup;
- if (isInPrimaryFile()) {
- Lookup = 0;
- Diag(IncludeNextTok, diag::pp_include_next_in_primary);
- } else if (Lookup == 0) {
- Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
- } else {
- // Start looking up in the next directory.
- ++Lookup;
- }
-
- return HandleIncludeDirective(IncludeNextTok, Lookup);
-}
-
-/// HandleImportDirective - Implements #import.
-///
-void Preprocessor::HandleImportDirective(Token &ImportTok) {
- Diag(ImportTok, diag::ext_pp_import_directive);
-
- return HandleIncludeDirective(ImportTok, 0, true);
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Macro Directive Handling.
-//===----------------------------------------------------------------------===//
-
-/// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
-/// definition has just been read. Lex the rest of the arguments and the
-/// closing ), updating MI with what we learn. Return true if an error occurs
-/// parsing the arg list.
-bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
- llvm::SmallVector<IdentifierInfo*, 32> Arguments;
-
- Token Tok;
- while (1) {
- LexUnexpandedToken(Tok);
- switch (Tok.getKind()) {
- case tok::r_paren:
- // Found the end of the argument list.
- if (Arguments.empty()) { // #define FOO()
- MI->setArgumentList(Arguments.begin(), Arguments.end());
- return false;
- }
- // Otherwise we have #define FOO(A,)
- Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
- return true;
- case tok::ellipsis: // #define X(... -> C99 varargs
- // Warn if use of C99 feature in non-C99 mode.
- if (!Features.C99) Diag(Tok, diag::ext_variadic_macro);
-
- // Lex the token after the identifier.
- LexUnexpandedToken(Tok);
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
- return true;
- }
- // Add the __VA_ARGS__ identifier as an argument.
- Arguments.push_back(Ident__VA_ARGS__);
- MI->setIsC99Varargs();
- MI->setArgumentList(Arguments.begin(), Arguments.end());
- return false;
- case tok::eom: // #define X(
- Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
- return true;
- default:
- // Handle keywords and identifiers here to accept things like
- // #define Foo(for) for.
- IdentifierInfo *II = Tok.getIdentifierInfo();
- if (II == 0) {
- // #define X(1
- Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
- return true;
- }
-
- // If this is already used as an argument, it is used multiple times (e.g.
- // #define X(A,A.
- if (std::find(Arguments.begin(), Arguments.end(), II) !=
- Arguments.end()) { // C99 6.10.3p6
- Diag(Tok, diag::err_pp_duplicate_name_in_arg_list, II->getName());
- return true;
- }
-
- // Add the argument to the macro info.
- Arguments.push_back(II);
-
- // Lex the token after the identifier.
- LexUnexpandedToken(Tok);
-
- switch (Tok.getKind()) {
- default: // #define X(A B
- Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
- return true;
- case tok::r_paren: // #define X(A)
- MI->setArgumentList(Arguments.begin(), Arguments.end());
- return false;
- case tok::comma: // #define X(A,
- break;
- case tok::ellipsis: // #define X(A... -> GCC extension
- // Diagnose extension.
- Diag(Tok, diag::ext_named_variadic_macro);
-
- // Lex the token after the identifier.
- LexUnexpandedToken(Tok);
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
- return true;
- }
-
- MI->setIsGNUVarargs();
- MI->setArgumentList(Arguments.begin(), Arguments.end());
- return false;
- }
- }
- }
-}
-
-/// HandleDefineDirective - Implements #define. This consumes the entire macro
-/// line then lets the caller lex the next real token.
-void Preprocessor::HandleDefineDirective(Token &DefineTok) {
- ++NumDefined;
-
- Token MacroNameTok;
- ReadMacroName(MacroNameTok, 1);
-
- // Error reading macro name? If so, diagnostic already issued.
- if (MacroNameTok.is(tok::eom))
- return;
-
- // If we are supposed to keep comments in #defines, reenable comment saving
- // mode.
- CurLexer->KeepCommentMode = KeepMacroComments;
-
- // Create the new macro.
- MacroInfo *MI = new MacroInfo(MacroNameTok.getLocation());
-
- Token Tok;
- LexUnexpandedToken(Tok);
-
- // If this is a function-like macro definition, parse the argument list,
- // marking each of the identifiers as being used as macro arguments. Also,
- // check other constraints on the first token of the macro body.
- if (Tok.is(tok::eom)) {
- // If there is no body to this macro, we have no special handling here.
- } else if (Tok.is(tok::l_paren) && !Tok.hasLeadingSpace()) {
- // This is a function-like macro definition. Read the argument list.
- MI->setIsFunctionLike();
- if (ReadMacroDefinitionArgList(MI)) {
- // Forget about MI.
- delete MI;
- // Throw away the rest of the line.
- if (CurLexer->ParsingPreprocessorDirective)
- DiscardUntilEndOfDirective();
- return;
- }
-
- // Read the first token after the arg list for down below.
- LexUnexpandedToken(Tok);
- } else if (!Tok.hasLeadingSpace()) {
- // C99 requires whitespace between the macro definition and the body. Emit
- // a diagnostic for something like "#define X+".
- if (Features.C99) {
- Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
- } else {
- // FIXME: C90/C++ do not get this diagnostic, but it does get a similar
- // one in some cases!
- }
- } else {
- // This is a normal token with leading space. Clear the leading space
- // marker on the first token to get proper expansion.
- Tok.clearFlag(Token::LeadingSpace);
- }
-
- // If this is a definition of a variadic C99 function-like macro, not using
- // the GNU named varargs extension, enabled __VA_ARGS__.
-
- // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
- // This gets unpoisoned where it is allowed.
- assert(Ident__VA_ARGS__->isPoisoned() && "__VA_ARGS__ should be poisoned!");
- if (MI->isC99Varargs())
- Ident__VA_ARGS__->setIsPoisoned(false);
-
- // Read the rest of the macro body.
- if (MI->isObjectLike()) {
- // Object-like macros are very simple, just read their body.
- while (Tok.isNot(tok::eom)) {
- MI->AddTokenToBody(Tok);
- // Get the next token of the macro.
- LexUnexpandedToken(Tok);
- }
-
- } else {
- // Otherwise, read the body of a function-like macro. This has to validate
- // the # (stringize) operator.
- while (Tok.isNot(tok::eom)) {
- MI->AddTokenToBody(Tok);
-
- // Check C99 6.10.3.2p1: ensure that # operators are followed by macro
- // parameters in function-like macro expansions.
- if (Tok.isNot(tok::hash)) {
- // Get the next token of the macro.
- LexUnexpandedToken(Tok);
- continue;
- }
-
- // Get the next token of the macro.
- LexUnexpandedToken(Tok);
-
- // Not a macro arg identifier?
- if (!Tok.getIdentifierInfo() ||
- MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) {
- Diag(Tok, diag::err_pp_stringize_not_parameter);
- delete MI;
-
- // Disable __VA_ARGS__ again.
- Ident__VA_ARGS__->setIsPoisoned(true);
- return;
- }
-
- // Things look ok, add the param name token to the macro.
- MI->AddTokenToBody(Tok);
-
- // Get the next token of the macro.
- LexUnexpandedToken(Tok);
- }
- }
-
-
- // Disable __VA_ARGS__ again.
- Ident__VA_ARGS__->setIsPoisoned(true);
-
- // Check that there is no paste (##) operator at the begining or end of the
- // replacement list.
- unsigned NumTokens = MI->getNumTokens();
- if (NumTokens != 0) {
- if (MI->getReplacementToken(0).is(tok::hashhash)) {
- Diag(MI->getReplacementToken(0), diag::err_paste_at_start);
- delete MI;
- return;
- }
- if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) {
- Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end);
- delete MI;
- return;
- }
- }
-
- // If this is the primary source file, remember that this macro hasn't been
- // used yet.
- if (isInPrimaryFile())
- MI->setIsUsed(false);
-
- // Finally, if this identifier already had a macro defined for it, verify that
- // the macro bodies are identical and free the old definition.
- if (MacroInfo *OtherMI = getMacroInfo(MacroNameTok.getIdentifierInfo())) {
- if (!OtherMI->isUsed())
- Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
-
- // Macros must be identical. This means all tokes and whitespace separation
- // must be the same. C99 6.10.3.2.
- if (!MI->isIdenticalTo(*OtherMI, *this)) {
- Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef,
- MacroNameTok.getIdentifierInfo()->getName());
- Diag(OtherMI->getDefinitionLoc(), diag::ext_pp_macro_redef2);
- }
- delete OtherMI;
- }
-
- setMacroInfo(MacroNameTok.getIdentifierInfo(), MI);
-}
-
-/// HandleUndefDirective - Implements #undef.
-///
-void Preprocessor::HandleUndefDirective(Token &UndefTok) {
- ++NumUndefined;
-
- Token MacroNameTok;
- ReadMacroName(MacroNameTok, 2);
-
- // Error reading macro name? If so, diagnostic already issued.
- if (MacroNameTok.is(tok::eom))
- return;
-
- // Check to see if this is the last token on the #undef line.
- CheckEndOfDirective("#undef");
-
- // Okay, we finally have a valid identifier to undef.
- MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo());
-
- // If the macro is not defined, this is a noop undef, just return.
- if (MI == 0) return;
-
- if (!MI->isUsed())
- Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
-
- // Free macro definition.
- delete MI;
- setMacroInfo(MacroNameTok.getIdentifierInfo(), 0);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Conditional Directive Handling.
-//===----------------------------------------------------------------------===//
-
-/// HandleIfdefDirective - Implements the #ifdef/#ifndef directive. isIfndef is
-/// true when this is a #ifndef directive. ReadAnyTokensBeforeDirective is true
-/// if any tokens have been returned or pp-directives activated before this
-/// #ifndef has been lexed.
-///
-void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
- bool ReadAnyTokensBeforeDirective) {
- ++NumIf;
- Token DirectiveTok = Result;
-
- Token MacroNameTok;
- ReadMacroName(MacroNameTok);
-
- // Error reading macro name? If so, diagnostic already issued.
- if (MacroNameTok.is(tok::eom)) {
- // Skip code until we get to #endif. This helps with recovery by not
- // emitting an error when the #endif is reached.
- SkipExcludedConditionalBlock(DirectiveTok.getLocation(),
- /*Foundnonskip*/false, /*FoundElse*/false);
- return;
- }
-
- // Check to see if this is the last token on the #if[n]def line.
- CheckEndOfDirective(isIfndef ? "#ifndef" : "#ifdef");
-
- if (CurLexer->getConditionalStackDepth() == 0) {
- // If the start of a top-level #ifdef, inform MIOpt.
- if (!ReadAnyTokensBeforeDirective) {
- assert(isIfndef && "#ifdef shouldn't reach here");
- CurLexer->MIOpt.EnterTopLevelIFNDEF(MacroNameTok.getIdentifierInfo());
- } else
- CurLexer->MIOpt.EnterTopLevelConditional();
- }
-
- IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
- MacroInfo *MI = getMacroInfo(MII);
-
- // If there is a macro, process it.
- if (MI) // Mark it used.
- MI->setIsUsed(true);
-
- // Should we include the stuff contained by this directive?
- if (!MI == isIfndef) {
- // Yes, remember that we are inside a conditional, then lex the next token.
- CurLexer->pushConditionalLevel(DirectiveTok.getLocation(), /*wasskip*/false,
- /*foundnonskip*/true, /*foundelse*/false);
- } else {
- // No, skip the contents of this block and return the first token after it.
- SkipExcludedConditionalBlock(DirectiveTok.getLocation(),
- /*Foundnonskip*/false,
- /*FoundElse*/false);
- }
-}
-
-/// HandleIfDirective - Implements the #if directive.
-///
-void Preprocessor::HandleIfDirective(Token &IfToken,
- bool ReadAnyTokensBeforeDirective) {
- ++NumIf;
-
- // Parse and evaluation the conditional expression.
- IdentifierInfo *IfNDefMacro = 0;
- bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro);
-
-
- // If this condition is equivalent to #ifndef X, and if this is the first
- // directive seen, handle it for the multiple-include optimization.
- if (CurLexer->getConditionalStackDepth() == 0) {
- if (!ReadAnyTokensBeforeDirective && IfNDefMacro)
- CurLexer->MIOpt.EnterTopLevelIFNDEF(IfNDefMacro);
- else
- CurLexer->MIOpt.EnterTopLevelConditional();
- }
-
- // Should we include the stuff contained by this directive?
- if (ConditionalTrue) {
- // Yes, remember that we are inside a conditional, then lex the next token.
- CurLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
- /*foundnonskip*/true, /*foundelse*/false);
- } else {
- // No, skip the contents of this block and return the first token after it.
- SkipExcludedConditionalBlock(IfToken.getLocation(), /*Foundnonskip*/false,
- /*FoundElse*/false);
- }
-}
-
-/// HandleEndifDirective - Implements the #endif directive.
-///
-void Preprocessor::HandleEndifDirective(Token &EndifToken) {
- ++NumEndif;
-
- // Check that this is the whole directive.
- CheckEndOfDirective("#endif");
-
- PPConditionalInfo CondInfo;
- if (CurLexer->popConditionalLevel(CondInfo)) {
- // No conditionals on the stack: this is an #endif without an #if.
- return Diag(EndifToken, diag::err_pp_endif_without_if);
- }
-
- // If this the end of a top-level #endif, inform MIOpt.
- if (CurLexer->getConditionalStackDepth() == 0)
- CurLexer->MIOpt.ExitTopLevelConditional();
-
- assert(!CondInfo.WasSkipping && !CurLexer->LexingRawMode &&
- "This code should only be reachable in the non-skipping case!");
-}
-
-
-void Preprocessor::HandleElseDirective(Token &Result) {
- ++NumElse;
-
- // #else directive in a non-skipping conditional... start skipping.
- CheckEndOfDirective("#else");
-
- PPConditionalInfo CI;
- if (CurLexer->popConditionalLevel(CI))
- return Diag(Result, diag::pp_err_else_without_if);
-
- // If this is a top-level #else, inform the MIOpt.
- if (CurLexer->getConditionalStackDepth() == 0)
- CurLexer->MIOpt.EnterTopLevelConditional();
-
- // If this is a #else with a #else before it, report the error.
- if (CI.FoundElse) Diag(Result, diag::pp_err_else_after_else);
-
- // Finally, skip the rest of the contents of this block and return the first
- // token after it.
- return SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
- /*FoundElse*/true);
-}
-
-void Preprocessor::HandleElifDirective(Token &ElifToken) {
- ++NumElse;
-
- // #elif directive in a non-skipping conditional... start skipping.
- // We don't care what the condition is, because we will always skip it (since
- // the block immediately before it was included).
- DiscardUntilEndOfDirective();
-
- PPConditionalInfo CI;
- if (CurLexer->popConditionalLevel(CI))
- return Diag(ElifToken, diag::pp_err_elif_without_if);
-
- // If this is a top-level #elif, inform the MIOpt.
- if (CurLexer->getConditionalStackDepth() == 0)
- CurLexer->MIOpt.EnterTopLevelConditional();
-
- // If this is a #elif with a #else before it, report the error.
- if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
-
- // Finally, skip the rest of the contents of this block and return the first
- // token after it.
- return SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
- /*FoundElse*/CI.FoundElse);
-}
-
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
deleted file mode 100644
index 4042604391c2..000000000000
--- a/clang/lib/Lex/PPExpressions.cpp
+++ /dev/null
@@ -1,711 +0,0 @@
-//===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Preprocessor::EvaluateDirectiveExpression method,
-// which parses and evaluates integer constant expressions for #if directives.
-//
-//===----------------------------------------------------------------------===//
-//
-// FIXME: implement testing for #assert's.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/LiteralSupport.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/APSInt.h"
-using namespace clang;
-
-/// PPValue - Represents the value of a subexpression of a preprocessor
-/// conditional and the source range covered by it.
-class PPValue {
- SourceRange Range;
-public:
- llvm::APSInt Val;
-
- // Default ctor - Construct an 'invalid' PPValue.
- PPValue(unsigned BitWidth) : Val(BitWidth) {}
-
- unsigned getBitWidth() const { return Val.getBitWidth(); }
- bool isUnsigned() const { return Val.isUnsigned(); }
-
- const SourceRange &getRange() const { return Range; }
-
- void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
- void setRange(SourceLocation B, SourceLocation E) {
- Range.setBegin(B); Range.setEnd(E);
- }
- void setBegin(SourceLocation L) { Range.setBegin(L); }
- void setEnd(SourceLocation L) { Range.setEnd(L); }
-};
-
-static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
- Token &PeekTok, bool ValueLive,
- Preprocessor &PP);
-
-/// DefinedTracker - This struct is used while parsing expressions to keep track
-/// of whether !defined(X) has been seen.
-///
-/// With this simple scheme, we handle the basic forms:
-/// !defined(X) and !defined X
-/// but we also trivially handle (silly) stuff like:
-/// !!!defined(X) and +!defined(X) and !+!+!defined(X) and !(defined(X)).
-struct DefinedTracker {
- /// Each time a Value is evaluated, it returns information about whether the
- /// parsed value is of the form defined(X), !defined(X) or is something else.
- enum TrackerState {
- DefinedMacro, // defined(X)
- NotDefinedMacro, // !defined(X)
- Unknown // Something else.
- } State;
- /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this
- /// indicates the macro that was checked.
- IdentifierInfo *TheMacro;
-};
-
-/// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
-/// return the computed value in Result. Return true if there was an error
-/// parsing. This function also returns information about the form of the
-/// expression in DT. See above for information on what DT means.
-///
-/// If ValueLive is false, then this value is being evaluated in a context where
-/// the result is not used. As such, avoid diagnostics that relate to
-/// evaluation.
-static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
- bool ValueLive, Preprocessor &PP) {
- DT.State = DefinedTracker::Unknown;
-
- // If this token's spelling is a pp-identifier, check to see if it is
- // 'defined' or if it is a macro. Note that we check here because many
- // keywords are pp-identifiers, so we can't check the kind.
- if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
- // If this identifier isn't 'defined' and it wasn't macro expanded, it turns
- // into a simple 0, unless it is the C++ keyword "true", in which case it
- // turns into "1".
- if (II->getPPKeywordID() != tok::pp_defined) {
- PP.Diag(PeekTok, diag::warn_pp_undef_identifier, II->getName());
- Result.Val = II->getTokenID() == tok::kw_true;
- Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
- Result.setRange(PeekTok.getLocation());
- PP.LexNonComment(PeekTok);
- return false;
- }
-
- // Handle "defined X" and "defined(X)".
- Result.setBegin(PeekTok.getLocation());
-
- // Get the next token, don't expand it.
- PP.LexUnexpandedToken(PeekTok);
-
- // Two options, it can either be a pp-identifier or a (.
- SourceLocation LParenLoc;
- if (PeekTok.is(tok::l_paren)) {
- // Found a paren, remember we saw it and skip it.
- LParenLoc = PeekTok.getLocation();
- PP.LexUnexpandedToken(PeekTok);
- }
-
- // If we don't have a pp-identifier now, this is an error.
- if ((II = PeekTok.getIdentifierInfo()) == 0) {
- PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
- return true;
- }
-
- // Otherwise, we got an identifier, is it defined to something?
- Result.Val = II->hasMacroDefinition();
- Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
-
- // If there is a macro, mark it used.
- if (Result.Val != 0 && ValueLive) {
- MacroInfo *Macro = PP.getMacroInfo(II);
- Macro->setIsUsed(true);
- }
-
- // Consume identifier.
- Result.setEnd(PeekTok.getLocation());
- PP.LexNonComment(PeekTok);
-
- // If we are in parens, ensure we have a trailing ).
- if (LParenLoc.isValid()) {
- if (PeekTok.isNot(tok::r_paren)) {
- PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen);
- PP.Diag(LParenLoc, diag::err_matching, "(");
- return true;
- }
- // Consume the ).
- Result.setEnd(PeekTok.getLocation());
- PP.LexNonComment(PeekTok);
- }
-
- // Success, remember that we saw defined(X).
- DT.State = DefinedTracker::DefinedMacro;
- DT.TheMacro = II;
- return false;
- }
-
- switch (PeekTok.getKind()) {
- default: // Non-value token.
- PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
- return true;
- case tok::eom:
- case tok::r_paren:
- // If there is no expression, report and exit.
- PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
- return true;
- case tok::numeric_constant: {
- llvm::SmallString<64> IntegerBuffer;
- IntegerBuffer.resize(PeekTok.getLength());
- const char *ThisTokBegin = &IntegerBuffer[0];
- unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
- NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
- PeekTok.getLocation(), PP);
- if (Literal.hadError)
- return true; // a diagnostic was already reported.
-
- if (Literal.isFloatingLiteral() || Literal.isImaginary) {
- PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
- return true;
- }
- assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
-
- // long long is a C99 feature.
- if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
- && Literal.isLongLong)
- PP.Diag(PeekTok, diag::ext_longlong);
-
- // Parse the integer literal into Result.
- if (Literal.GetIntegerValue(Result.Val)) {
- // Overflow parsing integer literal.
- if (ValueLive) PP.Diag(PeekTok, diag::warn_integer_too_large);
- Result.Val.setIsUnsigned(true);
- } else {
- // Set the signedness of the result to match whether there was a U suffix
- // or not.
- Result.Val.setIsUnsigned(Literal.isUnsigned);
-
- // Detect overflow based on whether the value is signed. If signed
- // and if the value is too large, emit a warning "integer constant is so
- // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
- // is 64-bits.
- if (!Literal.isUnsigned && Result.Val.isNegative()) {
- // Don't warn for a hex literal: 0x8000..0 shouldn't warn.
- if (ValueLive && Literal.getRadix() != 16)
- PP.Diag(PeekTok, diag::warn_integer_too_large_for_signed);
- Result.Val.setIsUnsigned(true);
- }
- }
-
- // Consume the token.
- Result.setRange(PeekTok.getLocation());
- PP.LexNonComment(PeekTok);
- return false;
- }
- case tok::char_constant: { // 'x'
- llvm::SmallString<32> CharBuffer;
- CharBuffer.resize(PeekTok.getLength());
- const char *ThisTokBegin = &CharBuffer[0];
- unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
- CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
- PeekTok.getLocation(), PP);
- if (Literal.hadError())
- return true; // A diagnostic was already emitted.
-
- // Character literals are always int or wchar_t, expand to intmax_t.
- TargetInfo &TI = PP.getTargetInfo();
- unsigned NumBits = TI.getCharWidth(Literal.isWide());
-
- // Set the width.
- llvm::APSInt Val(NumBits);
- // Set the value.
- Val = Literal.getValue();
- // Set the signedness.
- Val.setIsUnsigned(!TI.isCharSigned());
-
- if (Result.Val.getBitWidth() > Val.getBitWidth()) {
- Result.Val = Val.extend(Result.Val.getBitWidth());
- } else {
- assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
- "intmax_t smaller than char/wchar_t?");
- Result.Val = Val;
- }
-
- // Consume the token.
- Result.setRange(PeekTok.getLocation());
- PP.LexNonComment(PeekTok);
- return false;
- }
- case tok::l_paren: {
- SourceLocation Start = PeekTok.getLocation();
- PP.LexNonComment(PeekTok); // Eat the (.
- // Parse the value and if there are any binary operators involved, parse
- // them.
- if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
-
- // If this is a silly value like (X), which doesn't need parens, check for
- // !(defined X).
- if (PeekTok.is(tok::r_paren)) {
- // Just use DT unmodified as our result.
- } else {
- // Otherwise, we have something like (x+y), and we consumed '(x'.
- if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP))
- return true;
-
- if (PeekTok.isNot(tok::r_paren)) {
- PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen,
- Result.getRange());
- PP.Diag(Start, diag::err_matching, "(");
- return true;
- }
- DT.State = DefinedTracker::Unknown;
- }
- Result.setRange(Start, PeekTok.getLocation());
- PP.LexNonComment(PeekTok); // Eat the ).
- return false;
- }
- case tok::plus: {
- SourceLocation Start = PeekTok.getLocation();
- // Unary plus doesn't modify the value.
- PP.LexNonComment(PeekTok);
- if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
- Result.setBegin(Start);
- return false;
- }
- case tok::minus: {
- SourceLocation Loc = PeekTok.getLocation();
- PP.LexNonComment(PeekTok);
- if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
- Result.setBegin(Loc);
-
- // C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
- Result.Val = -Result.Val;
-
- // -MININT is the only thing that overflows. Unsigned never overflows.
- bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
-
- // If this operator is live and overflowed, report the issue.
- if (Overflow && ValueLive)
- PP.Diag(Loc, diag::warn_pp_expr_overflow, Result.getRange());
-
- DT.State = DefinedTracker::Unknown;
- return false;
- }
-
- case tok::tilde: {
- SourceLocation Start = PeekTok.getLocation();
- PP.LexNonComment(PeekTok);
- if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
- Result.setBegin(Start);
-
- // C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
- Result.Val = ~Result.Val;
- DT.State = DefinedTracker::Unknown;
- return false;
- }
-
- case tok::exclaim: {
- SourceLocation Start = PeekTok.getLocation();
- PP.LexNonComment(PeekTok);
- if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
- Result.setBegin(Start);
- Result.Val = !Result.Val;
- // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
- Result.Val.setIsUnsigned(false);
-
- if (DT.State == DefinedTracker::DefinedMacro)
- DT.State = DefinedTracker::NotDefinedMacro;
- else if (DT.State == DefinedTracker::NotDefinedMacro)
- DT.State = DefinedTracker::DefinedMacro;
- return false;
- }
-
- // FIXME: Handle #assert
- }
-}
-
-
-
-/// getPrecedence - Return the precedence of the specified binary operator
-/// token. This returns:
-/// ~0 - Invalid token.
-/// 14 -> 3 - various operators.
-/// 0 - 'eom' or ')'
-static unsigned getPrecedence(tok::TokenKind Kind) {
- switch (Kind) {
- default: return ~0U;
- case tok::percent:
- case tok::slash:
- case tok::star: return 14;
- case tok::plus:
- case tok::minus: return 13;
- case tok::lessless:
- case tok::greatergreater: return 12;
- case tok::lessequal:
- case tok::less:
- case tok::greaterequal:
- case tok::greater: return 11;
- case tok::exclaimequal:
- case tok::equalequal: return 10;
- case tok::amp: return 9;
- case tok::caret: return 8;
- case tok::pipe: return 7;
- case tok::ampamp: return 6;
- case tok::pipepipe: return 5;
- case tok::question: return 4;
- case tok::comma: return 3;
- case tok::colon: return 2;
- case tok::r_paren: return 0; // Lowest priority, end of expr.
- case tok::eom: return 0; // Lowest priority, end of macro.
- }
-}
-
-
-/// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
-/// PeekTok, and whose precedence is PeekPrec. This returns the result in LHS.
-///
-/// If ValueLive is false, then this value is being evaluated in a context where
-/// the result is not used. As such, avoid diagnostics that relate to
-/// evaluation, such as division by zero warnings.
-static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
- Token &PeekTok, bool ValueLive,
- Preprocessor &PP) {
- unsigned PeekPrec = getPrecedence(PeekTok.getKind());
- // If this token isn't valid, report the error.
- if (PeekPrec == ~0U) {
- PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop,
- LHS.getRange());
- return true;
- }
-
- while (1) {
- // If this token has a lower precedence than we are allowed to parse, return
- // it so that higher levels of the recursion can parse it.
- if (PeekPrec < MinPrec)
- return false;
-
- tok::TokenKind Operator = PeekTok.getKind();
-
- // If this is a short-circuiting operator, see if the RHS of the operator is
- // dead. Note that this cannot just clobber ValueLive. Consider
- // "0 && 1 ? 4 : 1 / 0", which is parsed as "(0 && 1) ? 4 : (1 / 0)". In
- // this example, the RHS of the && being dead does not make the rest of the
- // expr dead.
- bool RHSIsLive;
- if (Operator == tok::ampamp && LHS.Val == 0)
- RHSIsLive = false; // RHS of "0 && x" is dead.
- else if (Operator == tok::pipepipe && LHS.Val != 0)
- RHSIsLive = false; // RHS of "1 || x" is dead.
- else if (Operator == tok::question && LHS.Val == 0)
- RHSIsLive = false; // RHS (x) of "0 ? x : y" is dead.
- else
- RHSIsLive = ValueLive;
-
- // Consume the operator, remembering the operator's location for reporting.
- SourceLocation OpLoc = PeekTok.getLocation();
- PP.LexNonComment(PeekTok);
-
- PPValue RHS(LHS.getBitWidth());
- // Parse the RHS of the operator.
- DefinedTracker DT;
- if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
-
- // Remember the precedence of this operator and get the precedence of the
- // operator immediately to the right of the RHS.
- unsigned ThisPrec = PeekPrec;
- PeekPrec = getPrecedence(PeekTok.getKind());
-
- // If this token isn't valid, report the error.
- if (PeekPrec == ~0U) {
- PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop,
- RHS.getRange());
- return true;
- }
-
- // Decide whether to include the next binop in this subexpression. For
- // example, when parsing x+y*z and looking at '*', we want to recursively
- // handle y*z as a single subexpression. We do this because the precedence
- // of * is higher than that of +. The only strange case we have to handle
- // here is for the ?: operator, where the precedence is actually lower than
- // the LHS of the '?'. The grammar rule is:
- //
- // conditional-expression ::=
- // logical-OR-expression ? expression : conditional-expression
- // where 'expression' is actually comma-expression.
- unsigned RHSPrec;
- if (Operator == tok::question)
- // The RHS of "?" should be maximally consumed as an expression.
- RHSPrec = getPrecedence(tok::comma);
- else // All others should munch while higher precedence.
- RHSPrec = ThisPrec+1;
-
- if (PeekPrec >= RHSPrec) {
- if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP))
- return true;
- PeekPrec = getPrecedence(PeekTok.getKind());
- }
- assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
-
- // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
- // either operand is unsigned.
- llvm::APSInt Res(LHS.getBitWidth());
- switch (Operator) {
- case tok::question: // No UAC for x and y in "x ? y : z".
- case tok::lessless: // Shift amount doesn't UAC with shift value.
- case tok::greatergreater: // Shift amount doesn't UAC with shift value.
- case tok::comma: // Comma operands are not subject to UACs.
- case tok::pipepipe: // Logical || does not do UACs.
- case tok::ampamp: // Logical && does not do UACs.
- break; // No UAC
- default:
- Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
- // If this just promoted something from signed to unsigned, and if the
- // value was negative, warn about it.
- if (ValueLive && Res.isUnsigned()) {
- if (!LHS.isUnsigned() && LHS.Val.isNegative())
- PP.Diag(OpLoc, diag::warn_pp_convert_lhs_to_positive,
- LHS.Val.toString(10, true) + " to " +
- LHS.Val.toString(10, false),
- LHS.getRange(), RHS.getRange());
- if (!RHS.isUnsigned() && RHS.Val.isNegative())
- PP.Diag(OpLoc, diag::warn_pp_convert_rhs_to_positive,
- RHS.Val.toString(10, true) + " to " +
- RHS.Val.toString(10, false),
- LHS.getRange(), RHS.getRange());
- }
- LHS.Val.setIsUnsigned(Res.isUnsigned());
- RHS.Val.setIsUnsigned(Res.isUnsigned());
- }
-
- // FIXME: All of these should detect and report overflow??
- bool Overflow = false;
- switch (Operator) {
- default: assert(0 && "Unknown operator token!");
- case tok::percent:
- if (RHS.Val != 0)
- Res = LHS.Val % RHS.Val;
- else if (ValueLive) {
- PP.Diag(OpLoc, diag::err_pp_remainder_by_zero, LHS.getRange(),
- RHS.getRange());
- return true;
- }
- break;
- case tok::slash:
- if (RHS.Val != 0) {
- Res = LHS.Val / RHS.Val;
- if (LHS.Val.isSigned()) // MININT/-1 --> overflow.
- Overflow = LHS.Val.isMinSignedValue() && RHS.Val.isAllOnesValue();
- } else if (ValueLive) {
- PP.Diag(OpLoc, diag::err_pp_division_by_zero, LHS.getRange(),
- RHS.getRange());
- return true;
- }
- break;
-
- case tok::star:
- Res = LHS.Val * RHS.Val;
- if (LHS.Val != 0 && RHS.Val != 0)
- Overflow = Res/RHS.Val != LHS.Val || Res/LHS.Val != RHS.Val;
- break;
- case tok::lessless: {
- // Determine whether overflow is about to happen.
- unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
- if (ShAmt >= LHS.Val.getBitWidth())
- Overflow = true, ShAmt = LHS.Val.getBitWidth()-1;
- else if (LHS.isUnsigned())
- Overflow = ShAmt > LHS.Val.countLeadingZeros();
- else if (LHS.Val.isNonNegative()) // Don't allow sign change.
- Overflow = ShAmt >= LHS.Val.countLeadingZeros();
- else
- Overflow = ShAmt >= LHS.Val.countLeadingOnes();
-
- Res = LHS.Val << ShAmt;
- break;
- }
- case tok::greatergreater: {
- // Determine whether overflow is about to happen.
- unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
- if (ShAmt >= LHS.getBitWidth())
- Overflow = true, ShAmt = LHS.getBitWidth()-1;
- Res = LHS.Val >> ShAmt;
- break;
- }
- case tok::plus:
- Res = LHS.Val + RHS.Val;
- if (LHS.isUnsigned())
- Overflow = Res.ult(LHS.Val);
- else if (LHS.Val.isNonNegative() == RHS.Val.isNonNegative() &&
- Res.isNonNegative() != LHS.Val.isNonNegative())
- Overflow = true; // Overflow for signed addition.
- break;
- case tok::minus:
- Res = LHS.Val - RHS.Val;
- if (LHS.isUnsigned())
- Overflow = Res.ugt(LHS.Val);
- else if (LHS.Val.isNonNegative() != RHS.Val.isNonNegative() &&
- Res.isNonNegative() != LHS.Val.isNonNegative())
- Overflow = true; // Overflow for signed subtraction.
- break;
- case tok::lessequal:
- Res = LHS.Val <= RHS.Val;
- Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
- break;
- case tok::less:
- Res = LHS.Val < RHS.Val;
- Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
- break;
- case tok::greaterequal:
- Res = LHS.Val >= RHS.Val;
- Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
- break;
- case tok::greater:
- Res = LHS.Val > RHS.Val;
- Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
- break;
- case tok::exclaimequal:
- Res = LHS.Val != RHS.Val;
- Res.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed)
- break;
- case tok::equalequal:
- Res = LHS.Val == RHS.Val;
- Res.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed)
- break;
- case tok::amp:
- Res = LHS.Val & RHS.Val;
- break;
- case tok::caret:
- Res = LHS.Val ^ RHS.Val;
- break;
- case tok::pipe:
- Res = LHS.Val | RHS.Val;
- break;
- case tok::ampamp:
- Res = (LHS.Val != 0 && RHS.Val != 0);
- Res.setIsUnsigned(false); // C99 6.5.13p3, result is always int (signed)
- break;
- case tok::pipepipe:
- Res = (LHS.Val != 0 || RHS.Val != 0);
- Res.setIsUnsigned(false); // C99 6.5.14p3, result is always int (signed)
- break;
- case tok::comma:
- // Comma is invalid in pp expressions in c89/c++ mode, but is valid in C99
- // if not being evaluated.
- if (!PP.getLangOptions().C99 || ValueLive)
- PP.Diag(OpLoc, diag::ext_pp_comma_expr, LHS.getRange(), RHS.getRange());
- Res = RHS.Val; // LHS = LHS,RHS -> RHS.
- break;
- case tok::question: {
- // Parse the : part of the expression.
- if (PeekTok.isNot(tok::colon)) {
- PP.Diag(PeekTok.getLocation(), diag::err_expected_colon,
- LHS.getRange(), RHS.getRange());
- PP.Diag(OpLoc, diag::err_matching, "?");
- return true;
- }
- // Consume the :.
- PP.LexNonComment(PeekTok);
-
- // Evaluate the value after the :.
- bool AfterColonLive = ValueLive && LHS.Val == 0;
- PPValue AfterColonVal(LHS.getBitWidth());
- DefinedTracker DT;
- if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
- return true;
-
- // Parse anything after the : with the same precedence as ?. We allow
- // things of equal precedence because ?: is right associative.
- if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
- PeekTok, AfterColonLive, PP))
- return true;
-
- // Now that we have the condition, the LHS and the RHS of the :, evaluate.
- Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
- RHS.setEnd(AfterColonVal.getRange().getEnd());
-
- // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
- // either operand is unsigned.
- Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
-
- // Figure out the precedence of the token after the : part.
- PeekPrec = getPrecedence(PeekTok.getKind());
- break;
- }
- case tok::colon:
- // Don't allow :'s to float around without being part of ?: exprs.
- PP.Diag(OpLoc, diag::err_pp_colon_without_question, LHS.getRange(),
- RHS.getRange());
- return true;
- }
-
- // If this operator is live and overflowed, report the issue.
- if (Overflow && ValueLive)
- PP.Diag(OpLoc, diag::warn_pp_expr_overflow,
- LHS.getRange(), RHS.getRange());
-
- // Put the result back into 'LHS' for our next iteration.
- LHS.Val = Res;
- LHS.setEnd(RHS.getRange().getEnd());
- }
-
- return false;
-}
-
-/// EvaluateDirectiveExpression - Evaluate an integer constant expression that
-/// may occur after a #if or #elif directive. If the expression is equivalent
-/// to "!defined(X)" return X in IfNDefMacro.
-bool Preprocessor::
-EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
- // Peek ahead one token.
- Token Tok;
- Lex(Tok);
-
- // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
- unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
-
- PPValue ResVal(BitWidth);
- DefinedTracker DT;
- if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
- // Parse error, skip the rest of the macro line.
- if (Tok.isNot(tok::eom))
- DiscardUntilEndOfDirective();
- return false;
- }
-
- // If we are at the end of the expression after just parsing a value, there
- // must be no (unparenthesized) binary operators involved, so we can exit
- // directly.
- if (Tok.is(tok::eom)) {
- // If the expression we parsed was of the form !defined(macro), return the
- // macro in IfNDefMacro.
- if (DT.State == DefinedTracker::NotDefinedMacro)
- IfNDefMacro = DT.TheMacro;
-
- return ResVal.Val != 0;
- }
-
- // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
- // operator and the stuff after it.
- if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
- Tok, true, *this)) {
- // Parse error, skip the rest of the macro line.
- if (Tok.isNot(tok::eom))
- DiscardUntilEndOfDirective();
- return false;
- }
-
- // If we aren't at the tok::eom token, something bad happened, like an extra
- // ')' token.
- if (Tok.isNot(tok::eom)) {
- Diag(Tok, diag::err_pp_expected_eol);
- DiscardUntilEndOfDirective();
- }
-
- return ResVal.Val != 0;
-}
-
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
deleted file mode 100644
index ccaddf52ed56..000000000000
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-//===--- PPLexerChange.cpp - Handle changing lexers in the preprocessor ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements pieces of the Preprocessor interface that manage the
-// current lexer stack.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-using namespace clang;
-
-PPCallbacks::~PPCallbacks() {
-}
-
-
-//===----------------------------------------------------------------------===//
-// Miscellaneous Methods.
-//===----------------------------------------------------------------------===//
-
-/// isInPrimaryFile - Return true if we're in the top-level file, not in a
-/// #include. This looks through macro expansions and active _Pragma lexers.
-bool Preprocessor::isInPrimaryFile() const {
- if (CurLexer && !CurLexer->Is_PragmaLexer)
- return IncludeMacroStack.empty();
-
- // If there are any stacked lexers, we're in a #include.
- assert(IncludeMacroStack[0].TheLexer &&
- !IncludeMacroStack[0].TheLexer->Is_PragmaLexer &&
- "Top level include stack isn't our primary lexer?");
- for (unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i)
- if (IncludeMacroStack[i].TheLexer &&
- !IncludeMacroStack[i].TheLexer->Is_PragmaLexer)
- return false;
- return true;
-}
-
-/// getCurrentLexer - Return the current file lexer being lexed from. Note
-/// that this ignores any potentially active macro expansions and _Pragma
-/// expansions going on at the time.
-Lexer *Preprocessor::getCurrentFileLexer() const {
- if (CurLexer && !CurLexer->Is_PragmaLexer) return CurLexer;
-
- // Look for a stacked lexer.
- for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
- Lexer *L = IncludeMacroStack[i-1].TheLexer;
- if (L && !L->Is_PragmaLexer) // Ignore macro & _Pragma expansions.
- return L;
- }
- return 0;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Methods for Entering and Callbacks for leaving various contexts
-//===----------------------------------------------------------------------===//
-
-/// EnterSourceFile - Add a source file to the top of the include stack and
-/// start lexing tokens from it instead of the current buffer. Return true
-/// on failure.
-void Preprocessor::EnterSourceFile(unsigned FileID,
- const DirectoryLookup *CurDir) {
- assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!");
- ++NumEnteredSourceFiles;
-
- if (MaxIncludeStackDepth < IncludeMacroStack.size())
- MaxIncludeStackDepth = IncludeMacroStack.size();
-
- Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this);
- EnterSourceFileWithLexer(TheLexer, CurDir);
-}
-
-/// EnterSourceFile - Add a source file to the top of the include stack and
-/// start lexing tokens from it instead of the current buffer.
-void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
- const DirectoryLookup *CurDir) {
-
- // Add the current lexer to the include stack.
- if (CurLexer || CurTokenLexer)
- IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
- CurTokenLexer));
-
- CurLexer = TheLexer;
- CurDirLookup = CurDir;
- CurTokenLexer = 0;
-
- // Notify the client, if desired, that we are in a new source file.
- if (Callbacks && !CurLexer->Is_PragmaLexer) {
- SrcMgr::Characteristic_t FileType =
- SourceMgr.getFileCharacteristic(CurLexer->getFileLoc());
-
- Callbacks->FileChanged(CurLexer->getFileLoc(),
- PPCallbacks::EnterFile, FileType);
- }
-}
-
-
-
-/// EnterMacro - Add a Macro to the top of the include stack and start lexing
-/// tokens from it instead of the current buffer.
-void Preprocessor::EnterMacro(Token &Tok, MacroArgs *Args) {
- IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
- CurTokenLexer));
- CurLexer = 0;
- CurDirLookup = 0;
-
- if (NumCachedTokenLexers == 0) {
- CurTokenLexer = new TokenLexer(Tok, Args, *this);
- } else {
- CurTokenLexer = TokenLexerCache[--NumCachedTokenLexers];
- CurTokenLexer->Init(Tok, Args);
- }
-}
-
-/// EnterTokenStream - Add a "macro" context to the top of the include stack,
-/// which will cause the lexer to start returning the specified tokens.
-///
-/// If DisableMacroExpansion is true, tokens lexed from the token stream will
-/// not be subject to further macro expansion. Otherwise, these tokens will
-/// be re-macro-expanded when/if expansion is enabled.
-///
-/// If OwnsTokens is false, this method assumes that the specified stream of
-/// tokens has a permanent owner somewhere, so they do not need to be copied.
-/// If it is true, it assumes the array of tokens is allocated with new[] and
-/// must be freed.
-///
-void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,
- bool DisableMacroExpansion,
- bool OwnsTokens) {
- // Save our current state.
- IncludeMacroStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup,
- CurTokenLexer));
- CurLexer = 0;
- CurDirLookup = 0;
-
- // Create a macro expander to expand from the specified token stream.
- if (NumCachedTokenLexers == 0) {
- CurTokenLexer = new TokenLexer(Toks, NumToks, DisableMacroExpansion,
- OwnsTokens, *this);
- } else {
- CurTokenLexer = TokenLexerCache[--NumCachedTokenLexers];
- CurTokenLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
- }
-}
-
-/// HandleEndOfFile - This callback is invoked when the lexer hits the end of
-/// the current file. This either returns the EOF token or pops a level off
-/// the include stack and keeps going.
-bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
- assert(!CurTokenLexer &&
- "Ending a file when currently in a macro!");
-
- // See if this file had a controlling macro.
- if (CurLexer) { // Not ending a macro, ignore it.
- if (const IdentifierInfo *ControllingMacro =
- CurLexer->MIOpt.GetControllingMacroAtEndOfFile()) {
- // Okay, this has a controlling macro, remember in PerFileInfo.
- if (const FileEntry *FE =
- SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc()))
- HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);
- }
- }
-
- // If this is a #include'd file, pop it off the include stack and continue
- // lexing the #includer file.
- if (!IncludeMacroStack.empty()) {
- // We're done with the #included file.
- RemoveTopOfLexerStack();
-
- // Notify the client, if desired, that we are in a new source file.
- if (Callbacks && !isEndOfMacro && CurLexer) {
- SrcMgr::Characteristic_t FileType =
- SourceMgr.getFileCharacteristic(CurLexer->getFileLoc());
-
- Callbacks->FileChanged(CurLexer->getSourceLocation(CurLexer->BufferPtr),
- PPCallbacks::ExitFile, FileType);
- }
-
- // Client should lex another token.
- return false;
- }
-
- // If the file ends with a newline, form the EOF token on the newline itself,
- // rather than "on the line following it", which doesn't exist. This makes
- // diagnostics relating to the end of file include the last file that the user
- // actually typed, which is goodness.
- const char *EndPos = CurLexer->BufferEnd;
- if (EndPos != CurLexer->BufferStart &&
- (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {
- --EndPos;
-
- // Handle \n\r and \r\n:
- if (EndPos != CurLexer->BufferStart &&
- (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&
- EndPos[-1] != EndPos[0])
- --EndPos;
- }
-
- Result.startToken();
- CurLexer->BufferPtr = EndPos;
- CurLexer->FormTokenWithChars(Result, EndPos);
- Result.setKind(tok::eof);
-
- // We're done with the #included file.
- delete CurLexer;
- CurLexer = 0;
-
- // This is the end of the top-level file. If the diag::pp_macro_not_used
- // diagnostic is enabled, look for macros that have not been used.
- if (Diags.getDiagnosticLevel(diag::pp_macro_not_used) != Diagnostic::Ignored){
- for (llvm::DenseMap<IdentifierInfo*, MacroInfo*>::iterator I =
- Macros.begin(), E = Macros.end(); I != E; ++I) {
- if (!I->second->isUsed())
- Diag(I->second->getDefinitionLoc(), diag::pp_macro_not_used);
- }
- }
- return true;
-}
-
-/// HandleEndOfTokenLexer - This callback is invoked when the current TokenLexer
-/// hits the end of its token stream.
-bool Preprocessor::HandleEndOfTokenLexer(Token &Result) {
- assert(CurTokenLexer && !CurLexer &&
- "Ending a macro when currently in a #include file!");
-
- // Delete or cache the now-dead macro expander.
- if (NumCachedTokenLexers == TokenLexerCacheSize)
- delete CurTokenLexer;
- else
- TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer;
-
- // Handle this like a #include file being popped off the stack.
- CurTokenLexer = 0;
- return HandleEndOfFile(Result, true);
-}
-
-/// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
-/// lexer stack. This should only be used in situations where the current
-/// state of the top-of-stack lexer is unknown.
-void Preprocessor::RemoveTopOfLexerStack() {
- assert(!IncludeMacroStack.empty() && "Ran out of stack entries to load");
-
- if (CurTokenLexer) {
- // Delete or cache the now-dead macro expander.
- if (NumCachedTokenLexers == TokenLexerCacheSize)
- delete CurTokenLexer;
- else
- TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer;
- } else {
- delete CurLexer;
- }
- CurLexer = IncludeMacroStack.back().TheLexer;
- CurDirLookup = IncludeMacroStack.back().TheDirLookup;
- CurTokenLexer = IncludeMacroStack.back().TheTokenLexer;
- IncludeMacroStack.pop_back();
-}
-
-/// HandleMicrosoftCommentPaste - When the macro expander pastes together a
-/// comment (/##/) in microsoft mode, this method handles updating the current
-/// state, returning the token on the next source line.
-void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
- assert(CurTokenLexer && !CurLexer &&
- "Pasted comment can only be formed from macro");
-
- // We handle this by scanning for the closest real lexer, switching it to
- // raw mode and preprocessor mode. This will cause it to return \n as an
- // explicit EOM token.
- Lexer *FoundLexer = 0;
- bool LexerWasInPPMode = false;
- for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
- IncludeStackInfo &ISI = *(IncludeMacroStack.end()-i-1);
- if (ISI.TheLexer == 0) continue; // Scan for a real lexer.
-
- // Once we find a real lexer, mark it as raw mode (disabling macro
- // expansions) and preprocessor mode (return EOM). We know that the lexer
- // was *not* in raw mode before, because the macro that the comment came
- // from was expanded. However, it could have already been in preprocessor
- // mode (#if COMMENT) in which case we have to return it to that mode and
- // return EOM.
- FoundLexer = ISI.TheLexer;
- FoundLexer->LexingRawMode = true;
- LexerWasInPPMode = FoundLexer->ParsingPreprocessorDirective;
- FoundLexer->ParsingPreprocessorDirective = true;
- break;
- }
-
- // Okay, we either found and switched over the lexer, or we didn't find a
- // lexer. In either case, finish off the macro the comment came from, getting
- // the next token.
- if (!HandleEndOfTokenLexer(Tok)) Lex(Tok);
-
- // Discarding comments as long as we don't have EOF or EOM. This 'comments
- // out' the rest of the line, including any tokens that came from other macros
- // that were active, as in:
- // #define submacro a COMMENT b
- // submacro c
- // which should lex to 'a' only: 'b' and 'c' should be removed.
- while (Tok.isNot(tok::eom) && Tok.isNot(tok::eof))
- Lex(Tok);
-
- // If we got an eom token, then we successfully found the end of the line.
- if (Tok.is(tok::eom)) {
- assert(FoundLexer && "Can't get end of line without an active lexer");
- // Restore the lexer back to normal mode instead of raw mode.
- FoundLexer->LexingRawMode = false;
-
- // If the lexer was already in preprocessor mode, just return the EOM token
- // to finish the preprocessor line.
- if (LexerWasInPPMode) return;
-
- // Otherwise, switch out of PP mode and return the next lexed token.
- FoundLexer->ParsingPreprocessorDirective = false;
- return Lex(Tok);
- }
-
- // If we got an EOF token, then we reached the end of the token stream but
- // didn't find an explicit \n. This can only happen if there was no lexer
- // active (an active lexer would return EOM at EOF if there was no \n in
- // preprocessor directive mode), so just return EOF as our token.
- assert(!FoundLexer && "Lexer should return EOM before EOF in PP mode");
-}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
deleted file mode 100644
index 43df71a2cc8c..000000000000
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-//===--- MacroExpansion.cpp - Top level Macro Expansion -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the top level handling of macro expasion for the
-// preprocessor.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "MacroArgs.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/Diagnostic.h"
-#include <ctime>
-using namespace clang;
-
-/// setMacroInfo - Specify a macro for this identifier.
-///
-void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) {
- if (MI == 0) {
- if (II->hasMacroDefinition()) {
- Macros.erase(II);
- II->setHasMacroDefinition(false);
- }
- } else {
- Macros[II] = MI;
- II->setHasMacroDefinition(true);
- }
-}
-
-/// RegisterBuiltinMacro - Register the specified identifier in the identifier
-/// table and mark it as a builtin macro to be expanded.
-IdentifierInfo *Preprocessor::RegisterBuiltinMacro(const char *Name) {
- // Get the identifier.
- IdentifierInfo *Id = getIdentifierInfo(Name);
-
- // Mark it as being a macro that is builtin.
- MacroInfo *MI = new MacroInfo(SourceLocation());
- MI->setIsBuiltinMacro();
- setMacroInfo(Id, MI);
- return Id;
-}
-
-
-/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
-/// identifier table.
-void Preprocessor::RegisterBuiltinMacros() {
- Ident__LINE__ = RegisterBuiltinMacro("__LINE__");
- Ident__FILE__ = RegisterBuiltinMacro("__FILE__");
- Ident__DATE__ = RegisterBuiltinMacro("__DATE__");
- Ident__TIME__ = RegisterBuiltinMacro("__TIME__");
- Ident_Pragma = RegisterBuiltinMacro("_Pragma");
-
- // GCC Extensions.
- Ident__BASE_FILE__ = RegisterBuiltinMacro("__BASE_FILE__");
- Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro("__INCLUDE_LEVEL__");
- Ident__TIMESTAMP__ = RegisterBuiltinMacro("__TIMESTAMP__");
-}
-
-/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
-/// in its expansion, currently expands to that token literally.
-static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
- const IdentifierInfo *MacroIdent,
- Preprocessor &PP) {
- IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo();
-
- // If the token isn't an identifier, it's always literally expanded.
- if (II == 0) return true;
-
- // If the identifier is a macro, and if that macro is enabled, it may be
- // expanded so it's not a trivial expansion.
- if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&
- // Fast expanding "#define X X" is ok, because X would be disabled.
- II != MacroIdent)
- return false;
-
- // If this is an object-like macro invocation, it is safe to trivially expand
- // it.
- if (MI->isObjectLike()) return true;
-
- // If this is a function-like macro invocation, it's safe to trivially expand
- // as long as the identifier is not a macro argument.
- for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
- I != E; ++I)
- if (*I == II)
- return false; // Identifier is a macro argument.
-
- return true;
-}
-
-
-/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
-/// lexed is a '('. If so, consume the token and return true, if not, this
-/// method should have no observable side-effect on the lexed tokens.
-bool Preprocessor::isNextPPTokenLParen() {
- // Do some quick tests for rejection cases.
- unsigned Val;
- if (CurLexer)
- Val = CurLexer->isNextPPTokenLParen();
- else
- Val = CurTokenLexer->isNextTokenLParen();
-
- if (Val == 2) {
- // We have run off the end. If it's a source file we don't
- // examine enclosing ones (C99 5.1.1.2p4). Otherwise walk up the
- // macro stack.
- if (CurLexer)
- return false;
- for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
- IncludeStackInfo &Entry = IncludeMacroStack[i-1];
- if (Entry.TheLexer)
- Val = Entry.TheLexer->isNextPPTokenLParen();
- else
- Val = Entry.TheTokenLexer->isNextTokenLParen();
-
- if (Val != 2)
- break;
-
- // Ran off the end of a source file?
- if (Entry.TheLexer)
- return false;
- }
- }
-
- // Okay, if we know that the token is a '(', lex it and return. Otherwise we
- // have found something that isn't a '(' or we found the end of the
- // translation unit. In either case, return false.
- if (Val != 1)
- return false;
-
- Token Tok;
- LexUnexpandedToken(Tok);
- assert(Tok.is(tok::l_paren) && "Error computing l-paren-ness?");
- return true;
-}
-
-/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
-/// expanded as a macro, handle it and return the next token as 'Identifier'.
-bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
- MacroInfo *MI) {
- // If this is a macro exapnsion in the "#if !defined(x)" line for the file,
- // then the macro could expand to different things in other contexts, we need
- // to disable the optimization in this case.
- if (CurLexer) CurLexer->MIOpt.ExpandedMacro();
-
- // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
- if (MI->isBuiltinMacro()) {
- ExpandBuiltinMacro(Identifier);
- return false;
- }
-
- /// Args - If this is a function-like macro expansion, this contains,
- /// for each macro argument, the list of tokens that were provided to the
- /// invocation.
- MacroArgs *Args = 0;
-
- // If this is a function-like macro, read the arguments.
- if (MI->isFunctionLike()) {
- // C99 6.10.3p10: If the preprocessing token immediately after the the macro
- // name isn't a '(', this macro should not be expanded. Otherwise, consume
- // it.
- if (!isNextPPTokenLParen())
- return true;
-
- // Remember that we are now parsing the arguments to a macro invocation.
- // Preprocessor directives used inside macro arguments are not portable, and
- // this enables the warning.
- InMacroArgs = true;
- Args = ReadFunctionLikeMacroArgs(Identifier, MI);
-
- // Finished parsing args.
- InMacroArgs = false;
-
- // If there was an error parsing the arguments, bail out.
- if (Args == 0) return false;
-
- ++NumFnMacroExpanded;
- } else {
- ++NumMacroExpanded;
- }
-
- // Notice that this macro has been used.
- MI->setIsUsed(true);
-
- // If we started lexing a macro, enter the macro expansion body.
-
- // If this macro expands to no tokens, don't bother to push it onto the
- // expansion stack, only to take it right back off.
- if (MI->getNumTokens() == 0) {
- // No need for arg info.
- if (Args) Args->destroy();
-
- // Ignore this macro use, just return the next token in the current
- // buffer.
- bool HadLeadingSpace = Identifier.hasLeadingSpace();
- bool IsAtStartOfLine = Identifier.isAtStartOfLine();
-
- Lex(Identifier);
-
- // If the identifier isn't on some OTHER line, inherit the leading
- // whitespace/first-on-a-line property of this token. This handles
- // stuff like "! XX," -> "! ," and " XX," -> " ,", when XX is
- // empty.
- if (!Identifier.isAtStartOfLine()) {
- if (IsAtStartOfLine) Identifier.setFlag(Token::StartOfLine);
- if (HadLeadingSpace) Identifier.setFlag(Token::LeadingSpace);
- }
- ++NumFastMacroExpanded;
- return false;
-
- } else if (MI->getNumTokens() == 1 &&
- isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(),
- *this)){
- // Otherwise, if this macro expands into a single trivially-expanded
- // token: expand it now. This handles common cases like
- // "#define VAL 42".
-
- // No need for arg info.
- if (Args) Args->destroy();
-
- // Propagate the isAtStartOfLine/hasLeadingSpace markers of the macro
- // identifier to the expanded token.
- bool isAtStartOfLine = Identifier.isAtStartOfLine();
- bool hasLeadingSpace = Identifier.hasLeadingSpace();
-
- // Remember where the token is instantiated.
- SourceLocation InstantiateLoc = Identifier.getLocation();
-
- // Replace the result token.
- Identifier = MI->getReplacementToken(0);
-
- // Restore the StartOfLine/LeadingSpace markers.
- Identifier.setFlagValue(Token::StartOfLine , isAtStartOfLine);
- Identifier.setFlagValue(Token::LeadingSpace, hasLeadingSpace);
-
- // Update the tokens location to include both its logical and physical
- // locations.
- SourceLocation Loc =
- SourceMgr.getInstantiationLoc(Identifier.getLocation(), InstantiateLoc);
- Identifier.setLocation(Loc);
-
- // If this is #define X X, we must mark the result as unexpandible.
- if (IdentifierInfo *NewII = Identifier.getIdentifierInfo())
- if (getMacroInfo(NewII) == MI)
- Identifier.setFlag(Token::DisableExpand);
-
- // Since this is not an identifier token, it can't be macro expanded, so
- // we're done.
- ++NumFastMacroExpanded;
- return false;
- }
-
- // Start expanding the macro.
- EnterMacro(Identifier, Args);
-
- // Now that the macro is at the top of the include stack, ask the
- // preprocessor to read the next token from it.
- Lex(Identifier);
- return false;
-}
-
-/// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
-/// invoked to read all of the actual arguments specified for the macro
-/// invocation. This returns null on error.
-MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
- MacroInfo *MI) {
- // The number of fixed arguments to parse.
- unsigned NumFixedArgsLeft = MI->getNumArgs();
- bool isVariadic = MI->isVariadic();
-
- // Outer loop, while there are more arguments, keep reading them.
- Token Tok;
- Tok.setKind(tok::comma);
- --NumFixedArgsLeft; // Start reading the first arg.
-
- // ArgTokens - Build up a list of tokens that make up each argument. Each
- // argument is separated by an EOF token. Use a SmallVector so we can avoid
- // heap allocations in the common case.
- llvm::SmallVector<Token, 64> ArgTokens;
-
- unsigned NumActuals = 0;
- while (Tok.is(tok::comma)) {
- // C99 6.10.3p11: Keep track of the number of l_parens we have seen. Note
- // that we already consumed the first one.
- unsigned NumParens = 0;
-
- while (1) {
- // Read arguments as unexpanded tokens. This avoids issues, e.g., where
- // an argument value in a macro could expand to ',' or '(' or ')'.
- LexUnexpandedToken(Tok);
-
- if (Tok.is(tok::eof) || Tok.is(tok::eom)) { // "#if f(<eof>" & "#if f(\n"
- Diag(MacroName, diag::err_unterm_macro_invoc);
- // Do not lose the EOF/EOM. Return it to the client.
- MacroName = Tok;
- return 0;
- } else if (Tok.is(tok::r_paren)) {
- // If we found the ) token, the macro arg list is done.
- if (NumParens-- == 0)
- break;
- } else if (Tok.is(tok::l_paren)) {
- ++NumParens;
- } else if (Tok.is(tok::comma) && NumParens == 0) {
- // Comma ends this argument if there are more fixed arguments expected.
- if (NumFixedArgsLeft)
- break;
-
- // If this is not a variadic macro, too many args were specified.
- if (!isVariadic) {
- // Emit the diagnostic at the macro name in case there is a missing ).
- // Emitting it at the , could be far away from the macro name.
- Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
- return 0;
- }
- // Otherwise, continue to add the tokens to this variable argument.
- } else if (Tok.is(tok::comment) && !KeepMacroComments) {
- // If this is a comment token in the argument list and we're just in
- // -C mode (not -CC mode), discard the comment.
- continue;
- } else if (Tok.is(tok::identifier)) {
- // Reading macro arguments can cause macros that we are currently
- // expanding from to be popped off the expansion stack. Doing so causes
- // them to be reenabled for expansion. Here we record whether any
- // identifiers we lex as macro arguments correspond to disabled macros.
- // If so, we mark the token as noexpand. This is a subtle aspect of
- // C99 6.10.3.4p2.
- if (MacroInfo *MI = getMacroInfo(Tok.getIdentifierInfo()))
- if (!MI->isEnabled())
- Tok.setFlag(Token::DisableExpand);
- }
-
- ArgTokens.push_back(Tok);
- }
-
- // Empty arguments are standard in C99 and supported as an extension in
- // other modes.
- if (ArgTokens.empty() && !Features.C99)
- Diag(Tok, diag::ext_empty_fnmacro_arg);
-
- // Add a marker EOF token to the end of the token list for this argument.
- Token EOFTok;
- EOFTok.startToken();
- EOFTok.setKind(tok::eof);
- EOFTok.setLocation(Tok.getLocation());
- EOFTok.setLength(0);
- ArgTokens.push_back(EOFTok);
- ++NumActuals;
- --NumFixedArgsLeft;
- };
-
- // Okay, we either found the r_paren. Check to see if we parsed too few
- // arguments.
- unsigned MinArgsExpected = MI->getNumArgs();
-
- // See MacroArgs instance var for description of this.
- bool isVarargsElided = false;
-
- if (NumActuals < MinArgsExpected) {
- // There are several cases where too few arguments is ok, handle them now.
- if (NumActuals+1 == MinArgsExpected && MI->isVariadic()) {
- // Varargs where the named vararg parameter is missing: ok as extension.
- // #define A(x, ...)
- // A("blah")
- Diag(Tok, diag::ext_missing_varargs_arg);
-
- // Remember this occurred if this is a macro invocation with at least
- // one actual argument. This allows us to elide the comma when used for
- // cases like:
- // #define A(x, foo...) blah(a, ## foo)
- // #define A(x, ...) blah(a, ## __VA_ARGS__)
- isVarargsElided = MI->getNumArgs() > 1;
- } else if (MI->getNumArgs() == 1) {
- // #define A(x)
- // A()
- // is ok because it is an empty argument.
-
- // Empty arguments are standard in C99 and supported as an extension in
- // other modes.
- if (ArgTokens.empty() && !Features.C99)
- Diag(Tok, diag::ext_empty_fnmacro_arg);
- } else {
- // Otherwise, emit the error.
- Diag(Tok, diag::err_too_few_args_in_macro_invoc);
- return 0;
- }
-
- // Add a marker EOF token to the end of the token list for this argument.
- SourceLocation EndLoc = Tok.getLocation();
- Tok.startToken();
- Tok.setKind(tok::eof);
- Tok.setLocation(EndLoc);
- Tok.setLength(0);
- ArgTokens.push_back(Tok);
- }
-
- return MacroArgs::create(MI, &ArgTokens[0], ArgTokens.size(),isVarargsElided);
-}
-
-/// ComputeDATE_TIME - Compute the current time, enter it into the specified
-/// scratch buffer, then return DATELoc/TIMELoc locations with the position of
-/// the identifier tokens inserted.
-static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
- Preprocessor &PP) {
- time_t TT = time(0);
- struct tm *TM = localtime(&TT);
-
- static const char * const Months[] = {
- "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
- };
-
- char TmpBuffer[100];
- sprintf(TmpBuffer, "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
- TM->tm_year+1900);
- DATELoc = PP.CreateString(TmpBuffer, strlen(TmpBuffer));
-
- sprintf(TmpBuffer, "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
- TIMELoc = PP.CreateString(TmpBuffer, strlen(TmpBuffer));
-}
-
-/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
-/// as a builtin macro, handle it and return the next token as 'Tok'.
-void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
- // Figure out which token this is.
- IdentifierInfo *II = Tok.getIdentifierInfo();
- assert(II && "Can't be a macro without id info!");
-
- // If this is an _Pragma directive, expand it, invoke the pragma handler, then
- // lex the token after it.
- if (II == Ident_Pragma)
- return Handle_Pragma(Tok);
-
- ++NumBuiltinMacroExpanded;
-
- char TmpBuffer[100];
-
- // Set up the return result.
- Tok.setIdentifierInfo(0);
- Tok.clearFlag(Token::NeedsCleaning);
-
- if (II == Ident__LINE__) {
- // __LINE__ expands to a simple numeric value. Add a space after it so that
- // it will tokenize as a number (and not run into stuff after it in the temp
- // buffer).
- sprintf(TmpBuffer, "%u ",
- SourceMgr.getLogicalLineNumber(Tok.getLocation()));
- unsigned Length = strlen(TmpBuffer)-1;
- Tok.setKind(tok::numeric_constant);
- Tok.setLength(Length);
- Tok.setLocation(CreateString(TmpBuffer, Length+1, Tok.getLocation()));
- } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
- SourceLocation Loc = Tok.getLocation();
- if (II == Ident__BASE_FILE__) {
- Diag(Tok, diag::ext_pp_base_file);
- SourceLocation NextLoc = SourceMgr.getIncludeLoc(Loc);
- while (NextLoc.isValid()) {
- Loc = NextLoc;
- NextLoc = SourceMgr.getIncludeLoc(Loc);
- }
- }
-
- // Escape this filename. Turn '\' -> '\\' '"' -> '\"'
- std::string FN = SourceMgr.getSourceName(SourceMgr.getLogicalLoc(Loc));
- FN = '"' + Lexer::Stringify(FN) + '"';
- Tok.setKind(tok::string_literal);
- Tok.setLength(FN.size());
- Tok.setLocation(CreateString(&FN[0], FN.size(), Tok.getLocation()));
- } else if (II == Ident__DATE__) {
- if (!DATELoc.isValid())
- ComputeDATE_TIME(DATELoc, TIMELoc, *this);
- Tok.setKind(tok::string_literal);
- Tok.setLength(strlen("\"Mmm dd yyyy\""));
- Tok.setLocation(SourceMgr.getInstantiationLoc(DATELoc, Tok.getLocation()));
- } else if (II == Ident__TIME__) {
- if (!TIMELoc.isValid())
- ComputeDATE_TIME(DATELoc, TIMELoc, *this);
- Tok.setKind(tok::string_literal);
- Tok.setLength(strlen("\"hh:mm:ss\""));
- Tok.setLocation(SourceMgr.getInstantiationLoc(TIMELoc, Tok.getLocation()));
- } else if (II == Ident__INCLUDE_LEVEL__) {
- Diag(Tok, diag::ext_pp_include_level);
-
- // Compute the include depth of this token.
- unsigned Depth = 0;
- SourceLocation Loc = SourceMgr.getIncludeLoc(Tok.getLocation());
- for (; Loc.isValid(); ++Depth)
- Loc = SourceMgr.getIncludeLoc(Loc);
-
- // __INCLUDE_LEVEL__ expands to a simple numeric value. Add a space after
- // it so that it will tokenize as a number (and not run into stuff after it
- // in the temp buffer).
- sprintf(TmpBuffer, "%u ", Depth);
- unsigned Length = strlen(TmpBuffer)-1;
- Tok.setKind(tok::numeric_constant);
- Tok.setLength(Length);
- Tok.setLocation(CreateString(TmpBuffer, Length, Tok.getLocation()));
- } else if (II == Ident__TIMESTAMP__) {
- // MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be
- // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
- Diag(Tok, diag::ext_pp_timestamp);
-
- // Get the file that we are lexing out of. If we're currently lexing from
- // a macro, dig into the include stack.
- const FileEntry *CurFile = 0;
- Lexer *TheLexer = getCurrentFileLexer();
-
- if (TheLexer)
- CurFile = SourceMgr.getFileEntryForLoc(TheLexer->getFileLoc());
-
- // If this file is older than the file it depends on, emit a diagnostic.
- const char *Result;
- if (CurFile) {
- time_t TT = CurFile->getModificationTime();
- struct tm *TM = localtime(&TT);
- Result = asctime(TM);
- } else {
- Result = "??? ??? ?? ??:??:?? ????\n";
- }
- TmpBuffer[0] = '"';
- strcpy(TmpBuffer+1, Result);
- unsigned Len = strlen(TmpBuffer);
- TmpBuffer[Len-1] = '"'; // Replace the newline with a quote.
- Tok.setKind(tok::string_literal);
- Tok.setLength(Len);
- Tok.setLocation(CreateString(TmpBuffer, Len+1, Tok.getLocation()));
- } else {
- assert(0 && "Unknown identifier!");
- }
-}
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
deleted file mode 100644
index 6d8e047056d9..000000000000
--- a/clang/lib/Lex/Pragma.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-//===--- Pragma.cpp - Pragma registration and handling --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the PragmaHandler/PragmaTable interfaces and implements
-// pragma related methods of the Preprocessor class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Pragma.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-using namespace clang;
-
-// Out-of-line destructor to provide a home for the class.
-PragmaHandler::~PragmaHandler() {
-}
-
-//===----------------------------------------------------------------------===//
-// PragmaNamespace Implementation.
-//===----------------------------------------------------------------------===//
-
-
-PragmaNamespace::~PragmaNamespace() {
- for (unsigned i = 0, e = Handlers.size(); i != e; ++i)
- delete Handlers[i];
-}
-
-/// FindHandler - Check to see if there is already a handler for the
-/// specified name. If not, return the handler for the null identifier if it
-/// exists, otherwise return null. If IgnoreNull is true (the default) then
-/// the null handler isn't returned on failure to match.
-PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name,
- bool IgnoreNull) const {
- PragmaHandler *NullHandler = 0;
- for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
- if (Handlers[i]->getName() == Name)
- return Handlers[i];
-
- if (Handlers[i]->getName() == 0)
- NullHandler = Handlers[i];
- }
- return IgnoreNull ? 0 : NullHandler;
-}
-
-void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
- for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
- if (Handlers[i] == Handler) {
- Handlers[i] = Handlers.back();
- Handlers.pop_back();
- return;
- }
- }
- assert(0 && "Handler not registered in this namespace");
-}
-
-void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
- // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro
- // expand it, the user can have a STDC #define, that should not affect this.
- PP.LexUnexpandedToken(Tok);
-
- // Get the handler for this token. If there is no handler, ignore the pragma.
- PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false);
- if (Handler == 0) return;
-
- // Otherwise, pass it down.
- Handler->HandlePragma(PP, Tok);
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Pragma Directive Handling.
-//===----------------------------------------------------------------------===//
-
-/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the
-/// rest of the pragma, passing it to the registered pragma handlers.
-void Preprocessor::HandlePragmaDirective() {
- ++NumPragma;
-
- // Invoke the first level of pragma handlers which reads the namespace id.
- Token Tok;
- PragmaHandlers->HandlePragma(*this, Tok);
-
- // If the pragma handler didn't read the rest of the line, consume it now.
- if (CurLexer->ParsingPreprocessorDirective)
- DiscardUntilEndOfDirective();
-}
-
-/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
-/// return the first token after the directive. The _Pragma token has just
-/// been read into 'Tok'.
-void Preprocessor::Handle_Pragma(Token &Tok) {
- // Remember the pragma token location.
- SourceLocation PragmaLoc = Tok.getLocation();
-
- // Read the '('.
- Lex(Tok);
- if (Tok.isNot(tok::l_paren))
- return Diag(PragmaLoc, diag::err__Pragma_malformed);
-
- // Read the '"..."'.
- Lex(Tok);
- if (Tok.isNot(tok::string_literal) && Tok.isNot(tok::wide_string_literal))
- return Diag(PragmaLoc, diag::err__Pragma_malformed);
-
- // Remember the string.
- std::string StrVal = getSpelling(Tok);
- SourceLocation StrLoc = Tok.getLocation();
-
- // Read the ')'.
- Lex(Tok);
- if (Tok.isNot(tok::r_paren))
- return Diag(PragmaLoc, diag::err__Pragma_malformed);
-
- // The _Pragma is lexically sound. Destringize according to C99 6.10.9.1.
- if (StrVal[0] == 'L') // Remove L prefix.
- StrVal.erase(StrVal.begin());
- assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
- "Invalid string token!");
-
- // Remove the front quote, replacing it with a space, so that the pragma
- // contents appear to have a space before them.
- StrVal[0] = ' ';
-
- // Replace the terminating quote with a \n\0.
- StrVal[StrVal.size()-1] = '\n';
- StrVal += '\0';
-
- // Remove escaped quotes and escapes.
- for (unsigned i = 0, e = StrVal.size(); i != e-1; ++i) {
- if (StrVal[i] == '\\' &&
- (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
- // \\ -> '\' and \" -> '"'.
- StrVal.erase(StrVal.begin()+i);
- --e;
- }
- }
-
- // Plop the string (including the newline and trailing null) into a buffer
- // where we can lex it.
- SourceLocation TokLoc = CreateString(&StrVal[0], StrVal.size(), StrLoc);
- const char *StrData = SourceMgr.getCharacterData(TokLoc);
-
- // Make and enter a lexer object so that we lex and expand the tokens just
- // like any others.
- Lexer *TL = new Lexer(TokLoc, *this,
- StrData, StrData+StrVal.size()-1 /* no null */);
-
- // Ensure that the lexer thinks it is inside a directive, so that end \n will
- // return an EOM token.
- TL->ParsingPreprocessorDirective = true;
-
- // This lexer really is for _Pragma.
- TL->Is_PragmaLexer = true;
-
- EnterSourceFileWithLexer(TL, 0);
-
- // With everything set up, lex this as a #pragma directive.
- HandlePragmaDirective();
-
- // Finally, return whatever came after the pragma directive.
- return Lex(Tok);
-}
-
-
-
-/// HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
-///
-void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
- if (isInPrimaryFile()) {
- Diag(OnceTok, diag::pp_pragma_once_in_main_file);
- return;
- }
-
- // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
- SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
-
- // Mark the file as a once-only file now.
- HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForLoc(FileLoc));
-}
-
-void Preprocessor::HandlePragmaMark() {
- assert(CurLexer && "No current lexer?");
- CurLexer->ReadToEndOfLine();
-}
-
-
-/// HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
-///
-void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
- Token Tok;
-
- while (1) {
- // Read the next token to poison. While doing this, pretend that we are
- // skipping while reading the identifier to poison.
- // This avoids errors on code like:
- // #pragma GCC poison X
- // #pragma GCC poison X
- if (CurLexer) CurLexer->LexingRawMode = true;
- LexUnexpandedToken(Tok);
- if (CurLexer) CurLexer->LexingRawMode = false;
-
- // If we reached the end of line, we're done.
- if (Tok.is(tok::eom)) return;
-
- // Can only poison identifiers.
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_pp_invalid_poison);
- return;
- }
-
- // Look up the identifier info for the token. We disabled identifier lookup
- // by saying we're skipping contents, so we need to do this manually.
- IdentifierInfo *II = LookUpIdentifierInfo(Tok);
-
- // Already poisoned.
- if (II->isPoisoned()) continue;
-
- // If this is a macro identifier, emit a warning.
- if (II->hasMacroDefinition())
- Diag(Tok, diag::pp_poisoning_existing_macro);
-
- // Finally, poison it!
- II->setIsPoisoned();
- }
-}
-
-/// HandlePragmaSystemHeader - Implement #pragma GCC system_header. We know
-/// that the whole directive has been parsed.
-void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
- if (isInPrimaryFile()) {
- Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
- return;
- }
-
- // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
- Lexer *TheLexer = getCurrentFileLexer();
-
- // Mark the file as a system header.
- const FileEntry *File = SourceMgr.getFileEntryForLoc(TheLexer->getFileLoc());
- HeaderInfo.MarkFileSystemHeader(File);
-
- // Notify the client, if desired, that we are in a new source file.
- if (Callbacks)
- Callbacks->FileChanged(TheLexer->getSourceLocation(TheLexer->BufferPtr),
- PPCallbacks::SystemHeaderPragma, SrcMgr::C_System);
-}
-
-/// HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
-///
-void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
- Token FilenameTok;
- CurLexer->LexIncludeFilename(FilenameTok);
-
- // If the token kind is EOM, the error has already been diagnosed.
- if (FilenameTok.is(tok::eom))
- return;
-
- // Reserve a buffer to get the spelling.
- llvm::SmallVector<char, 128> FilenameBuffer;
- FilenameBuffer.resize(FilenameTok.getLength());
-
- const char *FilenameStart = &FilenameBuffer[0];
- unsigned Len = getSpelling(FilenameTok, FilenameStart);
- const char *FilenameEnd = FilenameStart+Len;
- bool isAngled = GetIncludeFilenameSpelling(FilenameTok.getLocation(),
- FilenameStart, FilenameEnd);
- // If GetIncludeFilenameSpelling set the start ptr to null, there was an
- // error.
- if (FilenameStart == 0)
- return;
-
- // Search include directories for this file.
- const DirectoryLookup *CurDir;
- const FileEntry *File = LookupFile(FilenameStart, FilenameEnd,
- isAngled, 0, CurDir);
- if (File == 0)
- return Diag(FilenameTok, diag::err_pp_file_not_found,
- std::string(FilenameStart, FilenameEnd));
-
- SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc();
- const FileEntry *CurFile = SourceMgr.getFileEntryForLoc(FileLoc);
-
- // If this file is older than the file it depends on, emit a diagnostic.
- if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {
- // Lex tokens at the end of the message and include them in the message.
- std::string Message;
- Lex(DependencyTok);
- while (DependencyTok.isNot(tok::eom)) {
- Message += getSpelling(DependencyTok) + " ";
- Lex(DependencyTok);
- }
-
- Message.erase(Message.end()-1);
- Diag(FilenameTok, diag::pp_out_of_date_dependency, Message);
- }
-}
-
-
-/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
-/// If 'Namespace' is non-null, then it is a token required to exist on the
-/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
-void Preprocessor::AddPragmaHandler(const char *Namespace,
- PragmaHandler *Handler) {
- PragmaNamespace *InsertNS = PragmaHandlers;
-
- // If this is specified to be in a namespace, step down into it.
- if (Namespace) {
- IdentifierInfo *NSID = getIdentifierInfo(Namespace);
-
- // If there is already a pragma handler with the name of this namespace,
- // we either have an error (directive with the same name as a namespace) or
- // we already have the namespace to insert into.
- if (PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID)) {
- InsertNS = Existing->getIfNamespace();
- assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
- " handler with the same name!");
- } else {
- // Otherwise, this namespace doesn't exist yet, create and insert the
- // handler for it.
- InsertNS = new PragmaNamespace(NSID);
- PragmaHandlers->AddPragma(InsertNS);
- }
- }
-
- // Check to make sure we don't already have a pragma for this identifier.
- assert(!InsertNS->FindHandler(Handler->getName()) &&
- "Pragma handler already exists for this identifier!");
- InsertNS->AddPragma(Handler);
-}
-
-/// RemovePragmaHandler - Remove the specific pragma handler from the
-/// preprocessor. If \arg Namespace is non-null, then it should be the
-/// namespace that \arg Handler was added to. It is an error to remove
-/// a handler that has not been registered.
-void Preprocessor::RemovePragmaHandler(const char *Namespace,
- PragmaHandler *Handler) {
- PragmaNamespace *NS = PragmaHandlers;
-
- // If this is specified to be in a namespace, step down into it.
- if (Namespace) {
- IdentifierInfo *NSID = getIdentifierInfo(Namespace);
- PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID);
- assert(Existing && "Namespace containing handler does not exist!");
-
- NS = Existing->getIfNamespace();
- assert(NS && "Invalid namespace, registered as a regular pragma handler!");
- }
-
- NS->RemovePragmaHandler(Handler);
-
- // If this is a non-default namespace and it is now empty, remove
- // it.
- if (NS != PragmaHandlers && NS->IsEmpty())
- PragmaHandlers->RemovePragmaHandler(NS);
-}
-
-namespace {
-/// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
-struct PragmaOnceHandler : public PragmaHandler {
- PragmaOnceHandler(const IdentifierInfo *OnceID) : PragmaHandler(OnceID) {}
- virtual void HandlePragma(Preprocessor &PP, Token &OnceTok) {
- PP.CheckEndOfDirective("#pragma once");
- PP.HandlePragmaOnce(OnceTok);
- }
-};
-
-/// PragmaMarkHandler - "#pragma mark ..." is ignored by the compiler, and the
-/// rest of the line is not lexed.
-struct PragmaMarkHandler : public PragmaHandler {
- PragmaMarkHandler(const IdentifierInfo *MarkID) : PragmaHandler(MarkID) {}
- virtual void HandlePragma(Preprocessor &PP, Token &MarkTok) {
- PP.HandlePragmaMark();
- }
-};
-
-/// PragmaPoisonHandler - "#pragma poison x" marks x as not usable.
-struct PragmaPoisonHandler : public PragmaHandler {
- PragmaPoisonHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
- virtual void HandlePragma(Preprocessor &PP, Token &PoisonTok) {
- PP.HandlePragmaPoison(PoisonTok);
- }
-};
-
-/// PragmaSystemHeaderHandler - "#pragma system_header" marks the current file
-/// as a system header, which silences warnings in it.
-struct PragmaSystemHeaderHandler : public PragmaHandler {
- PragmaSystemHeaderHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
- virtual void HandlePragma(Preprocessor &PP, Token &SHToken) {
- PP.HandlePragmaSystemHeader(SHToken);
- PP.CheckEndOfDirective("#pragma");
- }
-};
-struct PragmaDependencyHandler : public PragmaHandler {
- PragmaDependencyHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
- virtual void HandlePragma(Preprocessor &PP, Token &DepToken) {
- PP.HandlePragmaDependency(DepToken);
- }
-};
-} // end anonymous namespace
-
-
-/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
-/// #pragma GCC poison/system_header/dependency and #pragma once.
-void Preprocessor::RegisterBuiltinPragmas() {
- AddPragmaHandler(0, new PragmaOnceHandler(getIdentifierInfo("once")));
- AddPragmaHandler(0, new PragmaMarkHandler(getIdentifierInfo("mark")));
- AddPragmaHandler("GCC", new PragmaPoisonHandler(getIdentifierInfo("poison")));
- AddPragmaHandler("GCC", new PragmaSystemHeaderHandler(
- getIdentifierInfo("system_header")));
- AddPragmaHandler("GCC", new PragmaDependencyHandler(
- getIdentifierInfo("dependency")));
-}
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
deleted file mode 100644
index ed69e6f93360..000000000000
--- a/clang/lib/Lex/Preprocessor.cpp
+++ /dev/null
@@ -1,759 +0,0 @@
-//===--- Preprocess.cpp - C Language Family Preprocessor Implementation ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Preprocessor interface.
-//
-//===----------------------------------------------------------------------===//
-//
-// Options to support:
-// -H - Print the name of each header file used.
-// -d[MDNI] - Dump various things.
-// -fworking-directory - #line's with preprocessor's working dir.
-// -fpreprocessed
-// -dependency-file,-M,-MM,-MF,-MG,-MP,-MT,-MQ,-MD,-MMD
-// -W*
-// -w
-//
-// Messages to emit:
-// "Multiple include guards may be useful for:\n"
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/Pragma.h"
-#include "clang/Lex/ScratchBuffer.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Streams.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-
-PreprocessorFactory::~PreprocessorFactory() {}
-
-Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
- TargetInfo &target, SourceManager &SM,
- HeaderSearch &Headers)
- : Diags(diags), Features(opts), Target(target), FileMgr(Headers.getFileMgr()),
- SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts),
- CurLexer(0), CurDirLookup(0), CurTokenLexer(0), Callbacks(0) {
- ScratchBuf = new ScratchBuffer(SourceMgr);
-
- // Clear stats.
- NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
- NumIf = NumElse = NumEndif = 0;
- NumEnteredSourceFiles = 0;
- NumMacroExpanded = NumFnMacroExpanded = NumBuiltinMacroExpanded = 0;
- NumFastMacroExpanded = NumTokenPaste = NumFastTokenPaste = 0;
- MaxIncludeStackDepth = 0;
- NumSkipped = 0;
-
- // Default to discarding comments.
- KeepComments = false;
- KeepMacroComments = false;
-
- // Macro expansion is enabled.
- DisableMacroExpansion = false;
- InMacroArgs = false;
- NumCachedTokenLexers = 0;
-
- CacheTokens = false;
- CachedLexPos = 0;
-
- // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
- // This gets unpoisoned where it is allowed.
- (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
-
- // Initialize the pragma handlers.
- PragmaHandlers = new PragmaNamespace(0);
- RegisterBuiltinPragmas();
-
- // Initialize builtin macros like __LINE__ and friends.
- RegisterBuiltinMacros();
-}
-
-Preprocessor::~Preprocessor() {
- assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
-
- // Free any active lexers.
- delete CurLexer;
-
- while (!IncludeMacroStack.empty()) {
- delete IncludeMacroStack.back().TheLexer;
- delete IncludeMacroStack.back().TheTokenLexer;
- IncludeMacroStack.pop_back();
- }
-
- // Free any macro definitions.
- for (llvm::DenseMap<IdentifierInfo*, MacroInfo*>::iterator I =
- Macros.begin(), E = Macros.end(); I != E; ++I) {
- // Free the macro definition.
- delete I->second;
- I->second = 0;
- I->first->setHasMacroDefinition(false);
- }
-
- // Free any cached macro expanders.
- for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
- delete TokenLexerCache[i];
-
- // Release pragma information.
- delete PragmaHandlers;
-
- // Delete the scratch buffer info.
- delete ScratchBuf;
-
- delete Callbacks;
-}
-
-/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
-/// the specified Token's location, translating the token's start
-/// position in the current buffer into a SourcePosition object for rendering.
-void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID) {
- Diags.Report(getFullLoc(Loc), DiagID);
-}
-
-void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg) {
- Diags.Report(getFullLoc(Loc), DiagID, &Msg, 1);
-}
-
-void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg,
- const SourceRange &R1, const SourceRange &R2) {
- SourceRange R[] = {R1, R2};
- Diags.Report(getFullLoc(Loc), DiagID, &Msg, 1, R, 2);
-}
-
-
-void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
- const SourceRange &R) {
- Diags.Report(getFullLoc(Loc), DiagID, 0, 0, &R, 1);
-}
-
-void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
- const SourceRange &R1, const SourceRange &R2) {
- SourceRange R[] = {R1, R2};
- Diags.Report(getFullLoc(Loc), DiagID, 0, 0, R, 2);
-}
-
-
-void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const {
- llvm::cerr << tok::getTokenName(Tok.getKind()) << " '"
- << getSpelling(Tok) << "'";
-
- if (!DumpFlags) return;
-
- llvm::cerr << "\t";
- if (Tok.isAtStartOfLine())
- llvm::cerr << " [StartOfLine]";
- if (Tok.hasLeadingSpace())
- llvm::cerr << " [LeadingSpace]";
- if (Tok.isExpandDisabled())
- llvm::cerr << " [ExpandDisabled]";
- if (Tok.needsCleaning()) {
- const char *Start = SourceMgr.getCharacterData(Tok.getLocation());
- llvm::cerr << " [UnClean='" << std::string(Start, Start+Tok.getLength())
- << "']";
- }
-
- llvm::cerr << "\tLoc=<";
- DumpLocation(Tok.getLocation());
- llvm::cerr << ">";
-}
-
-void Preprocessor::DumpLocation(SourceLocation Loc) const {
- SourceLocation LogLoc = SourceMgr.getLogicalLoc(Loc);
- llvm::cerr << SourceMgr.getSourceName(LogLoc) << ':'
- << SourceMgr.getLineNumber(LogLoc) << ':'
- << SourceMgr.getColumnNumber(LogLoc);
-
- SourceLocation PhysLoc = SourceMgr.getPhysicalLoc(Loc);
- if (PhysLoc != LogLoc) {
- llvm::cerr << " <PhysLoc=";
- DumpLocation(PhysLoc);
- llvm::cerr << ">";
- }
-}
-
-void Preprocessor::DumpMacro(const MacroInfo &MI) const {
- llvm::cerr << "MACRO: ";
- for (unsigned i = 0, e = MI.getNumTokens(); i != e; ++i) {
- DumpToken(MI.getReplacementToken(i));
- llvm::cerr << " ";
- }
- llvm::cerr << "\n";
-}
-
-void Preprocessor::PrintStats() {
- llvm::cerr << "\n*** Preprocessor Stats:\n";
- llvm::cerr << NumDirectives << " directives found:\n";
- llvm::cerr << " " << NumDefined << " #define.\n";
- llvm::cerr << " " << NumUndefined << " #undef.\n";
- llvm::cerr << " #include/#include_next/#import:\n";
- llvm::cerr << " " << NumEnteredSourceFiles << " source files entered.\n";
- llvm::cerr << " " << MaxIncludeStackDepth << " max include stack depth\n";
- llvm::cerr << " " << NumIf << " #if/#ifndef/#ifdef.\n";
- llvm::cerr << " " << NumElse << " #else/#elif.\n";
- llvm::cerr << " " << NumEndif << " #endif.\n";
- llvm::cerr << " " << NumPragma << " #pragma.\n";
- llvm::cerr << NumSkipped << " #if/#ifndef#ifdef regions skipped\n";
-
- llvm::cerr << NumMacroExpanded << "/" << NumFnMacroExpanded << "/"
- << NumBuiltinMacroExpanded << " obj/fn/builtin macros expanded, "
- << NumFastMacroExpanded << " on the fast path.\n";
- llvm::cerr << (NumFastTokenPaste+NumTokenPaste)
- << " token paste (##) operations performed, "
- << NumFastTokenPaste << " on the fast path.\n";
-}
-
-//===----------------------------------------------------------------------===//
-// Token Spelling
-//===----------------------------------------------------------------------===//
-
-
-/// getSpelling() - Return the 'spelling' of this token. The spelling of a
-/// token are 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.
-std::string Preprocessor::getSpelling(const Token &Tok) const {
- assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
-
- // If this token contains nothing interesting, return it directly.
- const char *TokStart = SourceMgr.getCharacterData(Tok.getLocation());
- if (!Tok.needsCleaning())
- return std::string(TokStart, TokStart+Tok.getLength());
-
- std::string Result;
- Result.reserve(Tok.getLength());
-
- // Otherwise, hard case, relex the characters into the string.
- for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength();
- Ptr != End; ) {
- unsigned CharSize;
- Result.push_back(Lexer::getCharAndSizeNoWarn(Ptr, CharSize, Features));
- Ptr += CharSize;
- }
- assert(Result.size() != unsigned(Tok.getLength()) &&
- "NeedsCleaning flag set on something that didn't need cleaning!");
- return Result;
-}
-
-/// 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
-/// Tok.getLength() bytes long. The actual length of the token is returned.
-///
-/// Note that this method may do two possible things: it may either fill in
-/// the buffer specified with characters, or it may *change the input pointer*
-/// to point to a constant buffer with the data already in it (avoiding a
-/// copy). The caller is not allowed to modify the returned buffer pointer
-/// if an internal buffer is returned.
-unsigned Preprocessor::getSpelling(const Token &Tok,
- const char *&Buffer) const {
- assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
-
- // If this token is an identifier, just return the string from the identifier
- // table, which is very quick.
- if (const IdentifierInfo *II = Tok.getIdentifierInfo()) {
- Buffer = II->getName();
-
- // Return the length of the token. If the token needed cleaning, don't
- // include the size of the newlines or trigraphs in it.
- if (!Tok.needsCleaning())
- return Tok.getLength();
- else
- return strlen(Buffer);
- }
-
- // Otherwise, compute the start of the token in the input lexer buffer.
- const char *TokStart = SourceMgr.getCharacterData(Tok.getLocation());
-
- // If this token contains nothing interesting, return it directly.
- if (!Tok.needsCleaning()) {
- Buffer = TokStart;
- return Tok.getLength();
- }
- // Otherwise, hard case, relex the characters into the string.
- char *OutBuf = const_cast<char*>(Buffer);
- for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength();
- Ptr != End; ) {
- unsigned CharSize;
- *OutBuf++ = Lexer::getCharAndSizeNoWarn(Ptr, CharSize, Features);
- Ptr += CharSize;
- }
- assert(unsigned(OutBuf-Buffer) != Tok.getLength() &&
- "NeedsCleaning flag set on something that didn't need cleaning!");
-
- return OutBuf-Buffer;
-}
-
-
-/// CreateString - Plop the specified string into a scratch buffer and return a
-/// location for it. If specified, the source location provides a source
-/// location for the token.
-SourceLocation Preprocessor::
-CreateString(const char *Buf, unsigned Len, SourceLocation SLoc) {
- if (SLoc.isValid())
- return ScratchBuf->getToken(Buf, Len, SLoc);
- return ScratchBuf->getToken(Buf, Len);
-}
-
-
-/// AdvanceToTokenCharacter - Given a location that specifies the start of a
-/// token, return a new location that specifies a character within the token.
-SourceLocation Preprocessor::AdvanceToTokenCharacter(SourceLocation TokStart,
- unsigned CharNo) {
- // If they request the first char of the token, we're trivially done. If this
- // is a macro expansion, it doesn't make sense to point to a character within
- // the instantiation point (the name). We could point to the source
- // character, but without also pointing to instantiation info, this is
- // confusing.
- if (CharNo == 0 || TokStart.isMacroID()) return TokStart;
-
- // Figure out how many physical characters away the specified logical
- // character is. This needs to take into consideration newlines and
- // trigraphs.
- const char *TokPtr = SourceMgr.getCharacterData(TokStart);
- unsigned PhysOffset = 0;
-
- // The usual case is that tokens don't contain anything interesting. Skip
- // over the uninteresting characters. If a token only consists of simple
- // chars, this method is extremely fast.
- while (CharNo && Lexer::isObviouslySimpleCharacter(*TokPtr))
- ++TokPtr, --CharNo, ++PhysOffset;
-
- // If we have a character that may be a trigraph or escaped newline, create a
- // lexer to parse it correctly.
- if (CharNo != 0) {
- // Create a lexer starting at this token position.
- Lexer TheLexer(TokStart, *this, TokPtr);
- Token Tok;
- // Skip over characters the remaining characters.
- const char *TokStartPtr = TokPtr;
- for (; CharNo; --CharNo)
- TheLexer.getAndAdvanceChar(TokPtr, Tok);
-
- PhysOffset += TokPtr-TokStartPtr;
- }
-
- return TokStart.getFileLocWithOffset(PhysOffset);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Initialization Methods
-//===----------------------------------------------------------------------===//
-
-// Append a #define line to Buf for Macro. Macro should be of the form XXX,
-// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
-// "#define XXX Y z W". To get a #define with no value, use "XXX=".
-static void DefineBuiltinMacro(std::vector<char> &Buf, const char *Macro,
- const char *Command = "#define ") {
- Buf.insert(Buf.end(), Command, Command+strlen(Command));
- if (const char *Equal = strchr(Macro, '=')) {
- // Turn the = into ' '.
- Buf.insert(Buf.end(), Macro, Equal);
- Buf.push_back(' ');
- Buf.insert(Buf.end(), Equal+1, Equal+strlen(Equal));
- } else {
- // Push "macroname 1".
- Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
- Buf.push_back(' ');
- Buf.push_back('1');
- }
- Buf.push_back('\n');
-}
-
-/// PickFP - This is used to pick a value based on the FP semantics of the
-/// specified FP model.
-template <typename T>
-static T PickFP(const llvm::fltSemantics *Sem, T IEEESingleVal,
- T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal) {
- if (Sem == &llvm::APFloat::IEEEsingle)
- return IEEESingleVal;
- if (Sem == &llvm::APFloat::IEEEdouble)
- return IEEEDoubleVal;
- if (Sem == &llvm::APFloat::x87DoubleExtended)
- return X87DoubleExtendedVal;
- assert(Sem == &llvm::APFloat::PPCDoubleDouble);
- return PPCDoubleDoubleVal;
-}
-
-static void DefineFloatMacros(std::vector<char> &Buf, const char *Prefix,
- const llvm::fltSemantics *Sem) {
- const char *DenormMin, *Epsilon, *Max, *Min;
- DenormMin = PickFP(Sem, "1.40129846e-45F", "4.9406564584124654e-324",
- "3.64519953188247460253e-4951L",
- "4.94065645841246544176568792868221e-324L");
- int Digits = PickFP(Sem, 6, 15, 18, 31);
- Epsilon = PickFP(Sem, "1.19209290e-7F", "2.2204460492503131e-16",
- "1.08420217248550443401e-19L",
- "4.94065645841246544176568792868221e-324L");
- int HasInifinity = 1, HasQuietNaN = 1;
- int MantissaDigits = PickFP(Sem, 24, 53, 64, 106);
- int Min10Exp = PickFP(Sem, -37, -307, -4931, -291);
- int Max10Exp = PickFP(Sem, 38, 308, 4932, 308);
- int MinExp = PickFP(Sem, -125, -1021, -16381, -968);
- int MaxExp = PickFP(Sem, 128, 1024, 16384, 1024);
- Min = PickFP(Sem, "1.17549435e-38F", "2.2250738585072014e-308",
- "3.36210314311209350626e-4932L",
- "2.00416836000897277799610805135016e-292L");
- Max = PickFP(Sem, "3.40282347e+38F", "1.7976931348623157e+308",
- "1.18973149535723176502e+4932L",
- "1.79769313486231580793728971405301e+308L");
-
- char MacroBuf[60];
- sprintf(MacroBuf, "__%s_DENORM_MIN__=%s", Prefix, DenormMin);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_DIG__=%d", Prefix, Digits);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_EPSILON__=%s", Prefix, Epsilon);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_HAS_INFINITY__=%d", Prefix, HasInifinity);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_HAS_QUIET_NAN__=%d", Prefix, HasQuietNaN);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MANT_DIG__=%d", Prefix, MantissaDigits);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MAX_10_EXP__=%d", Prefix, Max10Exp);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MAX_EXP__=%d", Prefix, MaxExp);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MAX__=%s", Prefix, Max);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MIN_10_EXP__=(%d)", Prefix, Min10Exp);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MIN_EXP__=(%d)", Prefix, MinExp);
- DefineBuiltinMacro(Buf, MacroBuf);
- sprintf(MacroBuf, "__%s_MIN__=%s", Prefix, Min);
- DefineBuiltinMacro(Buf, MacroBuf);
-}
-
-
-static void InitializePredefinedMacros(Preprocessor &PP,
- std::vector<char> &Buf) {
- // Compiler version introspection macros.
- DefineBuiltinMacro(Buf, "__llvm__=1"); // LLVM Backend
- DefineBuiltinMacro(Buf, "__clang__=1"); // Clang Frontend
-
- // Currently claim to be compatible with GCC 4.2.1-5621.
- DefineBuiltinMacro(Buf, "__APPLE_CC__=5621");
- DefineBuiltinMacro(Buf, "__GNUC_MINOR__=2");
- DefineBuiltinMacro(Buf, "__GNUC_PATCHLEVEL__=1");
- DefineBuiltinMacro(Buf, "__GNUC__=4");
- DefineBuiltinMacro(Buf, "__GXX_ABI_VERSION=1002");
- DefineBuiltinMacro(Buf, "__VERSION__=\"4.2.1 (Apple Computer, Inc. "
- "build 5621) (dot 3)\"");
-
-
- // Initialize language-specific preprocessor defines.
-
- // FIXME: Implement magic like cpp_init_builtins for things like __STDC__
- // and __DATE__ etc.
- // These should all be defined in the preprocessor according to the
- // current language configuration.
- DefineBuiltinMacro(Buf, "__STDC__=1");
- //DefineBuiltinMacro(Buf, "__ASSEMBLER__=1");
- if (PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus)
- DefineBuiltinMacro(Buf, "__STDC_VERSION__=199901L");
- else if (0) // STDC94 ?
- DefineBuiltinMacro(Buf, "__STDC_VERSION__=199409L");
-
- DefineBuiltinMacro(Buf, "__STDC_HOSTED__=1");
- if (PP.getLangOptions().ObjC1) {
- DefineBuiltinMacro(Buf, "__OBJC__=1");
-
- if (PP.getLangOptions().getGCMode() == LangOptions::NonGC) {
- DefineBuiltinMacro(Buf, "__weak=");
- DefineBuiltinMacro(Buf, "__strong=");
- } else {
- DefineBuiltinMacro(Buf, "__weak=__attribute__((objc_gc(weak)))");
- DefineBuiltinMacro(Buf, "__strong=__attribute__((objc_gc(strong)))");
- DefineBuiltinMacro(Buf, "__OBJC_GC__=1");
- }
-
- if (PP.getLangOptions().NeXTRuntime)
- DefineBuiltinMacro(Buf, "__NEXT_RUNTIME__=1");
- }
-
- // darwin_constant_cfstrings controls this. This is also dependent
- // on other things like the runtime I believe. This is set even for C code.
- DefineBuiltinMacro(Buf, "__CONSTANT_CFSTRINGS__=1");
-
- if (PP.getLangOptions().ObjC2)
- DefineBuiltinMacro(Buf, "OBJC_NEW_PROPERTIES");
-
- if (PP.getLangOptions().PascalStrings)
- DefineBuiltinMacro(Buf, "__PASCAL_STRINGS__");
-
- if (PP.getLangOptions().Blocks) {
- DefineBuiltinMacro(Buf, "__block=__attribute__((__blocks__(byref)))");
- DefineBuiltinMacro(Buf, "__BLOCKS__=1");
- }
-
- if (PP.getLangOptions().CPlusPlus) {
- DefineBuiltinMacro(Buf, "__DEPRECATED=1");
- DefineBuiltinMacro(Buf, "__EXCEPTIONS=1");
- DefineBuiltinMacro(Buf, "__GNUG__=4");
- DefineBuiltinMacro(Buf, "__GXX_WEAK__=1");
- DefineBuiltinMacro(Buf, "__cplusplus=1");
- DefineBuiltinMacro(Buf, "__private_extern__=extern");
- }
-
- // Filter out some microsoft extensions when trying to parse in ms-compat
- // mode.
- if (PP.getLangOptions().Microsoft) {
- DefineBuiltinMacro(Buf, "__stdcall=");
- DefineBuiltinMacro(Buf, "__cdecl=");
- DefineBuiltinMacro(Buf, "_cdecl=");
- DefineBuiltinMacro(Buf, "__ptr64=");
- DefineBuiltinMacro(Buf, "__w64=");
- DefineBuiltinMacro(Buf, "__forceinline=");
- DefineBuiltinMacro(Buf, "__int8=char");
- DefineBuiltinMacro(Buf, "__int16=short");
- DefineBuiltinMacro(Buf, "__int32=int");
- DefineBuiltinMacro(Buf, "__int64=long long");
- DefineBuiltinMacro(Buf, "__declspec(X)=");
- }
-
-
- // Initialize target-specific preprocessor defines.
- const TargetInfo &TI = PP.getTargetInfo();
-
- // Define type sizing macros based on the target properties.
- assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
- DefineBuiltinMacro(Buf, "__CHAR_BIT__=8");
- DefineBuiltinMacro(Buf, "__SCHAR_MAX__=127");
-
- assert(TI.getWCharWidth() == 32 && "Only support 32-bit wchar so far");
- DefineBuiltinMacro(Buf, "__WCHAR_MAX__=2147483647");
- DefineBuiltinMacro(Buf, "__WCHAR_TYPE__=int");
- DefineBuiltinMacro(Buf, "__WINT_TYPE__=int");
-
- assert(TI.getShortWidth() == 16 && "Only support 16-bit short so far");
- DefineBuiltinMacro(Buf, "__SHRT_MAX__=32767");
-
- if (TI.getIntWidth() == 32)
- DefineBuiltinMacro(Buf, "__INT_MAX__=2147483647");
- else if (TI.getIntWidth() == 16)
- DefineBuiltinMacro(Buf, "__INT_MAX__=32767");
- else
- assert(0 && "Unknown integer size");
-
- assert(TI.getLongLongWidth() == 64 && "Only support 64-bit long long so far");
- DefineBuiltinMacro(Buf, "__LONG_LONG_MAX__=9223372036854775807LL");
-
- if (TI.getLongWidth() == 32)
- DefineBuiltinMacro(Buf, "__LONG_MAX__=2147483647L");
- else if (TI.getLongWidth() == 64)
- DefineBuiltinMacro(Buf, "__LONG_MAX__=9223372036854775807L");
- else if (TI.getLongWidth() == 16)
- DefineBuiltinMacro(Buf, "__LONG_MAX__=32767L");
- else
- assert(0 && "Unknown long size");
-
- // For "32-bit" targets, GCC generally defines intmax to be 'long long' and
- // ptrdiff_t to be 'int'. On "64-bit" targets, it defines intmax to be long,
- // and ptrdiff_t to be 'long int'. This sort of stuff shouldn't matter in
- // theory, but can affect C++ overloading, stringizing, etc.
- if (TI.getPointerWidth(0) == TI.getLongLongWidth()) {
- // If sizeof(void*) == sizeof(long long) assume we have an LP64 target,
- // because we assume sizeof(long) always is sizeof(void*) currently.
- assert(TI.getPointerWidth(0) == TI.getLongWidth() &&
- TI.getLongWidth() == 64 &&
- TI.getIntWidth() == 32 && "Not I32 LP64?");
- assert(TI.getIntMaxTWidth() == 64);
- DefineBuiltinMacro(Buf, "__INTMAX_MAX__=9223372036854775807L");
- DefineBuiltinMacro(Buf, "__INTMAX_TYPE__=long int");
- DefineBuiltinMacro(Buf, "__PTRDIFF_TYPE__=long int");
- DefineBuiltinMacro(Buf, "__UINTMAX_TYPE__=long unsigned int");
- } else {
- // Otherwise we know that the pointer is smaller than long long. We continue
- // to assume that sizeof(void*) == sizeof(long).
- assert(TI.getPointerWidth(0) < TI.getLongLongWidth() &&
- TI.getPointerWidth(0) == TI.getLongWidth() &&
- "Unexpected target sizes");
- // We currently only support targets where long is 32-bit. This can be
- // easily generalized in the future.
- assert(TI.getIntMaxTWidth() == 64);
- DefineBuiltinMacro(Buf, "__INTMAX_MAX__=9223372036854775807LL");
- DefineBuiltinMacro(Buf, "__INTMAX_TYPE__=long long int");
- DefineBuiltinMacro(Buf, "__PTRDIFF_TYPE__=int");
- DefineBuiltinMacro(Buf, "__UINTMAX_TYPE__=long long unsigned int");
- }
-
- // All of our current targets have sizeof(long) == sizeof(void*).
- assert(TI.getPointerWidth(0) == TI.getLongWidth());
- DefineBuiltinMacro(Buf, "__SIZE_TYPE__=long unsigned int");
-
- DefineFloatMacros(Buf, "FLT", &TI.getFloatFormat());
- DefineFloatMacros(Buf, "DBL", &TI.getDoubleFormat());
- DefineFloatMacros(Buf, "LDBL", &TI.getLongDoubleFormat());
-
-
- // Add __builtin_va_list typedef.
- {
- const char *VAList = TI.getVAListDeclaration();
- Buf.insert(Buf.end(), VAList, VAList+strlen(VAList));
- Buf.push_back('\n');
- }
-
- char MacroBuf[60];
- if (const char *Prefix = TI.getUserLabelPrefix()) {
- sprintf(MacroBuf, "__USER_LABEL_PREFIX__=%s", Prefix);
- DefineBuiltinMacro(Buf, MacroBuf);
- }
-
- // Build configuration options. FIXME: these should be controlled by
- // command line options or something.
- DefineBuiltinMacro(Buf, "__DYNAMIC__=1");
- DefineBuiltinMacro(Buf, "__FINITE_MATH_ONLY__=0");
- DefineBuiltinMacro(Buf, "__NO_INLINE__=1");
- DefineBuiltinMacro(Buf, "__PIC__=1");
-
- // Macros to control C99 numerics and <float.h>
- DefineBuiltinMacro(Buf, "__FLT_EVAL_METHOD__=0");
- DefineBuiltinMacro(Buf, "__FLT_RADIX__=2");
- sprintf(MacroBuf, "__DECIMAL_DIG__=%d",
- PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33));
- DefineBuiltinMacro(Buf, MacroBuf);
-
- // Get other target #defines.
- TI.getTargetDefines(Buf);
-
- // FIXME: Should emit a #line directive here.
-}
-
-
-/// EnterMainSourceFile - Enter the specified FileID as the main source file,
-/// which implicitly adds the builtin defines etc.
-void Preprocessor::EnterMainSourceFile() {
-
- unsigned MainFileID = SourceMgr.getMainFileID();
-
- // Enter the main file source buffer.
- EnterSourceFile(MainFileID, 0);
-
- // Tell the header info that the main file was entered. If the file is later
- // #imported, it won't be re-entered.
- if (const FileEntry *FE =
- SourceMgr.getFileEntryForLoc(SourceLocation::getFileLoc(MainFileID, 0)))
- HeaderInfo.IncrementIncludeCount(FE);
-
- std::vector<char> PrologFile;
- PrologFile.reserve(4080);
-
- // Install things like __POWERPC__, __GNUC__, etc into the macro table.
- InitializePredefinedMacros(*this, PrologFile);
-
- // Add on the predefines from the driver.
- PrologFile.insert(PrologFile.end(), Predefines.begin(), Predefines.end());
-
- // Memory buffer must end with a null byte!
- PrologFile.push_back(0);
-
- // Now that we have emitted the predefined macros, #includes, etc into
- // PrologFile, preprocess it to populate the initial preprocessor state.
- llvm::MemoryBuffer *SB =
- llvm::MemoryBuffer::getMemBufferCopy(&PrologFile.front(),&PrologFile.back(),
- "<predefines>");
- assert(SB && "Cannot fail to create predefined source buffer");
- unsigned FileID = SourceMgr.createFileIDForMemBuffer(SB);
- assert(FileID && "Could not create FileID for predefines?");
-
- // Start parsing the predefines.
- EnterSourceFile(FileID, 0);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Lexer Event Handling.
-//===----------------------------------------------------------------------===//
-
-/// LookUpIdentifierInfo - Given a tok::identifier token, look up the
-/// identifier information for the token and install it into the token.
-IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier,
- const char *BufPtr) {
- assert(Identifier.is(tok::identifier) && "Not an identifier!");
- assert(Identifier.getIdentifierInfo() == 0 && "Identinfo already exists!");
-
- // Look up this token, see if it is a macro, or if it is a language keyword.
- IdentifierInfo *II;
- if (BufPtr && !Identifier.needsCleaning()) {
- // No cleaning needed, just use the characters from the lexed buffer.
- II = getIdentifierInfo(BufPtr, BufPtr+Identifier.getLength());
- } else {
- // Cleaning needed, alloca a buffer, clean into it, then use the buffer.
- llvm::SmallVector<char, 64> IdentifierBuffer;
- IdentifierBuffer.resize(Identifier.getLength());
- const char *TmpBuf = &IdentifierBuffer[0];
- unsigned Size = getSpelling(Identifier, TmpBuf);
- II = getIdentifierInfo(TmpBuf, TmpBuf+Size);
- }
- Identifier.setIdentifierInfo(II);
- return II;
-}
-
-
-/// HandleIdentifier - This callback is invoked when the lexer reads an
-/// identifier. This callback looks up the identifier in the map and/or
-/// potentially macro expands it or turns it into a named token (like 'for').
-void Preprocessor::HandleIdentifier(Token &Identifier) {
- assert(Identifier.getIdentifierInfo() &&
- "Can't handle identifiers without identifier info!");
-
- IdentifierInfo &II = *Identifier.getIdentifierInfo();
-
- // If this identifier was poisoned, and if it was not produced from a macro
- // expansion, emit an error.
- if (II.isPoisoned() && CurLexer) {
- if (&II != Ident__VA_ARGS__) // We warn about __VA_ARGS__ with poisoning.
- Diag(Identifier, diag::err_pp_used_poisoned_id);
- else
- Diag(Identifier, diag::ext_pp_bad_vaargs_use);
- }
-
- // If this is a macro to be expanded, do it.
- if (MacroInfo *MI = getMacroInfo(&II)) {
- if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) {
- if (MI->isEnabled()) {
- if (!HandleMacroExpandedIdentifier(Identifier, MI))
- return;
- } else {
- // C99 6.10.3.4p2 says that a disabled macro may never again be
- // expanded, even if it's in a context where it could be expanded in the
- // future.
- Identifier.setFlag(Token::DisableExpand);
- }
- }
- }
-
- // C++ 2.11p2: If this is an alternative representation of a C++ operator,
- // then we act as if it is the actual operator and not the textual
- // representation of it.
- if (II.isCPlusPlusOperatorKeyword())
- Identifier.setIdentifierInfo(0);
-
- // Change the kind of this identifier to the appropriate token kind, e.g.
- // turning "for" into a keyword.
- Identifier.setKind(II.getTokenID());
-
- // If this is an extension token, diagnose its use.
- // We avoid diagnosing tokens that originate from macro definitions.
- if (II.isExtensionToken() && Features.C99 && !DisableMacroExpansion)
- Diag(Identifier, diag::ext_token_used);
-}
diff --git a/clang/lib/Lex/ScratchBuffer.cpp b/clang/lib/Lex/ScratchBuffer.cpp
deleted file mode 100644
index 99fbdf75654a..000000000000
--- a/clang/lib/Lex/ScratchBuffer.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-//===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the ScratchBuffer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/ScratchBuffer.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cstring>
-using namespace clang;
-
-// ScratchBufSize - The size of each chunk of scratch memory. Slightly less
-//than a page, almost certainly enough for anything. :)
-static const unsigned ScratchBufSize = 4060;
-
-ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) {
- // Set BytesUsed so that the first call to getToken will require an alloc.
- BytesUsed = ScratchBufSize;
- FileID = 0;
-}
-
-/// getToken - Splat the specified text into a temporary MemoryBuffer and
-/// return a SourceLocation that refers to the token. This is just like the
-/// method below, but returns a location that indicates the physloc of the
-/// token.
-SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len) {
- if (BytesUsed+Len > ScratchBufSize)
- AllocScratchBuffer(Len);
-
- // Copy the token data into the buffer.
- memcpy(CurBuffer+BytesUsed, Buf, Len);
-
- // Remember that we used these bytes.
- BytesUsed += Len;
-
- assert(BytesUsed-Len < (1 << SourceLocation::FilePosBits) &&
- "Out of range file position!");
-
- return SourceLocation::getFileLoc(FileID, BytesUsed-Len);
-}
-
-
-/// getToken - Splat the specified text into a temporary MemoryBuffer and
-/// return a SourceLocation that refers to the token. The SourceLoc value
-/// gives a virtual location that the token will appear to be from.
-SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len,
- SourceLocation SourceLoc) {
- // Map the physloc to the specified sourceloc.
- return SourceMgr.getInstantiationLoc(getToken(Buf, Len), SourceLoc);
-}
-
-void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) {
- // Only pay attention to the requested length if it is larger than our default
- // page size. If it is, we allocate an entire chunk for it. This is to
- // support gigantic tokens, which almost certainly won't happen. :)
- if (RequestLen < ScratchBufSize)
- RequestLen = ScratchBufSize;
-
- llvm::MemoryBuffer *Buf =
- llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>");
- FileID = SourceMgr.createFileIDForMemBuffer(Buf);
- CurBuffer = const_cast<char*>(Buf->getBufferStart());
- BytesUsed = 0;
-}
diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp
deleted file mode 100644
index a3fe7350f2a7..000000000000
--- a/clang/lib/Lex/TokenLexer.cpp
+++ /dev/null
@@ -1,488 +0,0 @@
-//===--- TokenLexer.cpp - Lex from a token stream -------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the TokenLexer interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/TokenLexer.h"
-#include "MacroArgs.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-using namespace clang;
-
-
-/// Create a TokenLexer for the specified macro with the specified actual
-/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
-void TokenLexer::Init(Token &Tok, MacroArgs *Actuals) {
- // If the client is reusing a TokenLexer, make sure to free any memory
- // associated with it.
- destroy();
-
- Macro = PP.getMacroInfo(Tok.getIdentifierInfo());
- ActualArgs = Actuals;
- CurToken = 0;
- InstantiateLoc = Tok.getLocation();
- AtStartOfLine = Tok.isAtStartOfLine();
- HasLeadingSpace = Tok.hasLeadingSpace();
- Tokens = &*Macro->tokens_begin();
- OwnsTokens = false;
- DisableMacroExpansion = false;
- NumTokens = Macro->tokens_end()-Macro->tokens_begin();
-
- // If this is a function-like macro, expand the arguments and change
- // Tokens to point to the expanded tokens.
- if (Macro->isFunctionLike() && Macro->getNumArgs())
- ExpandFunctionArguments();
-
- // Mark the macro as currently disabled, so that it is not recursively
- // expanded. The macro must be disabled only after argument pre-expansion of
- // function-like macro arguments occurs.
- Macro->DisableMacro();
-}
-
-
-
-/// Create a TokenLexer for the specified token stream. This does not
-/// take ownership of the specified token vector.
-void TokenLexer::Init(const Token *TokArray, unsigned NumToks,
- bool disableMacroExpansion, bool ownsTokens) {
- // If the client is reusing a TokenLexer, make sure to free any memory
- // associated with it.
- destroy();
-
- Macro = 0;
- ActualArgs = 0;
- Tokens = TokArray;
- OwnsTokens = ownsTokens;
- DisableMacroExpansion = disableMacroExpansion;
- NumTokens = NumToks;
- CurToken = 0;
- InstantiateLoc = SourceLocation();
- AtStartOfLine = false;
- HasLeadingSpace = false;
-
- // Set HasLeadingSpace/AtStartOfLine so that the first token will be
- // returned unmodified.
- if (NumToks != 0) {
- AtStartOfLine = TokArray[0].isAtStartOfLine();
- HasLeadingSpace = TokArray[0].hasLeadingSpace();
- }
-}
-
-
-void TokenLexer::destroy() {
- // If this was a function-like macro that actually uses its arguments, delete
- // the expanded tokens.
- if (OwnsTokens) {
- delete [] Tokens;
- Tokens = 0;
- }
-
- // TokenLexer owns its formal arguments.
- if (ActualArgs) ActualArgs->destroy();
-}
-
-/// Expand the arguments of a function-like macro so that we can quickly
-/// return preexpanded tokens from Tokens.
-void TokenLexer::ExpandFunctionArguments() {
- llvm::SmallVector<Token, 128> ResultToks;
-
- // Loop through 'Tokens', expanding them into ResultToks. Keep
- // track of whether we change anything. If not, no need to keep them. If so,
- // we install the newly expanded sequence as the new 'Tokens' list.
- bool MadeChange = false;
-
- // NextTokGetsSpace - When this is true, the next token appended to the
- // output list will get a leading space, regardless of whether it had one to
- // begin with or not. This is used for placemarker support.
- bool NextTokGetsSpace = false;
-
- for (unsigned i = 0, e = NumTokens; i != e; ++i) {
- // If we found the stringify operator, get the argument stringified. The
- // preprocessor already verified that the following token is a macro name
- // when the #define was parsed.
- const Token &CurTok = Tokens[i];
- if (CurTok.is(tok::hash) || CurTok.is(tok::hashat)) {
- int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
- assert(ArgNo != -1 && "Token following # is not an argument?");
-
- Token Res;
- if (CurTok.is(tok::hash)) // Stringify
- Res = ActualArgs->getStringifiedArgument(ArgNo, PP);
- else {
- // 'charify': don't bother caching these.
- Res = MacroArgs::StringifyArgument(ActualArgs->getUnexpArgument(ArgNo),
- PP, true);
- }
-
- // The stringified/charified string leading space flag gets set to match
- // the #/#@ operator.
- if (CurTok.hasLeadingSpace() || NextTokGetsSpace)
- Res.setFlag(Token::LeadingSpace);
-
- ResultToks.push_back(Res);
- MadeChange = true;
- ++i; // Skip arg name.
- NextTokGetsSpace = false;
- continue;
- }
-
- // Otherwise, if this is not an argument token, just add the token to the
- // output buffer.
- IdentifierInfo *II = CurTok.getIdentifierInfo();
- int ArgNo = II ? Macro->getArgumentNum(II) : -1;
- if (ArgNo == -1) {
- // This isn't an argument, just add it.
- ResultToks.push_back(CurTok);
-
- if (NextTokGetsSpace) {
- ResultToks.back().setFlag(Token::LeadingSpace);
- NextTokGetsSpace = false;
- }
- continue;
- }
-
- // An argument is expanded somehow, the result is different than the
- // input.
- MadeChange = true;
-
- // Otherwise, this is a use of the argument. Find out if there is a paste
- // (##) operator before or after the argument.
- bool PasteBefore =
- !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
- bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
-
- // If it is not the LHS/RHS of a ## operator, we must pre-expand the
- // argument and substitute the expanded tokens into the result. This is
- // C99 6.10.3.1p1.
- if (!PasteBefore && !PasteAfter) {
- const Token *ResultArgToks;
-
- // Only preexpand the argument if it could possibly need it. This
- // avoids some work in common cases.
- const Token *ArgTok = ActualArgs->getUnexpArgument(ArgNo);
- if (ActualArgs->ArgNeedsPreexpansion(ArgTok, PP))
- ResultArgToks = &ActualArgs->getPreExpArgument(ArgNo, PP)[0];
- else
- ResultArgToks = ArgTok; // Use non-preexpanded tokens.
-
- // If the arg token expanded into anything, append it.
- if (ResultArgToks->isNot(tok::eof)) {
- unsigned FirstResult = ResultToks.size();
- unsigned NumToks = MacroArgs::getArgLength(ResultArgToks);
- ResultToks.append(ResultArgToks, ResultArgToks+NumToks);
-
- // If any tokens were substituted from the argument, the whitespace
- // before the first token should match the whitespace of the arg
- // identifier.
- ResultToks[FirstResult].setFlagValue(Token::LeadingSpace,
- CurTok.hasLeadingSpace() ||
- NextTokGetsSpace);
- NextTokGetsSpace = false;
- } else {
- // If this is an empty argument, and if there was whitespace before the
- // formal token, make sure the next token gets whitespace before it.
- NextTokGetsSpace = CurTok.hasLeadingSpace();
- }
- continue;
- }
-
- // Okay, we have a token that is either the LHS or RHS of a paste (##)
- // argument. It gets substituted as its non-pre-expanded tokens.
- const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
- unsigned NumToks = MacroArgs::getArgLength(ArgToks);
- if (NumToks) { // Not an empty argument?
- // If this is the GNU ", ## __VA_ARG__" extension, and we just learned
- // that __VA_ARG__ expands to multiple tokens, avoid a pasting error when
- // the expander trys to paste ',' with the first token of the __VA_ARG__
- // expansion.
- if (PasteBefore && ResultToks.size() >= 2 &&
- ResultToks[ResultToks.size()-2].is(tok::comma) &&
- (unsigned)ArgNo == Macro->getNumArgs()-1 &&
- Macro->isVariadic()) {
- // Remove the paste operator, report use of the extension.
- PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
- ResultToks.pop_back();
- }
-
- ResultToks.append(ArgToks, ArgToks+NumToks);
-
- // If the next token was supposed to get leading whitespace, ensure it has
- // it now.
- if (NextTokGetsSpace) {
- ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace);
- NextTokGetsSpace = false;
- }
- continue;
- }
-
- // If an empty argument is on the LHS or RHS of a paste, the standard (C99
- // 6.10.3.3p2,3) calls for a bunch of placemarker stuff to occur. We
- // implement this by eating ## operators when a LHS or RHS expands to
- // empty.
- NextTokGetsSpace |= CurTok.hasLeadingSpace();
- if (PasteAfter) {
- // Discard the argument token and skip (don't copy to the expansion
- // buffer) the paste operator after it.
- NextTokGetsSpace |= Tokens[i+1].hasLeadingSpace();
- ++i;
- continue;
- }
-
- // If this is on the RHS of a paste operator, we've already copied the
- // paste operator to the ResultToks list. Remove it.
- assert(PasteBefore && ResultToks.back().is(tok::hashhash));
- NextTokGetsSpace |= ResultToks.back().hasLeadingSpace();
- ResultToks.pop_back();
-
- // If this is the __VA_ARGS__ token, and if the argument wasn't provided,
- // and if the macro had at least one real argument, and if the token before
- // the ## was a comma, remove the comma.
- if ((unsigned)ArgNo == Macro->getNumArgs()-1 && // is __VA_ARGS__
- ActualArgs->isVarargsElidedUse() && // Argument elided.
- !ResultToks.empty() && ResultToks.back().is(tok::comma)) {
- // Never add a space, even if the comma, ##, or arg had a space.
- NextTokGetsSpace = false;
- // Remove the paste operator, report use of the extension.
- PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma);
- ResultToks.pop_back();
- }
- continue;
- }
-
- // If anything changed, install this as the new Tokens list.
- if (MadeChange) {
- // This is deleted in the dtor.
- NumTokens = ResultToks.size();
- Token *Res = new Token[ResultToks.size()];
- if (NumTokens)
- memcpy(Res, &ResultToks[0], NumTokens*sizeof(Token));
- Tokens = Res;
- OwnsTokens = true;
- }
-}
-
-/// Lex - Lex and return a token from this macro stream.
-///
-void TokenLexer::Lex(Token &Tok) {
- // Lexing off the end of the macro, pop this macro off the expansion stack.
- if (isAtEnd()) {
- // If this is a macro (not a token stream), mark the macro enabled now
- // that it is no longer being expanded.
- if (Macro) Macro->EnableMacro();
-
- // Pop this context off the preprocessors lexer stack and get the next
- // token. This will delete "this" so remember the PP instance var.
- Preprocessor &PPCache = PP;
- if (PP.HandleEndOfTokenLexer(Tok))
- return;
-
- // HandleEndOfTokenLexer may not return a token. If it doesn't, lex
- // whatever is next.
- return PPCache.Lex(Tok);
- }
-
- // If this is the first token of the expanded result, we inherit spacing
- // properties later.
- bool isFirstToken = CurToken == 0;
-
- // Get the next token to return.
- Tok = Tokens[CurToken++];
-
- // If this token is followed by a token paste (##) operator, paste the tokens!
- if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash))
- if (PasteTokens(Tok)) {
- // When handling the microsoft /##/ extension, the final token is
- // returned by PasteTokens, not the pasted token.
- return;
- }
-
- // The token's current location indicate where the token was lexed from. We
- // need this information to compute the spelling of the token, but any
- // diagnostics for the expanded token should appear as if they came from
- // InstantiationLoc. Pull this information together into a new SourceLocation
- // that captures all of this.
- if (InstantiateLoc.isValid()) { // Don't do this for token streams.
- SourceManager &SrcMgr = PP.getSourceManager();
- Tok.setLocation(SrcMgr.getInstantiationLoc(Tok.getLocation(),
- InstantiateLoc));
- }
-
- // If this is the first token, set the lexical properties of the token to
- // match the lexical properties of the macro identifier.
- if (isFirstToken) {
- Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
- Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
- }
-
- // Handle recursive expansion!
- if (Tok.getIdentifierInfo() && !DisableMacroExpansion)
- return PP.HandleIdentifier(Tok);
-
- // Otherwise, return a normal token.
-}
-
-/// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
-/// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
-/// are more ## after it, chomp them iteratively. Return the result as Tok.
-/// If this returns true, the caller should immediately return the token.
-bool TokenLexer::PasteTokens(Token &Tok) {
- llvm::SmallVector<char, 128> Buffer;
- do {
- // Consume the ## operator.
- SourceLocation PasteOpLoc = Tokens[CurToken].getLocation();
- ++CurToken;
- assert(!isAtEnd() && "No token on the RHS of a paste operator!");
-
- // Get the RHS token.
- const Token &RHS = Tokens[CurToken];
-
- bool isInvalid = false;
-
- // Allocate space for the result token. This is guaranteed to be enough for
- // the two tokens and a null terminator.
- Buffer.resize(Tok.getLength() + RHS.getLength() + 1);
-
- // Get the spelling of the LHS token in Buffer.
- const char *BufPtr = &Buffer[0];
- unsigned LHSLen = PP.getSpelling(Tok, BufPtr);
- if (BufPtr != &Buffer[0]) // Really, we want the chars in Buffer!
- memcpy(&Buffer[0], BufPtr, LHSLen);
-
- BufPtr = &Buffer[LHSLen];
- unsigned RHSLen = PP.getSpelling(RHS, BufPtr);
- if (BufPtr != &Buffer[LHSLen]) // Really, we want the chars in Buffer!
- memcpy(&Buffer[LHSLen], BufPtr, RHSLen);
-
- // Add null terminator.
- Buffer[LHSLen+RHSLen] = '\0';
-
- // Trim excess space.
- Buffer.resize(LHSLen+RHSLen+1);
-
- // Plop the pasted result (including the trailing newline and null) into a
- // scratch buffer where we can lex it.
- SourceLocation ResultTokLoc = PP.CreateString(&Buffer[0], Buffer.size());
-
- // Lex the resultant pasted token into Result.
- Token Result;
-
- // Avoid testing /*, as the lexer would think it is the start of a comment
- // and emit an error that it is unterminated.
- if (Tok.is(tok::slash) && RHS.is(tok::star)) {
- isInvalid = true;
- } else if (Tok.is(tok::identifier) && RHS.is(tok::identifier)) {
- // Common paste case: identifier+identifier = identifier. Avoid creating
- // a lexer and other overhead.
- PP.IncrementPasteCounter(true);
- Result.startToken();
- Result.setKind(tok::identifier);
- Result.setLocation(ResultTokLoc);
- Result.setLength(LHSLen+RHSLen);
- } else {
- PP.IncrementPasteCounter(false);
-
- // Make a lexer to lex this string from.
- SourceManager &SourceMgr = PP.getSourceManager();
- const char *ResultStrData = SourceMgr.getCharacterData(ResultTokLoc);
-
- // Make a lexer object so that we lex and expand the paste result.
- Lexer *TL = new Lexer(ResultTokLoc, PP, ResultStrData,
- ResultStrData+LHSLen+RHSLen /*don't include null*/);
-
- // Lex a token in raw mode. This way it won't look up identifiers
- // automatically, lexing off the end will return an eof token, and
- // warnings are disabled. This returns true if the result token is the
- // entire buffer.
- bool IsComplete = TL->LexRawToken(Result);
-
- // If we got an EOF token, we didn't form even ONE token. For example, we
- // did "/ ## /" to get "//".
- IsComplete &= Result.isNot(tok::eof);
- isInvalid = !IsComplete;
-
- // We're now done with the temporary lexer.
- delete TL;
- }
-
- // If pasting the two tokens didn't form a full new token, this is an error.
- // This occurs with "x ## +" and other stuff. Return with Tok unmodified
- // and with RHS as the next token to lex.
- if (isInvalid) {
- // Test for the Microsoft extension of /##/ turning into // here on the
- // error path.
- if (PP.getLangOptions().Microsoft && Tok.is(tok::slash) &&
- RHS.is(tok::slash)) {
- HandleMicrosoftCommentPaste(Tok);
- return true;
- } else {
- // TODO: If not in assembler language mode.
- PP.Diag(PasteOpLoc, diag::err_pp_bad_paste,
- std::string(Buffer.begin(), Buffer.end()-1));
- return false;
- }
- }
-
- // Turn ## into 'unknown' to avoid # ## # from looking like a paste
- // operator.
- if (Result.is(tok::hashhash))
- Result.setKind(tok::unknown);
- // FIXME: Turn __VA_ARGS__ into "not a token"?
-
- // Transfer properties of the LHS over the the Result.
- Result.setFlagValue(Token::StartOfLine , Tok.isAtStartOfLine());
- Result.setFlagValue(Token::LeadingSpace, Tok.hasLeadingSpace());
-
- // Finally, replace LHS with the result, consume the RHS, and iterate.
- ++CurToken;
- Tok = Result;
- } while (!isAtEnd() && Tokens[CurToken].is(tok::hashhash));
-
- // Now that we got the result token, it will be subject to expansion. Since
- // token pasting re-lexes the result token in raw mode, identifier information
- // isn't looked up. As such, if the result is an identifier, look up id info.
- if (Tok.is(tok::identifier)) {
- // Look up the identifier info for the token. We disabled identifier lookup
- // by saying we're skipping contents, so we need to do this manually.
- Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok));
- }
- return false;
-}
-
-/// isNextTokenLParen - If the next token lexed will pop this macro off the
-/// expansion stack, return 2. If the next unexpanded token is a '(', return
-/// 1, otherwise return 0.
-unsigned TokenLexer::isNextTokenLParen() const {
- // Out of tokens?
- if (isAtEnd())
- return 2;
- return Tokens[CurToken].is(tok::l_paren);
-}
-
-
-/// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
-/// together to form a comment that comments out everything in the current
-/// macro, other active macros, and anything left on the current physical
-/// source line of the instantiated buffer. Handle this by returning the
-/// first token on the next line.
-void TokenLexer::HandleMicrosoftCommentPaste(Token &Tok) {
- // We 'comment out' the rest of this macro by just ignoring the rest of the
- // tokens that have not been lexed yet, if any.
-
- // Since this must be a macro, mark the macro enabled now that it is no longer
- // being expanded.
- assert(Macro && "Token streams can't paste comments");
- Macro->EnableMacro();
-
- PP.HandleMicrosoftCommentPaste(Tok);
-}
diff --git a/clang/lib/Makefile b/clang/lib/Makefile
deleted file mode 100755
index c72c353f8b53..000000000000
--- a/clang/lib/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Makefile ----------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-
-PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis Rewrite Driver
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp
deleted file mode 100644
index 825570dce2e1..000000000000
--- a/clang/lib/Parse/AttributeList.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-//===--- AttributeList.cpp --------------------------------------*- 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 AttributeList class implementation
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/AttributeList.h"
-using namespace clang;
-
-AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
- IdentifierInfo *pName, SourceLocation pLoc,
- Action::ExprTy **elist, unsigned numargs,
- AttributeList *n)
- : AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc),
- NumArgs(numargs), Next(n) {
- Args = new Action::ExprTy*[numargs];
- for (unsigned i = 0; i != numargs; ++i)
- Args[i] = elist[i];
-}
-
-AttributeList::~AttributeList() {
- if (Args) {
- // FIXME: before we delete the vector, we need to make sure the Expr's
- // have been deleted. Since Action::ExprTy is "void", we are dependent
- // on the actions module for actually freeing the memory. The specific
- // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType,
- // ParseField, ParseTag. Once these routines have freed the expression,
- // they should zero out the Args slot (to indicate the memory has been
- // freed). If any element of the vector is non-null, we should assert.
- delete [] Args;
- }
- delete Next;
-}
-
-AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
- const char *Str = Name->getName();
- unsigned Len = Name->getLength();
-
- // Normalize the attribute name, __foo__ becomes foo.
- if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
- Str[Len - 2] == '_' && Str[Len - 1] == '_') {
- Str += 2;
- Len -= 4;
- }
-
- // FIXME: Hand generating this is neither smart nor efficient.
- switch (Len) {
- case 4:
- if (!memcmp(Str, "weak", 4)) return AT_weak;
- if (!memcmp(Str, "pure", 4)) return AT_pure;
- if (!memcmp(Str, "mode", 4)) return AT_mode;
- break;
- case 5:
- if (!memcmp(Str, "alias", 5)) return AT_alias;
- break;
- case 6:
- if (!memcmp(Str, "packed", 6)) return AT_packed;
- if (!memcmp(Str, "malloc", 6)) return AT_malloc;
- if (!memcmp(Str, "format", 6)) return AT_format;
- if (!memcmp(Str, "unused", 6)) return AT_unused;
- if (!memcmp(Str, "blocks", 6)) return AT_blocks;
- break;
- case 7:
- if (!memcmp(Str, "aligned", 7)) return AT_aligned;
- if (!memcmp(Str, "nothrow", 7)) return AT_nothrow;
- if (!memcmp(Str, "nonnull", 7)) return AT_nonnull;
- if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc;
- if (!memcmp(Str, "stdcall", 7)) return AT_stdcall;
- break;
- case 8:
- if (!memcmp(Str, "annotate", 8)) return AT_annotate;
- if (!memcmp(Str, "noreturn", 8)) return AT_noreturn;
- if (!memcmp(Str, "noinline", 8)) return AT_noinline;
- if (!memcmp(Str, "fastcall", 8)) return AT_fastcall;
- if (!memcmp(Str, "iboutlet", 8)) return AT_IBOutlet;
- if (!memcmp(Str, "sentinel", 8)) return AT_sentinel;
- break;
- case 9:
- if (!memcmp(Str, "dllimport", 9)) return AT_dllimport;
- if (!memcmp(Str, "dllexport", 9)) return AT_dllexport;
- break;
- case 10:
- if (!memcmp(Str, "deprecated", 10)) return AT_deprecated;
- if (!memcmp(Str, "visibility", 10)) return AT_visibility;
- if (!memcmp(Str, "destructor", 10)) return AT_destructor;
- break;
- case 11:
- if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
- if (!memcmp(Str, "constructor", 11)) return AT_constructor;
- break;
- case 13:
- if (!memcmp(Str, "address_space", 13)) return AT_address_space;
- break;
- case 15:
- if (!memcmp(Str, "ext_vector_type", 15)) return AT_ext_vector_type;
- break;
- case 17:
- if (!memcmp(Str, "transparent_union", 17)) return AT_transparent_union;
- break;
- case 18:
- if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
- break;
- }
- return UnknownAttribute;
-}
diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp
deleted file mode 100644
index 1d42feda1e83..000000000000
--- a/clang/lib/Parse/DeclSpec.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for declaration specifiers.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-using namespace clang;
-
-/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
-///
-unsigned DeclSpec::getParsedSpecifiers() const {
- unsigned Res = 0;
- if (StorageClassSpec != SCS_unspecified ||
- SCS_thread_specified)
- Res |= PQ_StorageClassSpecifier;
-
- if (TypeQualifiers != TQ_unspecified)
- Res |= PQ_TypeQualifier;
-
- if (hasTypeSpecifier())
- Res |= PQ_TypeSpecifier;
-
- if (FS_inline_specified)
- Res |= PQ_FunctionSpecifier;
- return Res;
-}
-
-const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
- switch (S) {
- default: assert(0 && "Unknown typespec!");
- case DeclSpec::SCS_unspecified: return "unspecified";
- case DeclSpec::SCS_typedef: return "typedef";
- case DeclSpec::SCS_extern: return "extern";
- case DeclSpec::SCS_static: return "static";
- case DeclSpec::SCS_auto: return "auto";
- case DeclSpec::SCS_register: return "register";
- }
-}
-
-bool DeclSpec::BadSpecifier(SCS S, const char *&PrevSpec) {
- PrevSpec = getSpecifierName(S);
- return true;
-}
-
-bool DeclSpec::BadSpecifier(TSW W, const char *&PrevSpec) {
- switch (W) {
- case TSW_unspecified: PrevSpec = "unspecified"; break;
- case TSW_short: PrevSpec = "short"; break;
- case TSW_long: PrevSpec = "long"; break;
- case TSW_longlong: PrevSpec = "long long"; break;
- }
- return true;
-}
-
-bool DeclSpec::BadSpecifier(TSC C, const char *&PrevSpec) {
- switch (C) {
- case TSC_unspecified: PrevSpec = "unspecified"; break;
- case TSC_imaginary: PrevSpec = "imaginary"; break;
- case TSC_complex: PrevSpec = "complex"; break;
- }
- return true;
-}
-
-
-bool DeclSpec::BadSpecifier(TSS S, const char *&PrevSpec) {
- switch (S) {
- case TSS_unspecified: PrevSpec = "unspecified"; break;
- case TSS_signed: PrevSpec = "signed"; break;
- case TSS_unsigned: PrevSpec = "unsigned"; break;
- }
- return true;
-}
-
-const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
- switch (T) {
- default: assert(0 && "Unknown typespec!");
- case DeclSpec::TST_unspecified: return "unspecified";
- case DeclSpec::TST_void: return "void";
- case DeclSpec::TST_char: return "char";
- case DeclSpec::TST_wchar: return "wchar_t";
- case DeclSpec::TST_int: return "int";
- case DeclSpec::TST_float: return "float";
- case DeclSpec::TST_double: return "double";
- case DeclSpec::TST_bool: return "_Bool";
- case DeclSpec::TST_decimal32: return "_Decimal32";
- case DeclSpec::TST_decimal64: return "_Decimal64";
- case DeclSpec::TST_decimal128: return "_Decimal128";
- case DeclSpec::TST_enum: return "enum";
- case DeclSpec::TST_class: return "class";
- case DeclSpec::TST_union: return "union";
- case DeclSpec::TST_struct: return "struct";
- case DeclSpec::TST_typedef: return "typedef";
- case DeclSpec::TST_typeofType:
- case DeclSpec::TST_typeofExpr: return "typeof";
- }
-}
-
-bool DeclSpec::BadSpecifier(TST T, const char *&PrevSpec) {
- PrevSpec = getSpecifierName(T);
- return true;
-}
-
-bool DeclSpec::BadSpecifier(TQ T, const char *&PrevSpec) {
- switch (T) {
- case DeclSpec::TQ_unspecified: PrevSpec = "unspecified"; break;
- case DeclSpec::TQ_const: PrevSpec = "const"; break;
- case DeclSpec::TQ_restrict: PrevSpec = "restrict"; break;
- case DeclSpec::TQ_volatile: PrevSpec = "volatile"; break;
- }
- return true;
-}
-
-bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
- const char *&PrevSpec) {
- if (StorageClassSpec != SCS_unspecified)
- return BadSpecifier( (SCS)StorageClassSpec, PrevSpec);
- StorageClassSpec = S;
- StorageClassSpecLoc = Loc;
- return false;
-}
-
-bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
- const char *&PrevSpec) {
- if (SCS_thread_specified) {
- PrevSpec = "__thread";
- return true;
- }
- SCS_thread_specified = true;
- SCS_threadLoc = Loc;
- return false;
-}
-
-
-/// These methods set the specified attribute of the DeclSpec, but return true
-/// and ignore the request if invalid (e.g. "extern" then "auto" is
-/// specified).
-bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
- const char *&PrevSpec) {
- if (TypeSpecWidth != TSW_unspecified &&
- // Allow turning long -> long long.
- (W != TSW_longlong || TypeSpecWidth != TSW_long))
- return BadSpecifier( (TSW)TypeSpecWidth, PrevSpec);
- TypeSpecWidth = W;
- TSWLoc = Loc;
- return false;
-}
-
-bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
- const char *&PrevSpec) {
- if (TypeSpecComplex != TSC_unspecified)
- return BadSpecifier( (TSC)TypeSpecComplex, PrevSpec);
- TypeSpecComplex = C;
- TSCLoc = Loc;
- return false;
-}
-
-bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
- const char *&PrevSpec) {
- if (TypeSpecSign != TSS_unspecified)
- return BadSpecifier( (TSS)TypeSpecSign, PrevSpec);
- TypeSpecSign = S;
- TSSLoc = Loc;
- return false;
-}
-
-bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
- const char *&PrevSpec, Action::TypeTy *Rep) {
- if (TypeSpecType != TST_unspecified)
- return BadSpecifier( (TST)TypeSpecType, PrevSpec);
- TypeSpecType = T;
- TypeRep = Rep;
- TSTLoc = Loc;
- return false;
-}
-
-bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
- const LangOptions &Lang) {
- // Duplicates turn into warnings pre-C99.
- if ((TypeQualifiers & T) && !Lang.C99)
- return BadSpecifier(T, PrevSpec);
- TypeQualifiers |= T;
-
- switch (T) {
- default: assert(0 && "Unknown type qualifier!");
- case TQ_const: TQ_constLoc = Loc; break;
- case TQ_restrict: TQ_restrictLoc = Loc; break;
- case TQ_volatile: TQ_volatileLoc = Loc; break;
- }
- return false;
-}
-
-bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec){
- // 'inline inline' is ok.
- FS_inline_specified = true;
- FS_inlineLoc = Loc;
- return false;
-}
-
-
-/// Finish - This does final analysis of the declspec, rejecting things like
-/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
-/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
-/// DeclSpec is guaranteed self-consistent, even if an error occurred.
-void DeclSpec::Finish(Diagnostic &D, SourceManager& SrcMgr,
- const LangOptions &Lang) {
- // Check the type specifier components first.
-
- // signed/unsigned are only valid with int/char/wchar_t.
- if (TypeSpecSign != TSS_unspecified) {
- if (TypeSpecType == TST_unspecified)
- TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
- else if (TypeSpecType != TST_int &&
- TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
- Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec,
- getSpecifierName( (TST)TypeSpecType));
- // signed double -> double.
- TypeSpecSign = TSS_unspecified;
- }
- }
-
- // Validate the width of the type.
- switch (TypeSpecWidth) {
- case TSW_unspecified: break;
- case TSW_short: // short int
- case TSW_longlong: // long long int
- if (TypeSpecType == TST_unspecified)
- TypeSpecType = TST_int; // short -> short int, long long -> long long int.
- else if (TypeSpecType != TST_int) {
- Diag(D, TSWLoc, SrcMgr,
- TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
- : diag::err_invalid_longlong_spec,
- getSpecifierName( (TST)TypeSpecType));
- TypeSpecType = TST_int;
- }
- break;
- case TSW_long: // long double, long int
- if (TypeSpecType == TST_unspecified)
- TypeSpecType = TST_int; // long -> long int.
- else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
- Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec,
- getSpecifierName( (TST)TypeSpecType));
- TypeSpecType = TST_int;
- }
- break;
- }
-
- // TODO: if the implementation does not implement _Complex or _Imaginary,
- // disallow their use. Need information about the backend.
- if (TypeSpecComplex != TSC_unspecified) {
- if (TypeSpecType == TST_unspecified) {
- Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex);
- TypeSpecType = TST_double; // _Complex -> _Complex double.
- } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
- // Note that this intentionally doesn't include _Complex _Bool.
- Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
- } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
- Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec,
- getSpecifierName( (TST)TypeSpecType));
- TypeSpecComplex = TSC_unspecified;
- }
- }
-
- // Verify __thread.
- if (SCS_thread_specified) {
- if (StorageClassSpec == SCS_unspecified) {
- StorageClassSpec = SCS_extern; // '__thread int' -> 'extern __thread int'
- } else if (StorageClassSpec != SCS_extern &&
- StorageClassSpec != SCS_static) {
- Diag(D, getStorageClassSpecLoc(), SrcMgr, diag::err_invalid_thread_spec,
- getSpecifierName( (SCS)StorageClassSpec));
- SCS_thread_specified = false;
- }
- }
-
- // Okay, now we can infer the real type.
-
- // TODO: return "auto function" and other bad things based on the real type.
-
- // 'data definition has no type or storage class'?
-}
-
-void DeclSpec::Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr,
- unsigned DiagID) {
- D.Report(FullSourceLoc(Loc,SrcMgr), DiagID);
-}
-
-void DeclSpec::Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr,
- unsigned DiagID, const std::string &info) {
- D.Report(FullSourceLoc(Loc,SrcMgr), DiagID, &info, 1);
-}
diff --git a/clang/lib/Parse/Makefile b/clang/lib/Parse/Makefile
deleted file mode 100644
index b5d2653bb09a..000000000000
--- a/clang/lib/Parse/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- clang/lib/Parse/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the Parser library for the C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangParse
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Parse/MinimalAction.cpp b/clang/lib/Parse/MinimalAction.cpp
deleted file mode 100644
index cb130c3d268a..000000000000
--- a/clang/lib/Parse/MinimalAction.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-//===--- MinimalAction.cpp - Implement the MinimalAction class ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MinimalAction interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-using namespace clang;
-
-/// TypeNameInfo - A link exists here for each scope that an identifier is
-/// defined.
-struct TypeNameInfo {
- TypeNameInfo *Prev;
- bool isTypeName;
-
- TypeNameInfo(bool istypename, TypeNameInfo *prev) {
- isTypeName = istypename;
- Prev = prev;
- }
-};
-
-void MinimalAction:: ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
- TUScope = S;
- IdentifierInfo *II;
- TypeNameInfo *TI;
-
- // recognize the ObjC built-in type identifiers.
- II = &Idents.get("id");
- TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>());
- II->setFETokenInfo(TI);
- II = &Idents.get("SEL");
- TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>());
- II->setFETokenInfo(TI);
- II = &Idents.get("Class");
- TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>());
- II->setFETokenInfo(TI);
- II = &Idents.get("Protocol");
- TI = new TypeNameInfo(1, II->getFETokenInfo<TypeNameInfo>());
- II->setFETokenInfo(TI);
-}
-
-/// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to
-/// determine whether the name is a type name (objc class name or typedef) or
-/// not in this scope.
-Action::TypeTy *
-MinimalAction::isTypeName(const IdentifierInfo &II, Scope *S) {
- if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>())
- if (TI->isTypeName)
- return TI;
- return 0;
-}
-
-/// ActOnDeclarator - If this is a typedef declarator, we modify the
-/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
-/// popped.
-Action::DeclTy *
-MinimalAction::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) {
- IdentifierInfo *II = D.getIdentifier();
-
- // If there is no identifier associated with this declarator, bail out.
- if (II == 0) return 0;
-
- TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>();
- bool isTypeName =
- D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef;
-
- // this check avoids creating TypeNameInfo objects for the common case.
- // It does need to handle the uncommon case of shadowing a typedef name with a
- // non-typedef name. e.g. { typedef int a; a xx; { int a; } }
- if (weCurrentlyHaveTypeInfo || isTypeName) {
- TypeNameInfo *TI = new TypeNameInfo(isTypeName, weCurrentlyHaveTypeInfo);
-
- II->setFETokenInfo(TI);
-
- // Remember that this needs to be removed when the scope is popped.
- S->AddDecl(II);
- }
- return 0;
-}
-
-Action::DeclTy *
-MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtocols,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
- TypeNameInfo *TI =
- new TypeNameInfo(1, ClassName->getFETokenInfo<TypeNameInfo>());
-
- ClassName->setFETokenInfo(TI);
- return 0;
-}
-
-/// ActOnForwardClassDeclaration -
-/// Scope will always be top level file scope.
-Action::DeclTy *
-MinimalAction::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
- IdentifierInfo **IdentList, unsigned NumElts) {
- for (unsigned i = 0; i != NumElts; ++i) {
- TypeNameInfo *TI =
- new TypeNameInfo(1, IdentList[i]->getFETokenInfo<TypeNameInfo>());
-
- IdentList[i]->setFETokenInfo(TI);
-
- // Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IdentList[i]);
- }
- return 0;
-}
-
-/// ActOnPopScope - When a scope is popped, if any typedefs are now
-/// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
-void MinimalAction::ActOnPopScope(SourceLocation Loc, Scope *S) {
- for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
- IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
- TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>();
- assert(TI && "This decl didn't get pushed??");
-
- if (TI) {
- TypeNameInfo *Next = TI->Prev;
- delete TI;
-
- II.setFETokenInfo(Next);
- }
- }
-}
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
deleted file mode 100644
index ca0003440fe0..000000000000
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements parsing for C++ class inline methods.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-using namespace clang;
-
-/// ParseInlineCXXMethodDef - We parsed and verified that the specified
-/// Declarator is a well formed C++ inline method definition. Now lex its body
-/// and store its tokens for parsing after the C++ class is complete.
-Parser::DeclTy *
-Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "This isn't a function declarator!");
- assert(Tok.is(tok::l_brace) && "Current token not a '{'!");
-
- DeclTy *FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0, 0);
-
- // Consume the tokens and store them for later parsing.
-
- getCurTopClassStack().push(LexedMethod(FnD));
- TokensTy &Toks = getCurTopClassStack().top().Toks;
-
- // Begin by storing the '{' token.
- Toks.push_back(Tok);
- ConsumeBrace();
- ConsumeAndStoreUntil(tok::r_brace, Toks);
-
- return FnD;
-}
-
-/// ParseLexedMethodDefs - We finished parsing the member specification of a top
-/// (non-nested) C++ class. Now go over the stack of lexed methods that were
-/// collected during its parsing and parse them all.
-void Parser::ParseLexedMethodDefs() {
- while (!getCurTopClassStack().empty()) {
- LexedMethod &LM = getCurTopClassStack().top();
-
- assert(!LM.Toks.empty() && "Empty body!");
- // Append the current token at the end of the new token stream so that it
- // doesn't get lost.
- LM.Toks.push_back(Tok);
- PP.EnterTokenStream(&LM.Toks.front(), LM.Toks.size(), true, false);
-
- // Consume the previously pushed token.
- ConsumeAnyToken();
- assert(Tok.is(tok::l_brace) && "Inline method not starting with '{'");
-
- // Parse the method body. Function body parsing code is similar enough
- // to be re-used for method bodies as well.
- EnterScope(Scope::FnScope|Scope::DeclScope);
- Actions.ActOnStartOfFunctionDef(CurScope, LM.D);
-
- ParseFunctionStatementBody(LM.D, Tok.getLocation(), Tok.getLocation());
-
- getCurTopClassStack().pop();
- }
-}
-
-/// ConsumeAndStoreUntil - Consume and store the token at the passed token
-/// container until the token 'T' is reached (which gets consumed/stored too).
-/// Returns true if token 'T' was found.
-/// NOTE: This is a specialized version of Parser::SkipUntil.
-bool Parser::ConsumeAndStoreUntil(tok::TokenKind T, TokensTy &Toks) {
- // We always want this function to consume at least one token if the first
- // token isn't T and if not at EOF.
- bool isFirstTokenConsumed = true;
- while (1) {
- // If we found one of the tokens, stop and return true.
- if (Tok.is(T)) {
- Toks.push_back(Tok);
- ConsumeAnyToken();
- return true;
- }
-
- switch (Tok.getKind()) {
- case tok::eof:
- // Ran out of tokens.
- return false;
-
- case tok::l_paren:
- // Recursively consume properly-nested parens.
- Toks.push_back(Tok);
- ConsumeParen();
- ConsumeAndStoreUntil(tok::r_paren, Toks);
- break;
- case tok::l_square:
- // Recursively consume properly-nested square brackets.
- Toks.push_back(Tok);
- ConsumeBracket();
- ConsumeAndStoreUntil(tok::r_square, Toks);
- break;
- case tok::l_brace:
- // Recursively consume properly-nested braces.
- Toks.push_back(Tok);
- ConsumeBrace();
- ConsumeAndStoreUntil(tok::r_brace, Toks);
- break;
-
- // Okay, we found a ']' or '}' or ')', which we think should be balanced.
- // Since the user wasn't looking for this token (if they were, it would
- // already be handled), this isn't balanced. If there is a LHS token at a
- // higher level, we will assume that this matches the unbalanced token
- // and return it. Otherwise, this is a spurious RHS token, which we skip.
- case tok::r_paren:
- if (ParenCount && !isFirstTokenConsumed)
- return false; // Matches something.
- Toks.push_back(Tok);
- ConsumeParen();
- break;
- case tok::r_square:
- if (BracketCount && !isFirstTokenConsumed)
- return false; // Matches something.
- Toks.push_back(Tok);
- ConsumeBracket();
- break;
- case tok::r_brace:
- if (BraceCount && !isFirstTokenConsumed)
- return false; // Matches something.
- Toks.push_back(Tok);
- ConsumeBrace();
- break;
-
- case tok::string_literal:
- case tok::wide_string_literal:
- Toks.push_back(Tok);
- ConsumeStringToken();
- break;
- default:
- // consume this token.
- Toks.push_back(Tok);
- ConsumeToken();
- break;
- }
- isFirstTokenConsumed = false;
- }
-}
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
deleted file mode 100644
index 7d1a9bb4b653..000000000000
--- a/clang/lib/Parse/ParseDecl.cpp
+++ /dev/null
@@ -1,1650 +0,0 @@
-//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Declaration portions of the Parser interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-#include "llvm/ADT/SmallSet.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// C99 6.7: Declarations.
-//===----------------------------------------------------------------------===//
-
-/// ParseTypeName
-/// type-name: [C99 6.7.6]
-/// specifier-qualifier-list abstract-declarator[opt]
-Parser::TypeTy *Parser::ParseTypeName() {
- // Parse the common declaration-specifiers piece.
- DeclSpec DS;
- ParseSpecifierQualifierList(DS);
-
- // Parse the abstract-declarator, if present.
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
- ParseDeclarator(DeclaratorInfo);
-
- return Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val;
-}
-
-/// ParseAttributes - Parse a non-empty attributes list.
-///
-/// [GNU] attributes:
-/// attribute
-/// attributes attribute
-///
-/// [GNU] attribute:
-/// '__attribute__' '(' '(' attribute-list ')' ')'
-///
-/// [GNU] attribute-list:
-/// attrib
-/// attribute_list ',' attrib
-///
-/// [GNU] attrib:
-/// empty
-/// attrib-name
-/// attrib-name '(' identifier ')'
-/// attrib-name '(' identifier ',' nonempty-expr-list ')'
-/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
-///
-/// [GNU] attrib-name:
-/// identifier
-/// typespec
-/// typequal
-/// storageclass
-///
-/// FIXME: The GCC grammar/code for this construct implies we need two
-/// token lookahead. Comment from gcc: "If they start with an identifier
-/// which is followed by a comma or close parenthesis, then the arguments
-/// start with that identifier; otherwise they are an expression list."
-///
-/// At the moment, I am not doing 2 token lookahead. I am also unaware of
-/// any attributes that don't work (based on my limited testing). Most
-/// attributes are very simple in practice. Until we find a bug, I don't see
-/// a pressing need to implement the 2 token lookahead.
-
-AttributeList *Parser::ParseAttributes() {
- assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
-
- AttributeList *CurrAttr = 0;
-
- while (Tok.is(tok::kw___attribute)) {
- ConsumeToken();
- if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
- "attribute")) {
- SkipUntil(tok::r_paren, true); // skip until ) or ;
- return CurrAttr;
- }
- if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
- SkipUntil(tok::r_paren, true); // skip until ) or ;
- return CurrAttr;
- }
- // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
- while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
- Tok.is(tok::comma)) {
-
- if (Tok.is(tok::comma)) {
- // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
- ConsumeToken();
- continue;
- }
- // we have an identifier or declaration specifier (const, int, etc.)
- IdentifierInfo *AttrName = Tok.getIdentifierInfo();
- SourceLocation AttrNameLoc = ConsumeToken();
-
- // check if we have a "paramterized" attribute
- if (Tok.is(tok::l_paren)) {
- ConsumeParen(); // ignore the left paren loc for now
-
- if (Tok.is(tok::identifier)) {
- IdentifierInfo *ParmName = Tok.getIdentifierInfo();
- SourceLocation ParmLoc = ConsumeToken();
-
- if (Tok.is(tok::r_paren)) {
- // __attribute__(( mode(byte) ))
- ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
- ParmName, ParmLoc, 0, 0, CurrAttr);
- } else if (Tok.is(tok::comma)) {
- ConsumeToken();
- // __attribute__(( format(printf, 1, 2) ))
- llvm::SmallVector<ExprTy*, 8> ArgExprs;
- bool ArgExprsOk = true;
-
- // now parse the non-empty comma separated list of expressions
- while (1) {
- ExprResult ArgExpr = ParseAssignmentExpression();
- if (ArgExpr.isInvalid) {
- ArgExprsOk = false;
- SkipUntil(tok::r_paren);
- break;
- } else {
- ArgExprs.push_back(ArgExpr.Val);
- }
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken(); // Eat the comma, move to the next argument
- }
- if (ArgExprsOk && Tok.is(tok::r_paren)) {
- ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, ParmName,
- ParmLoc, &ArgExprs[0], ArgExprs.size(), CurrAttr);
- }
- }
- } else { // not an identifier
- // parse a possibly empty comma separated list of expressions
- if (Tok.is(tok::r_paren)) {
- // __attribute__(( nonnull() ))
- ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
- } else {
- // __attribute__(( aligned(16) ))
- llvm::SmallVector<ExprTy*, 8> ArgExprs;
- bool ArgExprsOk = true;
-
- // now parse the list of expressions
- while (1) {
- ExprResult ArgExpr = ParseAssignmentExpression();
- if (ArgExpr.isInvalid) {
- ArgExprsOk = false;
- SkipUntil(tok::r_paren);
- break;
- } else {
- ArgExprs.push_back(ArgExpr.Val);
- }
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken(); // Eat the comma, move to the next argument
- }
- // Match the ')'.
- if (ArgExprsOk && Tok.is(tok::r_paren)) {
- ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
- SourceLocation(), &ArgExprs[0], ArgExprs.size(),
- CurrAttr);
- }
- }
- }
- } else {
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
- }
- }
- if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
- SkipUntil(tok::r_paren, false);
- if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
- SkipUntil(tok::r_paren, false);
- }
- return CurrAttr;
-}
-
-/// ParseDeclaration - Parse a full 'declaration', which consists of
-/// declaration-specifiers, some number of declarators, and a semicolon.
-/// 'Context' should be a Declarator::TheContext value.
-///
-/// declaration: [C99 6.7]
-/// block-declaration ->
-/// simple-declaration
-/// others [FIXME]
-/// [C++] namespace-definition
-/// others... [FIXME]
-///
-Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
- switch (Tok.getKind()) {
- case tok::kw_namespace:
- return ParseNamespace(Context);
- default:
- return ParseSimpleDeclaration(Context);
- }
-}
-
-/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
-/// declaration-specifiers init-declarator-list[opt] ';'
-///[C90/C++]init-declarator-list ';' [TODO]
-/// [OMP] threadprivate-directive [TODO]
-Parser::DeclTy *Parser::ParseSimpleDeclaration(unsigned Context) {
- // Parse the common declaration-specifiers piece.
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
-
- // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
- // declaration-specifiers init-declarator-list[opt] ';'
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
- }
-
- Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
- ParseDeclarator(DeclaratorInfo);
-
- return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
-}
-
-
-/// ParseInitDeclaratorListAfterFirstDeclarator - Parse 'declaration' after
-/// parsing 'declaration-specifiers declarator'. This method is split out this
-/// way to handle the ambiguity between top-level function-definitions and
-/// declarations.
-///
-/// init-declarator-list: [C99 6.7]
-/// init-declarator
-/// init-declarator-list ',' init-declarator
-/// init-declarator: [C99 6.7]
-/// declarator
-/// declarator '=' initializer
-/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
-/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
-/// [C++] declarator initializer[opt]
-///
-/// [C++] initializer:
-/// [C++] '=' initializer-clause
-/// [C++] '(' expression-list ')'
-///
-Parser::DeclTy *Parser::
-ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
-
- // Declarators may be grouped together ("int X, *Y, Z();"). Provide info so
- // that they can be chained properly if the actions want this.
- Parser::DeclTy *LastDeclInGroup = 0;
-
- // At this point, we know that it is not a function definition. Parse the
- // rest of the init-declarator-list.
- while (1) {
- // If a simple-asm-expr is present, parse it.
- if (Tok.is(tok::kw_asm)) {
- ExprResult AsmLabel = ParseSimpleAsm();
- if (AsmLabel.isInvalid) {
- SkipUntil(tok::semi);
- return 0;
- }
-
- D.setAsmLabel(AsmLabel.Val);
- }
-
- // If attributes are present, parse them.
- if (Tok.is(tok::kw___attribute))
- D.AddAttributes(ParseAttributes());
-
- // Inform the current actions module that we just parsed this declarator.
- // FIXME: pass asm & attributes.
- LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
-
- // Parse declarator '=' initializer.
- if (Tok.is(tok::equal)) {
- ConsumeToken();
- ExprResult Init = ParseInitializer();
- if (Init.isInvalid) {
- SkipUntil(tok::semi);
- return 0;
- }
- Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
- } else if (Tok.is(tok::l_paren)) {
- // Parse C++ direct initializer: '(' expression-list ')'
- SourceLocation LParenLoc = ConsumeParen();
- ExprListTy Exprs;
- CommaLocsTy CommaLocs;
-
- bool InvalidExpr = false;
- if (ParseExpressionList(Exprs, CommaLocs)) {
- SkipUntil(tok::r_paren);
- InvalidExpr = true;
- }
- // Match the ')'.
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-
- if (!InvalidExpr) {
- assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
- "Unexpected number of commas!");
- Actions.AddCXXDirectInitializerToDecl(LastDeclInGroup, LParenLoc,
- &Exprs[0], Exprs.size(),
- &CommaLocs[0], RParenLoc);
- }
- }
-
- // If we don't have a comma, it is either the end of the list (a ';') or an
- // error, bail out.
- if (Tok.isNot(tok::comma))
- break;
-
- // Consume the comma.
- ConsumeToken();
-
- // Parse the next declarator.
- D.clear();
- ParseDeclarator(D);
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
- }
- // If this is an ObjC2 for-each loop, this is a successful declarator
- // parse. The syntax for these looks like:
- // 'for' '(' declaration 'in' expr ')' statement
- if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) {
- return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
- }
- Diag(Tok, diag::err_parse_error);
- // Skip to end of block or statement
- SkipUntil(tok::r_brace, true, true);
- if (Tok.is(tok::semi))
- ConsumeToken();
- return 0;
-}
-
-/// ParseSpecifierQualifierList
-/// specifier-qualifier-list:
-/// type-specifier specifier-qualifier-list[opt]
-/// type-qualifier specifier-qualifier-list[opt]
-/// [GNU] attributes specifier-qualifier-list[opt]
-///
-void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
- /// specifier-qualifier-list is a subset of declaration-specifiers. Just
- /// parse declaration-specifiers and complain about extra stuff.
- ParseDeclarationSpecifiers(DS);
-
- // Validate declspec for type-name.
- unsigned Specs = DS.getParsedSpecifiers();
- if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers())
- Diag(Tok, diag::err_typename_requires_specqual);
-
- // Issue diagnostic and remove storage class if present.
- if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
- if (DS.getStorageClassSpecLoc().isValid())
- Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
- else
- Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
- DS.ClearStorageClassSpecs();
- }
-
- // Issue diagnostic and remove function specfier if present.
- if (Specs & DeclSpec::PQ_FunctionSpecifier) {
- Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
- DS.ClearFunctionSpecs();
- }
-}
-
-/// ParseDeclarationSpecifiers
-/// declaration-specifiers: [C99 6.7]
-/// storage-class-specifier declaration-specifiers[opt]
-/// type-specifier declaration-specifiers[opt]
-/// type-qualifier declaration-specifiers[opt]
-/// [C99] function-specifier declaration-specifiers[opt]
-/// [GNU] attributes declaration-specifiers[opt]
-///
-/// storage-class-specifier: [C99 6.7.1]
-/// 'typedef'
-/// 'extern'
-/// 'static'
-/// 'auto'
-/// 'register'
-/// [GNU] '__thread'
-/// type-specifier: [C99 6.7.2]
-/// 'void'
-/// 'char'
-/// 'short'
-/// 'int'
-/// 'long'
-/// 'float'
-/// 'double'
-/// 'signed'
-/// 'unsigned'
-/// struct-or-union-specifier
-/// enum-specifier
-/// typedef-name
-/// [C++] 'wchar_t'
-/// [C++] 'bool'
-/// [C99] '_Bool'
-/// [C99] '_Complex'
-/// [C99] '_Imaginary' // Removed in TC2?
-/// [GNU] '_Decimal32'
-/// [GNU] '_Decimal64'
-/// [GNU] '_Decimal128'
-/// [GNU] typeof-specifier
-/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
-/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
-/// type-qualifier:
-/// 'const'
-/// 'volatile'
-/// [C99] 'restrict'
-/// function-specifier: [C99 6.7.4]
-/// [C99] 'inline'
-///
-void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
- DS.SetRangeStart(Tok.getLocation());
- while (1) {
- int isInvalid = false;
- const char *PrevSpec = 0;
- SourceLocation Loc = Tok.getLocation();
-
- switch (Tok.getKind()) {
- default:
- DoneWithDeclSpec:
- // If this is not a declaration specifier token, we're done reading decl
- // specifiers. First verify that DeclSpec's are consistent.
- DS.Finish(Diags, PP.getSourceManager(), getLang());
- return;
-
- // typedef-name
- case tok::identifier: {
- // This identifier can only be a typedef name if we haven't already seen
- // a type-specifier. Without this check we misparse:
- // typedef int X; struct Y { short X; }; as 'short int'.
- if (DS.hasTypeSpecifier())
- goto DoneWithDeclSpec;
-
- // It has to be available as a typedef too!
- TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
- if (TypeRep == 0)
- goto DoneWithDeclSpec;
-
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
- TypeRep);
- if (isInvalid)
- break;
-
- DS.SetRangeEnd(Tok.getLocation());
- ConsumeToken(); // The identifier
-
- // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
- // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
- // Objective-C interface. If we don't have Objective-C or a '<', this is
- // just a normal reference to a typedef name.
- if (!Tok.is(tok::less) || !getLang().ObjC1)
- continue;
-
- SourceLocation EndProtoLoc;
- llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
- ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
-
- DS.SetRangeEnd(EndProtoLoc);
-
- // Need to support trailing type qualifiers (e.g. "id<p> const").
- // If a type specifier follows, it will be diagnosed elsewhere.
- continue;
- }
- // GNU attributes support.
- case tok::kw___attribute:
- DS.AddAttributes(ParseAttributes());
- continue;
-
- // storage-class-specifier
- case tok::kw_typedef:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
- break;
- case tok::kw_extern:
- if (DS.isThreadSpecified())
- Diag(Tok, diag::ext_thread_before, "extern");
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
- break;
- case tok::kw___private_extern__:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
- PrevSpec);
- break;
- case tok::kw_static:
- if (DS.isThreadSpecified())
- Diag(Tok, diag::ext_thread_before, "static");
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
- break;
- case tok::kw_auto:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
- break;
- case tok::kw_register:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
- break;
- case tok::kw___thread:
- isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
- break;
-
- // type-specifiers
- case tok::kw_short:
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
- break;
- case tok::kw_long:
- if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
- else
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
- break;
- case tok::kw_signed:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
- break;
- case tok::kw_unsigned:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
- break;
- case tok::kw__Complex:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
- break;
- case tok::kw__Imaginary:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
- break;
- case tok::kw_void:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
- break;
- case tok::kw_char:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
- break;
- case tok::kw_int:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
- break;
- case tok::kw_float:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
- break;
- case tok::kw_double:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
- break;
- case tok::kw_wchar_t: // [C++ 2.11p1]
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
- break;
- case tok::kw_bool: // [C++ 2.11p1]
- case tok::kw__Bool:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
- break;
- case tok::kw__Decimal32:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
- break;
- case tok::kw__Decimal64:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
- break;
- case tok::kw__Decimal128:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
- break;
-
- case tok::kw_class:
- case tok::kw_struct:
- case tok::kw_union:
- ParseClassSpecifier(DS);
- continue;
- case tok::kw_enum:
- ParseEnumSpecifier(DS);
- continue;
-
- // GNU typeof support.
- case tok::kw_typeof:
- ParseTypeofSpecifier(DS);
- continue;
-
- // type-qualifier
- case tok::kw_const:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
- getLang())*2;
- break;
- case tok::kw_volatile:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
- getLang())*2;
- break;
- case tok::kw_restrict:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
- getLang())*2;
- break;
-
- // function-specifier
- case tok::kw_inline:
- isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec);
- break;
-
- case tok::less:
- // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
- // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
- // but we support it.
- if (DS.hasTypeSpecifier() || !getLang().ObjC1)
- goto DoneWithDeclSpec;
-
- {
- SourceLocation EndProtoLoc;
- llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
- ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
- DS.SetRangeEnd(EndProtoLoc);
-
- Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id,
- SourceRange(Loc, EndProtoLoc));
- // Need to support trailing type qualifiers (e.g. "id<p> const").
- // If a type specifier follows, it will be diagnosed elsewhere.
- continue;
- }
- }
- // If the specifier combination wasn't legal, issue a diagnostic.
- if (isInvalid) {
- assert(PrevSpec && "Method did not return previous specifier!");
- if (isInvalid == 1) // Error.
- Diag(Tok, diag::err_invalid_decl_spec_combination, PrevSpec);
- else // extwarn.
- Diag(Tok, diag::ext_duplicate_declspec, PrevSpec);
- }
- DS.SetRangeEnd(Tok.getLocation());
- ConsumeToken();
- }
-}
-
-/// ParseStructDeclaration - Parse a struct declaration without the terminating
-/// semicolon.
-///
-/// struct-declaration:
-/// specifier-qualifier-list struct-declarator-list
-/// [GNU] __extension__ struct-declaration
-/// [GNU] specifier-qualifier-list
-/// struct-declarator-list:
-/// struct-declarator
-/// struct-declarator-list ',' struct-declarator
-/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
-/// struct-declarator:
-/// declarator
-/// [GNU] declarator attributes[opt]
-/// declarator[opt] ':' constant-expression
-/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
-///
-void Parser::
-ParseStructDeclaration(DeclSpec &DS,
- llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
- // FIXME: When __extension__ is specified, disable extension diagnostics.
- while (Tok.is(tok::kw___extension__))
- ConsumeToken();
-
- // Parse the common specifier-qualifiers-list piece.
- SourceLocation DSStart = Tok.getLocation();
- ParseSpecifierQualifierList(DS);
- // TODO: Does specifier-qualifier list correctly check that *something* is
- // specified?
-
- // If there are no declarators, issue a warning.
- if (Tok.is(tok::semi)) {
- Diag(DSStart, diag::w_no_declarators);
- return;
- }
-
- // Read struct-declarators until we find the semicolon.
- Fields.push_back(FieldDeclarator(DS));
- while (1) {
- FieldDeclarator &DeclaratorInfo = Fields.back();
-
- /// struct-declarator: declarator
- /// struct-declarator: declarator[opt] ':' constant-expression
- if (Tok.isNot(tok::colon))
- ParseDeclarator(DeclaratorInfo.D);
-
- if (Tok.is(tok::colon)) {
- ConsumeToken();
- ExprResult Res = ParseConstantExpression();
- if (Res.isInvalid)
- SkipUntil(tok::semi, true, true);
- else
- DeclaratorInfo.BitfieldSize = Res.Val;
- }
-
- // If attributes exist after the declarator, parse them.
- if (Tok.is(tok::kw___attribute))
- DeclaratorInfo.D.AddAttributes(ParseAttributes());
-
- // If we don't have a comma, it is either the end of the list (a ';')
- // or an error, bail out.
- if (Tok.isNot(tok::comma))
- return;
-
- // Consume the comma.
- ConsumeToken();
-
- // Parse the next declarator.
- Fields.push_back(FieldDeclarator(DS));
-
- // Attributes are only allowed on the second declarator.
- if (Tok.is(tok::kw___attribute))
- Fields.back().D.AddAttributes(ParseAttributes());
- }
-}
-
-/// ParseStructUnionBody
-/// struct-contents:
-/// struct-declaration-list
-/// [EXT] empty
-/// [GNU] "struct-declaration-list" without terminatoring ';'
-/// struct-declaration-list:
-/// struct-declaration
-/// struct-declaration-list struct-declaration
-/// [OBC] '@' 'defs' '(' class-name ')'
-///
-void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
- unsigned TagType, DeclTy *TagDecl) {
- SourceLocation LBraceLoc = ConsumeBrace();
-
- // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
- // C++.
- if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
- Diag(Tok, diag::ext_empty_struct_union_enum,
- DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
-
- llvm::SmallVector<DeclTy*, 32> FieldDecls;
- llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
-
- // While we still have something to read, read the declarations in the struct.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- // Each iteration of this loop reads one struct-declaration.
-
- // Check for extraneous top-level semicolon.
- if (Tok.is(tok::semi)) {
- Diag(Tok, diag::ext_extra_struct_semi);
- ConsumeToken();
- continue;
- }
-
- // Parse all the comma separated declarators.
- DeclSpec DS;
- FieldDeclarators.clear();
- if (!Tok.is(tok::at)) {
- ParseStructDeclaration(DS, FieldDeclarators);
-
- // Convert them all to fields.
- for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
- FieldDeclarator &FD = FieldDeclarators[i];
- // Install the declarator into the current TagDecl.
- DeclTy *Field = Actions.ActOnField(CurScope,
- DS.getSourceRange().getBegin(),
- FD.D, FD.BitfieldSize);
- FieldDecls.push_back(Field);
- }
- } else { // Handle @defs
- ConsumeToken();
- if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
- Diag(Tok, diag::err_unexpected_at);
- SkipUntil(tok::semi, true, true);
- continue;
- }
- ConsumeToken();
- ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
- if (!Tok.is(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::semi, true, true);
- continue;
- }
- llvm::SmallVector<DeclTy*, 16> Fields;
- Actions.ActOnDefs(CurScope, Tok.getLocation(), Tok.getIdentifierInfo(),
- Fields);
- FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
- ConsumeToken();
- ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- } else if (Tok.is(tok::r_brace)) {
- Diag(Tok.getLocation(), diag::ext_expected_semi_decl_list);
- break;
- } else {
- Diag(Tok, diag::err_expected_semi_decl_list);
- // Skip to end of block or statement
- SkipUntil(tok::r_brace, true, true);
- }
- }
-
- SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
-
- AttributeList *AttrList = 0;
- // If attributes exist after struct contents, parse them.
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseAttributes();
-
- Actions.ActOnFields(CurScope,
- RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size(),
- LBraceLoc, RBraceLoc,
- AttrList);
-}
-
-
-/// ParseEnumSpecifier
-/// enum-specifier: [C99 6.7.2.2]
-/// 'enum' identifier[opt] '{' enumerator-list '}'
-/// [C99] 'enum' identifier[opt] '{' enumerator-list ',' '}'
-/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
-/// '}' attributes[opt]
-/// 'enum' identifier
-/// [GNU] 'enum' attributes[opt] identifier
-void Parser::ParseEnumSpecifier(DeclSpec &DS) {
- assert(Tok.is(tok::kw_enum) && "Not an enum specifier");
- SourceLocation StartLoc = ConsumeToken();
-
- // Parse the tag portion of this.
-
- AttributeList *Attr = 0;
- // If attributes exist after tag, parse them.
- if (Tok.is(tok::kw___attribute))
- Attr = ParseAttributes();
-
- // Must have either 'enum name' or 'enum {...}'.
- if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
- Diag(Tok, diag::err_expected_ident_lbrace);
-
- // Skip the rest of this declarator, up until the comma or semicolon.
- SkipUntil(tok::comma, true);
- return;
- }
-
- // If an identifier is present, consume and remember it.
- IdentifierInfo *Name = 0;
- SourceLocation NameLoc;
- if (Tok.is(tok::identifier)) {
- Name = Tok.getIdentifierInfo();
- NameLoc = ConsumeToken();
- }
-
- // There are three options here. If we have 'enum foo;', then this is a
- // forward declaration. If we have 'enum foo {...' then this is a
- // definition. Otherwise we have something like 'enum foo xyz', a reference.
- //
- // This is needed to handle stuff like this right (C99 6.7.2.3p11):
- // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
- // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
- //
- Action::TagKind TK;
- if (Tok.is(tok::l_brace))
- TK = Action::TK_Definition;
- else if (Tok.is(tok::semi))
- TK = Action::TK_Declaration;
- else
- TK = Action::TK_Reference;
- DeclTy *TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK, StartLoc,
- Name, NameLoc, Attr);
-
- if (Tok.is(tok::l_brace))
- ParseEnumBody(StartLoc, TagDecl);
-
- // TODO: semantic analysis on the declspec for enums.
- const char *PrevSpec = 0;
- if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, TagDecl))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
-}
-
-/// ParseEnumBody - Parse a {} enclosed enumerator-list.
-/// enumerator-list:
-/// enumerator
-/// enumerator-list ',' enumerator
-/// enumerator:
-/// enumeration-constant
-/// enumeration-constant '=' constant-expression
-/// enumeration-constant:
-/// identifier
-///
-void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
- SourceLocation LBraceLoc = ConsumeBrace();
-
- // C does not allow an empty enumerator-list, C++ does [dcl.enum].
- if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
- Diag(Tok, diag::ext_empty_struct_union_enum, "enum");
-
- llvm::SmallVector<DeclTy*, 32> EnumConstantDecls;
-
- DeclTy *LastEnumConstDecl = 0;
-
- // Parse the enumerator-list.
- while (Tok.is(tok::identifier)) {
- IdentifierInfo *Ident = Tok.getIdentifierInfo();
- SourceLocation IdentLoc = ConsumeToken();
-
- SourceLocation EqualLoc;
- ExprTy *AssignedVal = 0;
- if (Tok.is(tok::equal)) {
- EqualLoc = ConsumeToken();
- ExprResult Res = ParseConstantExpression();
- if (Res.isInvalid)
- SkipUntil(tok::comma, tok::r_brace, true, true);
- else
- AssignedVal = Res.Val;
- }
-
- // Install the enumerator constant into EnumDecl.
- DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
- LastEnumConstDecl,
- IdentLoc, Ident,
- EqualLoc, AssignedVal);
- EnumConstantDecls.push_back(EnumConstDecl);
- LastEnumConstDecl = EnumConstDecl;
-
- if (Tok.isNot(tok::comma))
- break;
- SourceLocation CommaLoc = ConsumeToken();
-
- if (Tok.isNot(tok::identifier) && !getLang().C99)
- Diag(CommaLoc, diag::ext_c99_enumerator_list_comma);
- }
-
- // Eat the }.
- MatchRHSPunctuation(tok::r_brace, LBraceLoc);
-
- Actions.ActOnEnumBody(StartLoc, EnumDecl, &EnumConstantDecls[0],
- EnumConstantDecls.size());
-
- DeclTy *AttrList = 0;
- // If attributes exist after the identifier list, parse them.
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseAttributes(); // FIXME: where do they do?
-}
-
-/// isTypeSpecifierQualifier - Return true if the current token could be the
-/// start of a type-qualifier-list.
-bool Parser::isTypeQualifier() const {
- switch (Tok.getKind()) {
- default: return false;
- // type-qualifier
- case tok::kw_const:
- case tok::kw_volatile:
- case tok::kw_restrict:
- return true;
- }
-}
-
-/// isTypeSpecifierQualifier - Return true if the current token could be the
-/// start of a specifier-qualifier-list.
-bool Parser::isTypeSpecifierQualifier() const {
- switch (Tok.getKind()) {
- default: return false;
- // GNU attributes support.
- case tok::kw___attribute:
- // GNU typeof support.
- case tok::kw_typeof:
- // GNU bizarre protocol extension. FIXME: make an extension?
- case tok::less:
-
- // type-specifiers
- case tok::kw_short:
- case tok::kw_long:
- case tok::kw_signed:
- case tok::kw_unsigned:
- case tok::kw__Complex:
- case tok::kw__Imaginary:
- case tok::kw_void:
- case tok::kw_char:
- case tok::kw_wchar_t:
- case tok::kw_int:
- case tok::kw_float:
- case tok::kw_double:
- case tok::kw_bool:
- case tok::kw__Bool:
- case tok::kw__Decimal32:
- case tok::kw__Decimal64:
- case tok::kw__Decimal128:
-
- // struct-or-union-specifier (C99) or class-specifier (C++)
- case tok::kw_class:
- case tok::kw_struct:
- case tok::kw_union:
- // enum-specifier
- case tok::kw_enum:
-
- // type-qualifier
- case tok::kw_const:
- case tok::kw_volatile:
- case tok::kw_restrict:
- return true;
-
- // typedef-name
- case tok::identifier:
- return Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope) != 0;
- }
-}
-
-/// isDeclarationSpecifier() - Return true if the current token is part of a
-/// declaration specifier.
-bool Parser::isDeclarationSpecifier() const {
- switch (Tok.getKind()) {
- default: return false;
- // storage-class-specifier
- case tok::kw_typedef:
- case tok::kw_extern:
- case tok::kw___private_extern__:
- case tok::kw_static:
- case tok::kw_auto:
- case tok::kw_register:
- case tok::kw___thread:
-
- // type-specifiers
- case tok::kw_short:
- case tok::kw_long:
- case tok::kw_signed:
- case tok::kw_unsigned:
- case tok::kw__Complex:
- case tok::kw__Imaginary:
- case tok::kw_void:
- case tok::kw_char:
- case tok::kw_wchar_t:
- case tok::kw_int:
- case tok::kw_float:
- case tok::kw_double:
- case tok::kw_bool:
- case tok::kw__Bool:
- case tok::kw__Decimal32:
- case tok::kw__Decimal64:
- case tok::kw__Decimal128:
-
- // struct-or-union-specifier (C99) or class-specifier (C++)
- case tok::kw_class:
- case tok::kw_struct:
- case tok::kw_union:
- // enum-specifier
- case tok::kw_enum:
-
- // type-qualifier
- case tok::kw_const:
- case tok::kw_volatile:
- case tok::kw_restrict:
-
- // function-specifier
- case tok::kw_inline:
-
- // GNU typeof support.
- case tok::kw_typeof:
-
- // GNU attributes.
- case tok::kw___attribute:
- return true;
-
- // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
- case tok::less:
- return getLang().ObjC1;
-
- // typedef-name
- case tok::identifier:
- return Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope) != 0;
- }
-}
-
-
-/// ParseTypeQualifierListOpt
-/// type-qualifier-list: [C99 6.7.5]
-/// type-qualifier
-/// [GNU] attributes
-/// type-qualifier-list type-qualifier
-/// [GNU] type-qualifier-list attributes
-///
-void Parser::ParseTypeQualifierListOpt(DeclSpec &DS) {
- while (1) {
- int isInvalid = false;
- const char *PrevSpec = 0;
- SourceLocation Loc = Tok.getLocation();
-
- switch (Tok.getKind()) {
- default:
- // If this is not a type-qualifier token, we're done reading type
- // qualifiers. First verify that DeclSpec's are consistent.
- DS.Finish(Diags, PP.getSourceManager(), getLang());
- return;
- case tok::kw_const:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
- getLang())*2;
- break;
- case tok::kw_volatile:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
- getLang())*2;
- break;
- case tok::kw_restrict:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
- getLang())*2;
- break;
- case tok::kw___attribute:
- DS.AddAttributes(ParseAttributes());
- continue; // do *not* consume the next token!
- }
-
- // If the specifier combination wasn't legal, issue a diagnostic.
- if (isInvalid) {
- assert(PrevSpec && "Method did not return previous specifier!");
- if (isInvalid == 1) // Error.
- Diag(Tok, diag::err_invalid_decl_spec_combination, PrevSpec);
- else // extwarn.
- Diag(Tok, diag::ext_duplicate_declspec, PrevSpec);
- }
- ConsumeToken();
- }
-}
-
-
-/// ParseDeclarator - Parse and verify a newly-initialized declarator.
-///
-void Parser::ParseDeclarator(Declarator &D) {
- /// This implements the 'declarator' production in the C grammar, then checks
- /// for well-formedness and issues diagnostics.
- ParseDeclaratorInternal(D);
-}
-
-/// ParseDeclaratorInternal
-/// declarator: [C99 6.7.5]
-/// pointer[opt] direct-declarator
-/// [C++] '&' declarator [C++ 8p4, dcl.decl]
-/// [GNU] '&' restrict[opt] attributes[opt] declarator
-///
-/// pointer: [C99 6.7.5]
-/// '*' type-qualifier-list[opt]
-/// '*' type-qualifier-list[opt] pointer
-///
-void Parser::ParseDeclaratorInternal(Declarator &D) {
- tok::TokenKind Kind = Tok.getKind();
-
- // Not a pointer, C++ reference, or block.
- if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus) &&
- (Kind != tok::caret || !getLang().Blocks))
- return ParseDirectDeclarator(D);
-
- // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference.
- SourceLocation Loc = ConsumeToken(); // Eat the * or &.
-
- if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
- // Is a pointer.
- DeclSpec DS;
-
- ParseTypeQualifierListOpt(DS);
-
- // Recursively parse the declarator.
- ParseDeclaratorInternal(D);
- if (Kind == tok::star)
- // Remember that we parsed a pointer type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
- DS.TakeAttributes()));
- else
- // Remember that we parsed a Block type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
- Loc));
- } else {
- // Is a reference
- DeclSpec DS;
-
- // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
- // cv-qualifiers are introduced through the use of a typedef or of a
- // template type argument, in which case the cv-qualifiers are ignored.
- //
- // [GNU] Retricted references are allowed.
- // [GNU] Attributes on references are allowed.
- ParseTypeQualifierListOpt(DS);
-
- if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
- if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
- Diag(DS.getConstSpecLoc(),
- diag::err_invalid_reference_qualifier_application,
- "const");
- if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
- Diag(DS.getVolatileSpecLoc(),
- diag::err_invalid_reference_qualifier_application,
- "volatile");
- }
-
- // Recursively parse the declarator.
- ParseDeclaratorInternal(D);
-
- // Remember that we parsed a reference type. It doesn't have type-quals.
- D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
- DS.TakeAttributes()));
- }
-}
-
-/// ParseDirectDeclarator
-/// direct-declarator: [C99 6.7.5]
-/// identifier
-/// '(' declarator ')'
-/// [GNU] '(' attributes declarator ')'
-/// [C90] direct-declarator '[' constant-expression[opt] ']'
-/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
-/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
-/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
-/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
-/// direct-declarator '(' parameter-type-list ')'
-/// direct-declarator '(' identifier-list[opt] ')'
-/// [GNU] direct-declarator '(' parameter-forward-declarations
-/// parameter-type-list[opt] ')'
-///
-void Parser::ParseDirectDeclarator(Declarator &D) {
- // Parse the first direct-declarator seen.
- if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
- assert(Tok.getIdentifierInfo() && "Not an identifier?");
- D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
- ConsumeToken();
- } else if (Tok.is(tok::l_paren)) {
- // direct-declarator: '(' declarator ')'
- // direct-declarator: '(' attributes declarator ')'
- // Example: 'char (*X)' or 'int (*XX)(void)'
- ParseParenDeclarator(D);
- } else if (D.mayOmitIdentifier()) {
- // This could be something simple like "int" (in which case the declarator
- // portion is empty), if an abstract-declarator is allowed.
- D.SetIdentifier(0, Tok.getLocation());
- } else {
- // Expected identifier or '('.
- Diag(Tok, diag::err_expected_ident_lparen);
- D.SetIdentifier(0, Tok.getLocation());
- }
-
- assert(D.isPastIdentifier() &&
- "Haven't past the location of the identifier yet?");
-
- while (1) {
- if (Tok.is(tok::l_paren)) {
- // The paren may be part of a C++ direct initializer, eg. "int x(1);".
- // In such a case, check if we actually have a function declarator; if it
- // is not, the declarator has been fully parsed.
- if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit() &&
- !isCXXFunctionDeclarator())
- break;
- ParseFunctionDeclarator(ConsumeParen(), D);
- } else if (Tok.is(tok::l_square)) {
- ParseBracketDeclarator(D);
- } else {
- break;
- }
- }
-}
-
-/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
-/// only called before the identifier, so these are most likely just grouping
-/// parens for precedence. If we find that these are actually function
-/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
-///
-/// direct-declarator:
-/// '(' declarator ')'
-/// [GNU] '(' attributes declarator ')'
-///
-void Parser::ParseParenDeclarator(Declarator &D) {
- SourceLocation StartLoc = ConsumeParen();
- assert(!D.isPastIdentifier() && "Should be called before passing identifier");
-
- // If we haven't past the identifier yet (or where the identifier would be
- // stored, if this is an abstract declarator), then this is probably just
- // grouping parens. However, if this could be an abstract-declarator, then
- // this could also be the start of function arguments (consider 'void()').
- bool isGrouping;
-
- if (!D.mayOmitIdentifier()) {
- // If this can't be an abstract-declarator, this *must* be a grouping
- // paren, because we haven't seen the identifier yet.
- isGrouping = true;
- } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
- (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
- isDeclarationSpecifier()) { // 'int(int)' is a function.
- // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
- // considered to be a type, not a K&R identifier-list.
- isGrouping = false;
- } else {
- // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
- isGrouping = true;
- }
-
- // If this is a grouping paren, handle:
- // direct-declarator: '(' declarator ')'
- // direct-declarator: '(' attributes declarator ')'
- if (isGrouping) {
- D.setGroupingParens(true);
-
- if (Tok.is(tok::kw___attribute))
- D.AddAttributes(ParseAttributes());
-
- ParseDeclaratorInternal(D);
- // Match the ')'.
- MatchRHSPunctuation(tok::r_paren, StartLoc);
- return;
- }
-
- // Okay, if this wasn't a grouping paren, it must be the start of a function
- // argument list. Recognize that this declarator will never have an
- // identifier (and remember where it would have been), then fall through to
- // the handling of argument lists.
- D.SetIdentifier(0, Tok.getLocation());
-
- ParseFunctionDeclarator(StartLoc, D);
-}
-
-/// ParseFunctionDeclarator - We are after the identifier and have parsed the
-/// declarator D up to a paren, which indicates that we are parsing function
-/// arguments.
-///
-/// This method also handles this portion of the grammar:
-/// parameter-type-list: [C99 6.7.5]
-/// parameter-list
-/// parameter-list ',' '...'
-///
-/// parameter-list: [C99 6.7.5]
-/// parameter-declaration
-/// parameter-list ',' parameter-declaration
-///
-/// parameter-declaration: [C99 6.7.5]
-/// declaration-specifiers declarator
-/// [C++] declaration-specifiers declarator '=' assignment-expression
-/// [GNU] declaration-specifiers declarator attributes
-/// declaration-specifiers abstract-declarator[opt]
-/// [C++] declaration-specifiers abstract-declarator[opt]
-/// '=' assignment-expression
-/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
-///
-void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D) {
- // lparen is already consumed!
- assert(D.isPastIdentifier() && "Should not call before identifier!");
-
- // Okay, this is the parameter list of a function definition, or it is an
- // identifier list of a K&R-style function.
-
- if (Tok.is(tok::r_paren)) {
- // Remember that we parsed a function type, and remember the attributes.
- // int() -> no prototype, no '...'.
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/ false,
- /*variadic*/ false,
- /*arglist*/ 0, 0, LParenLoc));
-
- ConsumeParen(); // Eat the closing ')'.
- return;
- } else if (Tok.is(tok::identifier) &&
- // K&R identifier lists can't have typedefs as identifiers, per
- // C99 6.7.5.3p11.
- !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
- // Identifier list. Note that '(' identifier-list ')' is only allowed for
- // normal declarators, not for abstract-declarators.
- return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
- }
-
- // Finally, a normal, non-empty parameter type list.
-
- // Build up an array of information about the parsed arguments.
- llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
-
- // Enter function-declaration scope, limiting any declarators to the
- // function prototype scope, including parameter declarators.
- EnterScope(Scope::FnScope|Scope::DeclScope);
-
- bool IsVariadic = false;
- while (1) {
- if (Tok.is(tok::ellipsis)) {
- IsVariadic = true;
-
- // Check to see if this is "void(...)" which is not allowed.
- if (!getLang().CPlusPlus && ParamInfo.empty()) {
- // Otherwise, parse parameter type list. If it starts with an
- // ellipsis, diagnose the malformed function.
- Diag(Tok, diag::err_ellipsis_first_arg);
- IsVariadic = false; // Treat this like 'void()'.
- }
-
- ConsumeToken(); // Consume the ellipsis.
- break;
- }
-
- SourceLocation DSStart = Tok.getLocation();
-
- // Parse the declaration-specifiers.
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
-
- // Parse the declarator. This is "PrototypeContext", because we must
- // accept either 'declarator' or 'abstract-declarator' here.
- Declarator ParmDecl(DS, Declarator::PrototypeContext);
- ParseDeclarator(ParmDecl);
-
- // Parse GNU attributes, if present.
- if (Tok.is(tok::kw___attribute))
- ParmDecl.AddAttributes(ParseAttributes());
-
- // Remember this parsed parameter in ParamInfo.
- IdentifierInfo *ParmII = ParmDecl.getIdentifier();
-
- // If no parameter was specified, verify that *something* was specified,
- // otherwise we have a missing type and identifier.
- if (DS.getParsedSpecifiers() == DeclSpec::PQ_None &&
- ParmDecl.getIdentifier() == 0 && ParmDecl.getNumTypeObjects() == 0) {
- // Completely missing, emit error.
- Diag(DSStart, diag::err_missing_param);
- } else {
- // Otherwise, we have something. Add it and let semantic analysis try
- // to grok it and add the result to the ParamInfo we are building.
-
- // Inform the actions module about the parameter declarator, so it gets
- // added to the current scope.
- DeclTy *Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
-
- // Parse the default argument, if any. We parse the default
- // arguments in all dialects; the semantic analysis in
- // ActOnParamDefaultArgument will reject the default argument in
- // C.
- if (Tok.is(tok::equal)) {
- SourceLocation EqualLoc = Tok.getLocation();
-
- // Consume the '='.
- ConsumeToken();
-
- // Parse the default argument
- ExprResult DefArgResult = ParseAssignmentExpression();
- if (DefArgResult.isInvalid) {
- SkipUntil(tok::comma, tok::r_paren, true, true);
- } else {
- // Inform the actions module about the default argument
- Actions.ActOnParamDefaultArgument(Param, EqualLoc, DefArgResult.Val);
- }
- }
-
- ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
- ParmDecl.getIdentifierLoc(), Param));
- }
-
- // If the next token is a comma, consume it and keep reading arguments.
- if (Tok.isNot(tok::comma)) break;
-
- // Consume the comma.
- ConsumeToken();
- }
-
- // Leave prototype scope.
- ExitScope();
-
- // Remember that we parsed a function type, and remember the attributes.
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
- &ParamInfo[0], ParamInfo.size(),
- LParenLoc));
-
- // If we have the closing ')', eat it and we're done.
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
-}
-
-/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
-/// we found a K&R-style identifier list instead of a type argument list. The
-/// current token is known to be the first identifier in the list.
-///
-/// identifier-list: [C99 6.7.5]
-/// identifier
-/// identifier-list ',' identifier
-///
-void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
- Declarator &D) {
- // Build up an array of information about the parsed arguments.
- llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
- llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
-
- // If there was no identifier specified for the declarator, either we are in
- // an abstract-declarator, or we are in a parameter declarator which was found
- // to be abstract. In abstract-declarators, identifier lists are not valid:
- // diagnose this.
- if (!D.getIdentifier())
- Diag(Tok, diag::ext_ident_list_in_param);
-
- // Tok is known to be the first identifier in the list. Remember this
- // identifier in ParamInfo.
- ParamsSoFar.insert(Tok.getIdentifierInfo());
- ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
- Tok.getLocation(), 0));
-
- ConsumeToken(); // eat the first identifier.
-
- while (Tok.is(tok::comma)) {
- // Eat the comma.
- ConsumeToken();
-
- // If this isn't an identifier, report the error and skip until ')'.
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::r_paren);
- return;
- }
-
- IdentifierInfo *ParmII = Tok.getIdentifierInfo();
-
- // Reject 'typedef int y; int test(x, y)', but continue parsing.
- if (Actions.isTypeName(*ParmII, CurScope))
- Diag(Tok, diag::err_unexpected_typedef_ident, ParmII->getName());
-
- // Verify that the argument identifier has not already been mentioned.
- if (!ParamsSoFar.insert(ParmII)) {
- Diag(Tok.getLocation(), diag::err_param_redefinition, ParmII->getName());
- } else {
- // Remember this identifier in ParamInfo.
- ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
- Tok.getLocation(), 0));
- }
-
- // Eat the identifier.
- ConsumeToken();
- }
-
- // Remember that we parsed a function type, and remember the attributes. This
- // function type is always a K&R style function type, which is not varargs and
- // has no prototype.
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
- &ParamInfo[0], ParamInfo.size(),
- LParenLoc));
-
- // If we have the closing ')', eat it and we're done.
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
-}
-
-/// [C90] direct-declarator '[' constant-expression[opt] ']'
-/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
-/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
-/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
-/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
-void Parser::ParseBracketDeclarator(Declarator &D) {
- SourceLocation StartLoc = ConsumeBracket();
-
- // If valid, this location is the position where we read the 'static' keyword.
- SourceLocation StaticLoc;
- if (Tok.is(tok::kw_static))
- StaticLoc = ConsumeToken();
-
- // If there is a type-qualifier-list, read it now.
- DeclSpec DS;
- ParseTypeQualifierListOpt(DS);
-
- // If we haven't already read 'static', check to see if there is one after the
- // type-qualifier-list.
- if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
- StaticLoc = ConsumeToken();
-
- // Handle "direct-declarator [ type-qual-list[opt] * ]".
- bool isStar = false;
- ExprResult NumElements(false);
-
- // Handle the case where we have '[*]' as the array size. However, a leading
- // star could be the start of an expression, for example 'X[*p + 4]'. Verify
- // the the token after the star is a ']'. Since stars in arrays are
- // infrequent, use of lookahead is not costly here.
- if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
- ConsumeToken(); // Eat the '*'.
-
- if (StaticLoc.isValid())
- Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
- StaticLoc = SourceLocation(); // Drop the static.
- isStar = true;
- } else if (Tok.isNot(tok::r_square)) {
- // Parse the assignment-expression now.
- NumElements = ParseAssignmentExpression();
- }
-
- // If there was an error parsing the assignment-expression, recover.
- if (NumElements.isInvalid) {
- // If the expression was invalid, skip it.
- SkipUntil(tok::r_square);
- return;
- }
-
- MatchRHSPunctuation(tok::r_square, StartLoc);
-
- // If C99 isn't enabled, emit an ext-warn if the arg list wasn't empty and if
- // it was not a constant expression.
- if (!getLang().C99) {
- // TODO: check C90 array constant exprness.
- if (isStar || StaticLoc.isValid() ||
- 0/*TODO: NumElts is not a C90 constantexpr */)
- Diag(StartLoc, diag::ext_c99_array_usage);
- }
-
- // Remember that we parsed a pointer type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
- StaticLoc.isValid(), isStar,
- NumElements.Val, StartLoc));
-}
-
-/// [GNU] typeof-specifier:
-/// typeof ( expressions )
-/// typeof ( type-name )
-/// [GNU/C++] typeof unary-expression
-///
-void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
- assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
- const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
- SourceLocation StartLoc = ConsumeToken();
-
- if (Tok.isNot(tok::l_paren)) {
- if (!getLang().CPlusPlus) {
- Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
- return;
- }
-
- ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
- if (Result.isInvalid)
- return;
-
- const char *PrevSpec = 0;
- // Check for duplicate type specifiers.
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- Result.Val))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
-
- // FIXME: Not accurate, the range gets one token more than it should.
- DS.SetRangeEnd(Tok.getLocation());
- return;
- }
-
- SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
-
- if (isTypeIdInParens()) {
- TypeTy *Ty = ParseTypeName();
-
- assert(Ty && "Parser::ParseTypeofSpecifier(): missing type");
-
- if (Tok.isNot(tok::r_paren)) {
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return;
- }
- RParenLoc = ConsumeParen();
- const char *PrevSpec = 0;
- // Check for duplicate type specifiers (e.g. "int typeof(int)").
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
- } else { // we have an expression.
- ExprResult Result = ParseExpression();
-
- if (Result.isInvalid || Tok.isNot(tok::r_paren)) {
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return;
- }
- RParenLoc = ConsumeParen();
- const char *PrevSpec = 0;
- // Check for duplicate type specifiers (e.g. "int typeof(int)").
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- Result.Val))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
- }
- DS.SetRangeEnd(RParenLoc);
-}
-
-
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
deleted file mode 100644
index abd432ce9f49..000000000000
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ /dev/null
@@ -1,630 +0,0 @@
-//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the C++ Declaration portions of the Parser interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-using namespace clang;
-
-/// ParseNamespace - We know that the current token is a namespace keyword. This
-/// may either be a top level namespace or a block-level namespace alias.
-///
-/// namespace-definition: [C++ 7.3: basic.namespace]
-/// named-namespace-definition
-/// unnamed-namespace-definition
-///
-/// unnamed-namespace-definition:
-/// 'namespace' attributes[opt] '{' namespace-body '}'
-///
-/// named-namespace-definition:
-/// original-namespace-definition
-/// extension-namespace-definition
-///
-/// original-namespace-definition:
-/// 'namespace' identifier attributes[opt] '{' namespace-body '}'
-///
-/// extension-namespace-definition:
-/// 'namespace' original-namespace-name '{' namespace-body '}'
-///
-/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
-/// 'namespace' identifier '=' qualified-namespace-specifier ';'
-///
-Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
- assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
- SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
-
- SourceLocation IdentLoc;
- IdentifierInfo *Ident = 0;
-
- if (Tok.is(tok::identifier)) {
- Ident = Tok.getIdentifierInfo();
- IdentLoc = ConsumeToken(); // eat the identifier.
- }
-
- // Read label attributes, if present.
- DeclTy *AttrList = 0;
- if (Tok.is(tok::kw___attribute))
- // FIXME: save these somewhere.
- AttrList = ParseAttributes();
-
- if (Tok.is(tok::equal)) {
- // FIXME: Verify no attributes were present.
- // FIXME: parse this.
- } else if (Tok.is(tok::l_brace)) {
-
- SourceLocation LBrace = ConsumeBrace();
-
- // Enter a scope for the namespace.
- EnterScope(Scope::DeclScope);
-
- DeclTy *NamespcDecl =
- Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
-
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
- ParseExternalDeclaration();
-
- // Leave the namespace scope.
- ExitScope();
-
- SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
- Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
-
- return NamespcDecl;
-
- } else {
- unsigned D = Ident ? diag::err_expected_lbrace :
- diag::err_expected_ident_lbrace;
- Diag(Tok.getLocation(), D);
- }
-
- return 0;
-}
-
-/// ParseLinkage - We know that the current token is a string_literal
-/// and just before that, that extern was seen.
-///
-/// linkage-specification: [C++ 7.5p2: dcl.link]
-/// 'extern' string-literal '{' declaration-seq[opt] '}'
-/// 'extern' string-literal declaration
-///
-Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
- assert(Tok.is(tok::string_literal) && "Not a stringliteral!");
- llvm::SmallVector<char, 8> LangBuffer;
- // LangBuffer is guaranteed to be big enough.
- LangBuffer.resize(Tok.getLength());
- const char *LangBufPtr = &LangBuffer[0];
- unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
-
- SourceLocation Loc = ConsumeStringToken();
- DeclTy *D = 0;
- SourceLocation LBrace, RBrace;
-
- if (Tok.isNot(tok::l_brace)) {
- D = ParseDeclaration(Context);
- } else {
- LBrace = ConsumeBrace();
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- // FIXME capture the decls.
- D = ParseExternalDeclaration();
- }
-
- RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
- }
-
- if (!D)
- return 0;
-
- return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize, D);
-}
-
-/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
-/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
-/// until we reach the start of a definition or see a token that
-/// cannot start a definition.
-///
-/// class-specifier: [C++ class]
-/// class-head '{' member-specification[opt] '}'
-/// class-head '{' member-specification[opt] '}' attributes[opt]
-/// class-head:
-/// class-key identifier[opt] base-clause[opt]
-/// class-key nested-name-specifier identifier base-clause[opt]
-/// class-key nested-name-specifier[opt] simple-template-id
-/// base-clause[opt]
-/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt]
-/// [GNU] class-key attributes[opt] nested-name-specifier
-/// identifier base-clause[opt]
-/// [GNU] class-key attributes[opt] nested-name-specifier[opt]
-/// simple-template-id base-clause[opt]
-/// class-key:
-/// 'class'
-/// 'struct'
-/// 'union'
-///
-/// elaborated-type-specifier: [C++ dcl.type.elab]
-/// class-key ::[opt] nested-name-specifier[opt] identifier
-/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
-/// simple-template-id
-///
-/// Note that the C++ class-specifier and elaborated-type-specifier,
-/// together, subsume the C99 struct-or-union-specifier:
-///
-/// struct-or-union-specifier: [C99 6.7.2.1]
-/// struct-or-union identifier[opt] '{' struct-contents '}'
-/// struct-or-union identifier
-/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents
-/// '}' attributes[opt]
-/// [GNU] struct-or-union attributes[opt] identifier
-/// struct-or-union:
-/// 'struct'
-/// 'union'
-void Parser::ParseClassSpecifier(DeclSpec &DS) {
- assert((Tok.is(tok::kw_class) ||
- Tok.is(tok::kw_struct) ||
- Tok.is(tok::kw_union)) &&
- "Not a class specifier");
- DeclSpec::TST TagType =
- Tok.is(tok::kw_class) ? DeclSpec::TST_class :
- Tok.is(tok::kw_struct) ? DeclSpec::TST_struct :
- DeclSpec::TST_union;
-
- SourceLocation StartLoc = ConsumeToken();
-
- AttributeList *Attr = 0;
- // If attributes exist after tag, parse them.
- if (Tok.is(tok::kw___attribute))
- Attr = ParseAttributes();
-
- // FIXME: Parse the (optional) nested-name-specifier.
-
- // Parse the (optional) class name.
- // FIXME: Alternatively, parse a simple-template-id.
- IdentifierInfo *Name = 0;
- SourceLocation NameLoc;
- if (Tok.is(tok::identifier)) {
- Name = Tok.getIdentifierInfo();
- NameLoc = ConsumeToken();
- }
-
- // There are three options here. If we have 'struct foo;', then
- // this is a forward declaration. If we have 'struct foo {...' or
- // 'struct fo :...' then this is a definition. Otherwise we have
- // something like 'struct foo xyz', a reference.
- Action::TagKind TK;
- if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon)))
- TK = Action::TK_Definition;
- else if (Tok.is(tok::semi))
- TK = Action::TK_Declaration;
- else
- TK = Action::TK_Reference;
-
- if (!Name && TK != Action::TK_Definition) {
- // We have a declaration or reference to an anonymous class.
- Diag(StartLoc, diag::err_anon_type_definition,
- DeclSpec::getSpecifierName(TagType));
-
- // Skip the rest of this declarator, up until the comma or semicolon.
- SkipUntil(tok::comma, true);
- return;
- }
-
- // Parse the tag portion of this.
- DeclTy *TagDecl = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, Name,
- NameLoc, Attr);
-
- // Parse the optional base clause (C++ only).
- if (getLang().CPlusPlus && Tok.is(tok::colon)) {
- ParseBaseClause(TagDecl);
- }
-
- // If there is a body, parse it and inform the actions module.
- if (Tok.is(tok::l_brace))
- if (getLang().CPlusPlus)
- ParseCXXMemberSpecification(StartLoc, TagType, TagDecl);
- else
- ParseStructUnionBody(StartLoc, TagType, TagDecl);
- else if (TK == Action::TK_Definition) {
- // FIXME: Complain that we have a base-specifier list but no
- // definition.
- Diag(Tok.getLocation(), diag::err_expected_lbrace);
- }
-
- const char *PrevSpec = 0;
- if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagDecl))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
-}
-
-/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
-///
-/// base-clause : [C++ class.derived]
-/// ':' base-specifier-list
-/// base-specifier-list:
-/// base-specifier '...'[opt]
-/// base-specifier-list ',' base-specifier '...'[opt]
-void Parser::ParseBaseClause(DeclTy *ClassDecl)
-{
- assert(Tok.is(tok::colon) && "Not a base clause");
- ConsumeToken();
-
- while (true) {
- // Parse a base-specifier.
- if (ParseBaseSpecifier(ClassDecl)) {
- // Skip the rest of this base specifier, up until the comma or
- // opening brace.
- SkipUntil(tok::comma, tok::l_brace);
- }
-
- // If the next token is a comma, consume it and keep reading
- // base-specifiers.
- if (Tok.isNot(tok::comma)) break;
-
- // Consume the comma.
- ConsumeToken();
- }
-}
-
-/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
-/// one entry in the base class list of a class specifier, for example:
-/// class foo : public bar, virtual private baz {
-/// 'public bar' and 'virtual private baz' are each base-specifiers.
-///
-/// base-specifier: [C++ class.derived]
-/// ::[opt] nested-name-specifier[opt] class-name
-/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
-/// class-name
-/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
-/// class-name
-bool Parser::ParseBaseSpecifier(DeclTy *ClassDecl)
-{
- bool IsVirtual = false;
- SourceLocation StartLoc = Tok.getLocation();
-
- // Parse the 'virtual' keyword.
- if (Tok.is(tok::kw_virtual)) {
- ConsumeToken();
- IsVirtual = true;
- }
-
- // Parse an (optional) access specifier.
- AccessSpecifier Access = getAccessSpecifierIfPresent();
- if (Access)
- ConsumeToken();
-
- // Parse the 'virtual' keyword (again!), in case it came after the
- // access specifier.
- if (Tok.is(tok::kw_virtual)) {
- SourceLocation VirtualLoc = ConsumeToken();
- if (IsVirtual) {
- // Complain about duplicate 'virtual'
- Diag(VirtualLoc, diag::err_dup_virtual);
- }
-
- IsVirtual = true;
- }
-
- // FIXME: Parse optional '::' and optional nested-name-specifier.
-
- // Parse the class-name.
- // FIXME: Alternatively, parse a simple-template-id.
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok.getLocation(), diag::err_expected_class_name);
- return true;
- }
-
- // We have an identifier; check whether it is actually a type.
- TypeTy *BaseType = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
- if (!BaseType) {
- Diag(Tok.getLocation(), diag::err_expected_class_name);
- return true;
- }
-
- // The location of the base class itself.
- SourceLocation BaseLoc = Tok.getLocation();
-
- // Find the complete source range for the base-specifier.
- SourceRange Range(StartLoc, BaseLoc);
-
- // Consume the identifier token (finally!).
- ConsumeToken();
-
- // Notify semantic analysis that we have parsed a complete
- // base-specifier.
- Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, BaseType,
- BaseLoc);
- return false;
-}
-
-/// getAccessSpecifierIfPresent - Determine whether the next token is
-/// a C++ access-specifier.
-///
-/// access-specifier: [C++ class.derived]
-/// 'private'
-/// 'protected'
-/// 'public'
-AccessSpecifier Parser::getAccessSpecifierIfPresent() const
-{
- switch (Tok.getKind()) {
- default: return AS_none;
- case tok::kw_private: return AS_private;
- case tok::kw_protected: return AS_protected;
- case tok::kw_public: return AS_public;
- }
-}
-
-/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
-///
-/// member-declaration:
-/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
-/// function-definition ';'[opt]
-/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
-/// using-declaration [TODO]
-/// [C++0x] static_assert-declaration [TODO]
-/// template-declaration [TODO]
-///
-/// member-declarator-list:
-/// member-declarator
-/// member-declarator-list ',' member-declarator
-///
-/// member-declarator:
-/// declarator pure-specifier[opt]
-/// declarator constant-initializer[opt]
-/// identifier[opt] ':' constant-expression
-///
-/// pure-specifier: [TODO]
-/// '= 0'
-///
-/// constant-initializer:
-/// '=' constant-expression
-///
-Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
- SourceLocation DSStart = Tok.getLocation();
- // decl-specifier-seq:
- // Parse the common declaration-specifiers piece.
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- // C++ 9.2p7: The member-declarator-list can be omitted only after a
- // class-specifier or an enum-specifier or in a friend declaration.
- // FIXME: Friend declarations.
- switch (DS.getTypeSpecType()) {
- case DeclSpec::TST_struct:
- case DeclSpec::TST_union:
- case DeclSpec::TST_class:
- case DeclSpec::TST_enum:
- return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
- default:
- Diag(DSStart, diag::err_no_declarators);
- return 0;
- }
- }
-
- Declarator DeclaratorInfo(DS, Declarator::MemberContext);
-
- if (Tok.isNot(tok::colon)) {
- // Parse the first declarator.
- ParseDeclarator(DeclaratorInfo);
- // Error parsing the declarator?
- if (DeclaratorInfo.getIdentifier() == 0) {
- // If so, skip until the semi-colon or a }.
- SkipUntil(tok::r_brace, true);
- if (Tok.is(tok::semi))
- ConsumeToken();
- return 0;
- }
-
- // function-definition:
- if (Tok.is(tok::l_brace)) {
- if (!DeclaratorInfo.isFunctionDeclarator()) {
- Diag(Tok, diag::err_func_def_no_params);
- ConsumeBrace();
- SkipUntil(tok::r_brace, true);
- return 0;
- }
-
- if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
- Diag(Tok, diag::err_function_declared_typedef);
- // This recovery skips the entire function body. It would be nice
- // to simply call ParseCXXInlineMethodDef() below, however Sema
- // assumes the declarator represents a function, not a typedef.
- ConsumeBrace();
- SkipUntil(tok::r_brace, true);
- return 0;
- }
-
- return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
- }
- }
-
- // member-declarator-list:
- // member-declarator
- // member-declarator-list ',' member-declarator
-
- DeclTy *LastDeclInGroup = 0;
- ExprTy *BitfieldSize = 0;
- ExprTy *Init = 0;
-
- while (1) {
-
- // member-declarator:
- // declarator pure-specifier[opt]
- // declarator constant-initializer[opt]
- // identifier[opt] ':' constant-expression
-
- if (Tok.is(tok::colon)) {
- ConsumeToken();
- ExprResult Res = ParseConstantExpression();
- if (Res.isInvalid)
- SkipUntil(tok::comma, true, true);
- else
- BitfieldSize = Res.Val;
- }
-
- // pure-specifier:
- // '= 0'
- //
- // constant-initializer:
- // '=' constant-expression
-
- if (Tok.is(tok::equal)) {
- ConsumeToken();
- ExprResult Res = ParseInitializer();
- if (Res.isInvalid)
- SkipUntil(tok::comma, true, true);
- else
- Init = Res.Val;
- }
-
- // If attributes exist after the declarator, parse them.
- if (Tok.is(tok::kw___attribute))
- DeclaratorInfo.AddAttributes(ParseAttributes());
-
- // NOTE: If Sema is the Action module and declarator is an instance field,
- // this call will *not* return the created decl; LastDeclInGroup will be
- // returned instead.
- // See Sema::ActOnCXXMemberDeclarator for details.
- LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
- DeclaratorInfo,
- BitfieldSize, Init,
- LastDeclInGroup);
-
- // If we don't have a comma, it is either the end of the list (a ';')
- // or an error, bail out.
- if (Tok.isNot(tok::comma))
- break;
-
- // Consume the comma.
- ConsumeToken();
-
- // Parse the next declarator.
- DeclaratorInfo.clear();
- BitfieldSize = Init = 0;
-
- // Attributes are only allowed on the second declarator.
- if (Tok.is(tok::kw___attribute))
- DeclaratorInfo.AddAttributes(ParseAttributes());
-
- if (Tok.isNot(tok::colon))
- ParseDeclarator(DeclaratorInfo);
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- // Reverse the chain list.
- return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
- }
-
- Diag(Tok, diag::err_expected_semi_decl_list);
- // Skip to end of block or statement
- SkipUntil(tok::r_brace, true, true);
- if (Tok.is(tok::semi))
- ConsumeToken();
- return 0;
-}
-
-/// ParseCXXMemberSpecification - Parse the class definition.
-///
-/// member-specification:
-/// member-declaration member-specification[opt]
-/// access-specifier ':' member-specification[opt]
-///
-void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
- unsigned TagType, DeclTy *TagDecl) {
- assert(TagType == DeclSpec::TST_struct ||
- TagType == DeclSpec::TST_union ||
- TagType == DeclSpec::TST_class && "Invalid TagType!");
-
- SourceLocation LBraceLoc = ConsumeBrace();
-
- if (!CurScope->isCXXClassScope() && // Not about to define a nested class.
- CurScope->isInCXXInlineMethodScope()) {
- // We will define a local class of an inline method.
- // Push a new LexedMethodsForTopClass for its inline methods.
- PushTopClassStack();
- }
-
- // Enter a scope for the class.
- EnterScope(Scope::CXXClassScope|Scope::DeclScope);
-
- Actions.ActOnStartCXXClassDef(CurScope, TagDecl, LBraceLoc);
-
- // C++ 11p3: Members of a class defined with the keyword class are private
- // by default. Members of a class defined with the keywords struct or union
- // are public by default.
- AccessSpecifier CurAS;
- if (TagType == DeclSpec::TST_class)
- CurAS = AS_private;
- else
- CurAS = AS_public;
-
- // While we still have something to read, read the member-declarations.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- // Each iteration of this loop reads one member-declaration.
-
- // Check for extraneous top-level semicolon.
- if (Tok.is(tok::semi)) {
- Diag(Tok, diag::ext_extra_struct_semi);
- ConsumeToken();
- continue;
- }
-
- AccessSpecifier AS = getAccessSpecifierIfPresent();
- if (AS != AS_none) {
- // Current token is a C++ access specifier.
- CurAS = AS;
- ConsumeToken();
- ExpectAndConsume(tok::colon, diag::err_expected_colon);
- continue;
- }
-
- // Parse all the comma separated declarators.
- ParseCXXClassMemberDeclaration(CurAS);
- }
-
- SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
-
- AttributeList *AttrList = 0;
- // If attributes exist after class contents, parse them.
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseAttributes(); // FIXME: where should I put them?
-
- Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
- LBraceLoc, RBraceLoc);
-
- // C++ 9.2p2: Within the class member-specification, the class is regarded as
- // complete within function bodies, default arguments,
- // exception-specifications, and constructor ctor-initializers (including
- // such things in nested classes).
- //
- // FIXME: Only function bodies are parsed correctly, fix the rest.
- if (!CurScope->getParent()->isCXXClassScope()) {
- // We are not inside a nested class. This class and its nested classes
- // are complete and we can parse the lexed inline method definitions.
- ParseLexedMethodDefs();
-
- // For a local class of inline method, pop the LexedMethodsForTopClass that
- // was previously pushed.
-
- assert(CurScope->isInCXXInlineMethodScope() ||
- TopClassStacks.size() == 1 &&
- "MethodLexers not getting popped properly!");
- if (CurScope->isInCXXInlineMethodScope())
- PopTopClassStack();
- }
-
- // Leave the class scope.
- ExitScope();
-
- Actions.ActOnFinishCXXClassDef(TagDecl);
-}
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
deleted file mode 100644
index c8d95cf053c8..000000000000
--- a/clang/lib/Parse/ParseExpr.cpp
+++ /dev/null
@@ -1,1136 +0,0 @@
-//===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Expression parsing implementation. Expressions in
-// C99 basically consist of a bunch of binary operators with unary operators and
-// other random stuff at the leaves.
-//
-// In the C99 grammar, these unary operators bind tightest and are represented
-// as the 'cast-expression' production. Everything else is either a binary
-// operator (e.g. '/') or a ternary operator ("?:"). The unary leaves are
-// handled by ParseCastExpression, the higher level pieces are handled by
-// ParseBinaryExpression.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/SmallString.h"
-using namespace clang;
-
-/// PrecedenceLevels - These are precedences for the binary/ternary operators in
-/// the C99 grammar. These have been named to relate with the C99 grammar
-/// productions. Low precedences numbers bind more weakly than high numbers.
-namespace prec {
- enum Level {
- Unknown = 0, // Not binary operator.
- Comma = 1, // ,
- Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
- Conditional = 3, // ?
- LogicalOr = 4, // ||
- LogicalAnd = 5, // &&
- InclusiveOr = 6, // |
- ExclusiveOr = 7, // ^
- And = 8, // &
- Equality = 9, // ==, !=
- Relational = 10, // >=, <=, >, <
- Shift = 11, // <<, >>
- Additive = 12, // -, +
- Multiplicative = 13 // *, /, %
- };
-}
-
-
-/// getBinOpPrecedence - Return the precedence of the specified binary operator
-/// token. This returns:
-///
-static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
- switch (Kind) {
- default: return prec::Unknown;
- case tok::comma: return prec::Comma;
- case tok::equal:
- case tok::starequal:
- case tok::slashequal:
- case tok::percentequal:
- case tok::plusequal:
- case tok::minusequal:
- case tok::lesslessequal:
- case tok::greatergreaterequal:
- case tok::ampequal:
- case tok::caretequal:
- case tok::pipeequal: return prec::Assignment;
- case tok::question: return prec::Conditional;
- case tok::pipepipe: return prec::LogicalOr;
- case tok::ampamp: return prec::LogicalAnd;
- case tok::pipe: return prec::InclusiveOr;
- case tok::caret: return prec::ExclusiveOr;
- case tok::amp: return prec::And;
- case tok::exclaimequal:
- case tok::equalequal: return prec::Equality;
- case tok::lessequal:
- case tok::less:
- case tok::greaterequal:
- case tok::greater: return prec::Relational;
- case tok::lessless:
- case tok::greatergreater: return prec::Shift;
- case tok::plus:
- case tok::minus: return prec::Additive;
- case tok::percent:
- case tok::slash:
- case tok::star: return prec::Multiplicative;
- }
-}
-
-
-/// ParseExpression - Simple precedence-based parser for binary/ternary
-/// operators.
-///
-/// Note: we diverge from the C99 grammar when parsing the assignment-expression
-/// production. C99 specifies that the LHS of an assignment operator should be
-/// parsed as a unary-expression, but consistency dictates that it be a
-/// conditional-expession. In practice, the important thing here is that the
-/// LHS of an assignment has to be an l-value, which productions between
-/// unary-expression and conditional-expression don't produce. Because we want
-/// consistency, we parse the LHS as a conditional-expression, then check for
-/// l-value-ness in semantic analysis stages.
-///
-/// multiplicative-expression: [C99 6.5.5]
-/// cast-expression
-/// multiplicative-expression '*' cast-expression
-/// multiplicative-expression '/' cast-expression
-/// multiplicative-expression '%' cast-expression
-///
-/// additive-expression: [C99 6.5.6]
-/// multiplicative-expression
-/// additive-expression '+' multiplicative-expression
-/// additive-expression '-' multiplicative-expression
-///
-/// shift-expression: [C99 6.5.7]
-/// additive-expression
-/// shift-expression '<<' additive-expression
-/// shift-expression '>>' additive-expression
-///
-/// relational-expression: [C99 6.5.8]
-/// shift-expression
-/// relational-expression '<' shift-expression
-/// relational-expression '>' shift-expression
-/// relational-expression '<=' shift-expression
-/// relational-expression '>=' shift-expression
-///
-/// equality-expression: [C99 6.5.9]
-/// relational-expression
-/// equality-expression '==' relational-expression
-/// equality-expression '!=' relational-expression
-///
-/// AND-expression: [C99 6.5.10]
-/// equality-expression
-/// AND-expression '&' equality-expression
-///
-/// exclusive-OR-expression: [C99 6.5.11]
-/// AND-expression
-/// exclusive-OR-expression '^' AND-expression
-///
-/// inclusive-OR-expression: [C99 6.5.12]
-/// exclusive-OR-expression
-/// inclusive-OR-expression '|' exclusive-OR-expression
-///
-/// logical-AND-expression: [C99 6.5.13]
-/// inclusive-OR-expression
-/// logical-AND-expression '&&' inclusive-OR-expression
-///
-/// logical-OR-expression: [C99 6.5.14]
-/// logical-AND-expression
-/// logical-OR-expression '||' logical-AND-expression
-///
-/// conditional-expression: [C99 6.5.15]
-/// logical-OR-expression
-/// logical-OR-expression '?' expression ':' conditional-expression
-/// [GNU] logical-OR-expression '?' ':' conditional-expression
-///
-/// assignment-expression: [C99 6.5.16]
-/// conditional-expression
-/// unary-expression assignment-operator assignment-expression
-/// [C++] throw-expression [C++ 15]
-///
-/// assignment-operator: one of
-/// = *= /= %= += -= <<= >>= &= ^= |=
-///
-/// expression: [C99 6.5.17]
-/// assignment-expression
-/// expression ',' assignment-expression
-///
-Parser::ExprResult Parser::ParseExpression() {
- if (Tok.is(tok::kw_throw))
- return ParseThrowExpression();
-
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
-
- return ParseRHSOfBinaryExpression(LHS, prec::Comma);
-}
-
-/// This routine is called when the '@' is seen and consumed.
-/// Current token is an Identifier and is not a 'try'. This
-/// routine is necessary to disambiguate @try-statement from,
-/// for example, @encode-expression.
-///
-Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
- ExprResult LHS = ParseObjCAtExpression(AtLoc);
- if (LHS.isInvalid) return LHS;
-
- return ParseRHSOfBinaryExpression(LHS, prec::Comma);
-}
-
-/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
-///
-Parser::ExprResult Parser::ParseAssignmentExpression() {
- if (Tok.is(tok::kw_throw))
- return ParseThrowExpression();
-
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
-
- return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
-}
-
-/// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
-/// where part of an objc message send has already been parsed. In this case
-/// LBracLoc indicates the location of the '[' of the message send, and either
-/// ReceiverName or ReceiverExpr is non-null indicating the receiver of the
-/// message.
-///
-/// Since this handles full assignment-expression's, it handles postfix
-/// expressions and other binary operators for these expressions as well.
-Parser::ExprResult
-Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
- IdentifierInfo *ReceiverName,
- ExprTy *ReceiverExpr) {
- ExprResult R = ParseObjCMessageExpressionBody(LBracLoc, ReceiverName,
- ReceiverExpr);
- if (R.isInvalid) return R;
- R = ParsePostfixExpressionSuffix(R);
- if (R.isInvalid) return R;
- return ParseRHSOfBinaryExpression(R, 2);
-}
-
-
-Parser::ExprResult Parser::ParseConstantExpression() {
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
-
- return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
-}
-
-/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
-/// LHS and has a precedence of at least MinPrec.
-Parser::ExprResult
-Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
- unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
- SourceLocation ColonLoc;
-
- while (1) {
- // If this token has a lower precedence than we are allowed to parse (e.g.
- // because we are called recursively, or because the token is not a binop),
- // then we are done!
- if (NextTokPrec < MinPrec)
- return LHS;
-
- // Consume the operator, saving the operator token for error reporting.
- Token OpToken = Tok;
- ConsumeToken();
-
- // Special case handling for the ternary operator.
- ExprResult TernaryMiddle(true);
- if (NextTokPrec == prec::Conditional) {
- if (Tok.isNot(tok::colon)) {
- // Handle this production specially:
- // logical-OR-expression '?' expression ':' conditional-expression
- // In particular, the RHS of the '?' is 'expression', not
- // 'logical-OR-expression' as we might expect.
- TernaryMiddle = ParseExpression();
- if (TernaryMiddle.isInvalid) {
- Actions.DeleteExpr(LHS.Val);
- return TernaryMiddle;
- }
- } else {
- // Special case handling of "X ? Y : Z" where Y is empty:
- // logical-OR-expression '?' ':' conditional-expression [GNU]
- TernaryMiddle = ExprResult(false);
- Diag(Tok, diag::ext_gnu_conditional_expr);
- }
-
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon);
- Diag(OpToken, diag::err_matching, "?");
- Actions.DeleteExpr(LHS.Val);
- Actions.DeleteExpr(TernaryMiddle.Val);
- return ExprResult(true);
- }
-
- // Eat the colon.
- ColonLoc = ConsumeToken();
- }
-
- // Parse another leaf here for the RHS of the operator.
- ExprResult RHS = ParseCastExpression(false);
- if (RHS.isInvalid) {
- Actions.DeleteExpr(LHS.Val);
- Actions.DeleteExpr(TernaryMiddle.Val);
- return RHS;
- }
-
- // Remember the precedence of this operator and get the precedence of the
- // operator immediately to the right of the RHS.
- unsigned ThisPrec = NextTokPrec;
- NextTokPrec = getBinOpPrecedence(Tok.getKind());
-
- // Assignment and conditional expressions are right-associative.
- bool isRightAssoc = ThisPrec == prec::Conditional ||
- ThisPrec == prec::Assignment;
-
- // Get the precedence of the operator to the right of the RHS. If it binds
- // more tightly with RHS than we do, evaluate it completely first.
- if (ThisPrec < NextTokPrec ||
- (ThisPrec == NextTokPrec && isRightAssoc)) {
- // If this is left-associative, only parse things on the RHS that bind
- // more tightly than the current operator. If it is left-associative, it
- // is okay, to bind exactly as tightly. For example, compile A=B=C=D as
- // A=(B=(C=D)), where each paren is a level of recursion here.
- RHS = ParseRHSOfBinaryExpression(RHS, ThisPrec + !isRightAssoc);
- if (RHS.isInvalid) {
- Actions.DeleteExpr(LHS.Val);
- Actions.DeleteExpr(TernaryMiddle.Val);
- return RHS;
- }
-
- NextTokPrec = getBinOpPrecedence(Tok.getKind());
- }
- assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
-
- if (!LHS.isInvalid) {
- // Combine the LHS and RHS into the LHS (e.g. build AST).
- if (TernaryMiddle.isInvalid)
- LHS = Actions.ActOnBinOp(OpToken.getLocation(), OpToken.getKind(),
- LHS.Val, RHS.Val);
- else
- LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
- LHS.Val, TernaryMiddle.Val, RHS.Val);
- } else {
- // We had a semantic error on the LHS. Just free the RHS and continue.
- Actions.DeleteExpr(TernaryMiddle.Val);
- Actions.DeleteExpr(RHS.Val);
- }
- }
-}
-
-/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
-/// true, parse a unary-expression.
-///
-/// cast-expression: [C99 6.5.4]
-/// unary-expression
-/// '(' type-name ')' cast-expression
-///
-/// unary-expression: [C99 6.5.3]
-/// postfix-expression
-/// '++' unary-expression
-/// '--' unary-expression
-/// unary-operator cast-expression
-/// 'sizeof' unary-expression
-/// 'sizeof' '(' type-name ')'
-/// [GNU] '__alignof' unary-expression
-/// [GNU] '__alignof' '(' type-name ')'
-/// [GNU] '&&' identifier
-///
-/// unary-operator: one of
-/// '&' '*' '+' '-' '~' '!'
-/// [GNU] '__extension__' '__real' '__imag'
-///
-/// primary-expression: [C99 6.5.1]
-/// identifier
-/// constant
-/// string-literal
-/// [C++] boolean-literal [C++ 2.13.5]
-/// '(' expression ')'
-/// '__func__' [C99 6.4.2.2]
-/// [GNU] '__FUNCTION__'
-/// [GNU] '__PRETTY_FUNCTION__'
-/// [GNU] '(' compound-statement ')'
-/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
-/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
-/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
-/// assign-expr ')'
-/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
-/// [OBJC] '[' objc-message-expr ']'
-/// [OBJC] '@selector' '(' objc-selector-arg ')'
-/// [OBJC] '@protocol' '(' identifier ')'
-/// [OBJC] '@encode' '(' type-name ')'
-/// [OBJC] objc-string-literal
-/// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
-/// [C++] typename-specifier '(' expression-list[opt] ')' [TODO]
-/// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
-/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
-/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
-/// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
-/// [C++] 'this' [C++ 9.3.2]
-/// [clang] '^' block-literal
-///
-/// constant: [C99 6.4.4]
-/// integer-constant
-/// floating-constant
-/// enumeration-constant -> identifier
-/// character-constant
-///
-Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
- ExprResult Res;
- tok::TokenKind SavedKind = Tok.getKind();
-
- // This handles all of cast-expression, unary-expression, postfix-expression,
- // and primary-expression. We handle them together like this for efficiency
- // and to simplify handling of an expression starting with a '(' token: which
- // may be one of a parenthesized expression, cast-expression, compound literal
- // expression, or statement expression.
- //
- // If the parsed tokens consist of a primary-expression, the cases below
- // call ParsePostfixExpressionSuffix to handle the postfix expression
- // suffixes. Cases that cannot be followed by postfix exprs should
- // return without invoking ParsePostfixExpressionSuffix.
- switch (SavedKind) {
- case tok::l_paren: {
- // If this expression is limited to being a unary-expression, the parent can
- // not start a cast expression.
- ParenParseOption ParenExprType =
- isUnaryExpression ? CompoundLiteral : CastExpr;
- TypeTy *CastTy;
- SourceLocation LParenLoc = Tok.getLocation();
- SourceLocation RParenLoc;
- Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
- if (Res.isInvalid) return Res;
-
- switch (ParenExprType) {
- case SimpleExpr: break; // Nothing else to do.
- case CompoundStmt: break; // Nothing else to do.
- case CompoundLiteral:
- // We parsed '(' type-name ')' '{' ... '}'. If any suffixes of
- // postfix-expression exist, parse them now.
- break;
- case CastExpr:
- // We parsed '(' type-name ')' and the thing after it wasn't a '{'. Parse
- // the cast-expression that follows it next.
- // TODO: For cast expression with CastTy.
- Res = ParseCastExpression(false);
- if (!Res.isInvalid)
- Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.Val);
- return Res;
- }
-
- // These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
- }
-
- // primary-expression
- case tok::numeric_constant:
- // constant: integer-constant
- // constant: floating-constant
-
- Res = Actions.ActOnNumericConstant(Tok);
- ConsumeToken();
-
- // These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
-
- case tok::kw_true:
- case tok::kw_false:
- return ParseCXXBoolLiteral();
-
- case tok::identifier: {
- if (getLang().CPlusPlus &&
- Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
- // Handle C++ function-style cast, e.g. "T(4.5)" where T is a typedef for
- // double.
- goto HandleType;
- }
-
- // primary-expression: identifier
- // constant: enumeration-constant
-
- // Consume the identifier so that we can see if it is followed by a '('.
- // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
- // need to know whether or not this identifier is a function designator or
- // not.
- IdentifierInfo &II = *Tok.getIdentifierInfo();
- SourceLocation L = ConsumeToken();
- Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
- // These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
- }
- case tok::char_constant: // constant: character-constant
- Res = Actions.ActOnCharacterConstant(Tok);
- ConsumeToken();
- // These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
- case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
- case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
- case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
- Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
- ConsumeToken();
- // These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
- case tok::string_literal: // primary-expression: string-literal
- case tok::wide_string_literal:
- Res = ParseStringLiteralExpression();
- if (Res.isInvalid) return Res;
- // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
- return ParsePostfixExpressionSuffix(Res);
- case tok::kw___builtin_va_arg:
- case tok::kw___builtin_offsetof:
- case tok::kw___builtin_choose_expr:
- case tok::kw___builtin_overload:
- case tok::kw___builtin_types_compatible_p:
- return ParseBuiltinPrimaryExpression();
- case tok::plusplus: // unary-expression: '++' unary-expression
- case tok::minusminus: { // unary-expression: '--' unary-expression
- SourceLocation SavedLoc = ConsumeToken();
- Res = ParseCastExpression(true);
- if (!Res.isInvalid)
- Res = Actions.ActOnUnaryOp(SavedLoc, SavedKind, Res.Val);
- return Res;
- }
- case tok::amp: // unary-expression: '&' cast-expression
- case tok::star: // unary-expression: '*' cast-expression
- case tok::plus: // unary-expression: '+' cast-expression
- case tok::minus: // unary-expression: '-' cast-expression
- case tok::tilde: // unary-expression: '~' cast-expression
- case tok::exclaim: // unary-expression: '!' cast-expression
- case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
- case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
- SourceLocation SavedLoc = ConsumeToken();
- Res = ParseCastExpression(false);
- if (!Res.isInvalid)
- Res = Actions.ActOnUnaryOp(SavedLoc, SavedKind, Res.Val);
- return Res;
- }
-
- case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
- // __extension__ silences extension warnings in the subexpression.
- bool SavedExtWarn = Diags.getWarnOnExtensions();
- Diags.setWarnOnExtensions(false);
- SourceLocation SavedLoc = ConsumeToken();
- Res = ParseCastExpression(false);
- if (!Res.isInvalid)
- Res = Actions.ActOnUnaryOp(SavedLoc, SavedKind, Res.Val);
- Diags.setWarnOnExtensions(SavedExtWarn);
- return Res;
- }
- case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
- // unary-expression: 'sizeof' '(' type-name ')'
- case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
- // unary-expression: '__alignof' '(' type-name ')'
- return ParseSizeofAlignofExpression();
- case tok::ampamp: { // unary-expression: '&&' identifier
- SourceLocation AmpAmpLoc = ConsumeToken();
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return ExprResult(true);
- }
-
- Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
- Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
- Tok.getIdentifierInfo());
- ConsumeToken();
- return Res;
- }
- case tok::kw_const_cast:
- case tok::kw_dynamic_cast:
- case tok::kw_reinterpret_cast:
- case tok::kw_static_cast:
- Res = ParseCXXCasts();
- // These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
- case tok::kw_this:
- Res = ParseCXXThis();
- // This can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
-
- case tok::kw_char:
- case tok::kw_wchar_t:
- case tok::kw_bool:
- case tok::kw_short:
- case tok::kw_int:
- case tok::kw_long:
- case tok::kw_signed:
- case tok::kw_unsigned:
- case tok::kw_float:
- case tok::kw_double:
- case tok::kw_void:
- case tok::kw_typeof: {
- if (!getLang().CPlusPlus)
- goto UnhandledToken;
- HandleType:
- // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
- //
- DeclSpec DS;
- ParseCXXSimpleTypeSpecifier(DS);
- if (Tok.isNot(tok::l_paren))
- return Diag(Tok.getLocation(), diag::err_expected_lparen_after_type,
- DS.getSourceRange());
-
- Res = ParseCXXTypeConstructExpression(DS);
- // This can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
- }
-
- case tok::at: {
- SourceLocation AtLoc = ConsumeToken();
- return ParseObjCAtExpression(AtLoc);
- }
- case tok::l_square:
- // These can be followed by postfix-expr pieces.
- if (getLang().ObjC1)
- return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
- // FALL THROUGH.
- case tok::caret:
- if (getLang().Blocks)
- return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
- Diag(Tok, diag::err_expected_expression);
- return ExprResult(true);
- default:
- UnhandledToken:
- Diag(Tok, diag::err_expected_expression);
- return ExprResult(true);
- }
-
- // unreachable.
- abort();
-}
-
-/// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
-/// is parsed, this method parses any suffixes that apply.
-///
-/// postfix-expression: [C99 6.5.2]
-/// primary-expression
-/// postfix-expression '[' expression ']'
-/// postfix-expression '(' argument-expression-list[opt] ')'
-/// postfix-expression '.' identifier
-/// postfix-expression '->' identifier
-/// postfix-expression '++'
-/// postfix-expression '--'
-/// '(' type-name ')' '{' initializer-list '}'
-/// '(' type-name ')' '{' initializer-list ',' '}'
-///
-/// argument-expression-list: [C99 6.5.2]
-/// argument-expression
-/// argument-expression-list ',' assignment-expression
-///
-Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
-
- // Now that the primary-expression piece of the postfix-expression has been
- // parsed, see if there are any postfix-expression pieces here.
- SourceLocation Loc;
- while (1) {
- switch (Tok.getKind()) {
- default: // Not a postfix-expression suffix.
- return LHS;
- case tok::l_square: { // postfix-expression: p-e '[' expression ']'
- Loc = ConsumeBracket();
- ExprResult Idx = ParseExpression();
-
- SourceLocation RLoc = Tok.getLocation();
-
- if (!LHS.isInvalid && !Idx.isInvalid && Tok.is(tok::r_square))
- LHS = Actions.ActOnArraySubscriptExpr(LHS.Val, Loc, Idx.Val, RLoc);
- else
- LHS = ExprResult(true);
-
- // Match the ']'.
- MatchRHSPunctuation(tok::r_square, Loc);
- break;
- }
-
- case tok::l_paren: { // p-e: p-e '(' argument-expression-list[opt] ')'
- ExprListTy ArgExprs;
- CommaLocsTy CommaLocs;
-
- Loc = ConsumeParen();
-
- if (Tok.isNot(tok::r_paren)) {
- if (ParseExpressionList(ArgExprs, CommaLocs)) {
- SkipUntil(tok::r_paren);
- return ExprResult(true);
- }
- }
-
- // Match the ')'.
- if (!LHS.isInvalid && Tok.is(tok::r_paren)) {
- assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
- "Unexpected number of commas!");
- LHS = Actions.ActOnCallExpr(LHS.Val, Loc, &ArgExprs[0], ArgExprs.size(),
- &CommaLocs[0], Tok.getLocation());
- }
-
- MatchRHSPunctuation(tok::r_paren, Loc);
- break;
- }
- case tok::arrow: // postfix-expression: p-e '->' identifier
- case tok::period: { // postfix-expression: p-e '.' identifier
- tok::TokenKind OpKind = Tok.getKind();
- SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token.
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return ExprResult(true);
- }
-
- if (!LHS.isInvalid)
- LHS = Actions.ActOnMemberReferenceExpr(LHS.Val, OpLoc, OpKind,
- Tok.getLocation(),
- *Tok.getIdentifierInfo());
- ConsumeToken();
- break;
- }
- case tok::plusplus: // postfix-expression: postfix-expression '++'
- case tok::minusminus: // postfix-expression: postfix-expression '--'
- if (!LHS.isInvalid)
- LHS = Actions.ActOnPostfixUnaryOp(Tok.getLocation(), Tok.getKind(),
- LHS.Val);
- ConsumeToken();
- break;
- }
- }
-}
-
-
-/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
-/// unary-expression: [C99 6.5.3]
-/// 'sizeof' unary-expression
-/// 'sizeof' '(' type-name ')'
-/// [GNU] '__alignof' unary-expression
-/// [GNU] '__alignof' '(' type-name ')'
-Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
- assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)) &&
- "Not a sizeof/alignof expression!");
- Token OpTok = Tok;
- ConsumeToken();
-
- // If the operand doesn't start with an '(', it must be an expression.
- ExprResult Operand;
- if (Tok.isNot(tok::l_paren)) {
- Operand = ParseCastExpression(true);
- } else {
- // If it starts with a '(', we know that it is either a parenthesized
- // type-name, or it is a unary-expression that starts with a compound
- // literal, or starts with a primary-expression that is a parenthesized
- // expression.
- ParenParseOption ExprType = CastExpr;
- TypeTy *CastTy;
- SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
- Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
-
- // If ParseParenExpression parsed a '(typename)' sequence only, the this is
- // sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression.
- if (ExprType == CastExpr)
- return Actions.ActOnSizeOfAlignOfTypeExpr(OpTok.getLocation(),
- OpTok.is(tok::kw_sizeof),
- LParenLoc, CastTy, RParenLoc);
-
- // If this is a parenthesized expression, it is the start of a
- // unary-expression, but doesn't include any postfix pieces. Parse these
- // now if present.
- Operand = ParsePostfixExpressionSuffix(Operand);
- }
-
- // If we get here, the operand to the sizeof/alignof was an expresion.
- if (!Operand.isInvalid)
- Operand = Actions.ActOnUnaryOp(OpTok.getLocation(), OpTok.getKind(),
- Operand.Val);
- return Operand;
-}
-
-/// ParseBuiltinPrimaryExpression
-///
-/// primary-expression: [C99 6.5.1]
-/// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
-/// [GNU] '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
-/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
-/// assign-expr ')'
-/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
-/// [CLANG] '__builtin_overload' '(' expr (',' expr)* ')'
-///
-/// [GNU] offsetof-member-designator:
-/// [GNU] identifier
-/// [GNU] offsetof-member-designator '.' identifier
-/// [GNU] offsetof-member-designator '[' expression ']'
-///
-Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
- ExprResult Res(false);
- const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
-
- tok::TokenKind T = Tok.getKind();
- SourceLocation StartLoc = ConsumeToken(); // Eat the builtin identifier.
-
- // All of these start with an open paren.
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
- return ExprResult(true);
- }
-
- SourceLocation LParenLoc = ConsumeParen();
- // TODO: Build AST.
-
- switch (T) {
- default: assert(0 && "Not a builtin primary expression!");
- case tok::kw___builtin_va_arg: {
- ExprResult Expr = ParseAssignmentExpression();
- if (Expr.isInvalid) {
- SkipUntil(tok::r_paren);
- return ExprResult(true);
- }
-
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
- return ExprResult(true);
-
- TypeTy *Ty = ParseTypeName();
-
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_rparen);
- return ExprResult(true);
- }
- Res = Actions.ActOnVAArg(StartLoc, Expr.Val, Ty, ConsumeParen());
- break;
- }
- case tok::kw___builtin_offsetof: {
- SourceLocation TypeLoc = Tok.getLocation();
- TypeTy *Ty = ParseTypeName();
-
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
- return ExprResult(true);
-
- // We must have at least one identifier here.
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::r_paren);
- return true;
- }
-
- // Keep track of the various subcomponents we see.
- llvm::SmallVector<Action::OffsetOfComponent, 4> Comps;
-
- Comps.push_back(Action::OffsetOfComponent());
- Comps.back().isBrackets = false;
- Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
- Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
-
- while (1) {
- if (Tok.is(tok::period)) {
- // offsetof-member-designator: offsetof-member-designator '.' identifier
- Comps.push_back(Action::OffsetOfComponent());
- Comps.back().isBrackets = false;
- Comps.back().LocStart = ConsumeToken();
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::r_paren);
- return true;
- }
- Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
- Comps.back().LocEnd = ConsumeToken();
-
- } else if (Tok.is(tok::l_square)) {
- // offsetof-member-designator: offsetof-member-design '[' expression ']'
- Comps.push_back(Action::OffsetOfComponent());
- Comps.back().isBrackets = true;
- Comps.back().LocStart = ConsumeBracket();
- Res = ParseExpression();
- if (Res.isInvalid) {
- SkipUntil(tok::r_paren);
- return Res;
- }
- Comps.back().U.E = Res.Val;
-
- Comps.back().LocEnd =
- MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
- } else if (Tok.is(tok::r_paren)) {
- Res = Actions.ActOnBuiltinOffsetOf(StartLoc, TypeLoc, Ty, &Comps[0],
- Comps.size(), ConsumeParen());
- break;
- } else {
- // Error occurred.
- return ExprResult(true);
- }
- }
- break;
- }
- case tok::kw___builtin_choose_expr: {
- ExprResult Cond = ParseAssignmentExpression();
- if (Cond.isInvalid) {
- SkipUntil(tok::r_paren);
- return Cond;
- }
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
- return ExprResult(true);
-
- ExprResult Expr1 = ParseAssignmentExpression();
- if (Expr1.isInvalid) {
- SkipUntil(tok::r_paren);
- return Expr1;
- }
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
- return ExprResult(true);
-
- ExprResult Expr2 = ParseAssignmentExpression();
- if (Expr2.isInvalid) {
- SkipUntil(tok::r_paren);
- return Expr2;
- }
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_rparen);
- return ExprResult(true);
- }
- Res = Actions.ActOnChooseExpr(StartLoc, Cond.Val, Expr1.Val, Expr2.Val,
- ConsumeParen());
- break;
- }
- case tok::kw___builtin_overload: {
- llvm::SmallVector<ExprTy*, 8> ArgExprs;
- llvm::SmallVector<SourceLocation, 8> CommaLocs;
-
- // For each iteration through the loop look for assign-expr followed by a
- // comma. If there is no comma, break and attempt to match r-paren.
- if (Tok.isNot(tok::r_paren)) {
- while (1) {
- ExprResult ArgExpr = ParseAssignmentExpression();
- if (ArgExpr.isInvalid) {
- SkipUntil(tok::r_paren);
- return ExprResult(true);
- } else
- ArgExprs.push_back(ArgExpr.Val);
-
- if (Tok.isNot(tok::comma))
- break;
- // Move to the next argument, remember where the comma was.
- CommaLocs.push_back(ConsumeToken());
- }
- }
-
- // Attempt to consume the r-paren
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_rparen);
- SkipUntil(tok::r_paren);
- return ExprResult(true);
- }
- Res = Actions.ActOnOverloadExpr(&ArgExprs[0], ArgExprs.size(),
- &CommaLocs[0], StartLoc, ConsumeParen());
- break;
- }
- case tok::kw___builtin_types_compatible_p:
- TypeTy *Ty1 = ParseTypeName();
-
- if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
- return ExprResult(true);
-
- TypeTy *Ty2 = ParseTypeName();
-
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_rparen);
- return ExprResult(true);
- }
- Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1, Ty2, ConsumeParen());
- break;
- }
-
- // These can be followed by postfix-expr pieces because they are
- // primary-expressions.
- return ParsePostfixExpressionSuffix(Res);
-}
-
-/// ParseParenExpression - This parses the unit that starts with a '(' token,
-/// based on what is allowed by ExprType. The actual thing parsed is returned
-/// in ExprType.
-///
-/// primary-expression: [C99 6.5.1]
-/// '(' expression ')'
-/// [GNU] '(' compound-statement ')' (if !ParenExprOnly)
-/// postfix-expression: [C99 6.5.2]
-/// '(' type-name ')' '{' initializer-list '}'
-/// '(' type-name ')' '{' initializer-list ',' '}'
-/// cast-expression: [C99 6.5.4]
-/// '(' type-name ')' cast-expression
-///
-Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
- TypeTy *&CastTy,
- SourceLocation &RParenLoc) {
- assert(Tok.is(tok::l_paren) && "Not a paren expr!");
- SourceLocation OpenLoc = ConsumeParen();
- ExprResult Result(true);
- CastTy = 0;
-
- if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::ext_gnu_statement_expr);
- Parser::StmtResult Stmt = ParseCompoundStatement(true);
- ExprType = CompoundStmt;
-
- // If the substmt parsed correctly, build the AST node.
- if (!Stmt.isInvalid && Tok.is(tok::r_paren))
- Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.Val, Tok.getLocation());
-
- } else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
- // Otherwise, this is a compound literal expression or cast expression.
- TypeTy *Ty = ParseTypeName();
-
- // Match the ')'.
- if (Tok.is(tok::r_paren))
- RParenLoc = ConsumeParen();
- else
- MatchRHSPunctuation(tok::r_paren, OpenLoc);
-
- if (Tok.is(tok::l_brace)) {
- if (!getLang().C99) // Compound literals don't exist in C90.
- Diag(OpenLoc, diag::ext_c99_compound_literal);
- Result = ParseInitializer();
- ExprType = CompoundLiteral;
- if (!Result.isInvalid)
- return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val);
- } else if (ExprType == CastExpr) {
- // Note that this doesn't parse the subsequence cast-expression, it just
- // returns the parsed type to the callee.
- ExprType = CastExpr;
- CastTy = Ty;
- return ExprResult(false);
- } else {
- Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
- return ExprResult(true);
- }
- return Result;
- } else {
- Result = ParseExpression();
- ExprType = SimpleExpr;
- if (!Result.isInvalid && Tok.is(tok::r_paren))
- Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.Val);
- }
-
- // Match the ')'.
- if (Result.isInvalid)
- SkipUntil(tok::r_paren);
- else {
- if (Tok.is(tok::r_paren))
- RParenLoc = ConsumeParen();
- else
- MatchRHSPunctuation(tok::r_paren, OpenLoc);
- }
-
- return Result;
-}
-
-/// ParseStringLiteralExpression - This handles the various token types that
-/// form string literals, and also handles string concatenation [C99 5.1.1.2,
-/// translation phase #6].
-///
-/// primary-expression: [C99 6.5.1]
-/// string-literal
-Parser::ExprResult Parser::ParseStringLiteralExpression() {
- assert(isTokenStringLiteral() && "Not a string literal!");
-
- // String concat. Note that keywords like __func__ and __FUNCTION__ are not
- // considered to be strings for concatenation purposes.
- llvm::SmallVector<Token, 4> StringToks;
-
- do {
- StringToks.push_back(Tok);
- ConsumeStringToken();
- } while (isTokenStringLiteral());
-
- // Pass the set of string tokens, ready for concatenation, to the actions.
- return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size());
-}
-
-/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
-///
-/// argument-expression-list:
-/// assignment-expression
-/// argument-expression-list , assignment-expression
-///
-/// [C++] expression-list:
-/// [C++] assignment-expression
-/// [C++] expression-list , assignment-expression
-///
-bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
- while (1) {
- ExprResult Expr = ParseAssignmentExpression();
- if (Expr.isInvalid)
- return true;
-
- Exprs.push_back(Expr.Val);
-
- if (Tok.isNot(tok::comma))
- return false;
- // Move to the next argument, remember where the comma was.
- CommaLocs.push_back(ConsumeToken());
- }
-}
-
-/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
-/// like ^(int x){ return x+1; }
-///
-/// block-literal:
-/// [clang] '^' block-args[opt] compound-statement
-/// [clang] block-args:
-/// [clang] '(' parameter-list ')'
-///
-Parser::ExprResult Parser::ParseBlockLiteralExpression() {
- assert(Tok.is(tok::caret) && "block literal starts with ^");
- SourceLocation CaretLoc = ConsumeToken();
-
- // Enter a scope to hold everything within the block. This includes the
- // argument decls, decls within the compound expression, etc. This also
- // allows determining whether a variable reference inside the block is
- // within or outside of the block.
- EnterScope(Scope::BlockScope|Scope::FnScope|Scope::BreakScope|
- Scope::ContinueScope|Scope::DeclScope);
-
- // Parse the return type if present.
- DeclSpec DS;
- Declarator ParamInfo(DS, Declarator::PrototypeContext);
-
- // If this block has arguments, parse them. There is no ambiguity here with
- // the expression case, because the expression case requires a parameter list.
- if (Tok.is(tok::l_paren)) {
- ParseParenDeclarator(ParamInfo);
- // Parse the pieces after the identifier as if we had "int(...)".
- ParamInfo.SetIdentifier(0, CaretLoc);
- if (ParamInfo.getInvalidType()) {
- // If there was an error parsing the arguments, they may have tried to use
- // ^(x+y) which requires an argument list. Just skip the whole block
- // literal.
- ExitScope();
- return true;
- }
- } else {
- // Otherwise, pretend we saw (void).
- ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
- 0, 0, CaretLoc));
- }
-
- // Inform sema that we are starting a block.
- Actions.ActOnBlockStart(CaretLoc, CurScope, ParamInfo);
-
- ExprResult Result = true;
- if (Tok.is(tok::l_brace)) {
- StmtResult Stmt = ParseCompoundStatementBody();
- if (!Stmt.isInvalid) {
- Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope);
- } else {
- Actions.ActOnBlockError(CaretLoc, CurScope);
- }
- }
- ExitScope();
- return Result;
-}
-
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
deleted file mode 100644
index 8b4db3095084..000000000000
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Expression parsing implementation for C++.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-using namespace clang;
-
-/// ParseCXXCasts - This handles the various ways to cast expressions to another
-/// type.
-///
-/// postfix-expression: [C++ 5.2p1]
-/// 'dynamic_cast' '<' type-name '>' '(' expression ')'
-/// 'static_cast' '<' type-name '>' '(' expression ')'
-/// 'reinterpret_cast' '<' type-name '>' '(' expression ')'
-/// 'const_cast' '<' type-name '>' '(' expression ')'
-///
-Parser::ExprResult Parser::ParseCXXCasts() {
- tok::TokenKind Kind = Tok.getKind();
- const char *CastName = 0; // For error messages
-
- switch (Kind) {
- default: assert(0 && "Unknown C++ cast!"); abort();
- case tok::kw_const_cast: CastName = "const_cast"; break;
- case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;
- case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
- case tok::kw_static_cast: CastName = "static_cast"; break;
- }
-
- SourceLocation OpLoc = ConsumeToken();
- SourceLocation LAngleBracketLoc = Tok.getLocation();
-
- if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
- return ExprResult(true);
-
- TypeTy *CastTy = ParseTypeName();
- SourceLocation RAngleBracketLoc = Tok.getLocation();
-
- if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) {
- Diag(LAngleBracketLoc, diag::err_matching, "<");
- return ExprResult(true);
- }
-
- SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, CastName);
- return ExprResult(true);
- }
-
- ExprResult Result = ParseSimpleParenExpression(RParenLoc);
-
- if (!Result.isInvalid)
- Result = Actions.ActOnCXXCasts(OpLoc, Kind,
- LAngleBracketLoc, CastTy, RAngleBracketLoc,
- LParenLoc, Result.Val, RParenLoc);
-
- return Result;
-}
-
-/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
-///
-/// boolean-literal: [C++ 2.13.5]
-/// 'true'
-/// 'false'
-Parser::ExprResult Parser::ParseCXXBoolLiteral() {
- tok::TokenKind Kind = Tok.getKind();
- return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
-}
-
-/// ParseThrowExpression - This handles the C++ throw expression.
-///
-/// throw-expression: [C++ 15]
-/// 'throw' assignment-expression[opt]
-Parser::ExprResult Parser::ParseThrowExpression() {
- assert(Tok.is(tok::kw_throw) && "Not throw!");
- SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token.
-
- // If the current token isn't the start of an assignment-expression,
- // then the expression is not present. This handles things like:
- // "C ? throw : (void)42", which is crazy but legal.
- switch (Tok.getKind()) { // FIXME: move this predicate somewhere common.
- case tok::semi:
- case tok::r_paren:
- case tok::r_square:
- case tok::r_brace:
- case tok::colon:
- case tok::comma:
- return Actions.ActOnCXXThrow(ThrowLoc);
-
- default:
- ExprResult Expr = ParseAssignmentExpression();
- if (Expr.isInvalid) return Expr;
- return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val);
- }
-}
-
-/// ParseCXXThis - This handles the C++ 'this' pointer.
-///
-/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
-/// a non-lvalue expression whose value is the address of the object for which
-/// the function is called.
-Parser::ExprResult Parser::ParseCXXThis() {
- assert(Tok.is(tok::kw_this) && "Not 'this'!");
- SourceLocation ThisLoc = ConsumeToken();
- return Actions.ActOnCXXThis(ThisLoc);
-}
-
-/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
-/// Can be interpreted either as function-style casting ("int(x)")
-/// or class type construction ("ClassType(x,y,z)")
-/// or creation of a value-initialized type ("int()").
-///
-/// postfix-expression: [C++ 5.2p1]
-/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
-/// typename-specifier '(' expression-list[opt] ')' [TODO]
-///
-Parser::ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
- Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
- TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val;
-
- assert(Tok.is(tok::l_paren) && "Expected '('!");
- SourceLocation LParenLoc = ConsumeParen();
-
- ExprListTy Exprs;
- CommaLocsTy CommaLocs;
-
- if (Tok.isNot(tok::r_paren)) {
- if (ParseExpressionList(Exprs, CommaLocs)) {
- SkipUntil(tok::r_paren);
- return ExprResult(true);
- }
- }
-
- // Match the ')'.
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-
- assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
- "Unexpected number of commas!");
- return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
- LParenLoc,
- &Exprs[0], Exprs.size(),
- &CommaLocs[0], RParenLoc);
-}
-
-/// ParseCXXCondition - if/switch/while/for condition expression.
-///
-/// condition:
-/// expression
-/// type-specifier-seq declarator '=' assignment-expression
-/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
-/// '=' assignment-expression
-///
-Parser::ExprResult Parser::ParseCXXCondition() {
- if (!isCXXConditionDeclaration())
- return ParseExpression(); // expression
-
- SourceLocation StartLoc = Tok.getLocation();
-
- // type-specifier-seq
- DeclSpec DS;
- ParseSpecifierQualifierList(DS);
-
- // declarator
- Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
- ParseDeclarator(DeclaratorInfo);
-
- // simple-asm-expr[opt]
- if (Tok.is(tok::kw_asm)) {
- ExprResult AsmLabel = ParseSimpleAsm();
- if (AsmLabel.isInvalid) {
- SkipUntil(tok::semi);
- return true;
- }
- DeclaratorInfo.setAsmLabel(AsmLabel.Val);
- }
-
- // If attributes are present, parse them.
- if (Tok.is(tok::kw___attribute))
- DeclaratorInfo.AddAttributes(ParseAttributes());
-
- // '=' assignment-expression
- if (Tok.isNot(tok::equal))
- return Diag(Tok, diag::err_expected_equal_after_declarator);
- SourceLocation EqualLoc = ConsumeToken();
- ExprResult AssignExpr = ParseAssignmentExpression();
- if (AssignExpr.isInvalid)
- return true;
-
- return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
- DeclaratorInfo,
- EqualLoc, AssignExpr.Val);
-}
-
-/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
-/// This should only be called when the current token is known to be part of
-/// simple-type-specifier.
-///
-/// simple-type-specifier:
-/// '::'[opt] nested-name-specifier[opt] type-name [TODO]
-/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
-/// char
-/// wchar_t
-/// bool
-/// short
-/// int
-/// long
-/// signed
-/// unsigned
-/// float
-/// double
-/// void
-/// [GNU] typeof-specifier
-/// [C++0x] auto [TODO]
-///
-/// type-name:
-/// class-name
-/// enum-name
-/// typedef-name
-///
-void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
- DS.SetRangeStart(Tok.getLocation());
- const char *PrevSpec;
- SourceLocation Loc = Tok.getLocation();
-
- switch (Tok.getKind()) {
- default:
- assert(0 && "Not a simple-type-specifier token!");
- abort();
-
- // type-name
- case tok::identifier: {
- TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
- assert(TypeRep && "Identifier wasn't a type-name!");
- DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, TypeRep);
- break;
- }
-
- // builtin types
- case tok::kw_short:
- DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
- break;
- case tok::kw_long:
- DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
- break;
- case tok::kw_signed:
- DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
- break;
- case tok::kw_unsigned:
- DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
- break;
- case tok::kw_void:
- DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
- break;
- case tok::kw_char:
- DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
- break;
- case tok::kw_int:
- DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
- break;
- case tok::kw_float:
- DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
- break;
- case tok::kw_double:
- DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
- break;
- case tok::kw_wchar_t:
- DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
- break;
- case tok::kw_bool:
- DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
- break;
-
- // GNU typeof support.
- case tok::kw_typeof:
- ParseTypeofSpecifier(DS);
- DS.Finish(Diags, PP.getSourceManager(), getLang());
- return;
- }
- DS.SetRangeEnd(Tok.getLocation());
- ConsumeToken();
- DS.Finish(Diags, PP.getSourceManager(), getLang());
-}
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
deleted file mode 100644
index c7c08dccbcba..000000000000
--- a/clang/lib/Parse/ParseInit.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-//===--- ParseInit.cpp - Initializer Parsing ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements initializer parsing as specified by C99 6.7.8.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/SmallString.h"
-using namespace clang;
-
-
-/// MayBeDesignationStart - Return true if this token might be the start of a
-/// designator.
-static bool MayBeDesignationStart(tok::TokenKind K) {
- switch (K) {
- default: return false;
- case tok::period: // designator: '.' identifier
- case tok::l_square: // designator: array-designator
- case tok::identifier: // designation: identifier ':'
- return true;
- }
-}
-
-/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
-/// checking to see if the token stream starts with a designator.
-///
-/// designation:
-/// designator-list '='
-/// [GNU] array-designator
-/// [GNU] identifier ':'
-///
-/// designator-list:
-/// designator
-/// designator-list designator
-///
-/// designator:
-/// array-designator
-/// '.' identifier
-///
-/// array-designator:
-/// '[' constant-expression ']'
-/// [GNU] '[' constant-expression '...' constant-expression ']'
-///
-/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
-/// initializer. We need to consider this case when parsing array designators.
-///
-Parser::ExprResult Parser::ParseInitializerWithPotentialDesignator() {
- // Parse each designator in the designator list until we find an initializer.
- while (1) {
- switch (Tok.getKind()) {
- case tok::equal:
- // We read some number (at least one due to the grammar we implemented)
- // of designators and found an '=' sign. The following tokens must be
- // the initializer.
- ConsumeToken();
- return ParseInitializer();
-
- default: {
- // We read some number (at least one due to the grammar we implemented)
- // of designators and found something that isn't an = or an initializer.
- // If we have exactly one array designator [TODO CHECK], this is the GNU
- // 'designation: array-designator' extension. Otherwise, it is a parse
- // error.
- SourceLocation Loc = Tok.getLocation();
- ExprResult Init = ParseInitializer();
- if (Init.isInvalid) return Init;
-
- Diag(Tok, diag::ext_gnu_missing_equal_designator);
- return Init;
- }
- case tok::period:
- // designator: '.' identifier
- ConsumeToken();
- if (ExpectAndConsume(tok::identifier, diag::err_expected_ident))
- return ExprResult(true);
- break;
-
- case tok::l_square: {
- // array-designator: '[' constant-expression ']'
- // array-designator: '[' constant-expression '...' constant-expression ']'
- // When designation is empty, this can be '[' objc-message-expr ']'. Note
- // that we also have the case of [4][foo bar], which is the gnu designator
- // extension + objc message send.
- SourceLocation StartLoc = ConsumeBracket();
-
- // If Objective-C is enabled and this is a typename or other identifier
- // receiver, parse this as a message send expression.
- if (getLang().ObjC1 && isTokObjCMessageIdentifierReceiver()) {
- // FIXME: Emit ext_gnu_missing_equal_designator for inits like
- // [4][foo bar].
- IdentifierInfo *Name = Tok.getIdentifierInfo();
- ConsumeToken();
- return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, Name, 0);
- }
-
- // Note that we parse this as an assignment expression, not a constant
- // expression (allowing *=, =, etc) to handle the objc case. Sema needs
- // to validate that the expression is a constant.
- ExprResult Idx = ParseAssignmentExpression();
- if (Idx.isInvalid) {
- SkipUntil(tok::r_square);
- return Idx;
- }
-
- // Given an expression, we could either have a designator (if the next
- // tokens are '...' or ']' or an objc message send. If this is an objc
- // message send, handle it now. An objc-message send is the start of
- // an assignment-expression production.
- if (getLang().ObjC1 && Tok.isNot(tok::ellipsis) &&
- Tok.isNot(tok::r_square)) {
- // FIXME: Emit ext_gnu_missing_equal_designator for inits like
- // [4][foo bar].
- return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 0,Idx.Val);
- }
-
- // Handle the gnu array range extension.
- if (Tok.is(tok::ellipsis)) {
- Diag(Tok, diag::ext_gnu_array_range);
- ConsumeToken();
-
- ExprResult RHS = ParseConstantExpression();
- if (RHS.isInvalid) {
- SkipUntil(tok::r_square);
- return RHS;
- }
- }
-
- MatchRHSPunctuation(tok::r_square, StartLoc);
- break;
- }
- case tok::identifier: {
- // Due to the GNU "designation: identifier ':'" extension, we don't know
- // whether something starting with an identifier is an
- // assignment-expression or if it is an old-style structure field
- // designator.
- // TODO: Check that this is the first designator.
-
- // If this is the gross GNU extension, handle it now.
- if (NextToken().is(tok::colon)) {
- Diag(Tok, diag::ext_gnu_old_style_field_designator);
- ConsumeToken(); // The identifier.
- assert(Tok.is(tok::colon) && "NextToken() not working properly!");
- ConsumeToken();
- return ParseInitializer();
- }
-
- // Otherwise, parse the assignment-expression.
- return ParseAssignmentExpression();
- }
- }
- }
-}
-
-
-/// ParseInitializer
-/// initializer: [C99 6.7.8]
-/// assignment-expression
-/// '{' initializer-list '}'
-/// '{' initializer-list ',' '}'
-/// [GNU] '{' '}'
-///
-/// initializer-list:
-/// designation[opt] initializer
-/// initializer-list ',' designation[opt] initializer
-///
-Parser::ExprResult Parser::ParseInitializer() {
- if (Tok.isNot(tok::l_brace))
- return ParseAssignmentExpression();
-
- SourceLocation LBraceLoc = ConsumeBrace();
-
- // We support empty initializers, but tell the user that they aren't using
- // C99-clean code.
- if (Tok.is(tok::r_brace)) {
- Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
- // Match the '}'.
- return Actions.ActOnInitList(LBraceLoc, 0, 0, ConsumeBrace());
- }
- llvm::SmallVector<ExprTy*, 8> InitExprs;
- bool InitExprsOk = true;
-
- while (1) {
- // Parse: designation[opt] initializer
-
- // If we know that this cannot be a designation, just parse the nested
- // initializer directly.
- ExprResult SubElt;
- if (!MayBeDesignationStart(Tok.getKind()))
- SubElt = ParseInitializer();
- else
- SubElt = ParseInitializerWithPotentialDesignator();
-
- // If we couldn't parse the subelement, bail out.
- if (!SubElt.isInvalid) {
- InitExprs.push_back(SubElt.Val);
- } else {
- InitExprsOk = false;
-
- // We have two ways to try to recover from this error: if the code looks
- // gramatically ok (i.e. we have a comma comming up) try to continue
- // parsing the rest of the initializer. This allows us to emit
- // diagnostics for later elements that we find. If we don't see a comma,
- // assume there is a parse error, and just skip to recover.
- if (Tok.isNot(tok::comma)) {
- SkipUntil(tok::r_brace, false, true);
- break;
- }
- }
-
- // If we don't have a comma continued list, we're done.
- if (Tok.isNot(tok::comma)) break;
-
- // FIXME: save comma locations.
- ConsumeToken();
-
- // Handle trailing comma.
- if (Tok.is(tok::r_brace)) break;
- }
- if (InitExprsOk && Tok.is(tok::r_brace))
- return Actions.ActOnInitList(LBraceLoc, &InitExprs[0], InitExprs.size(),
- ConsumeBrace());
-
- // Delete any parsed subexpressions.
- for (unsigned i = 0, e = InitExprs.size(); i != e; ++i)
- Actions.DeleteExpr(InitExprs[i]);
-
- // Match the '}'.
- MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- return ExprResult(true); // an error occurred.
-}
-
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
deleted file mode 100644
index 0222b0401a5e..000000000000
--- a/clang/lib/Parse/ParseObjc.cpp
+++ /dev/null
@@ -1,1689 +0,0 @@
-//===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Objective-C portions of the Parser interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-using namespace clang;
-
-
-/// ParseExternalDeclaration:
-/// external-declaration: [C99 6.9]
-/// [OBJC] objc-class-definition
-/// [OBJC] objc-class-declaration
-/// [OBJC] objc-alias-declaration
-/// [OBJC] objc-protocol-definition
-/// [OBJC] objc-method-definition
-/// [OBJC] '@' 'end'
-Parser::DeclTy *Parser::ParseObjCAtDirectives() {
- SourceLocation AtLoc = ConsumeToken(); // the "@"
-
- switch (Tok.getObjCKeywordID()) {
- case tok::objc_class:
- return ParseObjCAtClassDeclaration(AtLoc);
- case tok::objc_interface:
- return ParseObjCAtInterfaceDeclaration(AtLoc);
- case tok::objc_protocol:
- return ParseObjCAtProtocolDeclaration(AtLoc);
- case tok::objc_implementation:
- return ParseObjCAtImplementationDeclaration(AtLoc);
- case tok::objc_end:
- return ParseObjCAtEndDeclaration(AtLoc);
- case tok::objc_compatibility_alias:
- return ParseObjCAtAliasDeclaration(AtLoc);
- case tok::objc_synthesize:
- return ParseObjCPropertySynthesize(AtLoc);
- case tok::objc_dynamic:
- return ParseObjCPropertyDynamic(AtLoc);
- default:
- Diag(AtLoc, diag::err_unexpected_at);
- SkipUntil(tok::semi);
- return 0;
- }
-}
-
-///
-/// objc-class-declaration:
-/// '@' 'class' identifier-list ';'
-///
-Parser::DeclTy *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
- ConsumeToken(); // the identifier "class"
- llvm::SmallVector<IdentifierInfo *, 8> ClassNames;
-
- while (1) {
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::semi);
- return 0;
- }
- ClassNames.push_back(Tok.getIdentifierInfo());
- ConsumeToken();
-
- if (Tok.isNot(tok::comma))
- break;
-
- ConsumeToken();
- }
-
- // Consume the ';'.
- if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
- return 0;
-
- return Actions.ActOnForwardClassDeclaration(atLoc,
- &ClassNames[0], ClassNames.size());
-}
-
-///
-/// objc-interface:
-/// objc-class-interface-attributes[opt] objc-class-interface
-/// objc-category-interface
-///
-/// objc-class-interface:
-/// '@' 'interface' identifier objc-superclass[opt]
-/// objc-protocol-refs[opt]
-/// objc-class-instance-variables[opt]
-/// objc-interface-decl-list
-/// @end
-///
-/// objc-category-interface:
-/// '@' 'interface' identifier '(' identifier[opt] ')'
-/// objc-protocol-refs[opt]
-/// objc-interface-decl-list
-/// @end
-///
-/// objc-superclass:
-/// ':' identifier
-///
-/// objc-class-interface-attributes:
-/// __attribute__((visibility("default")))
-/// __attribute__((visibility("hidden")))
-/// __attribute__((deprecated))
-/// __attribute__((unavailable))
-/// __attribute__((objc_exception)) - used by NSException on 64-bit
-///
-Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration(
- SourceLocation atLoc, AttributeList *attrList) {
- assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
- "ParseObjCAtInterfaceDeclaration(): Expected @interface");
- ConsumeToken(); // the "interface" identifier
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing class or category name.
- return 0;
- }
- // We have a class or category name - consume it.
- IdentifierInfo *nameId = Tok.getIdentifierInfo();
- SourceLocation nameLoc = ConsumeToken();
-
- if (Tok.is(tok::l_paren)) { // we have a category.
- SourceLocation lparenLoc = ConsumeParen();
- SourceLocation categoryLoc, rparenLoc;
- IdentifierInfo *categoryId = 0;
-
- // For ObjC2, the category name is optional (not an error).
- if (Tok.is(tok::identifier)) {
- categoryId = Tok.getIdentifierInfo();
- categoryLoc = ConsumeToken();
- } else if (!getLang().ObjC2) {
- Diag(Tok, diag::err_expected_ident); // missing category name.
- return 0;
- }
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_rparen);
- SkipUntil(tok::r_paren, false); // don't stop at ';'
- return 0;
- }
- rparenLoc = ConsumeParen();
-
- // Next, we need to check for any protocol references.
- SourceLocation EndProtoLoc;
- llvm::SmallVector<DeclTy *, 8> ProtocolRefs;
- if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
- return 0;
-
- if (attrList) // categories don't support attributes.
- Diag(Tok, diag::err_objc_no_attributes_on_category);
-
- DeclTy *CategoryType = Actions.ActOnStartCategoryInterface(atLoc,
- nameId, nameLoc, categoryId, categoryLoc,
- &ProtocolRefs[0], ProtocolRefs.size(),
- EndProtoLoc);
-
- ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
-
- // The @ sign was already consumed by ParseObjCInterfaceDeclList().
- if (Tok.isObjCAtKeyword(tok::objc_end)) {
- ConsumeToken(); // the "end" identifier
- return CategoryType;
- }
- Diag(Tok, diag::err_objc_missing_end);
- return 0;
- }
- // Parse a class interface.
- IdentifierInfo *superClassId = 0;
- SourceLocation superClassLoc;
-
- if (Tok.is(tok::colon)) { // a super class is specified.
- ConsumeToken();
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing super class name.
- return 0;
- }
- superClassId = Tok.getIdentifierInfo();
- superClassLoc = ConsumeToken();
- }
- // Next, we need to check for any protocol references.
- llvm::SmallVector<Action::DeclTy*, 8> ProtocolRefs;
- SourceLocation EndProtoLoc;
- if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
- return 0;
-
- DeclTy *ClsType =
- Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc,
- superClassId, superClassLoc,
- &ProtocolRefs[0], ProtocolRefs.size(),
- EndProtoLoc, attrList);
-
- if (Tok.is(tok::l_brace))
- ParseObjCClassInstanceVariables(ClsType, atLoc);
-
- ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
-
- // The @ sign was already consumed by ParseObjCInterfaceDeclList().
- if (Tok.isObjCAtKeyword(tok::objc_end)) {
- ConsumeToken(); // the "end" identifier
- return ClsType;
- }
- Diag(Tok, diag::err_objc_missing_end);
- return 0;
-}
-
-/// constructSetterName - Return the setter name for the given
-/// identifier, i.e. "set" + Name where the initial character of Name
-/// has been capitalized.
-static IdentifierInfo *constructSetterName(IdentifierTable &Idents,
- const IdentifierInfo *Name) {
- unsigned N = Name->getLength();
- char *SelectorName = new char[3 + N];
- memcpy(SelectorName, "set", 3);
- memcpy(&SelectorName[3], Name->getName(), N);
- SelectorName[3] = toupper(SelectorName[3]);
-
- IdentifierInfo *Setter =
- &Idents.get(SelectorName, &SelectorName[3 + N]);
- delete[] SelectorName;
- return Setter;
-}
-
-/// objc-interface-decl-list:
-/// empty
-/// objc-interface-decl-list objc-property-decl [OBJC2]
-/// objc-interface-decl-list objc-method-requirement [OBJC2]
-/// objc-interface-decl-list objc-method-proto ';'
-/// objc-interface-decl-list declaration
-/// objc-interface-decl-list ';'
-///
-/// objc-method-requirement: [OBJC2]
-/// @required
-/// @optional
-///
-void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
- tok::ObjCKeywordKind contextKey) {
- llvm::SmallVector<DeclTy*, 32> allMethods;
- llvm::SmallVector<DeclTy*, 16> allProperties;
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
- SourceLocation AtEndLoc;
-
- while (1) {
- if (Tok.is(tok::at)) {
- SourceLocation AtLoc = ConsumeToken(); // the "@"
- tok::ObjCKeywordKind ocKind = Tok.getObjCKeywordID();
-
- if (ocKind == tok::objc_end) { // terminate list
- AtEndLoc = AtLoc;
- break;
- } else if (ocKind == tok::objc_required) { // protocols only
- ConsumeToken();
- MethodImplKind = ocKind;
- if (contextKey != tok::objc_protocol)
- Diag(AtLoc, diag::err_objc_protocol_required);
- } else if (ocKind == tok::objc_optional) { // protocols only
- ConsumeToken();
- MethodImplKind = ocKind;
- if (contextKey != tok::objc_protocol)
- Diag(AtLoc, diag::err_objc_protocol_optional);
- } else if (ocKind == tok::objc_property) {
- ObjCDeclSpec OCDS;
- ConsumeToken(); // the "property" identifier
- // Parse property attribute list, if any.
- if (Tok.is(tok::l_paren)) {
- // property has attribute list.
- ParseObjCPropertyAttribute(OCDS);
- }
- // Parse all the comma separated declarators.
- DeclSpec DS;
- llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
- ParseStructDeclaration(DS, FieldDeclarators);
-
- if (Tok.is(tok::semi))
- ConsumeToken();
- else {
- Diag(Tok, diag::err_expected_semi_decl_list);
- SkipUntil(tok::r_brace, true, true);
- }
- // Convert them all to property declarations.
- for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
- FieldDeclarator &FD = FieldDeclarators[i];
- // Install the property declarator into interfaceDecl.
- Selector GetterSel =
- PP.getSelectorTable().getNullarySelector(OCDS.getGetterName()
- ? OCDS.getGetterName()
- : FD.D.getIdentifier());
- IdentifierInfo *SetterName = OCDS.getSetterName();
- if (!SetterName)
- SetterName = constructSetterName(PP.getIdentifierTable(),
- FD.D.getIdentifier());
- Selector SetterSel =
- PP.getSelectorTable().getUnarySelector(SetterName);
- DeclTy *Property = Actions.ActOnProperty(CurScope,
- AtLoc, FD, OCDS,
- GetterSel, SetterSel,
- MethodImplKind);
- allProperties.push_back(Property);
- }
- continue;
- } else {
- Diag(Tok, diag::err_objc_illegal_interface_qual);
- ConsumeToken();
- }
- }
- if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
- DeclTy *methodPrototype =
- ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
- allMethods.push_back(methodPrototype);
- // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
- // method definitions.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,"method proto");
- continue;
- }
- else if (Tok.is(tok::at))
- continue;
-
- if (Tok.is(tok::semi))
- ConsumeToken();
- else if (Tok.is(tok::eof))
- break;
- else {
- // FIXME: as the name implies, this rule allows function definitions.
- // We could pass a flag or check for functions during semantic analysis.
- ParseDeclarationOrFunctionDefinition();
- }
- }
- /// Insert collected methods declarations into the @interface object.
- Actions.ActOnAtEnd(AtEndLoc, interfaceDecl,
- allMethods.empty() ? 0 : &allMethods[0],
- allMethods.size(),
- allProperties.empty() ? 0 : &allProperties[0],
- allProperties.size());
-}
-
-/// Parse property attribute declarations.
-///
-/// property-attr-decl: '(' property-attrlist ')'
-/// property-attrlist:
-/// property-attribute
-/// property-attrlist ',' property-attribute
-/// property-attribute:
-/// getter '=' identifier
-/// setter '=' identifier ':'
-/// readonly
-/// readwrite
-/// assign
-/// retain
-/// copy
-/// nonatomic
-///
-void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
- SourceLocation loc = ConsumeParen(); // consume '('
- while (isObjCPropertyAttribute()) {
- const IdentifierInfo *II = Tok.getIdentifierInfo();
- // getter/setter require extra treatment.
- if (II == ObjCPropertyAttrs[objc_getter] ||
- II == ObjCPropertyAttrs[objc_setter]) {
- // skip getter/setter part.
- SourceLocation loc = ConsumeToken();
- if (Tok.is(tok::equal)) {
- loc = ConsumeToken();
- if (Tok.is(tok::identifier)) {
- if (II == ObjCPropertyAttrs[objc_setter]) {
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
- DS.setSetterName(Tok.getIdentifierInfo());
- loc = ConsumeToken(); // consume method name
- if (Tok.isNot(tok::colon)) {
- Diag(loc, diag::err_expected_colon);
- SkipUntil(tok::r_paren,true,true);
- break;
- }
- }
- else {
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
- DS.setGetterName(Tok.getIdentifierInfo());
- }
- }
- else {
- Diag(loc, diag::err_expected_ident);
- SkipUntil(tok::r_paren,true,true);
- break;
- }
- }
- else {
- Diag(loc, diag::err_objc_expected_equal);
- SkipUntil(tok::r_paren,true,true);
- break;
- }
- }
-
- else if (II == ObjCPropertyAttrs[objc_readonly])
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
- else if (II == ObjCPropertyAttrs[objc_assign])
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
- else if (II == ObjCPropertyAttrs[objc_readwrite])
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
- else if (II == ObjCPropertyAttrs[objc_retain])
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
- else if (II == ObjCPropertyAttrs[objc_copy])
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
- else if (II == ObjCPropertyAttrs[objc_nonatomic])
- DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
-
- ConsumeToken(); // consume last attribute token
- if (Tok.is(tok::comma)) {
- loc = ConsumeToken();
- continue;
- }
- if (Tok.is(tok::r_paren))
- break;
- Diag(loc, diag::err_expected_rparen);
- SkipUntil(tok::semi);
- return;
- }
- if (Tok.is(tok::r_paren))
- ConsumeParen();
- else {
- Diag(loc, diag::err_objc_expected_property_attr);
- SkipUntil(tok::r_paren); // recover from error inside attribute list
- }
-}
-
-/// objc-method-proto:
-/// objc-instance-method objc-method-decl objc-method-attributes[opt]
-/// objc-class-method objc-method-decl objc-method-attributes[opt]
-///
-/// objc-instance-method: '-'
-/// objc-class-method: '+'
-///
-/// objc-method-attributes: [OBJC2]
-/// __attribute__((deprecated))
-///
-Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *IDecl,
- tok::ObjCKeywordKind MethodImplKind) {
- assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
-
- tok::TokenKind methodType = Tok.getKind();
- SourceLocation mLoc = ConsumeToken();
-
- DeclTy *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl, MethodImplKind);
- // Since this rule is used for both method declarations and definitions,
- // the caller is (optionally) responsible for consuming the ';'.
- return MDecl;
-}
-
-/// objc-selector:
-/// identifier
-/// one of
-/// enum struct union if else while do for switch case default
-/// break continue return goto asm sizeof typeof __alignof
-/// unsigned long const short volatile signed restrict _Complex
-/// in out inout bycopy byref oneway int char float double void _Bool
-///
-IdentifierInfo *Parser::ParseObjCSelector(SourceLocation &SelectorLoc) {
- switch (Tok.getKind()) {
- default:
- return 0;
- case tok::identifier:
- case tok::kw_asm:
- case tok::kw_auto:
- case tok::kw_bool:
- case tok::kw_break:
- case tok::kw_case:
- case tok::kw_catch:
- case tok::kw_char:
- case tok::kw_class:
- case tok::kw_const:
- case tok::kw_const_cast:
- case tok::kw_continue:
- case tok::kw_default:
- case tok::kw_delete:
- case tok::kw_do:
- case tok::kw_double:
- case tok::kw_dynamic_cast:
- case tok::kw_else:
- case tok::kw_enum:
- case tok::kw_explicit:
- case tok::kw_export:
- case tok::kw_extern:
- case tok::kw_false:
- case tok::kw_float:
- case tok::kw_for:
- case tok::kw_friend:
- case tok::kw_goto:
- case tok::kw_if:
- case tok::kw_inline:
- case tok::kw_int:
- case tok::kw_long:
- case tok::kw_mutable:
- case tok::kw_namespace:
- case tok::kw_new:
- case tok::kw_operator:
- case tok::kw_private:
- case tok::kw_protected:
- case tok::kw_public:
- case tok::kw_register:
- case tok::kw_reinterpret_cast:
- case tok::kw_restrict:
- case tok::kw_return:
- case tok::kw_short:
- case tok::kw_signed:
- case tok::kw_sizeof:
- case tok::kw_static:
- case tok::kw_static_cast:
- case tok::kw_struct:
- case tok::kw_switch:
- case tok::kw_template:
- case tok::kw_this:
- case tok::kw_throw:
- case tok::kw_true:
- case tok::kw_try:
- case tok::kw_typedef:
- case tok::kw_typeid:
- case tok::kw_typename:
- case tok::kw_typeof:
- case tok::kw_union:
- case tok::kw_unsigned:
- case tok::kw_using:
- case tok::kw_virtual:
- case tok::kw_void:
- case tok::kw_volatile:
- case tok::kw_wchar_t:
- case tok::kw_while:
- case tok::kw__Bool:
- case tok::kw__Complex:
- case tok::kw___alignof:
- IdentifierInfo *II = Tok.getIdentifierInfo();
- SelectorLoc = ConsumeToken();
- return II;
- }
-}
-
-/// property-attrlist: one of
-/// readonly getter setter assign retain copy nonatomic
-///
-bool Parser::isObjCPropertyAttribute() {
- if (Tok.is(tok::identifier)) {
- const IdentifierInfo *II = Tok.getIdentifierInfo();
- for (unsigned i = 0; i < objc_NumAttrs; ++i)
- if (II == ObjCPropertyAttrs[i]) return true;
- }
- return false;
-}
-
-/// objc-for-collection-in: 'in'
-///
-bool Parser::isTokIdentifier_in() const {
- // FIXME: May have to do additional look-ahead to only allow for
- // valid tokens following an 'in'; such as an identifier, unary operators,
- // '[' etc.
- return (getLang().ObjC2 && Tok.is(tok::identifier) &&
- Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
-}
-
-/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
-/// qualifier list and builds their bitmask representation in the input
-/// argument.
-///
-/// objc-type-qualifiers:
-/// objc-type-qualifier
-/// objc-type-qualifiers objc-type-qualifier
-///
-void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) {
- while (1) {
- if (Tok.isNot(tok::identifier))
- return;
-
- const IdentifierInfo *II = Tok.getIdentifierInfo();
- for (unsigned i = 0; i != objc_NumQuals; ++i) {
- if (II != ObjCTypeQuals[i])
- continue;
-
- ObjCDeclSpec::ObjCDeclQualifier Qual;
- switch (i) {
- default: assert(0 && "Unknown decl qualifier");
- case objc_in: Qual = ObjCDeclSpec::DQ_In; break;
- case objc_out: Qual = ObjCDeclSpec::DQ_Out; break;
- case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break;
- case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
- case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
- case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break;
- }
- DS.setObjCDeclQualifier(Qual);
- ConsumeToken();
- II = 0;
- break;
- }
-
- // If this wasn't a recognized qualifier, bail out.
- if (II) return;
- }
-}
-
-/// objc-type-name:
-/// '(' objc-type-qualifiers[opt] type-name ')'
-/// '(' objc-type-qualifiers[opt] ')'
-///
-Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
- assert(Tok.is(tok::l_paren) && "expected (");
-
- SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
- SourceLocation TypeStartLoc = Tok.getLocation();
- TypeTy *Ty = 0;
-
- // Parse type qualifiers, in, inout, etc.
- ParseObjCTypeQualifierList(DS);
-
- if (isTypeSpecifierQualifier()) {
- Ty = ParseTypeName();
- // FIXME: back when Sema support is in place...
- // assert(Ty && "Parser::ParseObjCTypeName(): missing type");
- }
-
- if (Tok.isNot(tok::r_paren)) {
- // If we didn't eat any tokens, then this isn't a type.
- if (Tok.getLocation() == TypeStartLoc) {
- Diag(Tok.getLocation(), diag::err_expected_type);
- SkipUntil(tok::r_brace);
- } else {
- // Otherwise, we found *something*, but didn't get a ')' in the right
- // place. Emit an error then return what we have as the type.
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- }
- }
- RParenLoc = ConsumeParen();
- return Ty;
-}
-
-/// objc-method-decl:
-/// objc-selector
-/// objc-keyword-selector objc-parmlist[opt]
-/// objc-type-name objc-selector
-/// objc-type-name objc-keyword-selector objc-parmlist[opt]
-///
-/// objc-keyword-selector:
-/// objc-keyword-decl
-/// objc-keyword-selector objc-keyword-decl
-///
-/// objc-keyword-decl:
-/// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
-/// objc-selector ':' objc-keyword-attributes[opt] identifier
-/// ':' objc-type-name objc-keyword-attributes[opt] identifier
-/// ':' objc-keyword-attributes[opt] identifier
-///
-/// objc-parmlist:
-/// objc-parms objc-ellipsis[opt]
-///
-/// objc-parms:
-/// objc-parms , parameter-declaration
-///
-/// objc-ellipsis:
-/// , ...
-///
-/// objc-keyword-attributes: [OBJC2]
-/// __attribute__((unused))
-///
-Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
- tok::TokenKind mType,
- DeclTy *IDecl,
- tok::ObjCKeywordKind MethodImplKind)
-{
- // Parse the return type if present.
- TypeTy *ReturnType = 0;
- ObjCDeclSpec DSRet;
- if (Tok.is(tok::l_paren))
- ReturnType = ParseObjCTypeName(DSRet);
-
- SourceLocation selLoc;
- IdentifierInfo *SelIdent = ParseObjCSelector(selLoc);
-
- if (!SelIdent) { // missing selector name.
- Diag(Tok.getLocation(), diag::err_expected_selector_for_method,
- SourceRange(mLoc, Tok.getLocation()));
- // Skip until we get a ; or {}.
- SkipUntil(tok::r_brace);
- return 0;
- }
-
- if (Tok.isNot(tok::colon)) {
- // If attributes exist after the method, parse them.
- AttributeList *MethodAttrs = 0;
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs = ParseAttributes();
-
- Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
- return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
- mType, IDecl, DSRet, ReturnType, Sel,
- 0, 0, 0, MethodAttrs, MethodImplKind);
- }
-
- llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
- llvm::SmallVector<Action::TypeTy *, 12> KeyTypes;
- llvm::SmallVector<ObjCDeclSpec, 12> ArgTypeQuals;
- llvm::SmallVector<IdentifierInfo *, 12> ArgNames;
-
- Action::TypeTy *TypeInfo;
- while (1) {
- KeyIdents.push_back(SelIdent);
-
- // Each iteration parses a single keyword argument.
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon);
- break;
- }
- ConsumeToken(); // Eat the ':'.
- ObjCDeclSpec DSType;
- if (Tok.is(tok::l_paren)) // Parse the argument type.
- TypeInfo = ParseObjCTypeName(DSType);
- else
- TypeInfo = 0;
- KeyTypes.push_back(TypeInfo);
- ArgTypeQuals.push_back(DSType);
-
- // If attributes exist before the argument name, parse them.
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- ParseAttributes(); // FIXME: pass attributes through.
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing argument name.
- break;
- }
- ArgNames.push_back(Tok.getIdentifierInfo());
- ConsumeToken(); // Eat the identifier.
-
- // Check for another keyword selector.
- SourceLocation Loc;
- SelIdent = ParseObjCSelector(Loc);
- if (!SelIdent && Tok.isNot(tok::colon))
- break;
- // We have a selector or a colon, continue parsing.
- }
-
- bool isVariadic = false;
-
- // Parse the (optional) parameter list.
- while (Tok.is(tok::comma)) {
- ConsumeToken();
- if (Tok.is(tok::ellipsis)) {
- isVariadic = true;
- ConsumeToken();
- break;
- }
- // FIXME: implement this...
- // Parse the c-style argument declaration-specifier.
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
- // Parse the declarator.
- Declarator ParmDecl(DS, Declarator::PrototypeContext);
- ParseDeclarator(ParmDecl);
- }
-
- // FIXME: Add support for optional parmameter list...
- // If attributes exist after the method, parse them.
- AttributeList *MethodAttrs = 0;
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs = ParseAttributes();
-
- Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
- &KeyIdents[0]);
- return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
- mType, IDecl, DSRet, ReturnType, Sel,
- &ArgTypeQuals[0], &KeyTypes[0],
- &ArgNames[0], MethodAttrs,
- MethodImplKind, isVariadic);
-}
-
-/// objc-protocol-refs:
-/// '<' identifier-list '>'
-///
-bool Parser::
-ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &Protocols,
- bool WarnOnDeclarations, SourceLocation &EndLoc) {
- assert(Tok.is(tok::less) && "expected <");
-
- ConsumeToken(); // the "<"
-
- llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;
-
- while (1) {
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::greater);
- return true;
- }
- ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
- Tok.getLocation()));
- ConsumeToken();
-
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken();
- }
-
- // Consume the '>'.
- if (Tok.isNot(tok::greater)) {
- Diag(Tok, diag::err_expected_greater);
- return true;
- }
-
- EndLoc = ConsumeAnyToken();
-
- // Convert the list of protocols identifiers into a list of protocol decls.
- Actions.FindProtocolDeclaration(WarnOnDeclarations,
- &ProtocolIdents[0], ProtocolIdents.size(),
- Protocols);
- return false;
-}
-
-/// objc-class-instance-variables:
-/// '{' objc-instance-variable-decl-list[opt] '}'
-///
-/// objc-instance-variable-decl-list:
-/// objc-visibility-spec
-/// objc-instance-variable-decl ';'
-/// ';'
-/// objc-instance-variable-decl-list objc-visibility-spec
-/// objc-instance-variable-decl-list objc-instance-variable-decl ';'
-/// objc-instance-variable-decl-list ';'
-///
-/// objc-visibility-spec:
-/// @private
-/// @protected
-/// @public
-/// @package [OBJC2]
-///
-/// objc-instance-variable-decl:
-/// struct-declaration
-///
-void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
- SourceLocation atLoc) {
- assert(Tok.is(tok::l_brace) && "expected {");
- llvm::SmallVector<DeclTy*, 32> AllIvarDecls;
- llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
-
- SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
-
- tok::ObjCKeywordKind visibility = tok::objc_protected;
- // While we still have something to read, read the instance variables.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- // Each iteration of this loop reads one objc-instance-variable-decl.
-
- // Check for extraneous top-level semicolon.
- if (Tok.is(tok::semi)) {
- Diag(Tok, diag::ext_extra_struct_semi);
- ConsumeToken();
- continue;
- }
-
- // Set the default visibility to private.
- if (Tok.is(tok::at)) { // parse objc-visibility-spec
- ConsumeToken(); // eat the @ sign
- switch (Tok.getObjCKeywordID()) {
- case tok::objc_private:
- case tok::objc_public:
- case tok::objc_protected:
- case tok::objc_package:
- visibility = Tok.getObjCKeywordID();
- ConsumeToken();
- continue;
- default:
- Diag(Tok, diag::err_objc_illegal_visibility_spec);
- continue;
- }
- }
-
- // Parse all the comma separated declarators.
- DeclSpec DS;
- FieldDeclarators.clear();
- ParseStructDeclaration(DS, FieldDeclarators);
-
- // Convert them all to fields.
- for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
- FieldDeclarator &FD = FieldDeclarators[i];
- // Install the declarator into interfaceDecl.
- DeclTy *Field = Actions.ActOnIvar(CurScope,
- DS.getSourceRange().getBegin(),
- FD.D, FD.BitfieldSize, visibility);
- AllIvarDecls.push_back(Field);
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- } else {
- Diag(Tok, diag::err_expected_semi_decl_list);
- // Skip to end of block or statement
- SkipUntil(tok::r_brace, true, true);
- }
- }
- SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- // Call ActOnFields() even if we don't have any decls. This is useful
- // for code rewriting tools that need to be aware of the empty list.
- Actions.ActOnFields(CurScope, atLoc, interfaceDecl,
- &AllIvarDecls[0], AllIvarDecls.size(),
- LBraceLoc, RBraceLoc, 0);
- return;
-}
-
-/// objc-protocol-declaration:
-/// objc-protocol-definition
-/// objc-protocol-forward-reference
-///
-/// objc-protocol-definition:
-/// @protocol identifier
-/// objc-protocol-refs[opt]
-/// objc-interface-decl-list
-/// @end
-///
-/// objc-protocol-forward-reference:
-/// @protocol identifier-list ';'
-///
-/// "@protocol identifier ;" should be resolved as "@protocol
-/// identifier-list ;": objc-interface-decl-list may not start with a
-/// semicolon in the first alternative if objc-protocol-refs are omitted.
-Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
- AttributeList *attrList) {
- assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
- "ParseObjCAtProtocolDeclaration(): Expected @protocol");
- ConsumeToken(); // the "protocol" identifier
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing protocol name.
- return 0;
- }
- // Save the protocol name, then consume it.
- IdentifierInfo *protocolName = Tok.getIdentifierInfo();
- SourceLocation nameLoc = ConsumeToken();
-
- if (Tok.is(tok::semi)) { // forward declaration of one protocol.
- IdentifierLocPair ProtoInfo(protocolName, nameLoc);
- ConsumeToken();
- return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1);
- }
-
- if (Tok.is(tok::comma)) { // list of forward declarations.
- llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
- ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
-
- // Parse the list of forward declarations.
- while (1) {
- ConsumeToken(); // the ','
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::semi);
- return 0;
- }
- ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
- Tok.getLocation()));
- ConsumeToken(); // the identifier
-
- if (Tok.isNot(tok::comma))
- break;
- }
- // Consume the ';'.
- if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
- return 0;
-
- return Actions.ActOnForwardProtocolDeclaration(AtLoc,
- &ProtocolRefs[0],
- ProtocolRefs.size());
- }
-
- // Last, and definitely not least, parse a protocol declaration.
- SourceLocation EndProtoLoc;
-
- llvm::SmallVector<DeclTy *, 8> ProtocolRefs;
- if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
- return 0;
-
- DeclTy *ProtoType =
- Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
- &ProtocolRefs[0], ProtocolRefs.size(),
- EndProtoLoc, attrList);
- ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
-
- // The @ sign was already consumed by ParseObjCInterfaceDeclList().
- if (Tok.isObjCAtKeyword(tok::objc_end)) {
- ConsumeToken(); // the "end" identifier
- return ProtoType;
- }
- Diag(Tok, diag::err_objc_missing_end);
- return 0;
-}
-
-/// objc-implementation:
-/// objc-class-implementation-prologue
-/// objc-category-implementation-prologue
-///
-/// objc-class-implementation-prologue:
-/// @implementation identifier objc-superclass[opt]
-/// objc-class-instance-variables[opt]
-///
-/// objc-category-implementation-prologue:
-/// @implementation identifier ( identifier )
-
-Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration(
- SourceLocation atLoc) {
- assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
- "ParseObjCAtImplementationDeclaration(): Expected @implementation");
- ConsumeToken(); // the "implementation" identifier
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing class or category name.
- return 0;
- }
- // We have a class or category name - consume it.
- IdentifierInfo *nameId = Tok.getIdentifierInfo();
- SourceLocation nameLoc = ConsumeToken(); // consume class or category name
-
- if (Tok.is(tok::l_paren)) {
- // we have a category implementation.
- SourceLocation lparenLoc = ConsumeParen();
- SourceLocation categoryLoc, rparenLoc;
- IdentifierInfo *categoryId = 0;
-
- if (Tok.is(tok::identifier)) {
- categoryId = Tok.getIdentifierInfo();
- categoryLoc = ConsumeToken();
- } else {
- Diag(Tok, diag::err_expected_ident); // missing category name.
- return 0;
- }
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_rparen);
- SkipUntil(tok::r_paren, false); // don't stop at ';'
- return 0;
- }
- rparenLoc = ConsumeParen();
- DeclTy *ImplCatType = Actions.ActOnStartCategoryImplementation(
- atLoc, nameId, nameLoc, categoryId,
- categoryLoc);
- ObjCImpDecl = ImplCatType;
- return 0;
- }
- // We have a class implementation
- SourceLocation superClassLoc;
- IdentifierInfo *superClassId = 0;
- if (Tok.is(tok::colon)) {
- // We have a super class
- ConsumeToken();
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident); // missing super class name.
- return 0;
- }
- superClassId = Tok.getIdentifierInfo();
- superClassLoc = ConsumeToken(); // Consume super class name
- }
- DeclTy *ImplClsType = Actions.ActOnStartClassImplementation(
- atLoc, nameId, nameLoc,
- superClassId, superClassLoc);
-
- if (Tok.is(tok::l_brace)) // we have ivars
- ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
- ObjCImpDecl = ImplClsType;
-
- return 0;
-}
-
-Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
- assert(Tok.isObjCAtKeyword(tok::objc_end) &&
- "ParseObjCAtEndDeclaration(): Expected @end");
- ConsumeToken(); // the "end" identifier
- if (ObjCImpDecl)
- Actions.ActOnAtEnd(atLoc, ObjCImpDecl);
- else
- Diag(atLoc, diag::warn_expected_implementation); // missing @implementation
- return ObjCImpDecl;
-}
-
-/// compatibility-alias-decl:
-/// @compatibility_alias alias-name class-name ';'
-///
-Parser::DeclTy *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
- assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
- "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
- ConsumeToken(); // consume compatibility_alias
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return 0;
- }
- IdentifierInfo *aliasId = Tok.getIdentifierInfo();
- SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return 0;
- }
- IdentifierInfo *classId = Tok.getIdentifierInfo();
- SourceLocation classLoc = ConsumeToken(); // consume class-name;
- if (Tok.isNot(tok::semi)) {
- Diag(Tok, diag::err_expected_semi_after, "@compatibility_alias");
- return 0;
- }
- DeclTy *ClsType = Actions.ActOnCompatiblityAlias(atLoc,
- aliasId, aliasLoc,
- classId, classLoc);
- return ClsType;
-}
-
-/// property-synthesis:
-/// @synthesize property-ivar-list ';'
-///
-/// property-ivar-list:
-/// property-ivar
-/// property-ivar-list ',' property-ivar
-///
-/// property-ivar:
-/// identifier
-/// identifier '=' identifier
-///
-Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
- assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
- "ParseObjCPropertyDynamic(): Expected '@synthesize'");
- SourceLocation loc = ConsumeToken(); // consume synthesize
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return 0;
- }
- while (Tok.is(tok::identifier)) {
- IdentifierInfo *propertyIvar = 0;
- IdentifierInfo *propertyId = Tok.getIdentifierInfo();
- SourceLocation propertyLoc = ConsumeToken(); // consume property name
- if (Tok.is(tok::equal)) {
- // property '=' ivar-name
- ConsumeToken(); // consume '='
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- break;
- }
- propertyIvar = Tok.getIdentifierInfo();
- ConsumeToken(); // consume ivar-name
- }
- Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
- propertyId, propertyIvar);
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken(); // consume ','
- }
- if (Tok.isNot(tok::semi))
- Diag(Tok, diag::err_expected_semi_after, "@synthesize");
- return 0;
-}
-
-/// property-dynamic:
-/// @dynamic property-list
-///
-/// property-list:
-/// identifier
-/// property-list ',' identifier
-///
-Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
- assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
- "ParseObjCPropertyDynamic(): Expected '@dynamic'");
- SourceLocation loc = ConsumeToken(); // consume dynamic
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return 0;
- }
- while (Tok.is(tok::identifier)) {
- IdentifierInfo *propertyId = Tok.getIdentifierInfo();
- SourceLocation propertyLoc = ConsumeToken(); // consume property name
- Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
- propertyId, 0);
-
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken(); // consume ','
- }
- if (Tok.isNot(tok::semi))
- Diag(Tok, diag::err_expected_semi_after, "@dynamic");
- return 0;
-}
-
-/// objc-throw-statement:
-/// throw expression[opt];
-///
-Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
- ExprResult Res;
- ConsumeToken(); // consume throw
- if (Tok.isNot(tok::semi)) {
- Res = ParseExpression();
- if (Res.isInvalid) {
- SkipUntil(tok::semi);
- return true;
- }
- }
- ConsumeToken(); // consume ';'
- return Actions.ActOnObjCAtThrowStmt(atLoc, Res.Val);
-}
-
-/// objc-synchronized-statement:
-/// @synchronized '(' expression ')' compound-statement
-///
-Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
- ConsumeToken(); // consume synchronized
- if (Tok.isNot(tok::l_paren)) {
- Diag (Tok, diag::err_expected_lparen_after, "@synchronized");
- return true;
- }
- ConsumeParen(); // '('
- ExprResult Res = ParseExpression();
- if (Res.isInvalid) {
- SkipUntil(tok::semi);
- return true;
- }
- if (Tok.isNot(tok::r_paren)) {
- Diag (Tok, diag::err_expected_lbrace);
- return true;
- }
- ConsumeParen(); // ')'
- if (Tok.isNot(tok::l_brace)) {
- Diag (Tok, diag::err_expected_lbrace);
- return true;
- }
- // Enter a scope to hold everything within the compound stmt. Compound
- // statements can always hold declarations.
- EnterScope(Scope::DeclScope);
-
- StmtResult SynchBody = ParseCompoundStatementBody();
-
- ExitScope();
- if (SynchBody.isInvalid)
- SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
- return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.Val, SynchBody.Val);
-}
-
-/// objc-try-catch-statement:
-/// @try compound-statement objc-catch-list[opt]
-/// @try compound-statement objc-catch-list[opt] @finally compound-statement
-///
-/// objc-catch-list:
-/// @catch ( parameter-declaration ) compound-statement
-/// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
-/// catch-parameter-declaration:
-/// parameter-declaration
-/// '...' [OBJC2]
-///
-Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
- bool catch_or_finally_seen = false;
-
- ConsumeToken(); // consume try
- if (Tok.isNot(tok::l_brace)) {
- Diag (Tok, diag::err_expected_lbrace);
- return true;
- }
- StmtResult CatchStmts;
- StmtResult FinallyStmt;
- EnterScope(Scope::DeclScope);
- StmtResult TryBody = ParseCompoundStatementBody();
- ExitScope();
- if (TryBody.isInvalid)
- TryBody = Actions.ActOnNullStmt(Tok.getLocation());
-
- while (Tok.is(tok::at)) {
- // At this point, we need to lookahead to determine if this @ is the start
- // of an @catch or @finally. We don't want to consume the @ token if this
- // is an @try or @encode or something else.
- Token AfterAt = GetLookAheadToken(1);
- if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
- !AfterAt.isObjCAtKeyword(tok::objc_finally))
- break;
-
- SourceLocation AtCatchFinallyLoc = ConsumeToken();
- if (Tok.isObjCAtKeyword(tok::objc_catch)) {
- StmtTy *FirstPart = 0;
- ConsumeToken(); // consume catch
- if (Tok.is(tok::l_paren)) {
- ConsumeParen();
- EnterScope(Scope::DeclScope);
- if (Tok.isNot(tok::ellipsis)) {
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
- // For some odd reason, the name of the exception variable is
- // optional. As a result, we need to use PrototypeContext.
- Declarator DeclaratorInfo(DS, Declarator::PrototypeContext);
- ParseDeclarator(DeclaratorInfo);
- if (DeclaratorInfo.getIdentifier()) {
- DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope,
- DeclaratorInfo, 0);
- StmtResult stmtResult =
- Actions.ActOnDeclStmt(aBlockVarDecl,
- DS.getSourceRange().getBegin(),
- DeclaratorInfo.getSourceRange().getEnd());
- FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
- }
- } else
- ConsumeToken(); // consume '...'
- SourceLocation RParenLoc = ConsumeParen();
-
- StmtResult CatchBody(true);
- if (Tok.is(tok::l_brace))
- CatchBody = ParseCompoundStatementBody();
- else
- Diag(Tok, diag::err_expected_lbrace);
- if (CatchBody.isInvalid)
- CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
- CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc,
- FirstPart, CatchBody.Val, CatchStmts.Val);
- ExitScope();
- } else {
- Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after,
- "@catch clause");
- return true;
- }
- catch_or_finally_seen = true;
- } else {
- assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
- ConsumeToken(); // consume finally
- EnterScope(Scope::DeclScope);
-
-
- StmtResult FinallyBody(true);
- if (Tok.is(tok::l_brace))
- FinallyBody = ParseCompoundStatementBody();
- else
- Diag(Tok, diag::err_expected_lbrace);
- if (FinallyBody.isInvalid)
- FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
- FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
- FinallyBody.Val);
- catch_or_finally_seen = true;
- ExitScope();
- break;
- }
- }
- if (!catch_or_finally_seen) {
- Diag(atLoc, diag::err_missing_catch_finally);
- return true;
- }
- return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.Val, CatchStmts.Val,
- FinallyStmt.Val);
-}
-
-/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
-///
-Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
- DeclTy *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
- // parse optional ';'
- if (Tok.is(tok::semi))
- ConsumeToken();
-
- // We should have an opening brace now.
- if (Tok.isNot(tok::l_brace)) {
- Diag(Tok, diag::err_expected_method_body);
-
- // Skip over garbage, until we get to '{'. Don't eat the '{'.
- SkipUntil(tok::l_brace, true, true);
-
- // If we didn't find the '{', bail out.
- if (Tok.isNot(tok::l_brace))
- return 0;
- }
- SourceLocation BraceLoc = Tok.getLocation();
-
- // Enter a scope for the method body.
- EnterScope(Scope::FnScope|Scope::DeclScope);
-
- // Tell the actions module that we have entered a method definition with the
- // specified Declarator for the method.
- Actions.ObjCActOnStartOfMethodDef(CurScope, MDecl);
-
- StmtResult FnBody = ParseCompoundStatementBody();
-
- // If the function body could not be parsed, make a bogus compoundstmt.
- if (FnBody.isInvalid)
- FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
-
- // Leave the function body scope.
- ExitScope();
-
- // TODO: Pass argument information.
- Actions.ActOnFinishFunctionBody(MDecl, FnBody.Val);
- return MDecl;
-}
-
-Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
- if (Tok.isObjCAtKeyword(tok::objc_try)) {
- return ParseObjCTryStmt(AtLoc);
- } else if (Tok.isObjCAtKeyword(tok::objc_throw))
- return ParseObjCThrowStmt(AtLoc);
- else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
- return ParseObjCSynchronizedStmt(AtLoc);
- ExprResult Res = ParseExpressionWithLeadingAt(AtLoc);
- if (Res.isInvalid) {
- // If the expression is invalid, skip ahead to the next semicolon. Not
- // doing this opens us up to the possibility of infinite loops if
- // ParseExpression does not consume any tokens.
- SkipUntil(tok::semi);
- return true;
- }
- // Otherwise, eat the semicolon.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Res.Val);
-}
-
-Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
- switch (Tok.getKind()) {
- case tok::string_literal: // primary-expression: string-literal
- case tok::wide_string_literal:
- return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
- default:
- if (Tok.getIdentifierInfo() == 0)
- return Diag(AtLoc, diag::err_unexpected_at);
-
- switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
- case tok::objc_encode:
- return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
- case tok::objc_protocol:
- return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
- case tok::objc_selector:
- return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
- default:
- return Diag(AtLoc, diag::err_unexpected_at);
- }
- }
-}
-
-/// objc-message-expr:
-/// '[' objc-receiver objc-message-args ']'
-///
-/// objc-receiver:
-/// expression
-/// class-name
-/// type-name
-Parser::ExprResult Parser::ParseObjCMessageExpression() {
- assert(Tok.is(tok::l_square) && "'[' expected");
- SourceLocation LBracLoc = ConsumeBracket(); // consume '['
-
- // Parse receiver
- if (isTokObjCMessageIdentifierReceiver()) {
- IdentifierInfo *ReceiverName = Tok.getIdentifierInfo();
- ConsumeToken();
- return ParseObjCMessageExpressionBody(LBracLoc, ReceiverName, 0);
- }
-
- ExprResult Res = ParseExpression();
- if (Res.isInvalid) {
- SkipUntil(tok::r_square);
- return Res;
- }
-
- return ParseObjCMessageExpressionBody(LBracLoc, 0, Res.Val);
-}
-
-/// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
-/// the rest of a message expression.
-///
-/// objc-message-args:
-/// objc-selector
-/// objc-keywordarg-list
-///
-/// objc-keywordarg-list:
-/// objc-keywordarg
-/// objc-keywordarg-list objc-keywordarg
-///
-/// objc-keywordarg:
-/// selector-name[opt] ':' objc-keywordexpr
-///
-/// objc-keywordexpr:
-/// nonempty-expr-list
-///
-/// nonempty-expr-list:
-/// assignment-expression
-/// nonempty-expr-list , assignment-expression
-///
-Parser::ExprResult
-Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
- IdentifierInfo *ReceiverName,
- ExprTy *ReceiverExpr) {
- // Parse objc-selector
- SourceLocation Loc;
- IdentifierInfo *selIdent = ParseObjCSelector(Loc);
-
- llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
- llvm::SmallVector<Action::ExprTy *, 12> KeyExprs;
-
- if (Tok.is(tok::colon)) {
- while (1) {
- // Each iteration parses a single keyword argument.
- KeyIdents.push_back(selIdent);
-
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon);
- // We must manually skip to a ']', otherwise the expression skipper will
- // stop at the ']' when it skips to the ';'. We want it to skip beyond
- // the enclosing expression.
- SkipUntil(tok::r_square);
- return true;
- }
-
- ConsumeToken(); // Eat the ':'.
- /// Parse the expression after ':'
- ExprResult Res = ParseAssignmentExpression();
- if (Res.isInvalid) {
- // We must manually skip to a ']', otherwise the expression skipper will
- // stop at the ']' when it skips to the ';'. We want it to skip beyond
- // the enclosing expression.
- SkipUntil(tok::r_square);
- return Res;
- }
-
- // We have a valid expression.
- KeyExprs.push_back(Res.Val);
-
- // Check for another keyword selector.
- selIdent = ParseObjCSelector(Loc);
- if (!selIdent && Tok.isNot(tok::colon))
- break;
- // We have a selector or a colon, continue parsing.
- }
- // Parse the, optional, argument list, comma separated.
- while (Tok.is(tok::comma)) {
- ConsumeToken(); // Eat the ','.
- /// Parse the expression after ','
- ExprResult Res = ParseAssignmentExpression();
- if (Res.isInvalid) {
- // We must manually skip to a ']', otherwise the expression skipper will
- // stop at the ']' when it skips to the ';'. We want it to skip beyond
- // the enclosing expression.
- SkipUntil(tok::r_square);
- return Res;
- }
-
- // We have a valid expression.
- KeyExprs.push_back(Res.Val);
- }
- } else if (!selIdent) {
- Diag(Tok, diag::err_expected_ident); // missing selector name.
-
- // We must manually skip to a ']', otherwise the expression skipper will
- // stop at the ']' when it skips to the ';'. We want it to skip beyond
- // the enclosing expression.
- SkipUntil(tok::r_square);
- return true;
- }
-
- if (Tok.isNot(tok::r_square)) {
- Diag(Tok, diag::err_expected_rsquare);
- // We must manually skip to a ']', otherwise the expression skipper will
- // stop at the ']' when it skips to the ';'. We want it to skip beyond
- // the enclosing expression.
- SkipUntil(tok::r_square);
- return true;
- }
-
- SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
-
- unsigned nKeys = KeyIdents.size();
- if (nKeys == 0)
- KeyIdents.push_back(selIdent);
- Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
-
- // We've just parsed a keyword message.
- if (ReceiverName)
- return Actions.ActOnClassMessage(CurScope,
- ReceiverName, Sel, LBracLoc, RBracLoc,
- &KeyExprs[0], KeyExprs.size());
- return Actions.ActOnInstanceMessage(ReceiverExpr, Sel, LBracLoc, RBracLoc,
- &KeyExprs[0], KeyExprs.size());
-}
-
-Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
- ExprResult Res = ParseStringLiteralExpression();
- if (Res.isInvalid) return Res;
-
- // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string
- // expressions. At this point, we know that the only valid thing that starts
- // with '@' is an @"".
- llvm::SmallVector<SourceLocation, 4> AtLocs;
- llvm::SmallVector<ExprTy*, 4> AtStrings;
- AtLocs.push_back(AtLoc);
- AtStrings.push_back(Res.Val);
-
- while (Tok.is(tok::at)) {
- AtLocs.push_back(ConsumeToken()); // eat the @.
-
- ExprResult Res(true); // Invalid unless there is a string literal.
- if (isTokenStringLiteral())
- Res = ParseStringLiteralExpression();
- else
- Diag(Tok, diag::err_objc_concat_string);
-
- if (Res.isInvalid) {
- while (!AtStrings.empty()) {
- Actions.DeleteExpr(AtStrings.back());
- AtStrings.pop_back();
- }
- return Res;
- }
-
- AtStrings.push_back(Res.Val);
- }
-
- return Actions.ParseObjCStringLiteral(&AtLocs[0], &AtStrings[0],
- AtStrings.size());
-}
-
-/// objc-encode-expression:
-/// @encode ( type-name )
-Parser::ExprResult Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
- assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
-
- SourceLocation EncLoc = ConsumeToken();
-
- if (Tok.isNot(tok::l_paren))
- return Diag(Tok, diag::err_expected_lparen_after, "@encode");
-
- SourceLocation LParenLoc = ConsumeParen();
-
- TypeTy *Ty = ParseTypeName();
-
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-
- return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, Ty,
- RParenLoc);
-}
-
-/// objc-protocol-expression
-/// @protocol ( protocol-name )
-
-Parser::ExprResult Parser::ParseObjCProtocolExpression(SourceLocation AtLoc)
-{
- SourceLocation ProtoLoc = ConsumeToken();
-
- if (Tok.isNot(tok::l_paren))
- return Diag(Tok, diag::err_expected_lparen_after, "@protocol");
-
- SourceLocation LParenLoc = ConsumeParen();
-
- if (Tok.isNot(tok::identifier))
- return Diag(Tok, diag::err_expected_ident);
-
- IdentifierInfo *protocolId = Tok.getIdentifierInfo();
- ConsumeToken();
-
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-
- return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
- LParenLoc, RParenLoc);
-}
-
-/// objc-selector-expression
-/// @selector '(' objc-keyword-selector ')'
-Parser::ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc)
-{
- SourceLocation SelectorLoc = ConsumeToken();
-
- if (Tok.isNot(tok::l_paren))
- return Diag(Tok, diag::err_expected_lparen_after, "@selector");
-
- llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
- SourceLocation LParenLoc = ConsumeParen();
- SourceLocation sLoc;
- IdentifierInfo *SelIdent = ParseObjCSelector(sLoc);
- if (!SelIdent && Tok.isNot(tok::colon))
- return Diag(Tok, diag::err_expected_ident); // missing selector name.
-
- KeyIdents.push_back(SelIdent);
- unsigned nColons = 0;
- if (Tok.isNot(tok::r_paren)) {
- while (1) {
- if (Tok.isNot(tok::colon))
- return Diag(Tok, diag::err_expected_colon);
-
- nColons++;
- ConsumeToken(); // Eat the ':'.
- if (Tok.is(tok::r_paren))
- break;
- // Check for another keyword selector.
- SourceLocation Loc;
- SelIdent = ParseObjCSelector(Loc);
- KeyIdents.push_back(SelIdent);
- if (!SelIdent && Tok.isNot(tok::colon))
- break;
- }
- }
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
- return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, LParenLoc,
- RParenLoc);
- }
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
deleted file mode 100644
index fbdb123bdabe..000000000000
--- a/clang/lib/Parse/ParsePragma.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the language specific #pragma handlers.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ParsePragma.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Action.h"
-using namespace clang;
-
-// #pragma pack(...) comes in the following delicious flavors:
-// pack '(' [integer] ')'
-// pack '(' 'show' ')'
-// pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
-void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
- // FIXME: Should we be expanding macros here? My guess is no.
- SourceLocation PackLoc = PackTok.getLocation();
-
- Token Tok;
- PP.Lex(Tok);
- if (Tok.isNot(tok::l_paren)) {
- PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_lparen);
- return;
- }
-
- Action::PragmaPackKind Kind = Action::PPK_Default;
- IdentifierInfo *Name = 0;
- Action::ExprResult Alignment;
- SourceLocation LParenLoc = Tok.getLocation();
- PP.Lex(Tok);
- if (Tok.is(tok::numeric_constant)) {
- Alignment = Actions.ActOnNumericConstant(Tok);
- if (Alignment.isInvalid)
- return;
-
- PP.Lex(Tok);
- } else if (Tok.is(tok::identifier)) {
- const IdentifierInfo *II = Tok.getIdentifierInfo();
- if (II == &PP.getIdentifierTable().get("show")) {
- Kind = Action::PPK_Show;
- PP.Lex(Tok);
- } else {
- if (II == &PP.getIdentifierTable().get("push")) {
- Kind = Action::PPK_Push;
- } else if (II == &PP.getIdentifierTable().get("pop")) {
- Kind = Action::PPK_Pop;
- } else {
- PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
- return;
- }
- PP.Lex(Tok);
-
- if (Tok.is(tok::comma)) {
- PP.Lex(Tok);
-
- if (Tok.is(tok::numeric_constant)) {
- Alignment = Actions.ActOnNumericConstant(Tok);
- if (Alignment.isInvalid)
- return;
-
- PP.Lex(Tok);
- } else if (Tok.is(tok::identifier)) {
- Name = Tok.getIdentifierInfo();
- PP.Lex(Tok);
-
- if (Tok.is(tok::comma)) {
- PP.Lex(Tok);
-
- if (Tok.isNot(tok::numeric_constant)) {
- PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed,
- II->getName());
- return;
- }
-
- Alignment = Actions.ActOnNumericConstant(Tok);
- if (Alignment.isInvalid)
- return;
-
- PP.Lex(Tok);
- }
- } else {
- PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed,
- II->getName());
- return;
- }
- }
- }
- }
-
- if (Tok.isNot(tok::r_paren)) {
- PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
- return;
- }
-
- SourceLocation RParenLoc = Tok.getLocation();
- Actions.ActOnPragmaPack(Kind, Name, Alignment.Val, PackLoc,
- LParenLoc, RParenLoc);
-}
-
diff --git a/clang/lib/Parse/ParsePragma.h b/clang/lib/Parse/ParsePragma.h
deleted file mode 100644
index 8a9ae5765ba6..000000000000
--- a/clang/lib/Parse/ParsePragma.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===---- ParserPragmas.h - Language specific pragmas -----------*- 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 #pragma handlers for language specific pragmas.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_PARSEPRAGMA_H
-#define LLVM_CLANG_PARSE_PARSEPRAGMA_H
-
-#include "clang/Lex/Pragma.h"
-
-namespace clang {
- class Action;
-
-class PragmaPackHandler : public PragmaHandler {
- Action &Actions;
-public:
- PragmaPackHandler(const IdentifierInfo *N, Action &A) : PragmaHandler(N),
- Actions(A) {}
-
- virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
deleted file mode 100644
index 228bc4886caf..000000000000
--- a/clang/lib/Parse/ParseStmt.cpp
+++ /dev/null
@@ -1,1228 +0,0 @@
-//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Statement and Block portions of the Parser
-// interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// C99 6.8: Statements and Blocks.
-//===----------------------------------------------------------------------===//
-
-/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
-/// StatementOrDeclaration:
-/// statement
-/// declaration
-///
-/// statement:
-/// labeled-statement
-/// compound-statement
-/// expression-statement
-/// selection-statement
-/// iteration-statement
-/// jump-statement
-/// [C++] declaration-statement
-/// [OBC] objc-throw-statement
-/// [OBC] objc-try-catch-statement
-/// [OBC] objc-synchronized-statement
-/// [GNU] asm-statement
-/// [OMP] openmp-construct [TODO]
-///
-/// labeled-statement:
-/// identifier ':' statement
-/// 'case' constant-expression ':' statement
-/// 'default' ':' statement
-///
-/// selection-statement:
-/// if-statement
-/// switch-statement
-///
-/// iteration-statement:
-/// while-statement
-/// do-statement
-/// for-statement
-///
-/// expression-statement:
-/// expression[opt] ';'
-///
-/// jump-statement:
-/// 'goto' identifier ';'
-/// 'continue' ';'
-/// 'break' ';'
-/// 'return' expression[opt] ';'
-/// [GNU] 'goto' '*' expression ';'
-///
-/// [OBC] objc-throw-statement:
-/// [OBC] '@' 'throw' expression ';'
-/// [OBC] '@' 'throw' ';'
-///
-Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
- const char *SemiError = 0;
- Parser::StmtResult Res;
-
- // Cases in this switch statement should fall through if the parser expects
- // the token to end in a semicolon (in which case SemiError should be set),
- // or they directly 'return;' if not.
- tok::TokenKind Kind = Tok.getKind();
- SourceLocation AtLoc;
- switch (Kind) {
- case tok::at: // May be a @try or @throw statement
- {
- AtLoc = ConsumeToken(); // consume @
- return ParseObjCAtStatement(AtLoc);
- }
-
- case tok::identifier:
- if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
- // identifier ':' statement
- return ParseLabeledStatement();
- }
- // PASS THROUGH.
-
- default:
- if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
- SourceLocation DeclStart = Tok.getLocation();
- DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
- // FIXME: Pass in the right location for the end of the declstmt.
- return Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
- } else if (Tok.is(tok::r_brace)) {
- Diag(Tok, diag::err_expected_statement);
- return true;
- } else {
- // expression[opt] ';'
- ExprResult Res = ParseExpression();
- if (Res.isInvalid) {
- // If the expression is invalid, skip ahead to the next semicolon. Not
- // doing this opens us up to the possibility of infinite loops if
- // ParseExpression does not consume any tokens.
- SkipUntil(tok::semi);
- return true;
- }
- // Otherwise, eat the semicolon.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Res.Val);
- }
-
- case tok::kw_case: // C99 6.8.1: labeled-statement
- return ParseCaseStatement();
- case tok::kw_default: // C99 6.8.1: labeled-statement
- return ParseDefaultStatement();
-
- case tok::l_brace: // C99 6.8.2: compound-statement
- return ParseCompoundStatement();
- case tok::semi: // C99 6.8.3p3: expression[opt] ';'
- return Actions.ActOnNullStmt(ConsumeToken());
-
- case tok::kw_if: // C99 6.8.4.1: if-statement
- return ParseIfStatement();
- case tok::kw_switch: // C99 6.8.4.2: switch-statement
- return ParseSwitchStatement();
-
- case tok::kw_while: // C99 6.8.5.1: while-statement
- return ParseWhileStatement();
- case tok::kw_do: // C99 6.8.5.2: do-statement
- Res = ParseDoStatement();
- SemiError = "do/while loop";
- break;
- case tok::kw_for: // C99 6.8.5.3: for-statement
- return ParseForStatement();
-
- case tok::kw_goto: // C99 6.8.6.1: goto-statement
- Res = ParseGotoStatement();
- SemiError = "goto statement";
- break;
- case tok::kw_continue: // C99 6.8.6.2: continue-statement
- Res = ParseContinueStatement();
- SemiError = "continue statement";
- break;
- case tok::kw_break: // C99 6.8.6.3: break-statement
- Res = ParseBreakStatement();
- SemiError = "break statement";
- break;
- case tok::kw_return: // C99 6.8.6.4: return-statement
- Res = ParseReturnStatement();
- SemiError = "return statement";
- break;
-
- case tok::kw_asm:
- bool msAsm = false;
- Res = ParseAsmStatement(msAsm);
- if (msAsm) return Res;
- SemiError = "asm statement";
- break;
- }
-
- // If we reached this code, the statement must end in a semicolon.
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- } else {
- Diag(Tok, diag::err_expected_semi_after, SemiError);
- SkipUntil(tok::semi);
- }
- return Res;
-}
-
-/// ParseLabeledStatement - We have an identifier and a ':' after it.
-///
-/// labeled-statement:
-/// identifier ':' statement
-/// [GNU] identifier ':' attributes[opt] statement
-///
-Parser::StmtResult Parser::ParseLabeledStatement() {
- assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
- "Not an identifier!");
-
- Token IdentTok = Tok; // Save the whole token.
- ConsumeToken(); // eat the identifier.
-
- assert(Tok.is(tok::colon) && "Not a label!");
-
- // identifier ':' statement
- SourceLocation ColonLoc = ConsumeToken();
-
- // Read label attributes, if present.
- DeclTy *AttrList = 0;
- if (Tok.is(tok::kw___attribute))
- // TODO: save these somewhere.
- AttrList = ParseAttributes();
-
- StmtResult SubStmt = ParseStatement();
-
- // Broken substmt shouldn't prevent the label from being added to the AST.
- if (SubStmt.isInvalid)
- SubStmt = Actions.ActOnNullStmt(ColonLoc);
-
- return Actions.ActOnLabelStmt(IdentTok.getLocation(),
- IdentTok.getIdentifierInfo(),
- ColonLoc, SubStmt.Val);
-}
-
-/// ParseCaseStatement
-/// labeled-statement:
-/// 'case' constant-expression ':' statement
-/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
-///
-/// Note that this does not parse the 'statement' at the end.
-///
-Parser::StmtResult Parser::ParseCaseStatement() {
- assert(Tok.is(tok::kw_case) && "Not a case stmt!");
- SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'.
-
- ExprResult LHS = ParseConstantExpression();
- if (LHS.isInvalid) {
- SkipUntil(tok::colon);
- return true;
- }
-
- // GNU case range extension.
- SourceLocation DotDotDotLoc;
- ExprTy *RHSVal = 0;
- if (Tok.is(tok::ellipsis)) {
- Diag(Tok, diag::ext_gnu_case_range);
- DotDotDotLoc = ConsumeToken();
-
- ExprResult RHS = ParseConstantExpression();
- if (RHS.isInvalid) {
- SkipUntil(tok::colon);
- return true;
- }
- RHSVal = RHS.Val;
- }
-
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon_after, "'case'");
- SkipUntil(tok::colon);
- return true;
- }
-
- SourceLocation ColonLoc = ConsumeToken();
-
- // Diagnose the common error "switch (X) { case 4: }", which is not valid.
- if (Tok.is(tok::r_brace)) {
- Diag(Tok, diag::err_label_end_of_compound_statement);
- return true;
- }
-
- StmtResult SubStmt = ParseStatement();
-
- // Broken substmt shouldn't prevent the case from being added to the AST.
- if (SubStmt.isInvalid)
- SubStmt = Actions.ActOnNullStmt(ColonLoc);
-
- return Actions.ActOnCaseStmt(CaseLoc, LHS.Val, DotDotDotLoc, RHSVal, ColonLoc,
- SubStmt.Val);
-}
-
-/// ParseDefaultStatement
-/// labeled-statement:
-/// 'default' ':' statement
-/// Note that this does not parse the 'statement' at the end.
-///
-Parser::StmtResult Parser::ParseDefaultStatement() {
- assert(Tok.is(tok::kw_default) && "Not a default stmt!");
- SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
-
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon_after, "'default'");
- SkipUntil(tok::colon);
- return true;
- }
-
- SourceLocation ColonLoc = ConsumeToken();
-
- // Diagnose the common error "switch (X) {... default: }", which is not valid.
- if (Tok.is(tok::r_brace)) {
- Diag(Tok, diag::err_label_end_of_compound_statement);
- return true;
- }
-
- StmtResult SubStmt = ParseStatement();
- if (SubStmt.isInvalid)
- return true;
-
- return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val, CurScope);
-}
-
-
-/// ParseCompoundStatement - Parse a "{}" block.
-///
-/// compound-statement: [C99 6.8.2]
-/// { block-item-list[opt] }
-/// [GNU] { label-declarations block-item-list } [TODO]
-///
-/// block-item-list:
-/// block-item
-/// block-item-list block-item
-///
-/// block-item:
-/// declaration
-/// [GNU] '__extension__' declaration
-/// statement
-/// [OMP] openmp-directive [TODO]
-///
-/// [GNU] label-declarations:
-/// [GNU] label-declaration
-/// [GNU] label-declarations label-declaration
-///
-/// [GNU] label-declaration:
-/// [GNU] '__label__' identifier-list ';'
-///
-/// [OMP] openmp-directive: [TODO]
-/// [OMP] barrier-directive
-/// [OMP] flush-directive
-///
-Parser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
- assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
-
- // Enter a scope to hold everything within the compound stmt. Compound
- // statements can always hold declarations.
- EnterScope(Scope::DeclScope);
-
- // Parse the statements in the body.
- StmtResult Body = ParseCompoundStatementBody(isStmtExpr);
-
- ExitScope();
- return Body;
-}
-
-
-/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
-/// ActOnCompoundStmt action. This expects the '{' to be the current token, and
-/// consume the '}' at the end of the block. It does not manipulate the scope
-/// stack.
-Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
- SourceLocation LBraceLoc = ConsumeBrace(); // eat the '{'.
-
- // TODO: "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are
- // only allowed at the start of a compound stmt regardless of the language.
-
- llvm::SmallVector<StmtTy*, 32> Stmts;
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- StmtResult R;
- if (Tok.isNot(tok::kw___extension__)) {
- R = ParseStatementOrDeclaration(false);
- } else {
- // __extension__ can start declarations and it can also be a unary
- // operator for expressions. Consume multiple __extension__ markers here
- // until we can determine which is which.
- SourceLocation ExtLoc = ConsumeToken();
- while (Tok.is(tok::kw___extension__))
- ConsumeToken();
-
- // __extension__ silences extension warnings in the subexpression.
- bool SavedExtWarn = Diags.getWarnOnExtensions();
- Diags.setWarnOnExtensions(false);
-
- // If this is the start of a declaration, parse it as such.
- if (isDeclarationStatement()) {
- // FIXME: Save the __extension__ on the decl as a node somehow.
- SourceLocation DeclStart = Tok.getLocation();
- DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
- // FIXME: Pass in the right location for the end of the declstmt.
- R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
-
- Diags.setWarnOnExtensions(SavedExtWarn);
- } else {
- // Otherwise this was a unary __extension__ marker. Parse the
- // subexpression and add the __extension__ unary op.
- ExprResult Res = ParseCastExpression(false);
- Diags.setWarnOnExtensions(SavedExtWarn);
-
- if (Res.isInvalid) {
- SkipUntil(tok::semi);
- continue;
- }
-
- // Add the __extension__ node to the AST.
- Res = Actions.ActOnUnaryOp(ExtLoc, tok::kw___extension__, Res.Val);
- if (Res.isInvalid)
- continue;
-
- // Eat the semicolon at the end of stmt and convert the expr into a stmt.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
- R = Actions.ActOnExprStmt(Res.Val);
- }
- }
-
- if (!R.isInvalid && R.Val)
- Stmts.push_back(R.Val);
- }
-
- // We broke out of the while loop because we found a '}' or EOF.
- if (Tok.isNot(tok::r_brace)) {
- Diag(Tok, diag::err_expected_rbrace);
- return true;
- }
-
- SourceLocation RBraceLoc = ConsumeBrace();
- return Actions.ActOnCompoundStmt(LBraceLoc, RBraceLoc,
- &Stmts[0], Stmts.size(), isStmtExpr);
-}
-
-/// ParseIfStatement
-/// if-statement: [C99 6.8.4.1]
-/// 'if' '(' expression ')' statement
-/// 'if' '(' expression ')' statement 'else' statement
-/// [C++] 'if' '(' condition ')' statement
-/// [C++] 'if' '(' condition ')' statement 'else' statement
-///
-Parser::StmtResult Parser::ParseIfStatement() {
- assert(Tok.is(tok::kw_if) && "Not an if stmt!");
- SourceLocation IfLoc = ConsumeToken(); // eat the 'if'.
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "if");
- SkipUntil(tok::semi);
- return true;
- }
-
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
-
- // C99 6.8.4p3 - In C99, the if statement is a block. This is not
- // the case for C90.
- //
- // C++ 6.4p3:
- // A name introduced by a declaration in a condition is in scope from its
- // point of declaration until the end of the substatements controlled by the
- // condition.
- // C++ 3.3.2p4:
- // Names declared in the for-init-statement, and in the condition of if,
- // while, for, and switch statements are local to the if, while, for, or
- // switch statement (including the controlled statement).
- //
- if (C99orCXX)
- EnterScope(Scope::DeclScope | Scope::ControlScope);
-
- // Parse the condition.
- ExprResult CondExp;
- if (getLang().CPlusPlus) {
- SourceLocation LParenLoc = ConsumeParen();
- CondExp = ParseCXXCondition();
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- } else {
- CondExp = ParseSimpleParenExpression();
- }
-
- if (CondExp.isInvalid) {
- SkipUntil(tok::semi);
- if (C99orCXX)
- ExitScope();
- return true;
- }
-
- // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
- // there is no compound stmt. C90 does not have this clause. We only do this
- // if the body isn't a compound statement to avoid push/pop in common cases.
- //
- // C++ 6.4p1:
- // The substatement in a selection-statement (each substatement, in the else
- // form of the if statement) implicitly defines a local scope.
- //
- // For C++ we create a scope for the condition and a new scope for
- // substatements because:
- // -When the 'then' scope exits, we want the condition declaration to still be
- // active for the 'else' scope too.
- // -Sema will detect name clashes by considering declarations of a
- // 'ControlScope' as part of its direct subscope.
- // -If we wanted the condition and substatement to be in the same scope, we
- // would have to notify ParseStatement not to create a new scope. It's
- // simpler to let it create a new scope.
- //
- bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
- if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-
- // Read the 'then' stmt.
- SourceLocation ThenStmtLoc = Tok.getLocation();
- StmtResult ThenStmt = ParseStatement();
-
- // Pop the 'if' scope if needed.
- if (NeedsInnerScope) ExitScope();
-
- // If it has an else, parse it.
- SourceLocation ElseLoc;
- SourceLocation ElseStmtLoc;
- StmtResult ElseStmt(false);
-
- if (Tok.is(tok::kw_else)) {
- ElseLoc = ConsumeToken();
-
- // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
- // there is no compound stmt. C90 does not have this clause. We only do
- // this if the body isn't a compound statement to avoid push/pop in common
- // cases.
- //
- // C++ 6.4p1:
- // The substatement in a selection-statement (each substatement, in the else
- // form of the if statement) implicitly defines a local scope.
- //
- NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
- if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-
- ElseStmtLoc = Tok.getLocation();
- ElseStmt = ParseStatement();
-
- // Pop the 'else' scope if needed.
- if (NeedsInnerScope) ExitScope();
- }
-
- if (C99orCXX)
- ExitScope();
-
- // If the then or else stmt is invalid and the other is valid (and present),
- // make turn the invalid one into a null stmt to avoid dropping the other
- // part. If both are invalid, return error.
- if ((ThenStmt.isInvalid && ElseStmt.isInvalid) ||
- (ThenStmt.isInvalid && ElseStmt.Val == 0) ||
- (ThenStmt.Val == 0 && ElseStmt.isInvalid)) {
- // Both invalid, or one is invalid and other is non-present: delete cond and
- // return error.
- Actions.DeleteExpr(CondExp.Val);
- return true;
- }
-
- // Now if either are invalid, replace with a ';'.
- if (ThenStmt.isInvalid)
- ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
- if (ElseStmt.isInvalid)
- ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
-
- return Actions.ActOnIfStmt(IfLoc, CondExp.Val, ThenStmt.Val,
- ElseLoc, ElseStmt.Val);
-}
-
-/// ParseSwitchStatement
-/// switch-statement:
-/// 'switch' '(' expression ')' statement
-/// [C++] 'switch' '(' condition ')' statement
-Parser::StmtResult Parser::ParseSwitchStatement() {
- assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
- SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'.
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "switch");
- SkipUntil(tok::semi);
- return true;
- }
-
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
-
- // C99 6.8.4p3 - In C99, the switch statement is a block. This is
- // not the case for C90. Start the switch scope.
- //
- // C++ 6.4p3:
- // A name introduced by a declaration in a condition is in scope from its
- // point of declaration until the end of the substatements controlled by the
- // condition.
- // C++ 3.3.2p4:
- // Names declared in the for-init-statement, and in the condition of if,
- // while, for, and switch statements are local to the if, while, for, or
- // switch statement (including the controlled statement).
- //
- if (C99orCXX)
- EnterScope(Scope::BreakScope | Scope::DeclScope | Scope::ControlScope);
- else
- EnterScope(Scope::BreakScope);
-
- // Parse the condition.
- ExprResult Cond;
- if (getLang().CPlusPlus) {
- SourceLocation LParenLoc = ConsumeParen();
- Cond = ParseCXXCondition();
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- } else {
- Cond = ParseSimpleParenExpression();
- }
-
- if (Cond.isInvalid) {
- ExitScope();
- return true;
- }
-
- StmtResult Switch = Actions.ActOnStartOfSwitchStmt(Cond.Val);
-
- // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
- // there is no compound stmt. C90 does not have this clause. We only do this
- // if the body isn't a compound statement to avoid push/pop in common cases.
- //
- // C++ 6.4p1:
- // The substatement in a selection-statement (each substatement, in the else
- // form of the if statement) implicitly defines a local scope.
- //
- // See comments in ParseIfStatement for why we create a scope for the
- // condition and a new scope for substatement in C++.
- //
- bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
- if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-
- // Read the body statement.
- StmtResult Body = ParseStatement();
-
- // Pop the body scope if needed.
- if (NeedsInnerScope) ExitScope();
-
- if (Body.isInvalid) {
- Body = Actions.ActOnNullStmt(Tok.getLocation());
- // FIXME: Remove the case statement list from the Switch statement.
- }
-
- ExitScope();
-
- return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.Val, Body.Val);
-}
-
-/// ParseWhileStatement
-/// while-statement: [C99 6.8.5.1]
-/// 'while' '(' expression ')' statement
-/// [C++] 'while' '(' condition ')' statement
-Parser::StmtResult Parser::ParseWhileStatement() {
- assert(Tok.is(tok::kw_while) && "Not a while stmt!");
- SourceLocation WhileLoc = Tok.getLocation();
- ConsumeToken(); // eat the 'while'.
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "while");
- SkipUntil(tok::semi);
- return true;
- }
-
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
-
- // C99 6.8.5p5 - In C99, the while statement is a block. This is not
- // the case for C90. Start the loop scope.
- //
- // C++ 6.4p3:
- // A name introduced by a declaration in a condition is in scope from its
- // point of declaration until the end of the substatements controlled by the
- // condition.
- // C++ 3.3.2p4:
- // Names declared in the for-init-statement, and in the condition of if,
- // while, for, and switch statements are local to the if, while, for, or
- // switch statement (including the controlled statement).
- //
- if (C99orCXX)
- EnterScope(Scope::BreakScope | Scope::ContinueScope |
- Scope::DeclScope | Scope::ControlScope);
- else
- EnterScope(Scope::BreakScope | Scope::ContinueScope);
-
- // Parse the condition.
- ExprResult Cond;
- if (getLang().CPlusPlus) {
- SourceLocation LParenLoc = ConsumeParen();
- Cond = ParseCXXCondition();
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- } else {
- Cond = ParseSimpleParenExpression();
- }
-
- // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
- // there is no compound stmt. C90 does not have this clause. We only do this
- // if the body isn't a compound statement to avoid push/pop in common cases.
- //
- // C++ 6.5p2:
- // The substatement in an iteration-statement implicitly defines a local scope
- // which is entered and exited each time through the loop.
- //
- // See comments in ParseIfStatement for why we create a scope for the
- // condition and a new scope for substatement in C++.
- //
- bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
- if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-
- // Read the body statement.
- StmtResult Body = ParseStatement();
-
- // Pop the body scope if needed.
- if (NeedsInnerScope) ExitScope();
-
- ExitScope();
-
- if (Cond.isInvalid || Body.isInvalid) return true;
-
- return Actions.ActOnWhileStmt(WhileLoc, Cond.Val, Body.Val);
-}
-
-/// ParseDoStatement
-/// do-statement: [C99 6.8.5.2]
-/// 'do' statement 'while' '(' expression ')' ';'
-/// Note: this lets the caller parse the end ';'.
-Parser::StmtResult Parser::ParseDoStatement() {
- assert(Tok.is(tok::kw_do) && "Not a do stmt!");
- SourceLocation DoLoc = ConsumeToken(); // eat the 'do'.
-
- // C99 6.8.5p5 - In C99, the do statement is a block. This is not
- // the case for C90. Start the loop scope.
- if (getLang().C99)
- EnterScope(Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
- else
- EnterScope(Scope::BreakScope | Scope::ContinueScope);
-
- // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
- // there is no compound stmt. C90 does not have this clause. We only do this
- // if the body isn't a compound statement to avoid push/pop in common cases.
- //
- // C++ 6.5p2:
- // The substatement in an iteration-statement implicitly defines a local scope
- // which is entered and exited each time through the loop.
- //
- bool NeedsInnerScope = (getLang().C99 || getLang().CPlusPlus) &&
- Tok.isNot(tok::l_brace);
- if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-
- // Read the body statement.
- StmtResult Body = ParseStatement();
-
- // Pop the body scope if needed.
- if (NeedsInnerScope) ExitScope();
-
- if (Tok.isNot(tok::kw_while)) {
- ExitScope();
- Diag(Tok, diag::err_expected_while);
- Diag(DoLoc, diag::err_matching, "do");
- SkipUntil(tok::semi);
- return true;
- }
- SourceLocation WhileLoc = ConsumeToken();
-
- if (Tok.isNot(tok::l_paren)) {
- ExitScope();
- Diag(Tok, diag::err_expected_lparen_after, "do/while");
- SkipUntil(tok::semi);
- return true;
- }
-
- // Parse the condition.
- ExprResult Cond = ParseSimpleParenExpression();
-
- ExitScope();
-
- if (Cond.isInvalid || Body.isInvalid) return true;
-
- return Actions.ActOnDoStmt(DoLoc, Body.Val, WhileLoc, Cond.Val);
-}
-
-/// ParseForStatement
-/// for-statement: [C99 6.8.5.3]
-/// 'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
-/// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
-/// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
-/// [C++] statement
-/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
-/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
-///
-/// [C++] for-init-statement:
-/// [C++] expression-statement
-/// [C++] simple-declaration
-///
-Parser::StmtResult Parser::ParseForStatement() {
- assert(Tok.is(tok::kw_for) && "Not a for stmt!");
- SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "for");
- SkipUntil(tok::semi);
- return true;
- }
-
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
-
- // C99 6.8.5p5 - In C99, the for statement is a block. This is not
- // the case for C90. Start the loop scope.
- //
- // C++ 6.4p3:
- // A name introduced by a declaration in a condition is in scope from its
- // point of declaration until the end of the substatements controlled by the
- // condition.
- // C++ 3.3.2p4:
- // Names declared in the for-init-statement, and in the condition of if,
- // while, for, and switch statements are local to the if, while, for, or
- // switch statement (including the controlled statement).
- // C++ 6.5.3p1:
- // Names declared in the for-init-statement are in the same declarative-region
- // as those declared in the condition.
- //
- if (C99orCXX)
- EnterScope(Scope::BreakScope | Scope::ContinueScope |
- Scope::DeclScope | Scope::ControlScope);
- else
- EnterScope(Scope::BreakScope | Scope::ContinueScope);
-
- SourceLocation LParenLoc = ConsumeParen();
- ExprResult Value;
-
- StmtTy *FirstPart = 0;
- ExprTy *SecondPart = 0;
- StmtTy *ThirdPart = 0;
- bool ForEach = false;
-
- // Parse the first part of the for specifier.
- if (Tok.is(tok::semi)) { // for (;
- // no first part, eat the ';'.
- ConsumeToken();
- } else if (isSimpleDeclaration()) { // for (int X = 4;
- // Parse declaration, which eats the ';'.
- if (!C99orCXX) // Use of C99-style for loops in C90 mode?
- Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
-
- SourceLocation DeclStart = Tok.getLocation();
- DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
- // FIXME: Pass in the right location for the end of the declstmt.
- StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
- DeclStart);
- FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
- if ((ForEach = isTokIdentifier_in())) {
- ConsumeToken(); // consume 'in'
- Value = ParseExpression();
- if (!Value.isInvalid)
- SecondPart = Value.Val;
- }
- } else {
- Value = ParseExpression();
-
- // Turn the expression into a stmt.
- if (!Value.isInvalid) {
- StmtResult R = Actions.ActOnExprStmt(Value.Val);
- if (!R.isInvalid)
- FirstPart = R.Val;
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- }
- else if ((ForEach = isTokIdentifier_in())) {
- ConsumeToken(); // consume 'in'
- Value = ParseExpression();
- if (!Value.isInvalid)
- SecondPart = Value.Val;
- }
- else {
- if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
- SkipUntil(tok::semi);
- }
- }
- if (!ForEach) {
- // Parse the second part of the for specifier.
- if (Tok.is(tok::semi)) { // for (...;;
- // no second part.
- Value = ExprResult();
- } else {
- Value = getLang().CPlusPlus ? ParseCXXCondition()
- : ParseExpression();
- if (!Value.isInvalid)
- SecondPart = Value.Val;
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- } else {
- if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
- SkipUntil(tok::semi);
- }
-
- // Parse the third part of the for specifier.
- if (Tok.is(tok::r_paren)) { // for (...;...;)
- // no third part.
- Value = ExprResult();
- } else {
- Value = ParseExpression();
- if (!Value.isInvalid) {
- // Turn the expression into a stmt.
- StmtResult R = Actions.ActOnExprStmt(Value.Val);
- if (!R.isInvalid)
- ThirdPart = R.Val;
- }
- }
- }
- // Match the ')'.
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-
- // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
- // there is no compound stmt. C90 does not have this clause. We only do this
- // if the body isn't a compound statement to avoid push/pop in common cases.
- //
- // C++ 6.5p2:
- // The substatement in an iteration-statement implicitly defines a local scope
- // which is entered and exited each time through the loop.
- //
- // See comments in ParseIfStatement for why we create a scope for
- // for-init-statement/condition and a new scope for substatement in C++.
- //
- bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
- if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-
- // Read the body statement.
- StmtResult Body = ParseStatement();
-
- // Pop the body scope if needed.
- if (NeedsInnerScope) ExitScope();
-
- // Leave the for-scope.
- ExitScope();
-
- if (Body.isInvalid)
- return Body;
-
- if (!ForEach)
- return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart,
- SecondPart, ThirdPart, RParenLoc, Body.Val);
- else
- return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, FirstPart,
- SecondPart, RParenLoc, Body.Val);
-}
-
-/// ParseGotoStatement
-/// jump-statement:
-/// 'goto' identifier ';'
-/// [GNU] 'goto' '*' expression ';'
-///
-/// Note: this lets the caller parse the end ';'.
-///
-Parser::StmtResult Parser::ParseGotoStatement() {
- assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
- SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
-
- StmtResult Res;
- if (Tok.is(tok::identifier)) {
- Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
- Tok.getIdentifierInfo());
- ConsumeToken();
- } else if (Tok.is(tok::star) && !getLang().NoExtensions) {
- // GNU indirect goto extension.
- Diag(Tok, diag::ext_gnu_indirect_goto);
- SourceLocation StarLoc = ConsumeToken();
- ExprResult R = ParseExpression();
- if (R.isInvalid) { // Skip to the semicolon, but don't consume it.
- SkipUntil(tok::semi, false, true);
- return true;
- }
- Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.Val);
- } else {
- Diag(Tok, diag::err_expected_ident);
- return true;
- }
-
- return Res;
-}
-
-/// ParseContinueStatement
-/// jump-statement:
-/// 'continue' ';'
-///
-/// Note: this lets the caller parse the end ';'.
-///
-Parser::StmtResult Parser::ParseContinueStatement() {
- SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
- return Actions.ActOnContinueStmt(ContinueLoc, CurScope);
-}
-
-/// ParseBreakStatement
-/// jump-statement:
-/// 'break' ';'
-///
-/// Note: this lets the caller parse the end ';'.
-///
-Parser::StmtResult Parser::ParseBreakStatement() {
- SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
- return Actions.ActOnBreakStmt(BreakLoc, CurScope);
-}
-
-/// ParseReturnStatement
-/// jump-statement:
-/// 'return' expression[opt] ';'
-Parser::StmtResult Parser::ParseReturnStatement() {
- assert(Tok.is(tok::kw_return) && "Not a return stmt!");
- SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
-
- ExprResult R(0);
- if (Tok.isNot(tok::semi)) {
- R = ParseExpression();
- if (R.isInvalid) { // Skip to the semicolon, but don't consume it.
- SkipUntil(tok::semi, false, true);
- return true;
- }
- }
- return Actions.ActOnReturnStmt(ReturnLoc, R.Val);
-}
-
-/// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
-/// routine is called to skip/ignore tokens that comprise the MS asm statement.
-Parser::StmtResult Parser::FuzzyParseMicrosoftAsmStatement() {
- if (Tok.is(tok::l_brace)) {
- unsigned short savedBraceCount = BraceCount;
- do {
- ConsumeAnyToken();
- } while (BraceCount > savedBraceCount && Tok.isNot(tok::eof));
- } else {
- // From the MS website: If used without braces, the __asm keyword means
- // that the rest of the line is an assembly-language statement.
- SourceManager &SrcMgr = PP.getSourceManager();
- SourceLocation TokLoc = Tok.getLocation();
- unsigned lineNo = SrcMgr.getLogicalLineNumber(TokLoc);
- do {
- ConsumeAnyToken();
- TokLoc = Tok.getLocation();
- } while ((SrcMgr.getLogicalLineNumber(TokLoc) == lineNo) &&
- Tok.isNot(tok::r_brace) && Tok.isNot(tok::semi) &&
- Tok.isNot(tok::eof));
- }
- return Actions.ActOnNullStmt(Tok.getLocation());
-}
-
-/// ParseAsmStatement - Parse a GNU extended asm statement.
-/// asm-statement:
-/// gnu-asm-statement
-/// ms-asm-statement
-///
-/// [GNU] gnu-asm-statement:
-/// 'asm' type-qualifier[opt] '(' asm-argument ')' ';'
-///
-/// [GNU] asm-argument:
-/// asm-string-literal
-/// asm-string-literal ':' asm-operands[opt]
-/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-/// asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-/// ':' asm-clobbers
-///
-/// [GNU] asm-clobbers:
-/// asm-string-literal
-/// asm-clobbers ',' asm-string-literal
-///
-/// [MS] ms-asm-statement:
-/// '__asm' assembly-instruction ';'[opt]
-/// '__asm' '{' assembly-instruction-list '}' ';'[opt]
-///
-/// [MS] assembly-instruction-list:
-/// assembly-instruction ';'[opt]
-/// assembly-instruction-list ';' assembly-instruction ';'[opt]
-///
-Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
- assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
- SourceLocation AsmLoc = ConsumeToken();
-
- if (getLang().Microsoft && Tok.isNot(tok::l_paren) && !isTypeQualifier()) {
- msAsm = true;
- return FuzzyParseMicrosoftAsmStatement();
- }
- DeclSpec DS;
- SourceLocation Loc = Tok.getLocation();
- ParseTypeQualifierListOpt(DS);
-
- // GNU asms accept, but warn, about type-qualifiers other than volatile.
- if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
- Diag(Loc, diag::w_asm_qualifier_ignored, "const");
- if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
- Diag(Loc, diag::w_asm_qualifier_ignored, "restrict");
-
- // Remember if this was a volatile asm.
- bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
- bool isSimple = false;
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "asm");
- SkipUntil(tok::r_paren);
- return true;
- }
- Loc = ConsumeParen();
-
- ExprResult AsmString = ParseAsmStringLiteral();
- if (AsmString.isInvalid)
- return true;
-
- llvm::SmallVector<std::string, 4> Names;
- llvm::SmallVector<ExprTy*, 4> Constraints;
- llvm::SmallVector<ExprTy*, 4> Exprs;
- llvm::SmallVector<ExprTy*, 4> Clobbers;
-
- unsigned NumInputs = 0, NumOutputs = 0;
-
- SourceLocation RParenLoc;
- if (Tok.is(tok::r_paren)) {
- // We have a simple asm expression
- isSimple = true;
-
- RParenLoc = ConsumeParen();
- } else {
- // Parse Outputs, if present.
- if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
- return true;
-
- NumOutputs = Names.size();
-
- // Parse Inputs, if present.
- if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
- return true;
-
- assert(Names.size() == Constraints.size() &&
- Constraints.size() == Exprs.size()
- && "Input operand size mismatch!");
-
- NumInputs = Names.size() - NumOutputs;
-
- // Parse the clobbers, if present.
- if (Tok.is(tok::colon)) {
- ConsumeToken();
-
- // Parse the asm-string list for clobbers.
- while (1) {
- ExprResult Clobber = ParseAsmStringLiteral();
-
- if (Clobber.isInvalid)
- break;
-
- Clobbers.push_back(Clobber.Val);
-
- if (Tok.isNot(tok::comma)) break;
- ConsumeToken();
- }
- }
-
- RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
- }
-
- return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
- NumOutputs, NumInputs,
- &Names[0], &Constraints[0], &Exprs[0],
- AsmString.Val,
- Clobbers.size(), &Clobbers[0],
- RParenLoc);
-}
-
-/// ParseAsmOperands - Parse the asm-operands production as used by
-/// asm-statement. We also parse a leading ':' token. If the leading colon is
-/// not present, we do not parse anything.
-///
-/// [GNU] asm-operands:
-/// asm-operand
-/// asm-operands ',' asm-operand
-///
-/// [GNU] asm-operand:
-/// asm-string-literal '(' expression ')'
-/// '[' identifier ']' asm-string-literal '(' expression ')'
-///
-bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
- llvm::SmallVectorImpl<ExprTy*> &Constraints,
- llvm::SmallVectorImpl<ExprTy*> &Exprs) {
- // Only do anything if this operand is present.
- if (Tok.isNot(tok::colon)) return false;
- ConsumeToken();
-
- // 'asm-operands' isn't present?
- if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
- return false;
-
- while (1) {
- // Read the [id] if present.
- if (Tok.is(tok::l_square)) {
- SourceLocation Loc = ConsumeBracket();
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::r_paren);
- return true;
- }
-
- IdentifierInfo *II = Tok.getIdentifierInfo();
- ConsumeToken();
-
- Names.push_back(std::string(II->getName(), II->getLength()));
- MatchRHSPunctuation(tok::r_square, Loc);
- } else
- Names.push_back(std::string());
-
- ExprResult Constraint = ParseAsmStringLiteral();
- if (Constraint.isInvalid) {
- SkipUntil(tok::r_paren);
- return true;
- }
- Constraints.push_back(Constraint.Val);
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "asm operand");
- SkipUntil(tok::r_paren);
- return true;
- }
-
- // Read the parenthesized expression.
- ExprResult Res = ParseSimpleParenExpression();
- if (Res.isInvalid) {
- SkipUntil(tok::r_paren);
- return true;
- }
- Exprs.push_back(Res.Val);
- // Eat the comma and continue parsing if it exists.
- if (Tok.isNot(tok::comma)) return false;
- ConsumeToken();
- }
-
- return true;
-}
-
-Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl,
- SourceLocation L, SourceLocation R) {
- // Do not enter a scope for the brace, as the arguments are in the same scope
- // (the function body) as the body itself. Instead, just read the statement
- // list and put it into a CompoundStmt for safe keeping.
- StmtResult FnBody = ParseCompoundStatementBody();
-
- // If the function body could not be parsed, make a bogus compoundstmt.
- if (FnBody.isInvalid)
- FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
-
- // Leave the function body scope.
- ExitScope();
-
- return Actions.ActOnFinishFunctionBody(Decl, FnBody.Val);
-}
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
deleted file mode 100644
index 5dbc327b7134..000000000000
--- a/clang/lib/Parse/ParseTentative.cpp
+++ /dev/null
@@ -1,877 +0,0 @@
-//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the tentative parsing portions of the Parser
-// interfaces, for ambiguity resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Basic/Diagnostic.h"
-using namespace clang;
-
-/// isCXXDeclarationStatement - C++-specialized function that disambiguates
-/// between a declaration or an expression statement, when parsing function
-/// bodies. Returns true for declaration, false for expression.
-///
-/// declaration-statement:
-/// block-declaration
-///
-/// block-declaration:
-/// simple-declaration
-/// asm-definition
-/// namespace-alias-definition
-/// using-declaration
-/// using-directive
-/// [C++0x] static_assert-declaration [TODO]
-///
-/// asm-definition:
-/// 'asm' '(' string-literal ')' ';'
-///
-/// namespace-alias-definition:
-/// 'namespace' identifier = qualified-namespace-specifier ';'
-///
-/// using-declaration:
-/// 'using' typename[opt] '::'[opt] nested-name-specifier
-/// unqualified-id ';'
-/// 'using' '::' unqualified-id ;
-///
-/// using-directive:
-/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt]
-/// namespace-name ';'
-///
-/// [C++0x] static_assert-declaration: [TODO]
-/// [C++0x] static_assert '(' constant-expression ',' string-literal ')' ';'
-///
-bool Parser::isCXXDeclarationStatement() {
- switch (Tok.getKind()) {
- // asm-definition
- case tok::kw_asm:
- // namespace-alias-definition
- case tok::kw_namespace:
- // using-declaration
- // using-directive
- case tok::kw_using:
- return true;
- default:
- // simple-declaration
- return isCXXSimpleDeclaration();
- }
-}
-
-/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
-/// between a simple-declaration or an expression-statement.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-/// Returns false if the statement is disambiguated as expression.
-///
-/// simple-declaration:
-/// decl-specifier-seq init-declarator-list[opt] ';'
-///
-bool Parser::isCXXSimpleDeclaration() {
- // C++ 6.8p1:
- // There is an ambiguity in the grammar involving expression-statements and
- // declarations: An expression-statement with a function-style explicit type
- // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
- // from a declaration where the first declarator starts with a '('. In those
- // cases the statement is a declaration. [Note: To disambiguate, the whole
- // statement might have to be examined to determine if it is an
- // expression-statement or a declaration].
-
- // C++ 6.8p3:
- // The disambiguation is purely syntactic; that is, the meaning of the names
- // occurring in such a statement, beyond whether they are type-names or not,
- // is not generally used in or changed by the disambiguation. Class
- // templates are instantiated as necessary to determine if a qualified name
- // is a type-name. Disambiguation precedes parsing, and a statement
- // disambiguated as a declaration may be an ill-formed declaration.
-
- // We don't have to parse all of the decl-specifier-seq part. There's only
- // an ambiguity if the first decl-specifier is
- // simple-type-specifier/typename-specifier followed by a '(', which may
- // indicate a function-style cast expression.
- // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
- // a case.
-
- TPResult TPR = isCXXDeclarationSpecifier();
- if (TPR != TPResult::Ambiguous())
- return TPR != TPResult::False(); // Returns true for TPResult::True() or
- // TPResult::Error().
-
- // FIXME: Add statistics about the number of ambiguous statements encountered
- // and how they were resolved (number of declarations+number of expressions).
-
- // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
- // We need tentative parsing...
-
- TentativeParsingAction PA(*this);
-
- TPR = TryParseSimpleDeclaration();
- SourceLocation TentativeParseLoc = Tok.getLocation();
-
- PA.Revert();
-
- // In case of an error, let the declaration parsing code handle it.
- if (TPR == TPResult::Error())
- return true;
-
- // Declarations take precedence over expressions.
- if (TPR == TPResult::Ambiguous())
- TPR = TPResult::True();
-
- assert(TPR == TPResult::True() || TPR == TPResult::False());
- if (TPR == TPResult::True() && Tok.isNot(tok::kw_void)) {
- // We have a declaration that looks like a functional cast; there's a high
- // chance that the author intended the statement to be an expression.
- // Emit a warning.
- Diag(Tok.getLocation(), diag::warn_statement_disambiguation,
- "declaration", SourceRange(Tok.getLocation(), TentativeParseLoc));
- } else if (TPR == TPResult::False() && Tok.is(tok::kw_void)) {
- // A functional cast to 'void' expression ? Warning..
- Diag(Tok.getLocation(), diag::warn_statement_disambiguation,
- "expression", SourceRange(Tok.getLocation(), TentativeParseLoc));
- }
-
- return TPR == TPResult::True();
-}
-
-/// simple-declaration:
-/// decl-specifier-seq init-declarator-list[opt] ';'
-///
-Parser::TPResult Parser::TryParseSimpleDeclaration() {
- // We know that we have a simple-type-specifier/typename-specifier followed
- // by a '('.
- assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous());
-
- if (Tok.is(tok::kw_typeof))
- TryParseTypeofSpecifier();
- else
- ConsumeToken();
-
- assert(Tok.is(tok::l_paren) && "Expected '('");
-
- TPResult TPR = TryParseInitDeclaratorList();
- if (TPR != TPResult::Ambiguous())
- return TPR;
-
- if (Tok.isNot(tok::semi))
- return TPResult::False();
-
- return TPResult::Ambiguous();
-}
-
-/// init-declarator-list:
-/// init-declarator
-/// init-declarator-list ',' init-declarator
-///
-/// init-declarator:
-/// declarator initializer[opt]
-/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
-///
-/// initializer:
-/// '=' initializer-clause
-/// '(' expression-list ')'
-///
-/// initializer-clause:
-/// assignment-expression
-/// '{' initializer-list ','[opt] '}'
-/// '{' '}'
-///
-Parser::TPResult Parser::TryParseInitDeclaratorList() {
- // GCC only examines the first declarator for disambiguation:
- // i.e:
- // int(x), ++x; // GCC regards it as ill-formed declaration.
- //
- // Comeau and MSVC will regard the above statement as correct expression.
- // Clang examines all of the declarators and also regards the above statement
- // as correct expression.
-
- while (1) {
- // declarator
- TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
- if (TPR != TPResult::Ambiguous())
- return TPR;
-
- // [GNU] simple-asm-expr[opt] attributes[opt]
- if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
- return TPResult::True();
-
- // initializer[opt]
- if (Tok.is(tok::l_paren)) {
- // Parse through the parens.
- ConsumeParen();
- if (!SkipUntil(tok::r_paren))
- return TPResult::Error();
- } else if (Tok.is(tok::equal)) {
- // MSVC won't examine the rest of declarators if '=' is encountered, it
- // will conclude that it is a declaration.
- // Comeau and Clang will examine the rest of declarators.
- // Note that "int(x) = {0}, ++x;" will be interpreted as ill-formed
- // expression.
- //
- // Parse through the initializer-clause.
- SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/);
- }
-
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken(); // the comma.
- }
-
- return TPResult::Ambiguous();
-}
-
-/// isCXXConditionDeclaration - Disambiguates between a declaration or an
-/// expression for a condition of a if/switch/while/for statement.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-/// condition:
-/// expression
-/// type-specifier-seq declarator '=' assignment-expression
-/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
-/// '=' assignment-expression
-///
-bool Parser::isCXXConditionDeclaration() {
- TPResult TPR = isCXXDeclarationSpecifier();
- if (TPR != TPResult::Ambiguous())
- return TPR != TPResult::False(); // Returns true for TPResult::True() or
- // TPResult::Error().
-
- // FIXME: Add statistics about the number of ambiguous statements encountered
- // and how they were resolved (number of declarations+number of expressions).
-
- // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
- // We need tentative parsing...
-
- TentativeParsingAction PA(*this);
-
- // type-specifier-seq
- if (Tok.is(tok::kw_typeof))
- TryParseTypeofSpecifier();
- else
- ConsumeToken();
- assert(Tok.is(tok::l_paren) && "Expected '('");
-
- // declarator
- TPR = TryParseDeclarator(false/*mayBeAbstract*/);
-
- // In case of an error, let the declaration parsing code handle it.
- if (TPR == TPResult::Error())
- TPR = TPResult::True();
-
- if (TPR == TPResult::Ambiguous()) {
- // '='
- // [GNU] simple-asm-expr[opt] attributes[opt]
- if (Tok.is(tok::equal) ||
- Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
- TPR = TPResult::True();
- else
- TPR = TPResult::False();
- }
-
- PA.Revert();
-
- assert(TPR == TPResult::True() || TPR == TPResult::False());
- return TPR == TPResult::True();
-}
-
-/// isCXXTypeIdInParens - Assumes that a '(' was parsed and now we want to
-/// know whether the parens contain an expression or a type-id.
-/// Returns true for a type-id and false for an expression.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-/// type-id:
-/// type-specifier-seq abstract-declarator[opt]
-///
-bool Parser::isCXXTypeIdInParens() {
-
- // C++ 8.2p2:
- // The ambiguity arising from the similarity between a function-style cast and
- // a type-id can occur in different contexts. The ambiguity appears as a
- // choice between a function-style cast expression and a declaration of a
- // type. The resolution is that any construct that could possibly be a type-id
- // in its syntactic context shall be considered a type-id.
-
- TPResult TPR = isCXXDeclarationSpecifier();
- if (TPR != TPResult::Ambiguous())
- return TPR != TPResult::False(); // Returns true for TPResult::True() or
- // TPResult::Error().
-
- // FIXME: Add statistics about the number of ambiguous statements encountered
- // and how they were resolved (number of declarations+number of expressions).
-
- // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
- // We need tentative parsing...
-
- TentativeParsingAction PA(*this);
-
- // type-specifier-seq
- if (Tok.is(tok::kw_typeof))
- TryParseTypeofSpecifier();
- else
- ConsumeToken();
- assert(Tok.is(tok::l_paren) && "Expected '('");
-
- // declarator
- TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
-
- // In case of an error, let the declaration parsing code handle it.
- if (TPR == TPResult::Error())
- TPR = TPResult::True();
-
- if (TPR == TPResult::Ambiguous()) {
- // We are supposed to be inside parens, so if after the abstract declarator
- // we encounter a ')' this is a type-id, otherwise it's an expression.
- if (Tok.is(tok::r_paren))
- TPR = TPResult::True();
- else
- TPR = TPResult::False();
- }
-
- PA.Revert();
-
- assert(TPR == TPResult::True() || TPR == TPResult::False());
- return TPR == TPResult::True();
-}
-
-/// declarator:
-/// direct-declarator
-/// ptr-operator declarator
-///
-/// direct-declarator:
-/// declarator-id
-/// direct-declarator '(' parameter-declaration-clause ')'
-/// cv-qualifier-seq[opt] exception-specification[opt]
-/// direct-declarator '[' constant-expression[opt] ']'
-/// '(' declarator ')'
-/// [GNU] '(' attributes declarator ')'
-///
-/// abstract-declarator:
-/// ptr-operator abstract-declarator[opt]
-/// direct-abstract-declarator
-///
-/// direct-abstract-declarator:
-/// direct-abstract-declarator[opt]
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-/// exception-specification[opt]
-/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
-/// '(' abstract-declarator ')'
-///
-/// ptr-operator:
-/// '*' cv-qualifier-seq[opt]
-/// '&'
-/// [C++0x] '&&' [TODO]
-/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] [TODO]
-///
-/// cv-qualifier-seq:
-/// cv-qualifier cv-qualifier-seq[opt]
-///
-/// cv-qualifier:
-/// 'const'
-/// 'volatile'
-///
-/// declarator-id:
-/// id-expression
-///
-/// id-expression:
-/// unqualified-id
-/// qualified-id [TODO]
-///
-/// unqualified-id:
-/// identifier
-/// operator-function-id [TODO]
-/// conversion-function-id [TODO]
-/// '~' class-name [TODO]
-/// template-id [TODO]
-///
-Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
- bool mayHaveIdentifier) {
- // declarator:
- // direct-declarator
- // ptr-operator declarator
-
- while (1) {
- if (Tok.is(tok::star) || Tok.is(tok::amp)) {
- // ptr-operator
- ConsumeToken();
- while (Tok.is(tok::kw_const) ||
- Tok.is(tok::kw_volatile) ||
- Tok.is(tok::kw_restrict) )
- ConsumeToken();
- } else {
- break;
- }
- }
-
- // direct-declarator:
- // direct-abstract-declarator:
-
- if (Tok.is(tok::identifier) && mayHaveIdentifier) {
- // declarator-id
- ConsumeToken();
- } else if (Tok.is(tok::l_paren)) {
- ConsumeParen();
- if (mayBeAbstract &&
- (Tok.is(tok::r_paren) || // 'int()' is a function.
- Tok.is(tok::ellipsis) || // 'int(...)' is a function.
- isDeclarationSpecifier())) { // 'int(int)' is a function.
- // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
- // exception-specification[opt]
- TPResult TPR = TryParseFunctionDeclarator();
- if (TPR != TPResult::Ambiguous())
- return TPR;
- } else {
- // '(' declarator ')'
- // '(' attributes declarator ')'
- // '(' abstract-declarator ')'
- if (Tok.is(tok::kw___attribute))
- return TPResult::True(); // attributes indicate declaration
- TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
- if (TPR != TPResult::Ambiguous())
- return TPR;
- if (Tok.isNot(tok::r_paren))
- return TPResult::False();
- ConsumeParen();
- }
- } else if (!mayBeAbstract) {
- return TPResult::False();
- }
-
- while (1) {
- TPResult TPR(TPResult::Ambiguous());
-
- if (Tok.is(tok::l_paren)) {
- // Check whether we have a function declarator or a possible ctor-style
- // initializer that follows the declarator. Note that ctor-style
- // initializers are not possible in contexts where abstract declarators
- // are allowed.
- if (!mayBeAbstract && !isCXXFunctionDeclarator())
- break;
-
- // direct-declarator '(' parameter-declaration-clause ')'
- // cv-qualifier-seq[opt] exception-specification[opt]
- ConsumeParen();
- TPR = TryParseFunctionDeclarator();
- } else if (Tok.is(tok::l_square)) {
- // direct-declarator '[' constant-expression[opt] ']'
- // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
- TPR = TryParseBracketDeclarator();
- } else {
- break;
- }
-
- if (TPR != TPResult::Ambiguous())
- return TPR;
- }
-
- return TPResult::Ambiguous();
-}
-
-/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
-/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
-/// be either a decl-specifier or a function-style cast, and TPResult::Error()
-/// if a parsing error was found and reported.
-///
-/// decl-specifier:
-/// storage-class-specifier
-/// type-specifier
-/// function-specifier
-/// 'friend'
-/// 'typedef'
-/// [GNU] attributes declaration-specifiers[opt]
-///
-/// storage-class-specifier:
-/// 'register'
-/// 'static'
-/// 'extern'
-/// 'mutable'
-/// 'auto'
-/// [GNU] '__thread'
-///
-/// function-specifier:
-/// 'inline'
-/// 'virtual'
-/// 'explicit'
-///
-/// typedef-name:
-/// identifier
-///
-/// type-specifier:
-/// simple-type-specifier
-/// class-specifier
-/// enum-specifier
-/// elaborated-type-specifier
-/// typename-specifier [TODO]
-/// cv-qualifier
-///
-/// simple-type-specifier:
-/// '::'[opt] nested-name-specifier[opt] type-name [TODO]
-/// '::'[opt] nested-name-specifier 'template'
-/// simple-template-id [TODO]
-/// 'char'
-/// 'wchar_t'
-/// 'bool'
-/// 'short'
-/// 'int'
-/// 'long'
-/// 'signed'
-/// 'unsigned'
-/// 'float'
-/// 'double'
-/// 'void'
-/// [GNU] typeof-specifier
-/// [GNU] '_Complex'
-/// [C++0x] 'auto' [TODO]
-///
-/// type-name:
-/// class-name
-/// enum-name
-/// typedef-name
-///
-/// elaborated-type-specifier:
-/// class-key '::'[opt] nested-name-specifier[opt] identifier
-/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
-/// simple-template-id
-/// 'enum' '::'[opt] nested-name-specifier[opt] identifier
-///
-/// enum-name:
-/// identifier
-///
-/// enum-specifier:
-/// 'enum' identifier[opt] '{' enumerator-list[opt] '}'
-/// 'enum' identifier[opt] '{' enumerator-list ',' '}'
-///
-/// class-specifier:
-/// class-head '{' member-specification[opt] '}'
-///
-/// class-head:
-/// class-key identifier[opt] base-clause[opt]
-/// class-key nested-name-specifier identifier base-clause[opt]
-/// class-key nested-name-specifier[opt] simple-template-id
-/// base-clause[opt]
-///
-/// class-key:
-/// 'class'
-/// 'struct'
-/// 'union'
-///
-/// cv-qualifier:
-/// 'const'
-/// 'volatile'
-/// [GNU] restrict
-///
-Parser::TPResult Parser::isCXXDeclarationSpecifier() {
- switch (Tok.getKind()) {
- // decl-specifier:
- // storage-class-specifier
- // type-specifier
- // function-specifier
- // 'friend'
- // 'typedef'
-
- case tok::kw_friend:
- case tok::kw_typedef:
- // storage-class-specifier
- case tok::kw_register:
- case tok::kw_static:
- case tok::kw_extern:
- case tok::kw_mutable:
- case tok::kw_auto:
- case tok::kw___thread:
- // function-specifier
- case tok::kw_inline:
- case tok::kw_virtual:
- case tok::kw_explicit:
-
- // type-specifier:
- // simple-type-specifier
- // class-specifier
- // enum-specifier
- // elaborated-type-specifier
- // typename-specifier
- // cv-qualifier
-
- // class-specifier
- // elaborated-type-specifier
- case tok::kw_class:
- case tok::kw_struct:
- case tok::kw_union:
- // enum-specifier
- case tok::kw_enum:
- // cv-qualifier
- case tok::kw_const:
- case tok::kw_volatile:
-
- // GNU
- case tok::kw_restrict:
- case tok::kw__Complex:
- case tok::kw___attribute:
- return TPResult::True();
-
- // The ambiguity resides in a simple-type-specifier/typename-specifier
- // followed by a '('. The '(' could either be the start of:
- //
- // direct-declarator:
- // '(' declarator ')'
- //
- // direct-abstract-declarator:
- // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
- // exception-specification[opt]
- // '(' abstract-declarator ')'
- //
- // or part of a function-style cast expression:
- //
- // simple-type-specifier '(' expression-list[opt] ')'
- //
-
- // simple-type-specifier:
-
- case tok::identifier:
- if (!Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
- return TPResult::False();
- // FALL THROUGH.
-
- case tok::kw_char:
- case tok::kw_wchar_t:
- case tok::kw_bool:
- case tok::kw_short:
- case tok::kw_int:
- case tok::kw_long:
- case tok::kw_signed:
- case tok::kw_unsigned:
- case tok::kw_float:
- case tok::kw_double:
- case tok::kw_void:
- if (NextToken().is(tok::l_paren))
- return TPResult::Ambiguous();
-
- return TPResult::True();
-
- // GNU typeof support.
- case tok::kw_typeof: {
- if (NextToken().isNot(tok::l_paren))
- return TPResult::True();
-
- TentativeParsingAction PA(*this);
-
- TPResult TPR = TryParseTypeofSpecifier();
- bool isFollowedByParen = Tok.is(tok::l_paren);
-
- PA.Revert();
-
- if (TPR == TPResult::Error())
- return TPResult::Error();
-
- if (isFollowedByParen)
- return TPResult::Ambiguous();
-
- return TPResult::True();
- }
-
- default:
- return TPResult::False();
- }
-}
-
-/// [GNU] typeof-specifier:
-/// 'typeof' '(' expressions ')'
-/// 'typeof' '(' type-name ')'
-///
-Parser::TPResult Parser::TryParseTypeofSpecifier() {
- assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
- ConsumeToken();
-
- assert(Tok.is(tok::l_paren) && "Expected '('");
- // Parse through the parens after 'typeof'.
- ConsumeParen();
- if (!SkipUntil(tok::r_paren))
- return TPResult::Error();
-
- return TPResult::Ambiguous();
-}
-
-Parser::TPResult Parser::TryParseDeclarationSpecifier() {
- TPResult TPR = isCXXDeclarationSpecifier();
- if (TPR != TPResult::Ambiguous())
- return TPR;
-
- if (Tok.is(tok::kw_typeof))
- TryParseTypeofSpecifier();
- else
- ConsumeToken();
-
- assert(Tok.is(tok::l_paren) && "Expected '('!");
- return TPResult::Ambiguous();
-}
-
-/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
-/// a constructor-style initializer, when parsing declaration statements.
-/// Returns true for function declarator and false for constructor-style
-/// initializer.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-/// exception-specification[opt]
-///
-bool Parser::isCXXFunctionDeclarator() {
-
- // C++ 8.2p1:
- // The ambiguity arising from the similarity between a function-style cast and
- // a declaration mentioned in 6.8 can also occur in the context of a
- // declaration. In that context, the choice is between a function declaration
- // with a redundant set of parentheses around a parameter name and an object
- // declaration with a function-style cast as the initializer. Just as for the
- // ambiguities mentioned in 6.8, the resolution is to consider any construct
- // that could possibly be a declaration a declaration.
-
- TentativeParsingAction PA(*this);
-
- ConsumeParen();
- TPResult TPR = TryParseParameterDeclarationClause();
- if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
- TPR = TPResult::False();
-
- PA.Revert();
-
- // In case of an error, let the declaration parsing code handle it.
- if (TPR == TPResult::Error())
- return true;
-
- // Function declarator has precedence over constructor-style initializer.
- if (TPR == TPResult::Ambiguous())
- return true;
-
- return TPR == TPResult::True();
-}
-
-/// parameter-declaration-clause:
-/// parameter-declaration-list[opt] '...'[opt]
-/// parameter-declaration-list ',' '...'
-///
-/// parameter-declaration-list:
-/// parameter-declaration
-/// parameter-declaration-list ',' parameter-declaration
-///
-/// parameter-declaration:
-/// decl-specifier-seq declarator
-/// decl-specifier-seq declarator '=' assignment-expression
-/// decl-specifier-seq abstract-declarator[opt]
-/// decl-specifier-seq abstract-declarator[opt] '=' assignment-expression
-///
-Parser::TPResult Parser::TryParseParameterDeclarationClause() {
-
- if (Tok.is(tok::r_paren))
- return TPResult::True();
-
- // parameter-declaration-list[opt] '...'[opt]
- // parameter-declaration-list ',' '...'
- //
- // parameter-declaration-list:
- // parameter-declaration
- // parameter-declaration-list ',' parameter-declaration
- //
- while (1) {
- // '...'[opt]
- if (Tok.is(tok::ellipsis)) {
- ConsumeToken();
- return TPResult::True(); // '...' is a sign of a function declarator.
- }
-
- // decl-specifier-seq
- TPResult TPR = TryParseDeclarationSpecifier();
- if (TPR != TPResult::Ambiguous())
- return TPR;
-
- // declarator
- // abstract-declarator[opt]
- TPR = TryParseDeclarator(true/*mayBeAbstract*/);
- if (TPR != TPResult::Ambiguous())
- return TPR;
-
- if (Tok.is(tok::equal)) {
- // '=' assignment-expression
- // Parse through assignment-expression.
- tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren };
- if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/))
- return TPResult::Error();
- }
-
- if (Tok.is(tok::ellipsis)) {
- ConsumeToken();
- return TPResult::True(); // '...' is a sign of a function declarator.
- }
-
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken(); // the comma.
- }
-
- return TPResult::Ambiguous();
-}
-
-/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
-/// parsing as a function declarator.
-/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
-/// return TPResult::Ambiguous(), otherwise it will return either False() or
-/// Error().
-///
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-/// exception-specification[opt]
-///
-/// exception-specification:
-/// 'throw' '(' type-id-list[opt] ')'
-///
-Parser::TPResult Parser::TryParseFunctionDeclarator() {
-
- // The '(' is already parsed.
-
- TPResult TPR = TryParseParameterDeclarationClause();
- if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
- TPR = TPResult::False();
-
- if (TPR == TPResult::False() || TPR == TPResult::Error())
- return TPR;
-
- // Parse through the parens.
- if (!SkipUntil(tok::r_paren))
- return TPResult::Error();
-
- // cv-qualifier-seq
- while (Tok.is(tok::kw_const) ||
- Tok.is(tok::kw_volatile) ||
- Tok.is(tok::kw_restrict) )
- ConsumeToken();
-
- // exception-specification
- if (Tok.is(tok::kw_throw)) {
- ConsumeToken();
- if (Tok.isNot(tok::l_paren))
- return TPResult::Error();
-
- // Parse through the parens after 'throw'.
- ConsumeParen();
- if (!SkipUntil(tok::r_paren))
- return TPResult::Error();
- }
-
- return TPResult::Ambiguous();
-}
-
-/// '[' constant-expression[opt] ']'
-///
-Parser::TPResult Parser::TryParseBracketDeclarator() {
- ConsumeBracket();
- if (!SkipUntil(tok::r_square))
- return TPResult::Error();
-
- return TPResult::Ambiguous();
-}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
deleted file mode 100644
index fa4bdfafb74b..000000000000
--- a/clang/lib/Parse/Parser.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-//===--- Parser.cpp - C Language Family Parser ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Parser interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Parse/Parser.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-#include "ParsePragma.h"
-using namespace clang;
-
-Parser::Parser(Preprocessor &pp, Action &actions)
- : PP(pp), Actions(actions), Diags(PP.getDiagnostics()) {
- Tok.setKind(tok::eof);
- CurScope = 0;
- NumCachedScopes = 0;
- ParenCount = BracketCount = BraceCount = 0;
- ObjCImpDecl = 0;
-
- // Add #pragma handlers. These are removed and destroyed in the
- // destructor.
- PackHandler =
- new PragmaPackHandler(&PP.getIdentifierTable().get("pack"), actions);
- PP.AddPragmaHandler(0, PackHandler);
-
- // Instantiate a LexedMethodsForTopClass for all the non-nested classes.
- PushTopClassStack();
-}
-
-/// Out-of-line virtual destructor to provide home for Action class.
-Action::~Action() {}
-
-
-bool Parser::Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg) {
- Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, &Msg, 1);
- return true;
-}
-
-bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange& Range) {
- Diags.Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, &Range,1);
- return true;
-}
-
-bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R) {
- Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, 0, 0,
- &R, 1);
- return true;
-}
-
-
-/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
-/// this helper function matches and consumes the specified RHS token if
-/// present. If not present, it emits the specified diagnostic indicating
-/// that the parser failed to match the RHS of the token at LHSLoc. LHSName
-/// should be the name of the unmatched LHS token.
-SourceLocation Parser::MatchRHSPunctuation(tok::TokenKind RHSTok,
- SourceLocation LHSLoc) {
-
- if (Tok.is(RHSTok))
- return ConsumeAnyToken();
-
- SourceLocation R = Tok.getLocation();
- const char *LHSName = "unknown";
- diag::kind DID = diag::err_parse_error;
- switch (RHSTok) {
- default: break;
- case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
- case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
- case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
- case tok::greater: LHSName = "<"; DID = diag::err_expected_greater; break;
- }
- Diag(Tok, DID);
- Diag(LHSLoc, diag::err_matching, LHSName);
- SkipUntil(RHSTok);
- return R;
-}
-
-/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
-/// input. If so, it is consumed and false is returned.
-///
-/// If the input is malformed, this emits the specified diagnostic. Next, if
-/// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
-/// returned.
-bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
- const char *Msg, tok::TokenKind SkipToTok) {
- if (Tok.is(ExpectedTok)) {
- ConsumeAnyToken();
- return false;
- }
-
- Diag(Tok, DiagID, Msg);
- if (SkipToTok != tok::unknown)
- SkipUntil(SkipToTok);
- return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Error recovery.
-//===----------------------------------------------------------------------===//
-
-/// SkipUntil - Read tokens until we get to the specified token, then consume
-/// it (unless DontConsume is true). Because we cannot guarantee that the
-/// token will ever occur, this skips to the next token, or to some likely
-/// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
-/// character.
-///
-/// If SkipUntil finds the specified token, it returns true, otherwise it
-/// returns false.
-bool Parser::SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
- bool StopAtSemi, bool DontConsume) {
- // We always want this function to skip at least one token if the first token
- // isn't T and if not at EOF.
- bool isFirstTokenSkipped = true;
- while (1) {
- // If we found one of the tokens, stop and return true.
- for (unsigned i = 0; i != NumToks; ++i) {
- if (Tok.is(Toks[i])) {
- if (DontConsume) {
- // Noop, don't consume the token.
- } else {
- ConsumeAnyToken();
- }
- return true;
- }
- }
-
- switch (Tok.getKind()) {
- case tok::eof:
- // Ran out of tokens.
- return false;
-
- case tok::l_paren:
- // Recursively skip properly-nested parens.
- ConsumeParen();
- SkipUntil(tok::r_paren, false);
- break;
- case tok::l_square:
- // Recursively skip properly-nested square brackets.
- ConsumeBracket();
- SkipUntil(tok::r_square, false);
- break;
- case tok::l_brace:
- // Recursively skip properly-nested braces.
- ConsumeBrace();
- SkipUntil(tok::r_brace, false);
- break;
-
- // Okay, we found a ']' or '}' or ')', which we think should be balanced.
- // Since the user wasn't looking for this token (if they were, it would
- // already be handled), this isn't balanced. If there is a LHS token at a
- // higher level, we will assume that this matches the unbalanced token
- // and return it. Otherwise, this is a spurious RHS token, which we skip.
- case tok::r_paren:
- if (ParenCount && !isFirstTokenSkipped)
- return false; // Matches something.
- ConsumeParen();
- break;
- case tok::r_square:
- if (BracketCount && !isFirstTokenSkipped)
- return false; // Matches something.
- ConsumeBracket();
- break;
- case tok::r_brace:
- if (BraceCount && !isFirstTokenSkipped)
- return false; // Matches something.
- ConsumeBrace();
- break;
-
- case tok::string_literal:
- case tok::wide_string_literal:
- ConsumeStringToken();
- break;
- case tok::semi:
- if (StopAtSemi)
- return false;
- // FALL THROUGH.
- default:
- // Skip this token.
- ConsumeToken();
- break;
- }
- isFirstTokenSkipped = false;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Scope manipulation
-//===----------------------------------------------------------------------===//
-
-/// EnterScope - Start a new scope.
-void Parser::EnterScope(unsigned ScopeFlags) {
- if (NumCachedScopes) {
- Scope *N = ScopeCache[--NumCachedScopes];
- N->Init(CurScope, ScopeFlags);
- CurScope = N;
- } else {
- CurScope = new Scope(CurScope, ScopeFlags);
- }
-}
-
-/// ExitScope - Pop a scope off the scope stack.
-void Parser::ExitScope() {
- assert(CurScope && "Scope imbalance!");
-
- // Inform the actions module that this scope is going away if there are any
- // decls in it.
- if (!CurScope->decl_empty())
- Actions.ActOnPopScope(Tok.getLocation(), CurScope);
-
- Scope *OldScope = CurScope;
- CurScope = OldScope->getParent();
-
- if (NumCachedScopes == ScopeCacheSize)
- delete OldScope;
- else
- ScopeCache[NumCachedScopes++] = OldScope;
-}
-
-
-
-
-//===----------------------------------------------------------------------===//
-// C99 6.9: External Definitions.
-//===----------------------------------------------------------------------===//
-
-Parser::~Parser() {
- // If we still have scopes active, delete the scope tree.
- delete CurScope;
-
- // Free the scope cache.
- for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
- delete ScopeCache[i];
-
- // Remove the pragma handlers we installed.
- PP.RemovePragmaHandler(0, PackHandler);
- delete PackHandler;
-}
-
-/// Initialize - Warm up the parser.
-///
-void Parser::Initialize() {
- // Prime the lexer look-ahead.
- ConsumeToken();
-
- // Create the translation unit scope. Install it as the current scope.
- assert(CurScope == 0 && "A scope is already active?");
- EnterScope(Scope::DeclScope);
- Actions.ActOnTranslationUnitScope(Tok.getLocation(), CurScope);
-
- if (Tok.is(tok::eof) &&
- !getLang().CPlusPlus) // Empty source file is an extension in C
- Diag(Tok, diag::ext_empty_source_file);
-
- // Initialization for Objective-C context sensitive keywords recognition.
- // Referenced in Parser::ParseObjCTypeQualifierList.
- if (getLang().ObjC1) {
- ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
- ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
- ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
- ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway");
- ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
- ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
- }
- if (getLang().ObjC2) {
- ObjCPropertyAttrs[objc_readonly] = &PP.getIdentifierTable().get("readonly");
- ObjCPropertyAttrs[objc_getter] = &PP.getIdentifierTable().get("getter");
- ObjCPropertyAttrs[objc_setter] = &PP.getIdentifierTable().get("setter");
- ObjCPropertyAttrs[objc_assign] = &PP.getIdentifierTable().get("assign");
- ObjCPropertyAttrs[objc_readwrite] =
- &PP.getIdentifierTable().get("readwrite");
- ObjCPropertyAttrs[objc_retain] = &PP.getIdentifierTable().get("retain");
- ObjCPropertyAttrs[objc_copy] = &PP.getIdentifierTable().get("copy");
- ObjCPropertyAttrs[objc_nonatomic] =
- &PP.getIdentifierTable().get("nonatomic");
- }
-
- Ident_super = &PP.getIdentifierTable().get("super");
-}
-
-/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
-/// action tells us to. This returns true if the EOF was encountered.
-bool Parser::ParseTopLevelDecl(DeclTy*& Result) {
- Result = 0;
- if (Tok.is(tok::eof)) {
- Actions.ActOnEndOfTranslationUnit();
- return true;
- }
-
- Result = ParseExternalDeclaration();
- return false;
-}
-
-/// ParseTranslationUnit:
-/// translation-unit: [C99 6.9]
-/// external-declaration
-/// translation-unit external-declaration
-void Parser::ParseTranslationUnit() {
- Initialize(); // pushes a scope.
-
- DeclTy *Res;
- while (!ParseTopLevelDecl(Res))
- /*parse them all*/;
-
- ExitScope();
- assert(CurScope == 0 && "Scope imbalance!");
-}
-
-/// ParseExternalDeclaration:
-/// external-declaration: [C99 6.9]
-/// function-definition
-/// declaration
-/// [EXT] ';'
-/// [GNU] asm-definition
-/// [GNU] __extension__ external-declaration
-/// [OBJC] objc-class-definition
-/// [OBJC] objc-class-declaration
-/// [OBJC] objc-alias-declaration
-/// [OBJC] objc-protocol-definition
-/// [OBJC] objc-method-definition
-/// [OBJC] @end
-///
-/// [GNU] asm-definition:
-/// simple-asm-expr ';'
-///
-Parser::DeclTy *Parser::ParseExternalDeclaration() {
- switch (Tok.getKind()) {
- case tok::semi:
- Diag(Tok, diag::ext_top_level_semi);
- ConsumeToken();
- // TODO: Invoke action for top-level semicolon.
- return 0;
- case tok::kw___extension__: {
- ConsumeToken();
- // FIXME: Disable extension warnings.
- DeclTy *RV = ParseExternalDeclaration();
- // FIXME: Restore extension warnings.
- return RV;
- }
- case tok::kw_asm: {
- ExprResult Result = ParseSimpleAsm();
-
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
- "top-level asm block");
-
- if (!Result.isInvalid)
- return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.Val);
- return 0;
- }
- case tok::at:
- // @ is not a legal token unless objc is enabled, no need to check.
- return ParseObjCAtDirectives();
- case tok::minus:
- case tok::plus:
- if (getLang().ObjC1)
- return ParseObjCMethodDefinition();
- else {
- Diag(Tok, diag::err_expected_external_declaration);
- ConsumeToken();
- }
- return 0;
- case tok::kw_namespace:
- case tok::kw_typedef:
- // A function definition cannot start with a these keywords.
- return ParseDeclaration(Declarator::FileContext);
- default:
- // We can't tell whether this is a function-definition or declaration yet.
- return ParseDeclarationOrFunctionDefinition();
- }
-}
-
-/// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
-/// a declaration. We can't tell which we have until we read up to the
-/// compound-statement in function-definition.
-///
-/// function-definition: [C99 6.9.1]
-/// decl-specs declarator declaration-list[opt] compound-statement
-/// [C90] function-definition: [C99 6.7.1] - implicit int result
-/// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
-///
-/// declaration: [C99 6.7]
-/// declaration-specifiers init-declarator-list[opt] ';'
-/// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
-/// [OMP] threadprivate-directive [TODO]
-///
-Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() {
- // Parse the common declaration-specifiers piece.
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
-
- // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
- // declaration-specifiers init-declarator-list[opt] ';'
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
- }
-
- // ObjC2 allows prefix attributes on class interfaces and protocols.
- // FIXME: This still needs better diagnostics. We should only accept
- // attributes here, no types, etc.
- if (getLang().ObjC2 && Tok.is(tok::at)) {
- SourceLocation AtLoc = ConsumeToken(); // the "@"
- if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
- !Tok.isObjCAtKeyword(tok::objc_protocol)) {
- Diag(Tok, diag::err_objc_unexpected_attr);
- SkipUntil(tok::semi); // FIXME: better skip?
- return 0;
- }
- const char *PrevSpec = 0;
- if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec))
- Diag(AtLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
- if (Tok.isObjCAtKeyword(tok::objc_protocol))
- return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
- return ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
- }
-
- // If the declspec consisted only of 'extern' and we have a string
- // literal following it, this must be a C++ linkage specifier like
- // 'extern "C"'.
- if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
- DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
- DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier)
- return ParseLinkage(Declarator::FileContext);
-
- // Parse the first declarator.
- Declarator DeclaratorInfo(DS, Declarator::FileContext);
- ParseDeclarator(DeclaratorInfo);
- // Error parsing the declarator?
- if (DeclaratorInfo.getIdentifier() == 0) {
- // If so, skip until the semi-colon or a }.
- SkipUntil(tok::r_brace, true);
- if (Tok.is(tok::semi))
- ConsumeToken();
- return 0;
- }
-
- // If the declarator is the start of a function definition, handle it.
- if (Tok.is(tok::equal) || // int X()= -> not a function def
- Tok.is(tok::comma) || // int X(), -> not a function def
- Tok.is(tok::semi) || // int X(); -> not a function def
- Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
- Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
- (getLang().CPlusPlus &&
- Tok.is(tok::l_paren)) ) { // int X(0) -> not a function def [C++]
- // FALL THROUGH.
- } else if (DeclaratorInfo.isFunctionDeclarator() &&
- (Tok.is(tok::l_brace) || // int X() {}
- ( !getLang().CPlusPlus &&
- isDeclarationSpecifier() ))) { // int X(f) int f; {}
- if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
- Diag(Tok, diag::err_function_declared_typedef);
-
- if (Tok.is(tok::l_brace)) {
- // This recovery skips the entire function body. It would be nice
- // to simply call ParseFunctionDefintion() below, however Sema
- // assumes the declarator represents a function, not a typedef.
- ConsumeBrace();
- SkipUntil(tok::r_brace, true);
- } else {
- SkipUntil(tok::semi);
- }
- return 0;
- }
- return ParseFunctionDefinition(DeclaratorInfo);
- } else {
- if (DeclaratorInfo.isFunctionDeclarator())
- Diag(Tok, diag::err_expected_fn_body);
- else
- Diag(Tok, diag::err_expected_after_declarator);
- SkipUntil(tok::semi);
- return 0;
- }
-
- // Parse the init-declarator-list for a normal declaration.
- return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
-}
-
-/// ParseFunctionDefinition - We parsed and verified that the specified
-/// Declarator is well formed. If this is a K&R-style function, read the
-/// parameters declaration-list, then start the compound-statement.
-///
-/// function-definition: [C99 6.9.1]
-/// decl-specs declarator declaration-list[opt] compound-statement
-/// [C90] function-definition: [C99 6.7.1] - implicit int result
-/// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
-///
-Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
- const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
- assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
- "This isn't a function declarator!");
- const DeclaratorChunk::FunctionTypeInfo &FTI = FnTypeInfo.Fun;
-
- // If this is C90 and the declspecs were completely missing, fudge in an
- // implicit int. We do this here because this is the only place where
- // declaration-specifiers are completely optional in the grammar.
- if (getLang().ImplicitInt && D.getDeclSpec().getParsedSpecifiers() == 0) {
- const char *PrevSpec;
- D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int, D.getIdentifierLoc(),
- PrevSpec);
- }
-
- // If this declaration was formed with a K&R-style identifier list for the
- // arguments, parse declarations for all of the args next.
- // int foo(a,b) int a; float b; {}
- if (!FTI.hasPrototype && FTI.NumArgs != 0)
- ParseKNRParamDeclarations(D);
-
- // We should have an opening brace now.
- if (Tok.isNot(tok::l_brace)) {
- Diag(Tok, diag::err_expected_fn_body);
-
- // Skip over garbage, until we get to '{'. Don't eat the '{'.
- SkipUntil(tok::l_brace, true, true);
-
- // If we didn't find the '{', bail out.
- if (Tok.isNot(tok::l_brace))
- return 0;
- }
-
- SourceLocation BraceLoc = Tok.getLocation();
-
- // Enter a scope for the function body.
- EnterScope(Scope::FnScope|Scope::DeclScope);
-
- // Tell the actions module that we have entered a function definition with the
- // specified Declarator for the function.
- DeclTy *Res = Actions.ActOnStartOfFunctionDef(CurScope, D);
-
- return ParseFunctionStatementBody(Res, BraceLoc, BraceLoc);
-}
-
-/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
-/// types for a function with a K&R-style identifier list for arguments.
-void Parser::ParseKNRParamDeclarations(Declarator &D) {
- // We know that the top-level of this declarator is a function.
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
-
- // Enter function-declaration scope, limiting any declarators to the
- // function prototype scope, including parameter declarators.
- EnterScope(Scope::FnScope|Scope::DeclScope);
-
- // Read all the argument declarations.
- while (isDeclarationSpecifier()) {
- SourceLocation DSStart = Tok.getLocation();
-
- // Parse the common declaration-specifiers piece.
- DeclSpec DS;
- ParseDeclarationSpecifiers(DS);
-
- // C99 6.9.1p6: 'each declaration in the declaration list shall have at
- // least one declarator'.
- // NOTE: GCC just makes this an ext-warn. It's not clear what it does with
- // the declarations though. It's trivial to ignore them, really hard to do
- // anything else with them.
- if (Tok.is(tok::semi)) {
- Diag(DSStart, diag::err_declaration_does_not_declare_param);
- ConsumeToken();
- continue;
- }
-
- // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other
- // than register.
- if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
- DS.getStorageClassSpec() != DeclSpec::SCS_register) {
- Diag(DS.getStorageClassSpecLoc(),
- diag::err_invalid_storage_class_in_func_decl);
- DS.ClearStorageClassSpecs();
- }
- if (DS.isThreadSpecified()) {
- Diag(DS.getThreadSpecLoc(),
- diag::err_invalid_storage_class_in_func_decl);
- DS.ClearStorageClassSpecs();
- }
-
- // Parse the first declarator attached to this declspec.
- Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext);
- ParseDeclarator(ParmDeclarator);
-
- // Handle the full declarator list.
- while (1) {
- DeclTy *AttrList;
- // If attributes are present, parse them.
- if (Tok.is(tok::kw___attribute))
- // FIXME: attach attributes too.
- AttrList = ParseAttributes();
-
- // Ask the actions module to compute the type for this declarator.
- Action::DeclTy *Param =
- Actions.ActOnParamDeclarator(CurScope, ParmDeclarator);
-
- if (Param &&
- // A missing identifier has already been diagnosed.
- ParmDeclarator.getIdentifier()) {
-
- // Scan the argument list looking for the correct param to apply this
- // type.
- for (unsigned i = 0; ; ++i) {
- // C99 6.9.1p6: those declarators shall declare only identifiers from
- // the identifier list.
- if (i == FTI.NumArgs) {
- Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param,
- ParmDeclarator.getIdentifier()->getName());
- break;
- }
-
- if (FTI.ArgInfo[i].Ident == ParmDeclarator.getIdentifier()) {
- // Reject redefinitions of parameters.
- if (FTI.ArgInfo[i].Param) {
- Diag(ParmDeclarator.getIdentifierLoc(),
- diag::err_param_redefinition,
- ParmDeclarator.getIdentifier()->getName());
- } else {
- FTI.ArgInfo[i].Param = Param;
- }
- break;
- }
- }
- }
-
- // If we don't have a comma, it is either the end of the list (a ';') or
- // an error, bail out.
- if (Tok.isNot(tok::comma))
- break;
-
- // Consume the comma.
- ConsumeToken();
-
- // Parse the next declarator.
- ParmDeclarator.clear();
- ParseDeclarator(ParmDeclarator);
- }
-
- if (Tok.is(tok::semi)) {
- ConsumeToken();
- } else {
- Diag(Tok, diag::err_parse_error);
- // Skip to end of block or statement
- SkipUntil(tok::semi, true);
- if (Tok.is(tok::semi))
- ConsumeToken();
- }
- }
-
- // Leave prototype scope.
- ExitScope();
-
- // The actions module must verify that all arguments were declared.
-}
-
-
-/// ParseAsmStringLiteral - This is just a normal string-literal, but is not
-/// allowed to be a wide string, and is not subject to character translation.
-///
-/// [GNU] asm-string-literal:
-/// string-literal
-///
-Parser::ExprResult Parser::ParseAsmStringLiteral() {
- if (!isTokenStringLiteral()) {
- Diag(Tok, diag::err_expected_string_literal);
- return true;
- }
-
- ExprResult Res = ParseStringLiteralExpression();
- if (Res.isInvalid) return true;
-
- // TODO: Diagnose: wide string literal in 'asm'
-
- return Res;
-}
-
-/// ParseSimpleAsm
-///
-/// [GNU] simple-asm-expr:
-/// 'asm' '(' asm-string-literal ')'
-///
-Parser::ExprResult Parser::ParseSimpleAsm() {
- assert(Tok.is(tok::kw_asm) && "Not an asm!");
- SourceLocation Loc = ConsumeToken();
-
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen_after, "asm");
- return true;
- }
-
- ConsumeParen();
-
- ExprResult Result = ParseAsmStringLiteral();
-
- if (Result.isInvalid) {
- SkipUntil(tok::r_paren);
- } else {
- MatchRHSPunctuation(tok::r_paren, Loc);
- }
-
- return Result;
-}
-
diff --git a/clang/lib/Rewrite/DeltaTree.cpp b/clang/lib/Rewrite/DeltaTree.cpp
deleted file mode 100644
index 5d51ddae0896..000000000000
--- a/clang/lib/Rewrite/DeltaTree.cpp
+++ /dev/null
@@ -1,485 +0,0 @@
-//===--- DeltaTree.cpp - B-Tree for Rewrite Delta tracking ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the DeltaTree and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/DeltaTree.h"
-#include "llvm/Support/Casting.h"
-#include <cstring>
-#include <cstdio>
-using namespace clang;
-using llvm::cast;
-using llvm::dyn_cast;
-
-namespace {
- struct SourceDelta;
- class DeltaTreeNode;
- class DeltaTreeInteriorNode;
-}
-
-/// The DeltaTree class is a multiway search tree (BTree) structure with some
-/// fancy features. B-Trees are are generally more memory and cache efficient
-/// than binary trees, because they store multiple keys/values in each node.
-///
-/// DeltaTree implements a key/value mapping from FileIndex to Delta, allowing
-/// fast lookup by FileIndex. However, an added (important) bonus is that it
-/// can also efficiently tell us the full accumulated delta for a specific
-/// file offset as well, without traversing the whole tree.
-///
-/// The nodes of the tree are made up of instances of two classes:
-/// DeltaTreeNode and DeltaTreeInteriorNode. The later subclasses the
-/// former and adds children pointers. Each node knows the full delta of all
-/// entries (recursively) contained inside of it, which allows us to get the
-/// full delta implied by a whole subtree in constant time.
-
-namespace {
- /// SourceDelta - As code in the original input buffer is added and deleted,
- /// SourceDelta records are used to keep track of how the input SourceLocation
- /// object is mapped into the output buffer.
- struct SourceDelta {
- unsigned FileLoc;
- int Delta;
-
- static SourceDelta get(unsigned Loc, int D) {
- SourceDelta Delta;
- Delta.FileLoc = Loc;
- Delta.Delta = D;
- return Delta;
- }
- };
-} // end anonymous namespace
-
-
-namespace {
- struct InsertResult {
- DeltaTreeNode *LHS, *RHS;
- SourceDelta Split;
- };
-} // end anonymous namespace
-
-
-namespace {
- /// DeltaTreeNode - The common part of all nodes.
- ///
- class DeltaTreeNode {
- friend class DeltaTreeInteriorNode;
-
- /// WidthFactor - This controls the number of K/V slots held in the BTree:
- /// how wide it is. Each level of the BTree is guaranteed to have at least
- /// WidthFactor-1 K/V pairs (except the root) and may have at most
- /// 2*WidthFactor-1 K/V pairs.
- enum { WidthFactor = 8 };
-
- /// Values - This tracks the SourceDelta's currently in this node.
- ///
- SourceDelta Values[2*WidthFactor-1];
-
- /// NumValuesUsed - This tracks the number of values this node currently
- /// holds.
- unsigned char NumValuesUsed;
-
- /// IsLeaf - This is true if this is a leaf of the btree. If false, this is
- /// an interior node, and is actually an instance of DeltaTreeInteriorNode.
- bool IsLeaf;
-
- /// FullDelta - This is the full delta of all the values in this node and
- /// all children nodes.
- int FullDelta;
- public:
- DeltaTreeNode(bool isLeaf = true)
- : NumValuesUsed(0), IsLeaf(isLeaf), FullDelta(0) {}
-
- bool isLeaf() const { return IsLeaf; }
- int getFullDelta() const { return FullDelta; }
- bool isFull() const { return NumValuesUsed == 2*WidthFactor-1; }
-
- unsigned getNumValuesUsed() const { return NumValuesUsed; }
- const SourceDelta &getValue(unsigned i) const {
- assert(i < NumValuesUsed && "Invalid value #");
- return Values[i];
- }
- SourceDelta &getValue(unsigned i) {
- assert(i < NumValuesUsed && "Invalid value #");
- return Values[i];
- }
-
- /// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
- /// this node. If insertion is easy, do it and return false. Otherwise,
- /// split the node, populate InsertRes with info about the split, and return
- /// true.
- bool DoInsertion(unsigned FileIndex, int Delta, InsertResult *InsertRes);
-
- void DoSplit(InsertResult &InsertRes);
-
-
- /// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
- /// local walk over our contained deltas.
- void RecomputeFullDeltaLocally();
-
- void Destroy();
-
- static inline bool classof(const DeltaTreeNode *) { return true; }
- };
-} // end anonymous namespace
-
-namespace {
- /// DeltaTreeInteriorNode - When isLeaf = false, a node has child pointers.
- /// This class tracks them.
- class DeltaTreeInteriorNode : public DeltaTreeNode {
- DeltaTreeNode *Children[2*WidthFactor];
- ~DeltaTreeInteriorNode() {
- for (unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
- Children[i]->Destroy();
- }
- friend class DeltaTreeNode;
- public:
- DeltaTreeInteriorNode() : DeltaTreeNode(false /*nonleaf*/) {}
-
- DeltaTreeInteriorNode(DeltaTreeNode *FirstChild)
- : DeltaTreeNode(false /*nonleaf*/) {
- FullDelta = FirstChild->FullDelta;
- Children[0] = FirstChild;
- }
-
- DeltaTreeInteriorNode(const InsertResult &IR)
- : DeltaTreeNode(false /*nonleaf*/) {
- Children[0] = IR.LHS;
- Children[1] = IR.RHS;
- Values[0] = IR.Split;
- FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
- NumValuesUsed = 1;
- }
-
- const DeltaTreeNode *getChild(unsigned i) const {
- assert(i < getNumValuesUsed()+1 && "Invalid child");
- return Children[i];
- }
- DeltaTreeNode *getChild(unsigned i) {
- assert(i < getNumValuesUsed()+1 && "Invalid child");
- return Children[i];
- }
-
- static inline bool classof(const DeltaTreeInteriorNode *) { return true; }
- static inline bool classof(const DeltaTreeNode *N) { return !N->isLeaf(); }
- };
-}
-
-
-/// Destroy - A 'virtual' destructor.
-void DeltaTreeNode::Destroy() {
- if (isLeaf())
- delete this;
- else
- delete cast<DeltaTreeInteriorNode>(this);
-}
-
-/// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
-/// local walk over our contained deltas.
-void DeltaTreeNode::RecomputeFullDeltaLocally() {
- int NewFullDelta = 0;
- for (unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
- NewFullDelta += Values[i].Delta;
- if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this))
- for (unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
- NewFullDelta += IN->getChild(i)->getFullDelta();
- FullDelta = NewFullDelta;
-}
-
-/// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
-/// this node. If insertion is easy, do it and return false. Otherwise,
-/// split the node, populate InsertRes with info about the split, and return
-/// true.
-bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
- InsertResult *InsertRes) {
- // Maintain full delta for this node.
- FullDelta += Delta;
-
- // Find the insertion point, the first delta whose index is >= FileIndex.
- unsigned i = 0, e = getNumValuesUsed();
- while (i != e && FileIndex > getValue(i).FileLoc)
- ++i;
-
- // If we found an a record for exactly this file index, just merge this
- // value into the pre-existing record and finish early.
- if (i != e && getValue(i).FileLoc == FileIndex) {
- // NOTE: Delta could drop to zero here. This means that the delta entry is
- // useless and could be removed. Supporting erases is more complex than
- // leaving an entry with Delta=0, so we just leave an entry with Delta=0 in
- // the tree.
- Values[i].Delta += Delta;
- return false;
- }
-
- // Otherwise, we found an insertion point, and we know that the value at the
- // specified index is > FileIndex. Handle the leaf case first.
- if (isLeaf()) {
- if (!isFull()) {
- // For an insertion into a non-full leaf node, just insert the value in
- // its sorted position. This requires moving later values over.
- if (i != e)
- memmove(&Values[i+1], &Values[i], sizeof(Values[0])*(e-i));
- Values[i] = SourceDelta::get(FileIndex, Delta);
- ++NumValuesUsed;
- return false;
- }
-
- // Otherwise, if this is leaf is full, split the node at its median, insert
- // the value into one of the children, and return the result.
- assert(InsertRes && "No result location specified");
- DoSplit(*InsertRes);
-
- if (InsertRes->Split.FileLoc > FileIndex)
- InsertRes->LHS->DoInsertion(FileIndex, Delta, 0 /*can't fail*/);
- else
- InsertRes->RHS->DoInsertion(FileIndex, Delta, 0 /*can't fail*/);
- return true;
- }
-
- // Otherwise, this is an interior node. Send the request down the tree.
- DeltaTreeInteriorNode *IN = cast<DeltaTreeInteriorNode>(this);
- if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
- return false; // If there was space in the child, just return.
-
- // Okay, this split the subtree, producing a new value and two children to
- // insert here. If this node is non-full, we can just insert it directly.
- if (!isFull()) {
- // Now that we have two nodes and a new element, insert the perclated value
- // into ourself by moving all the later values/children down, then inserting
- // the new one.
- if (i != e)
- memmove(&IN->Children[i+2], &IN->Children[i+1],
- (e-i)*sizeof(IN->Children[0]));
- IN->Children[i] = InsertRes->LHS;
- IN->Children[i+1] = InsertRes->RHS;
-
- if (e != i)
- memmove(&Values[i+1], &Values[i], (e-i)*sizeof(Values[0]));
- Values[i] = InsertRes->Split;
- ++NumValuesUsed;
- return false;
- }
-
- // Finally, if this interior node was full and a node is percolated up, split
- // ourself and return that up the chain. Start by saving all our info to
- // avoid having the split clobber it.
- IN->Children[i] = InsertRes->LHS;
- DeltaTreeNode *SubRHS = InsertRes->RHS;
- SourceDelta SubSplit = InsertRes->Split;
-
- // Do the split.
- DoSplit(*InsertRes);
-
- // Figure out where to insert SubRHS/NewSplit.
- DeltaTreeInteriorNode *InsertSide;
- if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
- InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
- else
- InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
-
- // We now have a non-empty interior node 'InsertSide' to insert
- // SubRHS/SubSplit into. Find out where to insert SubSplit.
-
- // Find the insertion point, the first delta whose index is >SubSplit.FileLoc.
- i = 0; e = InsertSide->getNumValuesUsed();
- while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
- ++i;
-
- // Now we know that i is the place to insert the split value into. Insert it
- // and the child right after it.
- if (i != e)
- memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
- (e-i)*sizeof(IN->Children[0]));
- InsertSide->Children[i+1] = SubRHS;
-
- if (e != i)
- memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
- (e-i)*sizeof(Values[0]));
- InsertSide->Values[i] = SubSplit;
- ++InsertSide->NumValuesUsed;
- InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
- return true;
-}
-
-/// DoSplit - Split the currently full node (which has 2*WidthFactor-1 values)
-/// into two subtrees each with "WidthFactor-1" values and a pivot value.
-/// Return the pieces in InsertRes.
-void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
- assert(isFull() && "Why split a non-full node?");
-
- // Since this node is full, it contains 2*WidthFactor-1 values. We move
- // the first 'WidthFactor-1' values to the LHS child (which we leave in this
- // node), propagate one value up, and move the last 'WidthFactor-1' values
- // into the RHS child.
-
- // Create the new child node.
- DeltaTreeNode *NewNode;
- if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this)) {
- // If this is an interior node, also move over 'WidthFactor' children
- // into the new node.
- DeltaTreeInteriorNode *New = new DeltaTreeInteriorNode();
- memcpy(&New->Children[0], &IN->Children[WidthFactor],
- WidthFactor*sizeof(IN->Children[0]));
- NewNode = New;
- } else {
- // Just create the new leaf node.
- NewNode = new DeltaTreeNode();
- }
-
- // Move over the last 'WidthFactor-1' values from here to NewNode.
- memcpy(&NewNode->Values[0], &Values[WidthFactor],
- (WidthFactor-1)*sizeof(Values[0]));
-
- // Decrease the number of values in the two nodes.
- NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
-
- // Recompute the two nodes' full delta.
- NewNode->RecomputeFullDeltaLocally();
- RecomputeFullDeltaLocally();
-
- InsertRes.LHS = this;
- InsertRes.RHS = NewNode;
- InsertRes.Split = Values[WidthFactor-1];
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// DeltaTree Implementation
-//===----------------------------------------------------------------------===//
-
-//#define VERIFY_TREE
-
-#ifdef VERIFY_TREE
-/// VerifyTree - Walk the btree performing assertions on various properties to
-/// verify consistency. This is useful for debugging new changes to the tree.
-static void VerifyTree(const DeltaTreeNode *N) {
- const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(N);
- if (IN == 0) {
- // Verify leaves, just ensure that FullDelta matches up and the elements
- // are in proper order.
- int FullDelta = 0;
- for (unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
- if (i)
- assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
- FullDelta += N->getValue(i).Delta;
- }
- assert(FullDelta == N->getFullDelta());
- return;
- }
-
- // Verify interior nodes: Ensure that FullDelta matches up and the
- // elements are in proper order and the children are in proper order.
- int FullDelta = 0;
- for (unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
- const SourceDelta &IVal = N->getValue(i);
- const DeltaTreeNode *IChild = IN->getChild(i);
- if (i)
- assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
- FullDelta += IVal.Delta;
- FullDelta += IChild->getFullDelta();
-
- // The largest value in child #i should be smaller than FileLoc.
- assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
- IVal.FileLoc);
-
- // The smallest value in child #i+1 should be larger than FileLoc.
- assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
- VerifyTree(IChild);
- }
-
- FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
-
- assert(FullDelta == N->getFullDelta());
-}
-#endif // VERIFY_TREE
-
-static DeltaTreeNode *getRoot(void *Root) {
- return (DeltaTreeNode*)Root;
-}
-
-DeltaTree::DeltaTree() {
- Root = new DeltaTreeNode();
-}
-DeltaTree::DeltaTree(const DeltaTree &RHS) {
- // Currently we only support copying when the RHS is empty.
- assert(getRoot(RHS.Root)->getNumValuesUsed() == 0 &&
- "Can only copy empty tree");
- Root = new DeltaTreeNode();
-}
-
-DeltaTree::~DeltaTree() {
- getRoot(Root)->Destroy();
-}
-
-/// getDeltaAt - Return the accumulated delta at the specified file offset.
-/// This includes all insertions or delections that occurred *before* the
-/// specified file index.
-int DeltaTree::getDeltaAt(unsigned FileIndex) const {
- const DeltaTreeNode *Node = getRoot(Root);
-
- int Result = 0;
-
- // Walk down the tree.
- while (1) {
- // For all nodes, include any local deltas before the specified file
- // index by summing them up directly. Keep track of how many were
- // included.
- unsigned NumValsGreater = 0;
- for (unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
- ++NumValsGreater) {
- const SourceDelta &Val = Node->getValue(NumValsGreater);
-
- if (Val.FileLoc >= FileIndex)
- break;
- Result += Val.Delta;
- }
-
- // If we have an interior node, include information about children and
- // recurse. Otherwise, if we have a leaf, we're done.
- const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(Node);
- if (!IN) return Result;
-
- // Include any children to the left of the values we skipped, all of
- // their deltas should be included as well.
- for (unsigned i = 0; i != NumValsGreater; ++i)
- Result += IN->getChild(i)->getFullDelta();
-
- // If we found exactly the value we were looking for, break off the
- // search early. There is no need to search the RHS of the value for
- // partial results.
- if (NumValsGreater != Node->getNumValuesUsed() &&
- Node->getValue(NumValsGreater).FileLoc == FileIndex)
- return Result+IN->getChild(NumValsGreater)->getFullDelta();
-
- // Otherwise, traverse down the tree. The selected subtree may be
- // partially included in the range.
- Node = IN->getChild(NumValsGreater);
- }
- // NOT REACHED.
-}
-
-/// AddDelta - When a change is made that shifts around the text buffer,
-/// this method is used to record that info. It inserts a delta of 'Delta'
-/// into the current DeltaTree at offset FileIndex.
-void DeltaTree::AddDelta(unsigned FileIndex, int Delta) {
- assert(Delta && "Adding a noop?");
- DeltaTreeNode *MyRoot = getRoot(Root);
-
- InsertResult InsertRes;
- if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
- Root = MyRoot = new DeltaTreeInteriorNode(InsertRes);
- }
-
-#ifdef VERIFY_TREE
- VerifyTree(MyRoot);
-#endif
-}
-
diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp
deleted file mode 100644
index b411e568f6dd..000000000000
--- a/clang/lib/Rewrite/HTMLRewrite.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-//== HTMLRewrite.cpp - Translate source code into prettified HTML --*- 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 HTMLRewriter clas, which is used to translate the
-// text of a source file into prettified HTML.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/Rewrite/HTMLRewrite.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-
-/// HighlightRange - Highlight a range in the source code with the specified
-/// start/end tags. B/E must be in the same file. This ensures that
-/// start/end tags are placed at the start/end of each line if the range is
-/// multiline.
-void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
- const char *StartTag, const char *EndTag) {
- SourceManager &SM = R.getSourceMgr();
- B = SM.getLogicalLoc(B);
- E = SM.getLogicalLoc(E);
- unsigned FileID = SM.getCanonicalFileID(B);
- assert(SM.getCanonicalFileID(E) == FileID && "B/E not in the same file!");
-
- unsigned BOffset = SM.getFullFilePos(B);
- unsigned EOffset = SM.getFullFilePos(E);
-
- // Include the whole end token in the range.
- EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr());
-
- HighlightRange(R.getEditBuffer(FileID), BOffset, EOffset,
- SM.getBufferData(FileID).first, StartTag, EndTag);
-}
-
-/// HighlightRange - This is the same as the above method, but takes
-/// decomposed file locations.
-void html::HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
- const char *BufferStart,
- const char *StartTag, const char *EndTag) {
- // Insert the tag at the absolute start/end of the range.
- RB.InsertTextAfter(B, StartTag, strlen(StartTag));
- RB.InsertTextBefore(E, EndTag, strlen(EndTag));
-
- // Scan the range to see if there is a \r or \n. If so, and if the line is
- // not blank, insert tags on that line as well.
- bool HadOpenTag = true;
-
- unsigned LastNonWhiteSpace = B;
- for (unsigned i = B; i != E; ++i) {
- switch (BufferStart[i]) {
- case '\r':
- case '\n':
- // Okay, we found a newline in the range. If we have an open tag, we need
- // to insert a close tag at the first non-whitespace before the newline.
- if (HadOpenTag)
- RB.InsertTextBefore(LastNonWhiteSpace+1, EndTag, strlen(EndTag));
-
- // Instead of inserting an open tag immediately after the newline, we
- // wait until we see a non-whitespace character. This prevents us from
- // inserting tags around blank lines, and also allows the open tag to
- // be put *after* whitespace on a non-blank line.
- HadOpenTag = false;
- break;
- case '\0':
- case ' ':
- case '\t':
- case '\f':
- case '\v':
- // Ignore whitespace.
- break;
-
- default:
- // If there is no tag open, do it now.
- if (!HadOpenTag) {
- RB.InsertTextAfter(i, StartTag, strlen(StartTag));
- HadOpenTag = true;
- }
-
- // Remember this character.
- LastNonWhiteSpace = i;
- break;
- }
- }
-}
-
-void html::EscapeText(Rewriter& R, unsigned FileID,
- bool EscapeSpaces, bool ReplaceTabs) {
-
- const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
- const char* C = Buf->getBufferStart();
- const char* FileEnd = Buf->getBufferEnd();
-
- assert (C <= FileEnd);
-
- RewriteBuffer &RB = R.getEditBuffer(FileID);
-
- unsigned ColNo = 0;
- for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
- switch (*C) {
- default: ++ColNo; break;
- case '\n':
- case '\r':
- ColNo = 0;
- break;
-
- case ' ':
- if (EscapeSpaces)
- RB.ReplaceText(FilePos, 1, "&nbsp;", 6);
- ++ColNo;
- break;
- case '\f':
- RB.ReplaceText(FilePos, 1, "<hr>", 4);
- ColNo = 0;
- break;
-
- case '\t': {
- if (!ReplaceTabs)
- break;
- unsigned NumSpaces = 8-(ColNo&7);
- if (EscapeSpaces)
- RB.ReplaceText(FilePos, 1, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
- "&nbsp;&nbsp;&nbsp;", 6*NumSpaces);
- else
- RB.ReplaceText(FilePos, 1, " ", NumSpaces);
- ColNo += NumSpaces;
- break;
- }
- case '<':
- RB.ReplaceText(FilePos, 1, "&lt;", 4);
- ++ColNo;
- break;
-
- case '>':
- RB.ReplaceText(FilePos, 1, "&gt;", 4);
- ++ColNo;
- break;
-
- case '&':
- RB.ReplaceText(FilePos, 1, "&amp;", 5);
- ++ColNo;
- break;
- }
- }
-}
-
-std::string html::EscapeText(const std::string& s, bool EscapeSpaces,
- bool ReplaceTabs) {
-
- unsigned len = s.size();
- std::string Str;
- llvm::raw_string_ostream os(Str);
-
- for (unsigned i = 0 ; i < len; ++i) {
-
- char c = s[i];
- switch (c) {
- default:
- os << c; break;
-
- case ' ':
- if (EscapeSpaces) os << "&nbsp;";
- else os << ' ';
- break;
-
- case '\t':
- if (ReplaceTabs) {
- if (EscapeSpaces)
- for (unsigned i = 0; i < 4; ++i)
- os << "&nbsp;";
- else
- for (unsigned i = 0; i < 4; ++i)
- os << " ";
- }
- else
- os << c;
-
- break;
-
- case '<': os << "&lt;"; break;
- case '>': os << "&gt;"; break;
- case '&': os << "&amp;"; break;
- }
- }
-
- return os.str();
-}
-
-static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo,
- unsigned B, unsigned E) {
- llvm::SmallString<100> Str;
- Str += "<tr><td class=\"num\" id=\"LN";
- Str.append_uint(LineNo);
- Str += "\">";
- Str.append_uint(LineNo);
- Str += "</td><td class=\"line\">";
-
- if (B == E) { // Handle empty lines.
- Str += " </td></tr>";
- RB.InsertTextBefore(B, &Str[0], Str.size());
- } else {
- RB.InsertTextBefore(B, &Str[0], Str.size());
- RB.InsertTextBefore(E, "</td></tr>", strlen("</td></tr>"));
- }
-}
-
-void html::AddLineNumbers(Rewriter& R, unsigned FileID) {
-
- const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
- const char* FileBeg = Buf->getBufferStart();
- const char* FileEnd = Buf->getBufferEnd();
- const char* C = FileBeg;
- RewriteBuffer &RB = R.getEditBuffer(FileID);
-
- assert (C <= FileEnd);
-
- unsigned LineNo = 0;
- unsigned FilePos = 0;
-
- while (C != FileEnd) {
-
- ++LineNo;
- unsigned LineStartPos = FilePos;
- unsigned LineEndPos = FileEnd - FileBeg;
-
- assert (FilePos <= LineEndPos);
- assert (C < FileEnd);
-
- // Scan until the newline (or end-of-file).
-
- while (C != FileEnd) {
- char c = *C;
- ++C;
-
- if (c == '\n') {
- LineEndPos = FilePos++;
- break;
- }
-
- ++FilePos;
- }
-
- AddLineNumber(RB, LineNo, LineStartPos, LineEndPos);
- }
-
- // Add one big table tag that surrounds all of the code.
- RB.InsertTextBefore(0, "<table class=\"code\">\n",
- strlen("<table class=\"code\">\n"));
-
- RB.InsertTextAfter(FileEnd - FileBeg, "</table>", strlen("</table>"));
-}
-
-void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID,
- const char *title) {
-
- const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);
- const char* FileStart = Buf->getBufferStart();
- const char* FileEnd = Buf->getBufferEnd();
-
- SourceLocation StartLoc = SourceLocation::getFileLoc(FileID, 0);
- SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart);
-
- std::string s;
- llvm::raw_string_ostream os(s);
- os << "<!doctype html>\n" // Use HTML 5 doctype
- "<html>\n<head>\n";
-
- if (title)
- os << "<title>" << html::EscapeText(title) << "</title>\n";
-
- os << "<style type=\"text/css\">\n"
- " body { color:#000000; background-color:#ffffff }\n"
- " body { font-family:Helvetica, sans-serif; font-size:10pt }\n"
- " h1 { font-size:14pt }\n"
- " .code { border-collapse:collapse; width:100%; }\n"
- " .code { font-family: \"Andale Mono\", monospace; font-size:10pt }\n"
- " .code { line-height: 1.2em }\n"
- " .comment { color: green; font-style: oblique }\n"
- " .keyword { color: blue }\n"
- " .string_literal { color: red }\n"
- " .directive { color: darkmagenta }\n"
- // Macro expansions.
- " .expansion { display: none; }\n"
- " .macro:hover .expansion { display: block; border: 2px solid #FF0000; "
- "padding: 2px; background-color:#FFF0F0; font-weight: normal; "
- " -webkit-border-radius:5px; -webkit-box-shadow:1px 1px 7px #000; "
- "position: absolute; top: -1em; left:10em; z-index: 1 } \n"
- " .macro { color: darkmagenta; background-color:LemonChiffon;"
- // Macros are position: relative to provide base for expansions.
- " position: relative }\n"
- " .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
- " .num { text-align:right; font-size: smaller }\n"
- " .num { color:#444444 }\n"
- " .line { padding-left: 1ex; border-left: 3px solid #ccc }\n"
- " .line { white-space: pre }\n"
- " .msg { background-color:#fff8b4; color:#000000 }\n"
- " .msg { -webkit-box-shadow:1px 1px 7px #000 }\n"
- " .msg { -webkit-border-radius:5px }\n"
- " .msg { font-family:Helvetica, sans-serif; font-size: smaller }\n"
- " .msg { font-weight: bold }\n"
- " .msg { float:left }\n"
- " .msg { padding:0.5em 1ex 0.5em 1ex }\n"
- " .msg { margin-top:10px; margin-bottom:10px }\n"
- " .msg { max-width:60em; word-wrap: break-word; white-space: pre-wrap;}\n"
- " .mrange { background-color:#dfddf3 }\n"
- " .mrange { border-bottom:1px solid #6F9DBE }\n"
- " .PathIndex { font-weight: bold }\n"
- " table.simpletable {\n"
- " padding: 5px;\n"
- " font-size:12pt;\n"
- " margin:20px;\n"
- " border-collapse: collapse; border-spacing: 0px;\n"
- " }\n"
- " td.rowname {\n"
- " text-align:right; font-weight:bold; color:#444444;\n"
- " padding-right:2ex; }\n"
- "</style>\n</head>\n<body>";
-
- // Generate header
- R.InsertStrBefore(StartLoc, os.str());
- // Generate footer
-
- R.InsertCStrAfter(EndLoc, "</body></html>\n");
-}
-
-/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
-/// information about keywords, macro expansions etc. This uses the macro
-/// table state from the end of the file, so it won't be perfectly perfect,
-/// but it will be reasonably close.
-void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
- RewriteBuffer &RB = R.getEditBuffer(FileID);
-
- const SourceManager &SourceMgr = PP.getSourceManager();
- std::pair<const char*, const char*> File = SourceMgr.getBufferData(FileID);
- const char *BufferStart = File.first;
-
- Lexer L(SourceLocation::getFileLoc(FileID, 0), PP.getLangOptions(),
- File.first, File.second);
-
- // Inform the preprocessor that we want to retain comments as tokens, so we
- // can highlight them.
- L.SetCommentRetentionState(true);
-
- // Lex all the tokens in raw mode, to avoid entering #includes or expanding
- // macros.
- Token Tok;
- L.LexRawToken(Tok);
-
- while (Tok.isNot(tok::eof)) {
- // Since we are lexing unexpanded tokens, all tokens are from the main
- // FileID.
- unsigned TokOffs = SourceMgr.getFullFilePos(Tok.getLocation());
- unsigned TokLen = Tok.getLength();
- switch (Tok.getKind()) {
- default: break;
- case tok::identifier: {
- // Fill in Result.IdentifierInfo, looking up the identifier in the
- // identifier table.
- IdentifierInfo *II = PP.LookUpIdentifierInfo(Tok, BufferStart+TokOffs);
-
- // If this is a pp-identifier, for a keyword, highlight it as such.
- if (II->getTokenID() != tok::identifier)
- HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
- "<span class='keyword'>", "</span>");
- break;
- }
- case tok::comment:
- HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
- "<span class='comment'>", "</span>");
- break;
- case tok::wide_string_literal:
- // Chop off the L prefix
- ++TokOffs;
- --TokLen;
- // FALL THROUGH.
- case tok::string_literal:
- HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
- "<span class='string_literal'>", "</span>");
- break;
- case tok::hash: {
- // If this is a preprocessor directive, all tokens to end of line are too.
- if (!Tok.isAtStartOfLine())
- break;
-
- // Eat all of the tokens until we get to the next one at the start of
- // line.
- unsigned TokEnd = TokOffs+TokLen;
- L.LexRawToken(Tok);
- while (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) {
- TokEnd = SourceMgr.getFullFilePos(Tok.getLocation())+Tok.getLength();
- L.LexRawToken(Tok);
- }
-
- // Find end of line. This is a hack.
- HighlightRange(RB, TokOffs, TokEnd, BufferStart,
- "<span class='directive'>", "</span>");
-
- // Don't skip the next token.
- continue;
- }
- }
-
- L.LexRawToken(Tok);
- }
-}
-
-/// HighlightMacros - This uses the macro table state from the end of the
-/// file, to reexpand macros and insert (into the HTML) information about the
-/// macro expansions. This won't be perfectly perfect, but it will be
-/// reasonably close.
-void html::HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor& PP) {
-
- RewriteBuffer &RB = R.getEditBuffer(FileID);
-
- // Inform the preprocessor that we don't want comments.
- PP.SetCommentRetentionState(false, false);
-
- // Start parsing the specified input file.
- PP.EnterMainSourceFile();
-
- // Lex all the tokens.
- const SourceManager &SourceMgr = PP.getSourceManager();
- Token Tok;
- PP.Lex(Tok);
- while (Tok.isNot(tok::eof)) {
- // Ignore non-macro tokens.
- if (!Tok.getLocation().isMacroID()) {
- PP.Lex(Tok);
- continue;
- }
-
- // Ignore tokens whose logical location was not the main file.
- SourceLocation LLoc = SourceMgr.getLogicalLoc(Tok.getLocation());
- std::pair<unsigned, unsigned> LLocInfo =
- SourceMgr.getDecomposedFileLoc(LLoc);
-
- if (LLocInfo.first != FileID) {
- PP.Lex(Tok);
- continue;
- }
-
- // Okay, we have the first token of a macro expansion: highlight the
- // instantiation.
-
- // Get the size of current macro call itself.
- // FIXME: This should highlight the args of a function-like
- // macro, using a heuristic.
- unsigned TokLen = Lexer::MeasureTokenLength(LLoc, SourceMgr);
-
- unsigned TokOffs = LLocInfo.second;
- // Highlight the macro invocation itself.
- RB.InsertTextAfter(TokOffs, "<span class='macro'>",
- strlen("<span class='macro'>"));
- RB.InsertTextBefore(TokOffs+TokLen, "</span>", strlen("</span>"));
-
- std::string Expansion = PP.getSpelling(Tok);
- unsigned LineLen = Expansion.size();
-
- // Okay, eat this token, getting the next one.
- PP.Lex(Tok);
-
- // Skip all the rest of the tokens that are part of this macro
- // instantiation. It would be really nice to pop up a window with all the
- // spelling of the tokens or something.
- while (!Tok.is(tok::eof) &&
- SourceMgr.getLogicalLoc(Tok.getLocation()) == LLoc) {
- // Insert a newline if the macro expansion is getting large.
- if (LineLen > 60) {
- Expansion += "<br>";
- LineLen = 0;
- }
-
- LineLen -= Expansion.size();
- // Escape any special characters in the token text.
- Expansion += ' ' + EscapeText(PP.getSpelling(Tok));
- LineLen += Expansion.size();
- PP.Lex(Tok);
- }
-
- // Insert the information about the expansion inside the macro span.
- Expansion = "<span class='expansion'>" + Expansion + "</span>";
- RB.InsertTextBefore(TokOffs+TokLen, Expansion.c_str(), Expansion.size());
- }
-}
-
-void html::HighlightMacros(Rewriter &R, unsigned FileID,
- PreprocessorFactory &PPF) {
-
- llvm::OwningPtr<Preprocessor> PP(PPF.CreatePreprocessor());
- HighlightMacros(R, FileID, *PP);
-}
diff --git a/clang/lib/Rewrite/Makefile b/clang/lib/Rewrite/Makefile
deleted file mode 100644
index 3c0b5a572744..000000000000
--- a/clang/lib/Rewrite/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements code transformation / rewriting facilities.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangRewrite
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Rewrite/RewriteRope.cpp b/clang/lib/Rewrite/RewriteRope.cpp
deleted file mode 100644
index 61cb02b9a591..000000000000
--- a/clang/lib/Rewrite/RewriteRope.cpp
+++ /dev/null
@@ -1,807 +0,0 @@
-//===--- RewriteRope.cpp - Rope specialized for rewriter --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the RewriteRope class, which is a powerful string.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/RewriteRope.h"
-#include "llvm/Support/Casting.h"
-#include <algorithm>
-using namespace clang;
-using llvm::dyn_cast;
-using llvm::cast;
-
-/// RewriteRope is a "strong" string class, designed to make insertions and
-/// deletions in the middle of the string nearly constant time (really, they are
-/// O(log N), but with a very low constant factor).
-///
-/// The implementation of this datastructure is a conceptual linear sequence of
-/// RopePiece elements. Each RopePiece represents a view on a separately
-/// allocated and reference counted string. This means that splitting a very
-/// long string can be done in constant time by splitting a RopePiece that
-/// references the whole string into two rope pieces that reference each half.
-/// Once split, another string can be inserted in between the two halves by
-/// inserting a RopePiece in between the two others. All of this is very
-/// inexpensive: it takes time proportional to the number of RopePieces, not the
-/// length of the strings they represent.
-///
-/// While a linear sequences of RopePieces is the conceptual model, the actual
-/// implementation captures them in an adapted B+ Tree. Using a B+ tree (which
-/// is a tree that keeps the values in the leaves and has where each node
-/// contains a reasonable number of pointers to children/values) allows us to
-/// maintain efficient operation when the RewriteRope contains a *huge* number
-/// of RopePieces. The basic idea of the B+ Tree is that it allows us to find
-/// the RopePiece corresponding to some offset very efficiently, and it
-/// automatically balances itself on insertions of RopePieces (which can happen
-/// for both insertions and erases of string ranges).
-///
-/// The one wrinkle on the theory is that we don't attempt to keep the tree
-/// properly balanced when erases happen. Erases of string data can both insert
-/// new RopePieces (e.g. when the middle of some other rope piece is deleted,
-/// which results in two rope pieces, which is just like an insert) or it can
-/// reduce the number of RopePieces maintained by the B+Tree. In the case when
-/// the number of RopePieces is reduced, we don't attempt to maintain the
-/// standard 'invariant' that each node in the tree contains at least
-/// 'WidthFactor' children/values. For our use cases, this doesn't seem to
-/// matter.
-///
-/// The implementation below is primarily implemented in terms of three classes:
-/// RopePieceBTreeNode - Common base class for:
-///
-/// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
-/// nodes. This directly represents a chunk of the string with those
-/// RopePieces contatenated.
-/// RopePieceBTreeInterior - An interior node in the B+ Tree, which manages
-/// up to '2*WidthFactor' other nodes in the tree.
-
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeNode Class
-//===----------------------------------------------------------------------===//
-
-namespace {
- /// RopePieceBTreeNode - Common base class of RopePieceBTreeLeaf and
- /// RopePieceBTreeInterior. This provides some 'virtual' dispatching methods
- /// and a flag that determines which subclass the instance is. Also
- /// important, this node knows the full extend of the node, including any
- /// children that it has. This allows efficient skipping over entire subtrees
- /// when looking for an offset in the BTree.
- class RopePieceBTreeNode {
- protected:
- /// WidthFactor - This controls the number of K/V slots held in the BTree:
- /// how wide it is. Each level of the BTree is guaranteed to have at least
- /// 'WidthFactor' elements in it (either ropepieces or children), (except
- /// the root, which may have less) and may have at most 2*WidthFactor
- /// elements.
- enum { WidthFactor = 8 };
-
- /// Size - This is the number of bytes of file this node (including any
- /// potential children) covers.
- unsigned Size;
-
- /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
- /// is an instance of RopePieceBTreeInterior.
- bool IsLeaf;
-
- RopePieceBTreeNode(bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
- ~RopePieceBTreeNode() {}
- public:
-
- bool isLeaf() const { return IsLeaf; }
- unsigned size() const { return Size; }
-
- void Destroy();
-
- /// split - Split the range containing the specified offset so that we are
- /// guaranteed that there is a place to do an insertion at the specified
- /// offset. The offset is relative, so "0" is the start of the node.
- ///
- /// If there is no space in this subtree for the extra piece, the extra tree
- /// node is returned and must be inserted into a parent.
- RopePieceBTreeNode *split(unsigned Offset);
-
- /// insert - Insert the specified ropepiece into this tree node at the
- /// specified offset. The offset is relative, so "0" is the start of the
- /// node.
- ///
- /// If there is no space in this subtree for the extra piece, the extra tree
- /// node is returned and must be inserted into a parent.
- RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
- /// erase - Remove NumBytes from this node at the specified offset. We are
- /// guaranteed that there is a split at Offset.
- void erase(unsigned Offset, unsigned NumBytes);
-
- static inline bool classof(const RopePieceBTreeNode *) { return true; }
-
- };
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeLeaf Class
-//===----------------------------------------------------------------------===//
-
-namespace {
- /// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
- /// nodes. This directly represents a chunk of the string with those
- /// RopePieces contatenated. Since this is a B+Tree, all values (in this case
- /// instances of RopePiece) are stored in leaves like this. To make iteration
- /// over the leaves efficient, they maintain a singly linked list through the
- /// NextLeaf field. This allows the B+Tree forward iterator to be constant
- /// time for all increments.
- class RopePieceBTreeLeaf : public RopePieceBTreeNode {
- /// NumPieces - This holds the number of rope pieces currently active in the
- /// Pieces array.
- unsigned char NumPieces;
-
- /// Pieces - This tracks the file chunks currently in this leaf.
- ///
- RopePiece Pieces[2*WidthFactor];
-
- /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
- /// efficient in-order forward iteration of the tree without traversal.
- RopePieceBTreeLeaf **PrevLeaf, *NextLeaf;
- public:
- RopePieceBTreeLeaf() : RopePieceBTreeNode(true), NumPieces(0),
- PrevLeaf(0), NextLeaf(0) {}
- ~RopePieceBTreeLeaf() {
- if (PrevLeaf || NextLeaf)
- removeFromLeafInOrder();
- }
-
- bool isFull() const { return NumPieces == 2*WidthFactor; }
-
- /// clear - Remove all rope pieces from this leaf.
- void clear() {
- while (NumPieces)
- Pieces[--NumPieces] = RopePiece();
- Size = 0;
- }
-
- unsigned getNumPieces() const { return NumPieces; }
-
- const RopePiece &getPiece(unsigned i) const {
- assert(i < getNumPieces() && "Invalid piece ID");
- return Pieces[i];
- }
-
- const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
- void insertAfterLeafInOrder(RopePieceBTreeLeaf *Node) {
- assert(PrevLeaf == 0 && NextLeaf == 0 && "Already in ordering");
-
- NextLeaf = Node->NextLeaf;
- if (NextLeaf)
- NextLeaf->PrevLeaf = &NextLeaf;
- PrevLeaf = &Node->NextLeaf;
- Node->NextLeaf = this;
- }
-
- void removeFromLeafInOrder() {
- if (PrevLeaf) {
- *PrevLeaf = NextLeaf;
- if (NextLeaf)
- NextLeaf->PrevLeaf = PrevLeaf;
- } else if (NextLeaf) {
- NextLeaf->PrevLeaf = 0;
- }
- }
-
- /// FullRecomputeSizeLocally - This method recomputes the 'Size' field by
- /// summing the size of all RopePieces.
- void FullRecomputeSizeLocally() {
- Size = 0;
- for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
- Size += getPiece(i).size();
- }
-
- /// split - Split the range containing the specified offset so that we are
- /// guaranteed that there is a place to do an insertion at the specified
- /// offset. The offset is relative, so "0" is the start of the node.
- ///
- /// If there is no space in this subtree for the extra piece, the extra tree
- /// node is returned and must be inserted into a parent.
- RopePieceBTreeNode *split(unsigned Offset);
-
- /// insert - Insert the specified ropepiece into this tree node at the
- /// specified offset. The offset is relative, so "0" is the start of the
- /// node.
- ///
- /// If there is no space in this subtree for the extra piece, the extra tree
- /// node is returned and must be inserted into a parent.
- RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-
- /// erase - Remove NumBytes from this node at the specified offset. We are
- /// guaranteed that there is a split at Offset.
- void erase(unsigned Offset, unsigned NumBytes);
-
- static inline bool classof(const RopePieceBTreeLeaf *) { return true; }
- static inline bool classof(const RopePieceBTreeNode *N) {
- return N->isLeaf();
- }
- };
-} // end anonymous namespace
-
-/// split - Split the range containing the specified offset so that we are
-/// guaranteed that there is a place to do an insertion at the specified
-/// offset. The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeLeaf::split(unsigned Offset) {
- // Find the insertion point. We are guaranteed that there is a split at the
- // specified offset so find it.
- if (Offset == 0 || Offset == size()) {
- // Fastpath for a common case. There is already a splitpoint at the end.
- return 0;
- }
-
- // Find the piece that this offset lands in.
- unsigned PieceOffs = 0;
- unsigned i = 0;
- while (Offset >= PieceOffs+Pieces[i].size()) {
- PieceOffs += Pieces[i].size();
- ++i;
- }
-
- // If there is already a split point at the specified offset, just return
- // success.
- if (PieceOffs == Offset)
- return 0;
-
- // Otherwise, we need to split piece 'i' at Offset-PieceOffs. Convert Offset
- // to being Piece relative.
- unsigned IntraPieceOffset = Offset-PieceOffs;
-
- // We do this by shrinking the RopePiece and then doing an insert of the tail.
- RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
- Pieces[i].EndOffs);
- Size -= Pieces[i].size();
- Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
- Size += Pieces[i].size();
-
- return insert(Offset, Tail);
-}
-
-
-/// insert - Insert the specified RopePiece into this tree node at the
-/// specified offset. The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeLeaf::insert(unsigned Offset,
- const RopePiece &R) {
- // If this node is not full, insert the piece.
- if (!isFull()) {
- // Find the insertion point. We are guaranteed that there is a split at the
- // specified offset so find it.
- unsigned i = 0, e = getNumPieces();
- if (Offset == size()) {
- // Fastpath for a common case.
- i = e;
- } else {
- unsigned SlotOffs = 0;
- for (; Offset > SlotOffs; ++i)
- SlotOffs += getPiece(i).size();
- assert(SlotOffs == Offset && "Split didn't occur before insertion!");
- }
-
- // For an insertion into a non-full leaf node, just insert the value in
- // its sorted position. This requires moving later values over.
- for (; i != e; --e)
- Pieces[e] = Pieces[e-1];
- Pieces[i] = R;
- ++NumPieces;
- Size += R.size();
- return 0;
- }
-
- // Otherwise, if this is leaf is full, split it in two halves. Since this
- // node is full, it contains 2*WidthFactor values. We move the first
- // 'WidthFactor' values to the LHS child (which we leave in this node) and
- // move the last 'WidthFactor' values into the RHS child.
-
- // Create the new node.
- RopePieceBTreeLeaf *NewNode = new RopePieceBTreeLeaf();
-
- // Move over the last 'WidthFactor' values from here to NewNode.
- std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
- &NewNode->Pieces[0]);
- // Replace old pieces with null RopePieces to drop refcounts.
- std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor], RopePiece());
-
- // Decrease the number of values in the two nodes.
- NewNode->NumPieces = NumPieces = WidthFactor;
-
- // Recompute the two nodes' size.
- NewNode->FullRecomputeSizeLocally();
- FullRecomputeSizeLocally();
-
- // Update the list of leaves.
- NewNode->insertAfterLeafInOrder(this);
-
- // These insertions can't fail.
- if (this->size() >= Offset)
- this->insert(Offset, R);
- else
- NewNode->insert(Offset - this->size(), R);
- return NewNode;
-}
-
-/// erase - Remove NumBytes from this node at the specified offset. We are
-/// guaranteed that there is a split at Offset.
-void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
- // Since we are guaranteed that there is a split at Offset, we start by
- // finding the Piece that starts there.
- unsigned PieceOffs = 0;
- unsigned i = 0;
- for (; Offset > PieceOffs; ++i)
- PieceOffs += getPiece(i).size();
- assert(PieceOffs == Offset && "Split didn't occur before erase!");
-
- unsigned StartPiece = i;
-
- // Figure out how many pieces completely cover 'NumBytes'. We want to remove
- // all of them.
- for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
- PieceOffs += getPiece(i).size();
-
- // If we exactly include the last one, include it in the region to delete.
- if (Offset+NumBytes == PieceOffs+getPiece(i).size())
- PieceOffs += getPiece(i).size(), ++i;
-
- // If we completely cover some RopePieces, erase them now.
- if (i != StartPiece) {
- unsigned NumDeleted = i-StartPiece;
- for (; i != getNumPieces(); ++i)
- Pieces[i-NumDeleted] = Pieces[i];
-
- // Drop references to dead rope pieces.
- std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
- RopePiece());
- NumPieces -= NumDeleted;
-
- unsigned CoverBytes = PieceOffs-Offset;
- NumBytes -= CoverBytes;
- Size -= CoverBytes;
- }
-
- // If we completely removed some stuff, we could be done.
- if (NumBytes == 0) return;
-
- // Okay, now might be erasing part of some Piece. If this is the case, then
- // move the start point of the piece.
- assert(getPiece(StartPiece).size() > NumBytes);
- Pieces[StartPiece].StartOffs += NumBytes;
-
- // The size of this node just shrunk by NumBytes.
- Size -= NumBytes;
-}
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeInterior Class
-//===----------------------------------------------------------------------===//
-
-namespace {
- /// RopePieceBTreeInterior - This represents an interior node in the B+Tree,
- /// which holds up to 2*WidthFactor pointers to child nodes.
- class RopePieceBTreeInterior : public RopePieceBTreeNode {
- /// NumChildren - This holds the number of children currently active in the
- /// Children array.
- unsigned char NumChildren;
- RopePieceBTreeNode *Children[2*WidthFactor];
- public:
- RopePieceBTreeInterior() : RopePieceBTreeNode(false), NumChildren(0) {}
-
- RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
- : RopePieceBTreeNode(false) {
- Children[0] = LHS;
- Children[1] = RHS;
- NumChildren = 2;
- Size = LHS->size() + RHS->size();
- }
-
- bool isFull() const { return NumChildren == 2*WidthFactor; }
-
- unsigned getNumChildren() const { return NumChildren; }
- const RopePieceBTreeNode *getChild(unsigned i) const {
- assert(i < NumChildren && "invalid child #");
- return Children[i];
- }
- RopePieceBTreeNode *getChild(unsigned i) {
- assert(i < NumChildren && "invalid child #");
- return Children[i];
- }
-
- /// FullRecomputeSizeLocally - Recompute the Size field of this node by
- /// summing up the sizes of the child nodes.
- void FullRecomputeSizeLocally() {
- Size = 0;
- for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- Size += getChild(i)->size();
- }
-
-
- /// split - Split the range containing the specified offset so that we are
- /// guaranteed that there is a place to do an insertion at the specified
- /// offset. The offset is relative, so "0" is the start of the node.
- ///
- /// If there is no space in this subtree for the extra piece, the extra tree
- /// node is returned and must be inserted into a parent.
- RopePieceBTreeNode *split(unsigned Offset);
-
-
- /// insert - Insert the specified ropepiece into this tree node at the
- /// specified offset. The offset is relative, so "0" is the start of the
- /// node.
- ///
- /// If there is no space in this subtree for the extra piece, the extra tree
- /// node is returned and must be inserted into a parent.
- RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
- /// HandleChildPiece - A child propagated an insertion result up to us.
- /// Insert the new child, and/or propagate the result further up the tree.
- RopePieceBTreeNode *HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS);
-
- /// erase - Remove NumBytes from this node at the specified offset. We are
- /// guaranteed that there is a split at Offset.
- void erase(unsigned Offset, unsigned NumBytes);
-
- static inline bool classof(const RopePieceBTreeInterior *) { return true; }
- static inline bool classof(const RopePieceBTreeNode *N) {
- return !N->isLeaf();
- }
- };
-} // end anonymous namespace
-
-/// split - Split the range containing the specified offset so that we are
-/// guaranteed that there is a place to do an insertion at the specified
-/// offset. The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeInterior::split(unsigned Offset) {
- // Figure out which child to split.
- if (Offset == 0 || Offset == size())
- return 0; // If we have an exact offset, we're already split.
-
- unsigned ChildOffset = 0;
- unsigned i = 0;
- for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
- ChildOffset += getChild(i)->size();
-
- // If already split there, we're done.
- if (ChildOffset == Offset)
- return 0;
-
- // Otherwise, recursively split the child.
- if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
- return HandleChildPiece(i, RHS);
- return 0; // Done!
-}
-
-/// insert - Insert the specified ropepiece into this tree node at the
-/// specified offset. The offset is relative, so "0" is the start of the
-/// node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeInterior::insert(unsigned Offset,
- const RopePiece &R) {
- // Find the insertion point. We are guaranteed that there is a split at the
- // specified offset so find it.
- unsigned i = 0, e = getNumChildren();
-
- unsigned ChildOffs = 0;
- if (Offset == size()) {
- // Fastpath for a common case. Insert at end of last child.
- i = e-1;
- ChildOffs = size()-getChild(i)->size();
- } else {
- for (; Offset > ChildOffs+getChild(i)->size(); ++i)
- ChildOffs += getChild(i)->size();
- }
-
- Size += R.size();
-
- // Insert at the end of this child.
- if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
- return HandleChildPiece(i, RHS);
-
- return 0;
-}
-
-/// HandleChildPiece - A child propagated an insertion result up to us.
-/// Insert the new child, and/or propagate the result further up the tree.
-RopePieceBTreeNode *
-RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
- // Otherwise the child propagated a subtree up to us as a new child. See if
- // we have space for it here.
- if (!isFull()) {
- // Insert RHS after child 'i'.
- if (i + 1 != getNumChildren())
- memmove(&Children[i+2], &Children[i+1],
- (getNumChildren()-i-1)*sizeof(Children[0]));
- Children[i+1] = RHS;
- ++NumChildren;
- return false;
- }
-
- // Okay, this node is full. Split it in half, moving WidthFactor children to
- // a newly allocated interior node.
-
- // Create the new node.
- RopePieceBTreeInterior *NewNode = new RopePieceBTreeInterior();
-
- // Move over the last 'WidthFactor' values from here to NewNode.
- memcpy(&NewNode->Children[0], &Children[WidthFactor],
- WidthFactor*sizeof(Children[0]));
-
- // Decrease the number of values in the two nodes.
- NewNode->NumChildren = NumChildren = WidthFactor;
-
- // Finally, insert the two new children in the side the can (now) hold them.
- // These insertions can't fail.
- if (i < WidthFactor)
- this->HandleChildPiece(i, RHS);
- else
- NewNode->HandleChildPiece(i-WidthFactor, RHS);
-
- // Recompute the two nodes' size.
- NewNode->FullRecomputeSizeLocally();
- FullRecomputeSizeLocally();
- return NewNode;
-}
-
-/// erase - Remove NumBytes from this node at the specified offset. We are
-/// guaranteed that there is a split at Offset.
-void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
- // This will shrink this node by NumBytes.
- Size -= NumBytes;
-
- // Find the first child that overlaps with Offset.
- unsigned i = 0;
- for (; Offset >= getChild(i)->size(); ++i)
- Offset -= getChild(i)->size();
-
- // Propagate the delete request into overlapping children, or completely
- // delete the children as appropriate.
- while (NumBytes) {
- RopePieceBTreeNode *CurChild = getChild(i);
-
- // If we are deleting something contained entirely in the child, pass on the
- // request.
- if (Offset+NumBytes < CurChild->size()) {
- CurChild->erase(Offset, NumBytes);
- return;
- }
-
- // If this deletion request starts somewhere in the middle of the child, it
- // must be deleting to the end of the child.
- if (Offset) {
- unsigned BytesFromChild = CurChild->size()-Offset;
- CurChild->erase(Offset, BytesFromChild);
- NumBytes -= BytesFromChild;
- // Start at the beginning of the next child.
- Offset = 0;
- ++i;
- continue;
- }
-
- // If the deletion request completely covers the child, delete it and move
- // the rest down.
- NumBytes -= CurChild->size();
- CurChild->Destroy();
- --NumChildren;
- if (i != getNumChildren())
- memmove(&Children[i], &Children[i+1],
- (getNumChildren()-i)*sizeof(Children[0]));
- }
-}
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeNode Implementation
-//===----------------------------------------------------------------------===//
-
-void RopePieceBTreeNode::Destroy() {
- if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
- delete Leaf;
- else
- delete cast<RopePieceBTreeInterior>(this);
-}
-
-/// split - Split the range containing the specified offset so that we are
-/// guaranteed that there is a place to do an insertion at the specified
-/// offset. The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeNode::split(unsigned Offset) {
- assert(Offset <= size() && "Invalid offset to split!");
- if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
- return Leaf->split(Offset);
- return cast<RopePieceBTreeInterior>(this)->split(Offset);
-}
-
-/// insert - Insert the specified ropepiece into this tree node at the
-/// specified offset. The offset is relative, so "0" is the start of the
-/// node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeNode::insert(unsigned Offset,
- const RopePiece &R) {
- assert(Offset <= size() && "Invalid offset to insert!");
- if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
- return Leaf->insert(Offset, R);
- return cast<RopePieceBTreeInterior>(this)->insert(Offset, R);
-}
-
-/// erase - Remove NumBytes from this node at the specified offset. We are
-/// guaranteed that there is a split at Offset.
-void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
- assert(Offset+NumBytes <= size() && "Invalid offset to erase!");
- if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
- return Leaf->erase(Offset, NumBytes);
- return cast<RopePieceBTreeInterior>(this)->erase(Offset, NumBytes);
-}
-
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeIterator Implementation
-//===----------------------------------------------------------------------===//
-
-static const RopePieceBTreeLeaf *getCN(const void *P) {
- return static_cast<const RopePieceBTreeLeaf*>(P);
-}
-
-// begin iterator.
-RopePieceBTreeIterator::RopePieceBTreeIterator(const void *n) {
- const RopePieceBTreeNode *N = static_cast<const RopePieceBTreeNode*>(n);
-
- // Walk down the left side of the tree until we get to a leaf.
- while (const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
- N = IN->getChild(0);
-
- // We must have at least one leaf.
- CurNode = cast<RopePieceBTreeLeaf>(N);
-
- // If we found a leaf that happens to be empty, skip over it until we get
- // to something full.
- while (CurNode && getCN(CurNode)->getNumPieces() == 0)
- CurNode = getCN(CurNode)->getNextLeafInOrder();
-
- if (CurNode != 0)
- CurPiece = &getCN(CurNode)->getPiece(0);
- else // Empty tree, this is an end() iterator.
- CurPiece = 0;
- CurChar = 0;
-}
-
-void RopePieceBTreeIterator::MoveToNextPiece() {
- if (CurPiece != &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces()-1)) {
- CurChar = 0;
- ++CurPiece;
- return;
- }
-
- // Find the next non-empty leaf node.
- do
- CurNode = getCN(CurNode)->getNextLeafInOrder();
- while (CurNode && getCN(CurNode)->getNumPieces() == 0);
-
- if (CurNode != 0)
- CurPiece = &getCN(CurNode)->getPiece(0);
- else // Hit end().
- CurPiece = 0;
- CurChar = 0;
-}
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTree Implementation
-//===----------------------------------------------------------------------===//
-
-static RopePieceBTreeNode *getRoot(void *P) {
- return static_cast<RopePieceBTreeNode*>(P);
-}
-
-RopePieceBTree::RopePieceBTree() {
- Root = new RopePieceBTreeLeaf();
-}
-RopePieceBTree::RopePieceBTree(const RopePieceBTree &RHS) {
- assert(RHS.empty() && "Can't copy non-empty tree yet");
- Root = new RopePieceBTreeLeaf();
-}
-RopePieceBTree::~RopePieceBTree() {
- getRoot(Root)->Destroy();
-}
-
-unsigned RopePieceBTree::size() const {
- return getRoot(Root)->size();
-}
-
-void RopePieceBTree::clear() {
- if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(getRoot(Root)))
- Leaf->clear();
- else {
- getRoot(Root)->Destroy();
- Root = new RopePieceBTreeLeaf();
- }
-}
-
-void RopePieceBTree::insert(unsigned Offset, const RopePiece &R) {
- // #1. Split at Offset.
- if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
- Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
-
- // #2. Do the insertion.
- if (RopePieceBTreeNode *RHS = getRoot(Root)->insert(Offset, R))
- Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
-}
-
-void RopePieceBTree::erase(unsigned Offset, unsigned NumBytes) {
- // #1. Split at Offset.
- if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
- Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
-
- // #2. Do the erasing.
- getRoot(Root)->erase(Offset, NumBytes);
-}
-
-//===----------------------------------------------------------------------===//
-// RewriteRope Implementation
-//===----------------------------------------------------------------------===//
-
-/// MakeRopeString - This copies the specified byte range into some instance of
-/// RopeRefCountString, and return a RopePiece that represents it. This uses
-/// the AllocBuffer object to aggregate requests for small strings into one
-/// allocation instead of doing tons of tiny allocations.
-RopePiece RewriteRope::MakeRopeString(const char *Start, const char *End) {
- unsigned Len = End-Start;
- assert(Len && "Zero length RopePiece is invalid!");
-
- // If we have space for this string in the current alloc buffer, use it.
- if (AllocOffs+Len <= AllocChunkSize) {
- memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
- AllocOffs += Len;
- return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
- }
-
- // If we don't have enough room because this specific allocation is huge,
- // just allocate a new rope piece for it alone.
- if (Len > AllocChunkSize) {
- unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
- RopeRefCountString *Res =
- reinterpret_cast<RopeRefCountString *>(new char[Size]);
- Res->RefCount = 0;
- memcpy(Res->Data, Start, End-Start);
- return RopePiece(Res, 0, End-Start);
- }
-
- // Otherwise, this was a small request but we just don't have space for it
- // Make a new chunk and share it with later allocations.
-
- // If we had an old allocation, drop our reference to it.
- if (AllocBuffer && --AllocBuffer->RefCount == 0)
- delete [] (char*)AllocBuffer;
-
- unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
- AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
- AllocBuffer->RefCount = 0;
- memcpy(AllocBuffer->Data, Start, Len);
- AllocOffs = Len;
-
- // Start out the new allocation with a refcount of 1, since we have an
- // internal reference to it.
- AllocBuffer->addRef();
- return RopePiece(AllocBuffer, 0, Len);
-}
-
-
diff --git a/clang/lib/Rewrite/Rewriter.cpp b/clang/lib/Rewrite/Rewriter.cpp
deleted file mode 100644
index 9235a91bef53..000000000000
--- a/clang/lib/Rewrite/Rewriter.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-//===--- Rewriter.cpp - Code rewriting interface --------------------------===//
-//
-// 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 Rewriter class, which is used for code
-// transformations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {
- // Nothing to remove, exit early.
- if (Size == 0) return;
-
- unsigned RealOffset = getMappedOffset(OrigOffset, true);
- assert(RealOffset+Size < Buffer.size() && "Invalid location");
-
- // Remove the dead characters.
- Buffer.erase(RealOffset, Size);
-
- // Add a delta so that future changes are offset correctly.
- AddDelta(OrigOffset, -Size);
-}
-
-void RewriteBuffer::InsertText(unsigned OrigOffset,
- const char *StrData, unsigned StrLen,
- bool InsertAfter) {
-
- // Nothing to insert, exit early.
- if (StrLen == 0) return;
-
- unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
- Buffer.insert(RealOffset, StrData, StrData+StrLen);
-
- // Add a delta so that future changes are offset correctly.
- AddDelta(OrigOffset, StrLen);
-}
-
-/// ReplaceText - This method replaces a range of characters in the input
-/// buffer with a new string. This is effectively a combined "remove+insert"
-/// operation.
-void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
- unsigned RealOffset = getMappedOffset(OrigOffset, false);
- Buffer.erase(RealOffset, OrigLength);
- Buffer.insert(RealOffset, NewStr, NewStr+NewLength);
- if (OrigLength != NewLength)
- AddDelta(OrigOffset, NewLength-OrigLength);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Rewriter class
-//===----------------------------------------------------------------------===//
-
-/// getRangeSize - Return the size in bytes of the specified range if they
-/// are in the same file. If not, this returns -1.
-int Rewriter::getRangeSize(SourceRange Range) const {
- if (!isRewritable(Range.getBegin()) ||
- !isRewritable(Range.getEnd())) return -1;
-
- unsigned StartOff, StartFileID;
- unsigned EndOff , EndFileID;
-
- StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
- EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
-
- if (StartFileID != EndFileID)
- return -1;
-
- // If edits have been made to this buffer, the delta between the range may
- // have changed.
- std::map<unsigned, RewriteBuffer>::const_iterator I =
- RewriteBuffers.find(StartFileID);
- if (I != RewriteBuffers.end()) {
- const RewriteBuffer &RB = I->second;
- EndOff = RB.getMappedOffset(EndOff, true);
- StartOff = RB.getMappedOffset(StartOff);
- }
-
-
- // Adjust the end offset to the end of the last token, instead of being the
- // start of the last token.
- EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr);
-
- return EndOff-StartOff;
-}
-
-/// getRewritenText - Return the rewritten form of the text in the specified
-/// range. If the start or end of the range was unrewritable or if they are
-/// in different buffers, this returns an empty string.
-///
-/// Note that this method is not particularly efficient.
-///
-std::string Rewriter::getRewritenText(SourceRange Range) const {
- if (!isRewritable(Range.getBegin()) ||
- !isRewritable(Range.getEnd()))
- return "";
-
- unsigned StartOff, StartFileID;
- unsigned EndOff , EndFileID;
- StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
- EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
-
- if (StartFileID != EndFileID)
- return ""; // Start and end in different buffers.
-
- // If edits have been made to this buffer, the delta between the range may
- // have changed.
- std::map<unsigned, RewriteBuffer>::const_iterator I =
- RewriteBuffers.find(StartFileID);
- if (I == RewriteBuffers.end()) {
- // If the buffer hasn't been rewritten, just return the text from the input.
- const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());
-
- // Adjust the end offset to the end of the last token, instead of being the
- // start of the last token.
- EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr);
- return std::string(Ptr, Ptr+EndOff-StartOff);
- }
-
- const RewriteBuffer &RB = I->second;
- EndOff = RB.getMappedOffset(EndOff, true);
- StartOff = RB.getMappedOffset(StartOff);
-
- // Adjust the end offset to the end of the last token, instead of being the
- // start of the last token.
- EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr);
-
- // Advance the iterators to the right spot, yay for linear time algorithms.
- RewriteBuffer::iterator Start = RB.begin();
- std::advance(Start, StartOff);
- RewriteBuffer::iterator End = Start;
- std::advance(End, EndOff-StartOff);
-
- return std::string(Start, End);
-}
-
-unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
- unsigned &FileID) const {
- assert(Loc.isValid() && "Invalid location");
- std::pair<unsigned,unsigned> V = SourceMgr->getDecomposedFileLoc(Loc);
- FileID = V.first;
- return V.second;
-}
-
-
-/// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
-///
-RewriteBuffer &Rewriter::getEditBuffer(unsigned FileID) {
- std::map<unsigned, RewriteBuffer>::iterator I =
- RewriteBuffers.lower_bound(FileID);
- if (I != RewriteBuffers.end() && I->first == FileID)
- return I->second;
- I = RewriteBuffers.insert(I, std::make_pair(FileID, RewriteBuffer()));
-
- std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FileID);
- I->second.Initialize(MB.first, MB.second);
-
- return I->second;
-}
-
-/// InsertText - Insert the specified string at the specified location in the
-/// original buffer.
-bool Rewriter::InsertText(SourceLocation Loc, const char *StrData,
- unsigned StrLen, bool InsertAfter) {
- if (!isRewritable(Loc)) return true;
- unsigned FileID;
- unsigned StartOffs = getLocationOffsetAndFileID(Loc, FileID);
- getEditBuffer(FileID).InsertText(StartOffs, StrData, StrLen, InsertAfter);
- return false;
-}
-
-/// RemoveText - Remove the specified text region.
-bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
- if (!isRewritable(Start)) return true;
- unsigned FileID;
- unsigned StartOffs = getLocationOffsetAndFileID(Start, FileID);
- getEditBuffer(FileID).RemoveText(StartOffs, Length);
- return false;
-}
-
-/// ReplaceText - This method replaces a range of characters in the input
-/// buffer with a new string. This is effectively a combined "remove/insert"
-/// operation.
-bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
- if (!isRewritable(Start)) return true;
- unsigned StartFileID;
- unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
-
- getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength,
- NewStr, NewLength);
- return false;
-}
-
-/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
-/// printer to generate the replacement code. This returns true if the input
-/// could not be rewritten, or false if successful.
-bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
- // Measaure the old text.
- int Size = getRangeSize(From->getSourceRange());
- if (Size == -1)
- return true;
-
- // Get the new text.
- std::string SStr;
- llvm::raw_string_ostream S(SStr);
- To->printPretty(S);
- const std::string &Str = S.str();
-
- ReplaceText(From->getLocStart(), Size, &Str[0], Str.size());
- return false;
-}
-
-
diff --git a/clang/lib/Sema/CXXFieldCollector.h b/clang/lib/Sema/CXXFieldCollector.h
deleted file mode 100644
index 44d482692b73..000000000000
--- a/clang/lib/Sema/CXXFieldCollector.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides CXXFieldCollector that is used during parsing & semantic
-// analysis of C++ classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class CXXFieldDecl;
-
-/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
-/// C++ classes.
-class CXXFieldCollector {
- /// Fields - Contains all CXXFieldDecls collected during parsing of a C++
- /// class. When a nested class is entered, its fields are appended to the
- /// fields of its parent class, when it is exited its fields are removed.
- llvm::SmallVector<CXXFieldDecl*, 32> Fields;
-
- /// FieldCount - Each entry represents the number of fields collected during
- /// the parsing of a C++ class. When a nested class is entered, a new field
- /// count is pushed, when it is exited, the field count is popped.
- llvm::SmallVector<size_t, 4> FieldCount;
-
- // Example:
- //
- // class C {
- // int x,y;
- // class NC {
- // int q;
- // // At this point, Fields contains [x,y,q] decls and FieldCount contains
- // // [2,1].
- // };
- // int z;
- // // At this point, Fields contains [x,y,z] decls and FieldCount contains
- // // [3].
- // };
-
-public:
- /// StartClass - Called by Sema::ActOnStartCXXClassDef.
- void StartClass() { FieldCount.push_back(0); }
-
- /// Add - Called by Sema::ActOnCXXMemberDeclarator.
- void Add(CXXFieldDecl *D) {
- Fields.push_back(D);
- ++FieldCount.back();
- }
-
- /// getCurNumField - The number of fields added to the currently parsed class.
- size_t getCurNumFields() const { return FieldCount.back(); }
-
- /// getCurFields - Pointer to array of fields added to the currently parsed
- /// class.
- CXXFieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
-
- /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
- void FinishClass() {
- Fields.resize(Fields.size() - getCurNumFields());
- FieldCount.pop_back();
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/Sema/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp
deleted file mode 100644
index e97de7381785..000000000000
--- a/clang/lib/Sema/IdentifierResolver.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-//===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the IdentifierResolver class, which is used for lexical
-// scoped lookup, based on identifier.
-//
-//===----------------------------------------------------------------------===//
-
-#include "IdentifierResolver.h"
-#include "clang/Basic/LangOptions.h"
-#include <list>
-#include <vector>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// IdDeclInfoMap class
-//===----------------------------------------------------------------------===//
-
-/// IdDeclInfoMap - Associates IdDeclInfos with Identifiers.
-/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
-/// individual IdDeclInfo to heap.
-class IdentifierResolver::IdDeclInfoMap {
- static const unsigned int VECTOR_SIZE = 512;
- // Holds vectors of IdDeclInfos that serve as 'pools'.
- // New vectors are added when the current one is full.
- std::list< std::vector<IdDeclInfo> > IDIVecs;
- unsigned int CurIndex;
-
-public:
- IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {}
-
- /// Returns the IdDeclInfo associated to the IdentifierInfo.
- /// It creates a new IdDeclInfo if one was not created before for this id.
- IdDeclInfo &operator[](IdentifierInfo *II);
-};
-
-
-//===----------------------------------------------------------------------===//
-// LookupContext Implementation
-//===----------------------------------------------------------------------===//
-
-/// getContext - Returns translation unit context for non ScopedDecls and
-/// for EnumConstantDecls returns the parent context of their EnumDecl.
-DeclContext *IdentifierResolver::LookupContext::getContext(Decl *D) {
- DeclContext *Ctx;
-
- if (CXXFieldDecl *FD = dyn_cast<CXXFieldDecl>(D))
- return FD->getParent();
-
- if (EnumConstantDecl *EnumD = dyn_cast<EnumConstantDecl>(D)) {
- Ctx = EnumD->getDeclContext()->getParent();
- } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
- Ctx = SD->getDeclContext();
- else
- return TUCtx();
-
- if (isa<TranslationUnitDecl>(Ctx))
- return TUCtx();
-
- return Ctx;
-}
-
-/// isEqOrContainedBy - Returns true of the given context is the same or a
-/// parent of this one.
-bool IdentifierResolver::LookupContext::isEqOrContainedBy(
- const LookupContext &PC) const {
- if (PC.isTU()) return true;
-
- for (LookupContext Next = *this; !Next.isTU(); Next = Next.getParent())
- if (Next.Ctx == PC.Ctx) return true;
-
- return false;
-}
-
-
-//===----------------------------------------------------------------------===//
-// IdDeclInfo Implementation
-//===----------------------------------------------------------------------===//
-
-/// FindContext - Returns an iterator pointing just after the decl that is
-/// in the given context or in a parent of it. The search is in reverse
-/// order, from end to begin.
-IdentifierResolver::IdDeclInfo::DeclsTy::iterator
-IdentifierResolver::IdDeclInfo::FindContext(const LookupContext &Ctx,
- const DeclsTy::iterator &Start) {
- for (DeclsTy::iterator I = Start; I != Decls.begin(); --I) {
- if (Ctx.isEqOrContainedBy(LookupContext(*(I-1))))
- return I;
- }
-
- return Decls.begin();
-}
-
-/// AddShadowed - Add a decl by putting it directly above the 'Shadow' decl.
-/// Later lookups will find the 'Shadow' decl first. The 'Shadow' decl must
-/// be already added to the scope chain and must be in the same context as
-/// the decl that we want to add.
-void IdentifierResolver::IdDeclInfo::AddShadowed(NamedDecl *D,
- NamedDecl *Shadow) {
- assert(LookupContext(D) == LookupContext(Shadow) &&
- "Decl and Shadow not in same context!");
-
- for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
- if (Shadow == *(I-1)) {
- Decls.insert(I-1, D);
- return;
- }
- }
-
- assert(0 && "Shadow wasn't in scope chain!");
-}
-
-/// RemoveDecl - Remove the decl from the scope chain.
-/// The decl must already be part of the decl chain.
-void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
- for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
- if (D == *(I-1)) {
- Decls.erase(I-1);
- return;
- }
- }
-
- assert(0 && "Didn't find this decl on its identifier's chain!");
-}
-
-
-//===----------------------------------------------------------------------===//
-// IdentifierResolver Implementation
-//===----------------------------------------------------------------------===//
-
-IdentifierResolver::IdentifierResolver(const LangOptions &langOpt)
- : LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) {
-}
-IdentifierResolver::~IdentifierResolver() {
- delete IdDeclInfos;
-}
-
-/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
-/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
-/// true if 'D' belongs to the given declaration context.
-bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
- Scope *S) const {
- if (Ctx->isFunctionOrMethod()) {
- if (S->isDeclScope(D))
- return true;
- if (LangOpt.CPlusPlus) {
- // C++ 3.3.2p4:
- // Names declared in the for-init-statement, and in the condition of if,
- // while, for, and switch statements are local to the if, while, for, or
- // switch statement (including the controlled statement), and shall not be
- // redeclared in a subsequent condition of that statement nor in the
- // outermost block (or, for the if statement, any of the outermost blocks)
- // of the controlled statement.
- //
- assert(S->getParent() && "No TUScope?");
- if (S->getParent()->getFlags() & Scope::ControlScope)
- return S->getParent()->isDeclScope(D);
- }
- return false;
- }
-
- return LookupContext(D) == LookupContext(Ctx);
-}
-
-/// AddDecl - Link the decl to its shadowed decl chain.
-void IdentifierResolver::AddDecl(NamedDecl *D) {
- IdentifierInfo *II = D->getIdentifier();
- void *Ptr = II->getFETokenInfo<void>();
-
- if (!Ptr) {
- II->setFETokenInfo(D);
- return;
- }
-
- IdDeclInfo *IDI;
-
- if (isDeclPtr(Ptr)) {
- II->setFETokenInfo(NULL);
- IDI = &(*IdDeclInfos)[II];
- NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
- IDI->AddDecl(PrevD);
- } else
- IDI = toIdDeclInfo(Ptr);
-
- IDI->AddDecl(D);
-}
-
-/// AddShadowedDecl - Link the decl to its shadowed decl chain putting it
-/// after the decl that the iterator points to, thus the 'Shadow' decl will be
-/// encountered before the 'D' decl.
-void IdentifierResolver::AddShadowedDecl(NamedDecl *D, NamedDecl *Shadow) {
- assert(D->getIdentifier() == Shadow->getIdentifier() && "Different ids!");
- assert(LookupContext(D) == LookupContext(Shadow) && "Different context!");
-
- IdentifierInfo *II = D->getIdentifier();
- void *Ptr = II->getFETokenInfo<void>();
- assert(Ptr && "No decl from Ptr ?");
-
- IdDeclInfo *IDI;
-
- if (isDeclPtr(Ptr)) {
- II->setFETokenInfo(NULL);
- IDI = &(*IdDeclInfos)[II];
- NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
- assert(PrevD == Shadow && "Invalid shadow decl ?");
- IDI->AddDecl(D);
- IDI->AddDecl(PrevD);
- return;
- }
-
- IDI = toIdDeclInfo(Ptr);
- IDI->AddShadowed(D, Shadow);
-}
-
-/// RemoveDecl - Unlink the decl from its shadowed decl chain.
-/// The decl must already be part of the decl chain.
-void IdentifierResolver::RemoveDecl(NamedDecl *D) {
- assert(D && "null param passed");
- IdentifierInfo *II = D->getIdentifier();
- void *Ptr = II->getFETokenInfo<void>();
-
- assert(Ptr && "Didn't find this decl on its identifier's chain!");
-
- if (isDeclPtr(Ptr)) {
- assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
- II->setFETokenInfo(NULL);
- return;
- }
-
- return toIdDeclInfo(Ptr)->RemoveDecl(D);
-}
-
-/// begin - Returns an iterator for decls of identifier 'II', starting at
-/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
-/// decls of parent declaration contexts too.
-IdentifierResolver::iterator
-IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx,
- bool LookInParentCtx) {
- assert(Ctx && "null param passed");
-
- void *Ptr = II->getFETokenInfo<void>();
- if (!Ptr) return end();
-
- LookupContext LC(Ctx);
-
- if (isDeclPtr(Ptr)) {
- NamedDecl *D = static_cast<NamedDecl*>(Ptr);
- LookupContext DC(D);
-
- if (( LookInParentCtx && LC.isEqOrContainedBy(DC)) ||
- (!LookInParentCtx && LC == DC))
- return iterator(D);
- else
- return end();
- }
-
- IdDeclInfo *IDI = toIdDeclInfo(Ptr);
-
- IdDeclInfo::DeclsTy::iterator I;
- if (LookInParentCtx)
- I = IDI->FindContext(LC);
- else {
- for (I = IDI->decls_end(); I != IDI->decls_begin(); --I)
- if (LookupContext(*(I-1)) == LC)
- break;
- }
-
- if (I != IDI->decls_begin())
- return iterator(I-1, LookInParentCtx);
- else // No decls found.
- return end();
-}
-
-/// PreIncIter - Do a preincrement when 'Ptr' is a BaseIter.
-void IdentifierResolver::iterator::PreIncIter() {
- NamedDecl *D = **this;
- LookupContext Ctx(D);
- void *InfoPtr = D->getIdentifier()->getFETokenInfo<void>();
- assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
- IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
-
- BaseIter I = getIterator();
- if (LookInParentCtx())
- I = Info->FindContext(Ctx, I);
- else {
- if (I != Info->decls_begin() && LookupContext(*(I-1)) != Ctx) {
- // The next decl is in different declaration context.
- // Skip remaining decls and set the iterator to the end.
- I = Info->decls_begin();
- }
- }
-
- if (I != Info->decls_begin())
- *this = iterator(I-1, LookInParentCtx());
- else // No more decls.
- *this = end();
-}
-
-
-//===----------------------------------------------------------------------===//
-// IdDeclInfoMap Implementation
-//===----------------------------------------------------------------------===//
-
-/// Returns the IdDeclInfo associated to the IdentifierInfo.
-/// It creates a new IdDeclInfo if one was not created before for this id.
-IdentifierResolver::IdDeclInfo &
-IdentifierResolver::IdDeclInfoMap::operator[](IdentifierInfo *II) {
- assert (II && "null IdentifierInfo passed");
- void *Ptr = II->getFETokenInfo<void>();
-
- if (Ptr) return *toIdDeclInfo(Ptr);
-
- if (CurIndex == VECTOR_SIZE) {
- // Add a IdDeclInfo vector 'pool'
- IDIVecs.push_back(std::vector<IdDeclInfo>());
- // Fill the vector
- IDIVecs.back().resize(VECTOR_SIZE);
- CurIndex = 0;
- }
- IdDeclInfo *IDI = &IDIVecs.back()[CurIndex];
- II->setFETokenInfo(reinterpret_cast<void*>(
- reinterpret_cast<uintptr_t>(IDI) | 0x1)
- );
- ++CurIndex;
- return *IDI;
-}
diff --git a/clang/lib/Sema/IdentifierResolver.h b/clang/lib/Sema/IdentifierResolver.h
deleted file mode 100644
index c661145d89f6..000000000000
--- a/clang/lib/Sema/IdentifierResolver.h
+++ /dev/null
@@ -1,250 +0,0 @@
-//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 IdentifierResolver class, which is used for lexical
-// scoped lookup, based on identifier.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Parse/Scope.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-
-namespace clang {
-
-/// IdentifierResolver - Keeps track of shadowed decls on enclosing scopes.
-/// It manages the shadowing chains of identifiers and implements efficent decl
-/// lookup based on an identifier.
-class IdentifierResolver {
-
- /// LookupContext - A wrapper for DeclContext. DeclContext is only part of
- /// ScopedDecls, LookupContext can be used with all decls (assumes
- /// translation unit context for non ScopedDecls).
- class LookupContext {
- DeclContext *Ctx;
-
- /// TUCtx - Provides a common value for translation unit context for all
- /// decls.
- /// FIXME: When (if ?) all decls can point to their translation unit context
- /// remove this hack.
- static inline DeclContext *TUCtx() {
- return reinterpret_cast<DeclContext*>(-1);
- }
-
- /// getContext - Returns translation unit context for non ScopedDecls and
- /// for EnumConstantDecls returns the parent context of their EnumDecl.
- static DeclContext *getContext(Decl *D);
-
- public:
- LookupContext(Decl *D) {
- Ctx = getContext(D);
- }
- LookupContext(DeclContext *DC) {
- if (!DC || isa<TranslationUnitDecl>(DC))
- Ctx = TUCtx();
- else
- Ctx = DC;
- }
-
- bool isTU() const {
- return (Ctx == TUCtx());
- }
-
- /// getParent - Returns the parent context. This should not be called for
- /// a translation unit context.
- LookupContext getParent() const {
- assert(!isTU() && "TU has no parent!");
- return LookupContext(Ctx->getParent());
- }
-
- /// isEqOrContainedBy - Returns true of the given context is the same or a
- /// parent of this one.
- bool isEqOrContainedBy(const LookupContext &PC) const;
-
- bool operator==(const LookupContext &RHS) const {
- return Ctx == RHS.Ctx;
- }
- bool operator!=(const LookupContext &RHS) const {
- return Ctx != RHS.Ctx;
- }
- };
-
- /// IdDeclInfo - Keeps track of information about decls associated to a
- /// particular identifier. IdDeclInfos are lazily constructed and assigned
- /// to an identifier the first time a decl with that identifier is shadowed
- /// in some scope.
- class IdDeclInfo {
- public:
- typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy;
-
- inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
- inline DeclsTy::iterator decls_end() { return Decls.end(); }
-
- /// FindContext - Returns an iterator pointing just after the decl that is
- /// in the given context or in a parent of it. The search is in reverse
- /// order, from end to begin.
- DeclsTy::iterator FindContext(const LookupContext &Ctx) {
- return FindContext(Ctx, Decls.end());
- }
-
- /// FindContext - Returns an iterator pointing just after the decl that is
- /// in the given context or in a parent of it. The search is in reverse
- /// order, from end to begin.
- DeclsTy::iterator FindContext(const LookupContext &Ctx,
- const DeclsTy::iterator &Start);
-
- void AddDecl(NamedDecl *D) {
- Decls.insert(FindContext(LookupContext(D)), D);
- }
-
- /// AddShadowed - Add a decl by putting it directly above the 'Shadow' decl.
- /// Later lookups will find the 'Shadow' decl first. The 'Shadow' decl must
- /// be already added to the scope chain and must be in the same context as
- /// the decl that we want to add.
- void AddShadowed(NamedDecl *D, NamedDecl *Shadow);
-
- /// RemoveDecl - Remove the decl from the scope chain.
- /// The decl must already be part of the decl chain.
- void RemoveDecl(NamedDecl *D);
-
- private:
- DeclsTy Decls;
- };
-
-public:
-
- /// iterator - Iterate over the decls of a specified identifier.
- /// It will walk or not the parent declaration contexts depending on how
- /// it was instantiated.
- class iterator {
- /// Ptr - There are 3 forms that 'Ptr' represents:
- /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
- /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
- /// same declaration context. (Ptr & 0x3 == 0x1)
- /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
- /// declaration contexts too. (Ptr & 0x3 == 0x3)
- uintptr_t Ptr;
- typedef IdDeclInfo::DeclsTy::iterator BaseIter;
-
- /// A single NamedDecl. (Ptr & 0x1 == 0)
- iterator(NamedDecl *D) {
- Ptr = reinterpret_cast<uintptr_t>(D);
- assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
- }
- /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
- /// contexts depending on 'LookInParentCtx'.
- iterator(BaseIter I, bool LookInParentCtx) {
- Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
- assert((Ptr & 0x2) == 0 && "Invalid Ptr!");
- if (LookInParentCtx) Ptr |= 0x2;
- }
-
- bool isIterator() const { return (Ptr & 0x1); }
-
- bool LookInParentCtx() const {
- assert(isIterator() && "Ptr not an iterator!");
- return (Ptr & 0x2) != 0;
- }
-
- BaseIter getIterator() const {
- assert(isIterator() && "Ptr not an iterator!");
- return reinterpret_cast<BaseIter>(Ptr & ~0x3);
- }
-
- friend class IdentifierResolver;
- public:
- iterator() : Ptr(0) {}
-
- NamedDecl *operator*() const {
- if (isIterator())
- return *getIterator();
- else
- return reinterpret_cast<NamedDecl*>(Ptr);
- }
-
- bool operator==(const iterator &RHS) const {
- return Ptr == RHS.Ptr;
- }
- bool operator!=(const iterator &RHS) const {
- return Ptr != RHS.Ptr;
- }
-
- // Preincrement.
- iterator& operator++() {
- if (!isIterator()) // common case.
- Ptr = 0;
- else
- PreIncIter();
- return *this;
- }
-
- private:
- void PreIncIter();
- };
-
- /// begin - Returns an iterator for decls of identifier 'II', starting at
- /// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
- /// decls of parent declaration contexts too.
- /// Default for 'LookInParentCtx is true.
- static iterator begin(const IdentifierInfo *II, DeclContext *Ctx,
- bool LookInParentCtx = true);
-
- /// end - Returns an iterator that has 'finished'.
- static iterator end() {
- return iterator();
- }
-
- /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
- /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
- /// true if 'D' belongs to the given declaration context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) const;
-
- /// AddDecl - Link the decl to its shadowed decl chain.
- void AddDecl(NamedDecl *D);
-
- /// AddShadowedDecl - Link the decl to its shadowed decl chain putting it
- /// after the decl that the iterator points to, thus the 'Shadow' decl will be
- /// encountered before the 'D' decl.
- void AddShadowedDecl(NamedDecl *D, NamedDecl *Shadow);
-
- /// RemoveDecl - Unlink the decl from its shadowed decl chain.
- /// The decl must already be part of the decl chain.
- void RemoveDecl(NamedDecl *D);
-
- explicit IdentifierResolver(const LangOptions &LangOpt);
- ~IdentifierResolver();
-
-private:
- const LangOptions &LangOpt;
-
- class IdDeclInfoMap;
- IdDeclInfoMap *IdDeclInfos;
-
- /// Identifier's FETokenInfo contains a Decl pointer if lower bit == 0.
- static inline bool isDeclPtr(void *Ptr) {
- return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
- }
-
- /// Identifier's FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
- static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
- assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
- && "Ptr not a IdDeclInfo* !");
- return reinterpret_cast<IdDeclInfo*>(
- reinterpret_cast<uintptr_t>(Ptr) & ~0x1
- );
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/Sema/Makefile b/clang/lib/Sema/Makefile
deleted file mode 100644
index 9193a546ca75..000000000000
--- a/clang/lib/Sema/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- clang/lib/Sema/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the semantic analyzer and AST builder library for the
-# C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME := clangSema
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Sema/ParseAST.cpp b/clang/lib/Sema/ParseAST.cpp
deleted file mode 100644
index fc3509682728..000000000000
--- a/clang/lib/Sema/ParseAST.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the clang::ParseAST method.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Sema/ParseAST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TranslationUnit.h"
-#include "Sema.h"
-#include "clang/Parse/Parser.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Public interface to the file
-//===----------------------------------------------------------------------===//
-
-/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
-/// the file is parsed. This takes ownership of the ASTConsumer and
-/// ultimately deletes it.
-void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, bool PrintStats) {
- // Collect global stats on Decls/Stmts (until we have a module streamer).
- if (PrintStats) {
- Decl::CollectingStats(true);
- Stmt::CollectingStats(true);
- }
-
- ASTContext Context(PP.getLangOptions(), PP.getSourceManager(),
- PP.getTargetInfo(),
- PP.getIdentifierTable(), PP.getSelectorTable());
-
- TranslationUnit TU(Context);
- Sema S(PP, Context, *Consumer);
- Parser P(PP, S);
- PP.EnterMainSourceFile();
-
- // Initialize the parser.
- P.Initialize();
-
- Consumer->InitializeTU(TU);
-
- Parser::DeclTy *ADecl;
-
- while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file.
- // If we got a null return and something *was* parsed, ignore it. This
- // is due to a top-level semicolon, an action override, or a parse error
- // skipping something.
- if (ADecl) {
- Decl* D = static_cast<Decl*>(ADecl);
- TU.AddTopLevelDecl(D); // TranslationUnit now owns the Decl.
- Consumer->HandleTopLevelDecl(D);
- }
- };
-
- Consumer->HandleTranslationUnit(TU);
-
- if (PrintStats) {
- fprintf(stderr, "\nSTATISTICS:\n");
- P.getActions().PrintStats();
- Context.PrintStats();
- Decl::PrintStats();
- Stmt::PrintStats();
- Consumer->PrintStats();
-
- Decl::CollectingStats(false);
- Stmt::CollectingStats(false);
- }
-}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
deleted file mode 100644
index 80ce2ccd0ef4..000000000000
--- a/clang/lib/Sema/Sema.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the actions class which performs semantic analysis and
-// builds an AST out of a parse stream.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-
-using namespace clang;
-
-static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name)
-{
- if (C.getLangOptions().CPlusPlus)
- return CXXRecordDecl::Create(C, TagDecl::TK_struct,
- C.getTranslationUnitDecl(),
- SourceLocation(), &C.Idents.get(Name));
- else
- return RecordDecl::Create(C, TagDecl::TK_struct,
- C.getTranslationUnitDecl(),
- SourceLocation(), &C.Idents.get(Name));
-}
-
-void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
- TUScope = S;
- CurContext = Context.getTranslationUnitDecl();
- if (!PP.getLangOptions().ObjC1) return;
-
- // Synthesize "typedef struct objc_selector *SEL;"
- RecordDecl *SelTag = CreateStructDecl(Context, "objc_selector");
- PushOnScopeChains(SelTag, TUScope);
-
- QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
- TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
- SourceLocation(),
- &Context.Idents.get("SEL"),
- SelT, 0);
- PushOnScopeChains(SelTypedef, TUScope);
- Context.setObjCSelType(SelTypedef);
-
- // FIXME: Make sure these don't leak!
- RecordDecl *ClassTag = CreateStructDecl(Context, "objc_class");
- QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
- TypedefDecl *ClassTypedef =
- TypedefDecl::Create(Context, CurContext, SourceLocation(),
- &Context.Idents.get("Class"), ClassT, 0);
- PushOnScopeChains(ClassTag, TUScope);
- PushOnScopeChains(ClassTypedef, TUScope);
- Context.setObjCClassType(ClassTypedef);
- // Synthesize "@class Protocol;
- ObjCInterfaceDecl *ProtocolDecl =
- ObjCInterfaceDecl::Create(Context, SourceLocation(),
- &Context.Idents.get("Protocol"),
- SourceLocation(), true);
- Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
- PushOnScopeChains(ProtocolDecl, TUScope);
-
- // Synthesize "typedef struct objc_object { Class isa; } *id;"
- RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
-
- QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
- PushOnScopeChains(ObjectTag, TUScope);
- TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
- SourceLocation(),
- &Context.Idents.get("id"),
- ObjT, 0);
- PushOnScopeChains(IdTypedef, TUScope);
- Context.setObjCIdType(IdTypedef);
-}
-
-Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
- : PP(pp), Context(ctxt), Consumer(consumer), CurContext(0), CurBlock(0),
- IdResolver(pp.getLangOptions()) {
-
- // Get IdentifierInfo objects for known functions for which we
- // do extra checking.
- IdentifierTable &IT = PP.getIdentifierTable();
-
- KnownFunctionIDs[id_printf] = &IT.get("printf");
- KnownFunctionIDs[id_fprintf] = &IT.get("fprintf");
- KnownFunctionIDs[id_sprintf] = &IT.get("sprintf");
- KnownFunctionIDs[id_sprintf_chk] = &IT.get("__builtin___sprintf_chk");
- KnownFunctionIDs[id_snprintf] = &IT.get("snprintf");
- KnownFunctionIDs[id_snprintf_chk] = &IT.get("__builtin___snprintf_chk");
- KnownFunctionIDs[id_asprintf] = &IT.get("asprintf");
- KnownFunctionIDs[id_NSLog] = &IT.get("NSLog");
- KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf");
- KnownFunctionIDs[id_vasprintf] = &IT.get("vasprintf");
- KnownFunctionIDs[id_vfprintf] = &IT.get("vfprintf");
- KnownFunctionIDs[id_vsprintf] = &IT.get("vsprintf");
- KnownFunctionIDs[id_vsprintf_chk] = &IT.get("__builtin___vsprintf_chk");
- KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf");
- KnownFunctionIDs[id_vsnprintf_chk] = &IT.get("__builtin___vsnprintf_chk");
- KnownFunctionIDs[id_vprintf] = &IT.get("vprintf");
-
- SuperID = &IT.get("super");
-
- // ObjC builtin typedef names.
- Ident_id = &IT.get("id");
- Ident_Class = &IT.get("Class");
- Ident_SEL = &IT.get("SEL");
- Ident_Protocol = &IT.get("Protocol");
-
- TUScope = 0;
- if (getLangOptions().CPlusPlus)
- FieldCollector.reset(new CXXFieldCollector());
-}
-
-/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
-/// If there is already an implicit cast, merge into the existing one.
-void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty) {
- QualType ExprTy = Context.getCanonicalType(Expr->getType());
- QualType TypeTy = Context.getCanonicalType(Ty);
-
- if (ExprTy == TypeTy)
- return;
-
- if (Expr->getType().getTypePtr()->isPointerType() &&
- Ty.getTypePtr()->isPointerType()) {
- QualType ExprBaseType =
- cast<PointerType>(ExprTy.getUnqualifiedType())->getPointeeType();
- QualType BaseType =
- cast<PointerType>(TypeTy.getUnqualifiedType())->getPointeeType();
- if (ExprBaseType.getAddressSpace() != BaseType.getAddressSpace()) {
- Diag(Expr->getExprLoc(), diag::err_implicit_pointer_address_space_cast,
- Expr->getSourceRange());
- }
- }
-
- if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr))
- ImpCast->setType(Ty);
- else
- Expr = new ImplicitCastExpr(Ty, Expr);
-}
-
-void Sema::DeleteExpr(ExprTy *E) {
- delete static_cast<Expr*>(E);
-}
-void Sema::DeleteStmt(StmtTy *S) {
- delete static_cast<Stmt*>(S);
-}
-
-/// ActOnEndOfTranslationUnit - This is called at the very end of the
-/// translation unit when EOF is reached and all but the top-level scope is
-/// popped.
-void Sema::ActOnEndOfTranslationUnit() {
-
-}
-
-
-//===----------------------------------------------------------------------===//
-// Helper functions.
-//===----------------------------------------------------------------------===//
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID) {
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2) {
- std::string MsgArr[] = { Msg1, Msg2 };
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange& Range) {
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, &Range,1);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange& Range) {
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, &Range,1);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, const SourceRange& Range) {
- std::string MsgArr[] = { Msg1, Msg2 };
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2, &Range, 1);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, const std::string &Msg3,
- const SourceRange& R1) {
- std::string MsgArr[] = { Msg1, Msg2, Msg3 };
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 3, &R1, 1);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID,
- const SourceRange& R1, const SourceRange& R2) {
- SourceRange RangeArr[] = { R1, R2 };
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, RangeArr, 2);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange& R1, const SourceRange& R2) {
- SourceRange RangeArr[] = { R1, R2 };
- PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, RangeArr, 2);
- return true;
-}
-
-bool Sema::Diag(SourceLocation Range, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, const SourceRange& R1,
- const SourceRange& R2) {
- std::string MsgArr[] = { Msg1, Msg2 };
- SourceRange RangeArr[] = { R1, R2 };
- PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID, MsgArr,2,RangeArr, 2);
- return true;
-}
-
-const LangOptions &Sema::getLangOptions() const {
- return PP.getLangOptions();
-}
-
-ObjCMethodDecl *Sema::getCurMethodDecl() {
- return dyn_cast<ObjCMethodDecl>(CurContext);
-}
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
deleted file mode 100644
index 406d9f7e7e17..000000000000
--- a/clang/lib/Sema/Sema.h
+++ /dev/null
@@ -1,1089 +0,0 @@
-//===--- Sema.h - Semantic Analysis & AST Building --------------*- 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 Sema class, which performs semantic analysis and
-// builds ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SEMA_H
-#define LLVM_CLANG_AST_SEMA_H
-
-#include "IdentifierResolver.h"
-#include "CXXFieldCollector.h"
-#include "clang/Parse/Action.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/OwningPtr.h"
-#include <vector>
-#include <string>
-
-namespace llvm {
- class APSInt;
-}
-
-namespace clang {
- class ASTContext;
- class ASTConsumer;
- class Preprocessor;
- class Decl;
- class DeclContext;
- class DeclSpec;
- class NamedDecl;
- class ScopedDecl;
- class Expr;
- class InitListExpr;
- class CallExpr;
- class VarDecl;
- class ParmVarDecl;
- class TypedefDecl;
- class FunctionDecl;
- class QualType;
- struct LangOptions;
- class Token;
- class IntegerLiteral;
- class StringLiteral;
- class ArrayType;
- class LabelStmt;
- class SwitchStmt;
- class ExtVectorType;
- class TypedefDecl;
- class ObjCInterfaceDecl;
- class ObjCCompatibleAliasDecl;
- class ObjCProtocolDecl;
- class ObjCImplementationDecl;
- class ObjCCategoryImplDecl;
- class ObjCCategoryDecl;
- class ObjCIvarDecl;
- class ObjCMethodDecl;
- class ObjCPropertyDecl;
- struct BlockSemaInfo;
-
-/// Sema - This implements semantic analysis and AST building for C.
-class Sema : public Action {
-public:
- Preprocessor &PP;
- ASTContext &Context;
- ASTConsumer &Consumer;
-
- /// CurContext - This is the current declaration context of parsing.
- DeclContext *CurContext;
-
- /// CurBlock - If inside of a block definition, this contains a pointer to
- /// the active block object that represents it.
- BlockSemaInfo *CurBlock;
-
- /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
- /// it (which acts like the label decl in some ways). Forward referenced
- /// labels have a LabelStmt created for them with a null location & SubStmt.
- llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
-
- llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
-
- /// ExtVectorDecls - This is a list all the extended vector types. This allows
- /// us to associate a raw vector type with one of the ext_vector type names.
- /// This is only necessary for issuing pretty diagnostics.
- llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
-
- /// ObjCImplementations - Keep track of all class @implementations
- /// so we can emit errors on duplicates.
- llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
-
- /// ObjCCategoryImpls - Maintain a list of category implementations so
- /// we can check for duplicates and find local method declarations.
- llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
-
- /// ObjCProtocols - Keep track of all protocol declarations declared
- /// with @protocol keyword, so that we can emit errors on duplicates and
- /// find the declarations when needed.
- llvm::DenseMap<IdentifierInfo*, ObjCProtocolDecl*> ObjCProtocols;
-
- /// ObjCInterfaceDecls - Keep track of all class declarations declared
- /// with @interface, so that we can emit errors on duplicates and
- /// find the declarations when needed.
- typedef llvm::DenseMap<const IdentifierInfo*,
- ObjCInterfaceDecl*> ObjCInterfaceDeclsTy;
- ObjCInterfaceDeclsTy ObjCInterfaceDecls;
-
- /// ObjCAliasDecls - Keep track of all class declarations declared
- /// with @compatibility_alias, so that we can emit errors on duplicates and
- /// find the declarations when needed. This construct is ancient and will
- /// likely never be seen. Nevertheless, it is here for compatibility.
- typedef llvm::DenseMap<const IdentifierInfo*,
- ObjCCompatibleAliasDecl*> ObjCAliasTy;
- ObjCAliasTy ObjCAliasDecls;
-
- /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
- llvm::OwningPtr<CXXFieldCollector> FieldCollector;
-
- IdentifierResolver IdResolver;
-
- // Enum values used by KnownFunctionIDs (see below).
- enum {
- id_NSLog,
- id_asprintf,
- id_fprintf,
- id_printf,
- id_snprintf,
- id_snprintf_chk,
- id_sprintf,
- id_sprintf_chk,
- id_vasprintf,
- id_vfprintf,
- id_vsnprintf,
- id_vsnprintf_chk,
- id_vsprintf,
- id_vsprintf_chk,
- id_vprintf,
- id_num_known_functions
- };
-
- /// KnownFunctionIDs - This is a list of IdentifierInfo objects to a set
- /// of known functions used by the semantic analysis to do various
- /// kinds of checking (e.g. checking format string errors in printf calls).
- /// This list is populated upon the creation of a Sema object.
- IdentifierInfo* KnownFunctionIDs[id_num_known_functions];
-
- /// SuperID - Identifier for "super" used for Objective-C checking.
- IdentifierInfo* SuperID;
-
- /// Identifiers for builtin ObjC typedef names.
- IdentifierInfo *Ident_id, *Ident_Class; // "id", "Class"
- IdentifierInfo *Ident_SEL, *Ident_Protocol; // "SEL", "Protocol"
-
- /// Translation Unit Scope - useful to Objective-C actions that need
- /// to lookup file scope declarations in the "ordinary" C decl namespace.
- /// For example, user-defined classes, built-in "id" type, etc.
- Scope *TUScope;
-
- /// ObjCMethodList - a linked list of methods with different signatures.
- struct ObjCMethodList {
- ObjCMethodDecl *Method;
- ObjCMethodList *Next;
-
- ObjCMethodList() {
- Method = 0;
- Next = 0;
- }
- ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
- Method = M;
- Next = C;
- }
- };
- /// Instance/Factory Method Pools - allows efficient lookup when typechecking
- /// messages to "id". We need to maintain a list, since selectors can have
- /// differing signatures across classes. In Cocoa, this happens to be
- /// extremely uncommon (only 1% of selectors are "overloaded").
- llvm::DenseMap<Selector, ObjCMethodList> InstanceMethodPool;
- llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool;
-public:
- Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer);
-
- const LangOptions &getLangOptions() const;
-
- /// The primitive diagnostic helpers - always returns true, which simplifies
- /// error handling (i.e. less code).
- bool Diag(SourceLocation Loc, unsigned DiagID);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2);
-
- /// More expressive diagnostic helpers for expressions (say that 6 times:-)
- bool Diag(SourceLocation Loc, unsigned DiagID, const SourceRange& R1);
- bool Diag(SourceLocation Loc, unsigned DiagID,
- const SourceRange& R1, const SourceRange& R2);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange& R1);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- const SourceRange& R1, const SourceRange& R2);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, const SourceRange& R1);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, const std::string &Msg3,
- const SourceRange& R1);
- bool Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg1, const std::string &Msg2,
- const SourceRange& R1, const SourceRange& R2);
-
- virtual void DeleteExpr(ExprTy *E);
- virtual void DeleteStmt(StmtTy *S);
-
- virtual void ActOnEndOfTranslationUnit();
-
- //===--------------------------------------------------------------------===//
- // Type Analysis / Processing: SemaType.cpp.
- //
- QualType ConvertDeclSpecToType(const DeclSpec &DS);
- void ProcessTypeAttributeList(QualType &Result, const AttributeList *AL);
- QualType GetTypeForDeclarator(Declarator &D, Scope *S);
-
-
- QualType ObjCGetTypeForMethodDefinition(DeclTy *D);
-
-
- virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
-private:
- //===--------------------------------------------------------------------===//
- // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
- //
- virtual TypeTy *isTypeName(const IdentifierInfo &II, Scope *S);
- virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup);
- virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D);
- virtual void ActOnParamDefaultArgument(DeclTy *param,
- SourceLocation EqualLoc,
- ExprTy *defarg);
- void AddInitializerToDecl(DeclTy *dcl, ExprTy *init);
- virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
-
- virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
- virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, DeclTy *D);
- virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
-
- virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body);
- virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
- SourceLocation RBrace, const char *Lang,
- unsigned StrSize, DeclTy *D);
- virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprTy *expr);
-
- /// Scope actions.
- virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
- virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
-
- /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
- /// no declarator (e.g. "struct foo;") is parsed.
- virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
-
- virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK,
- SourceLocation KWLoc, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr);
-
- DeclTy* ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK,
- SourceLocation KWLoc, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr);
-
- virtual void ActOnDefs(Scope *S, SourceLocation DeclStart,
- IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclTy*> &Decls);
- virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth);
-
- virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth,
- tok::ObjCKeywordKind visibility);
-
- // This is used for both record definitions and ObjC interface declarations.
- virtual void ActOnFields(Scope* S,
- SourceLocation RecLoc, DeclTy *TagDecl,
- DeclTy **Fields, unsigned NumFields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *AttrList);
- virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
- DeclTy *LastEnumConstant,
- SourceLocation IdLoc, IdentifierInfo *Id,
- SourceLocation EqualLoc, ExprTy *Val);
- virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
- DeclTy **Elements, unsigned NumElements);
-private:
- DeclContext *getDCParent(DeclContext *DC);
-
- /// Set the current declaration context until it gets popped.
- void PushDeclContext(DeclContext *DC);
- void PopDeclContext();
-
- /// CurFunctionDecl - If inside of a function body, this returns a pointer to
- /// the function decl for the function being parsed.
- FunctionDecl *getCurFunctionDecl() {
- return dyn_cast<FunctionDecl>(CurContext);
- }
-
- /// CurMethodDecl - If inside of a method body, this returns a pointer to
- /// the method decl for the method being parsed.
- ObjCMethodDecl *getCurMethodDecl();
-
- /// Add this decl to the scope shadowed decl chains.
- void PushOnScopeChains(NamedDecl *D, Scope *S);
-
- /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
- /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
- /// true if 'D' belongs to the given declaration context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) {
- return IdResolver.isDeclInScope(D, Ctx, S);
- }
-
- /// Subroutines of ActOnDeclarator().
- TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
- ScopedDecl *LastDecl);
- TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
- FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old,
- bool &Redeclaration);
- VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
- FunctionDecl *MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
- void CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD);
-
- /// Helpers for dealing with function parameters
- bool CheckParmsForFunctionDef(FunctionDecl *FD);
- void CheckCXXDefaultArguments(FunctionDecl *FD);
- void CheckExtraCXXDefaultArguments(Declarator &D);
-
- /// More parsing and symbol table subroutines...
- Decl *LookupDecl(const IdentifierInfo *II, unsigned NSI, Scope *S,
- bool enableLazyBuiltinCreation = true);
- ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
- ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
- Scope *S);
- ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
- Scope *S);
- // Decl attributes - this routine is the top level dispatcher.
- void ProcessDeclAttributes(Decl *D, const Declarator &PD);
- void ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList);
-
- void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
- bool &IncompleteImpl);
-
- /// CheckProtocolMethodDefs - This routine checks unimpletented
- /// methods declared in protocol, and those referenced by it.
- /// \param IDecl - Used for checking for methods which may have been
- /// inherited.
- void CheckProtocolMethodDefs(SourceLocation ImpLoc,
- ObjCProtocolDecl *PDecl,
- bool& IncompleteImpl,
- const llvm::DenseSet<Selector> &InsMap,
- const llvm::DenseSet<Selector> &ClsMap,
- ObjCInterfaceDecl *IDecl);
-
- /// CheckImplementationIvars - This routine checks if the instance variables
- /// listed in the implelementation match those listed in the interface.
- void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
- ObjCIvarDecl **Fields, unsigned nIvars,
- SourceLocation Loc);
-
- /// ImplMethodsVsClassMethods - This is main routine to warn if any method
- /// remains unimplemented in the @implementation class.
- void ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
- ObjCInterfaceDecl* IDecl);
-
- /// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
- /// category interface is implemented in the category @implementation.
- void ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
- ObjCCategoryDecl *CatClassDecl);
- /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
- /// true, or false, accordingly.
- bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
- const ObjCMethodDecl *PrevMethod);
-
- /// AddInstanceMethodToGlobalPool - All instance methods in a translation
- /// unit are added to a global pool. This allows us to efficiently associate
- /// a selector with a method declaraation for purposes of typechecking
- /// messages sent to "id" (where the class of the object is unknown).
- void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
-
- /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
- /// there are multiple signatures.
- ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R);
-
- /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
- void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
- //===--------------------------------------------------------------------===//
- // Statement Parsing Callbacks: SemaStmt.cpp.
-public:
- virtual StmtResult ActOnExprStmt(ExprTy *Expr);
-
- virtual StmtResult ActOnNullStmt(SourceLocation SemiLoc);
- virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
- StmtTy **Elts, unsigned NumElts,
- bool isStmtExpr);
- virtual StmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
- SourceLocation EndLoc);
- virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
- SourceLocation DotDotDotLoc, ExprTy *RHSVal,
- SourceLocation ColonLoc, StmtTy *SubStmt);
- virtual StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc, StmtTy *SubStmt,
- Scope *CurScope);
- virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, StmtTy *SubStmt);
- virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
- StmtTy *ThenVal, SourceLocation ElseLoc,
- StmtTy *ElseVal);
- virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond);
- virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
- StmtTy *Switch, ExprTy *Body);
- virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
- StmtTy *Body);
- virtual StmtResult ActOnDoStmt(SourceLocation DoLoc, StmtTy *Body,
- SourceLocation WhileLoc, ExprTy *Cond);
-
- virtual StmtResult ActOnForStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- StmtTy *First, ExprTy *Second, ExprTy *Third,
- SourceLocation RParenLoc, StmtTy *Body);
- virtual StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
- SourceLocation LParenLoc,
- StmtTy *First, ExprTy *Second,
- SourceLocation RParenLoc, StmtTy *Body);
-
- virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
- SourceLocation LabelLoc,
- IdentifierInfo *LabelII);
- virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
- SourceLocation StarLoc,
- ExprTy *DestExp);
- virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
- Scope *CurScope);
- virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope);
-
- virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
- ExprTy *RetValExp);
- StmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
-
- virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
- bool IsSimple,
- bool IsVolatile,
- unsigned NumOutputs,
- unsigned NumInputs,
- std::string *Names,
- ExprTy **Constraints,
- ExprTy **Exprs,
- ExprTy *AsmString,
- unsigned NumClobbers,
- ExprTy **Clobbers,
- SourceLocation RParenLoc);
-
- virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
- SourceLocation RParen, StmtTy *Parm,
- StmtTy *Body, StmtTy *CatchList);
-
- virtual StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
- StmtTy *Body);
-
- virtual StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtTy *Try,
- StmtTy *Catch, StmtTy *Finally);
-
- virtual StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
- StmtTy *Throw);
- virtual StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
- ExprTy *SynchExpr,
- StmtTy *SynchBody);
-
- //===--------------------------------------------------------------------===//
- // Expression Parsing Callbacks: SemaExpr.cpp.
-
- // Primary Expressions.
- virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
- IdentifierInfo &II,
- bool HasTrailingLParen);
- virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc,
- tok::TokenKind Kind);
- virtual ExprResult ActOnNumericConstant(const Token &);
- virtual ExprResult ActOnCharacterConstant(const Token &);
- virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
- ExprTy *Val);
-
- /// ActOnStringLiteral - The specified tokens were lexed as pasted string
- /// fragments (e.g. "foo" "bar" L"baz").
- virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks);
-
- // Binary/Unary Operators. 'Tok' is the token for the operator.
- virtual ExprResult ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
- ExprTy *Input);
- virtual ExprResult
- ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
- SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc);
-
- virtual ExprResult ActOnPostfixUnaryOp(SourceLocation OpLoc,
- tok::TokenKind Kind, ExprTy *Input);
-
- virtual ExprResult ActOnArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
- ExprTy *Idx, SourceLocation RLoc);
- virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation MemberLoc,
- IdentifierInfo &Member);
-
- /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
- /// This provides the location of the left/right parens and a list of comma
- /// locations.
- virtual ExprResult ActOnCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
- ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- virtual ExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprTy *Op);
-
- virtual ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprTy *Op);
-
- virtual ExprResult ActOnInitList(SourceLocation LParenLoc,
- ExprTy **InitList, unsigned NumInit,
- SourceLocation RParenLoc);
-
- virtual ExprResult ActOnBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
- ExprTy *LHS,ExprTy *RHS);
-
- /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
- /// in the case of a the GNU conditional expr extension.
- virtual ExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
- SourceLocation ColonLoc,
- ExprTy *Cond, ExprTy *LHS, ExprTy *RHS);
-
- /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
- virtual ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
- IdentifierInfo *LabelII);
-
- virtual ExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
- SourceLocation RPLoc); // "({..})"
-
- /// __builtin_offsetof(type, a.b[123][456].c)
- virtual ExprResult ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
- SourceLocation TypeLoc, TypeTy *Arg1,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RParenLoc);
-
- // __builtin_types_compatible_p(type1, type2)
- virtual ExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1, TypeTy *arg2,
- SourceLocation RPLoc);
-
- // __builtin_choose_expr(constExpr, expr1, expr2)
- virtual ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
- ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
- SourceLocation RPLoc);
-
- // __builtin_overload(...)
- virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation BuiltinLoc,
- SourceLocation RParenLoc);
-
- // __builtin_va_arg(expr, type)
- virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
- ExprTy *expr, TypeTy *type,
- SourceLocation RPLoc);
-
- //===------------------------- "Block" Extension ------------------------===//
-
- /// ActOnBlockStart - This callback is invoked when a block literal is
- /// started.
- virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope,
- Declarator &ParamInfo);
-
- /// ActOnBlockError - If there is an error parsing a block, this callback
- /// is invoked to pop the information about the block from the action impl.
- virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
-
- /// ActOnBlockStmtExpr - This is called when the body of a block statement
- /// literal was successfully completed. ^(int x){...}
- virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
- Scope *CurScope);
-
- // Act on C++ namespaces
- virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
- IdentifierInfo *Ident,
- SourceLocation LBrace);
- virtual void ActOnFinishNamespaceDef(DeclTy *Dcl, SourceLocation RBrace);
-
- /// AddCXXDirectInitializerToDecl - This action is called immediately after
- /// ActOnDeclarator, when a C++ direct initializer is present.
- /// e.g: "int x(1);"
- virtual void AddCXXDirectInitializerToDecl(DeclTy *Dcl,
- SourceLocation LParenLoc,
- ExprTy **Exprs, unsigned NumExprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
- virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
- SourceLocation LAngleBracketLoc, TypeTy *Ty,
- SourceLocation RAngleBracketLoc,
- SourceLocation LParenLoc, ExprTy *E,
- SourceLocation RParenLoc);
-
- //// ActOnCXXThis - Parse 'this' pointer.
- virtual ExprResult ActOnCXXThis(SourceLocation ThisLoc);
-
- /// ActOnCXXBoolLiteral - Parse {true,false} literals.
- virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
- tok::TokenKind Kind);
-
- //// ActOnCXXThrow - Parse throw expressions.
- virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
- ExprTy *expr);
-
- /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
- /// Can be interpreted either as function-style casting ("int(x)")
- /// or class type construction ("ClassType(x,y,z)")
- /// or creation of a value-initialized type ("int()").
- virtual ExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
- TypeTy *TypeRep,
- SourceLocation LParenLoc,
- ExprTy **Exprs,
- unsigned NumExprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
- /// C++ if/switch/while/for statement.
- /// e.g: "if (int x = f()) {...}"
- virtual ExprResult ActOnCXXConditionDeclarationExpr(Scope *S,
- SourceLocation StartLoc,
- Declarator &D,
- SourceLocation EqualLoc,
- ExprTy *AssignExprVal);
-
- // ParseObjCStringLiteral - Parse Objective-C string literals.
- virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
- ExprTy **Strings,
- unsigned NumStrings);
- virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
- SourceLocation EncodeLoc,
- SourceLocation LParenLoc,
- TypeTy *Ty,
- SourceLocation RParenLoc);
-
- // ParseObjCSelectorExpression - Build selector expression for @selector
- virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
- SourceLocation AtLoc,
- SourceLocation SelLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- // ParseObjCProtocolExpression - Build protocol expression for @protocol
- virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
- SourceLocation AtLoc,
- SourceLocation ProtoLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- //===--------------------------------------------------------------------===//
- // C++ Classes
- //
- /// ActOnBaseSpecifier - Parsed a base specifier
- virtual void ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- TypeTy *basetype, SourceLocation BaseLoc);
-
- virtual void ActOnStartCXXClassDef(Scope *S, DeclTy *TagDecl,
- SourceLocation LBrace);
-
- virtual DeclTy *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
- Declarator &D, ExprTy *BitfieldWidth,
- ExprTy *Init, DeclTy *LastInGroup);
-
- virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- DeclTy *TagDecl,
- SourceLocation LBrac,
- SourceLocation RBrac);
-
- virtual void ActOnFinishCXXClassDef(DeclTy *TagDecl);
-
-
- // Objective-C declarations.
- virtual DeclTy *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-
- virtual DeclTy *ActOnCompatiblityAlias(
- SourceLocation AtCompatibilityAliasLoc,
- IdentifierInfo *AliasName, SourceLocation AliasLocation,
- IdentifierInfo *ClassName, SourceLocation ClassLocation);
-
- virtual DeclTy *ActOnStartProtocolInterface(
- SourceLocation AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
- DeclTy * const *ProtoRefNames, unsigned NumProtoRefs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-
- virtual DeclTy *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc);
-
- virtual DeclTy *ActOnStartClassImplementation(
- SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc);
-
- virtual DeclTy *ActOnStartCategoryImplementation(
- SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CatName,
- SourceLocation CatLoc);
-
- virtual DeclTy *ActOnForwardClassDeclaration(SourceLocation Loc,
- IdentifierInfo **IdentList,
- unsigned NumElts);
-
- virtual DeclTy *ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
- const IdentifierLocPair *IdentList,
- unsigned NumElts);
-
- virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
- const IdentifierLocPair *ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVectorImpl<DeclTy *> &Protocols);
-
- /// Ensure attributes are consistent with type.
- /// \param [in, out] Attributes The attributes to check; they will
- /// be modified to be consistent with \arg PropertyTy.
- void CheckObjCPropertyAttributes(QualType PropertyTy,
- SourceLocation Loc,
- unsigned &Attributes);
- void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
- ObjCPropertyDecl *SuperProperty,
- const char *Name);
- void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
-
- void MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
- DeclTy *MergeProtocols);
-
- void MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
- ObjCProtocolDecl *PDecl);
-
- virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
- DeclTy **allMethods = 0, unsigned allNum = 0,
- DeclTy **allProperties = 0, unsigned pNum = 0);
-
- virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
- FieldDeclarator &FD, ObjCDeclSpec &ODS,
- Selector GetterSel, Selector SetterSel,
- tok::ObjCKeywordKind MethodImplKind);
-
- virtual DeclTy *ActOnPropertyImplDecl(SourceLocation AtLoc,
- SourceLocation PropertyLoc,
- bool ImplKind, DeclTy *ClassImplDecl,
- IdentifierInfo *PropertyId,
- IdentifierInfo *PropertyIvar);
-
- virtual DeclTy *ActOnMethodDeclaration(
- SourceLocation BeginLoc, // location of the + or -.
- SourceLocation EndLoc, // location of the ; or {.
- tok::TokenKind MethodType,
- DeclTy *ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
- Selector Sel,
- // optional arguments. The number of types/arguments is obtained
- // from the Sel.getNumArgs().
- ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
- AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
- bool isVariadic = false);
-
- // ActOnClassMessage - used for both unary and keyword messages.
- // ArgExprs is optional - if it is present, the number of expressions
- // is obtained from NumArgs.
- virtual ExprResult ActOnClassMessage(
- Scope *S,
- IdentifierInfo *receivingClassName, Selector Sel,
- SourceLocation lbrac, SourceLocation rbrac,
- ExprTy **ArgExprs, unsigned NumArgs);
-
- // ActOnInstanceMessage - used for both unary and keyword messages.
- // ArgExprs is optional - if it is present, the number of expressions
- // is obtained from NumArgs.
- virtual ExprResult ActOnInstanceMessage(
- ExprTy *receiver, Selector Sel,
- SourceLocation lbrac, SourceLocation rbrac,
- ExprTy **ArgExprs, unsigned NumArgs);
-private:
- /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
- /// cast. If there is already an implicit cast, merge into the existing one.
- void ImpCastExprToType(Expr *&Expr, QualType Type);
-
- // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
- // functions and arrays to their respective pointers (C99 6.3.2.1).
- Expr *UsualUnaryConversions(Expr *&expr);
-
- // UsualUnaryConversionType - Same as UsualUnaryConversions, but works
- // on types instead of expressions
- QualType UsualUnaryConversionType(QualType Ty);
-
- // DefaultFunctionArrayConversion - converts functions and arrays
- // to their respective pointers (C99 6.3.2.1).
- void DefaultFunctionArrayConversion(Expr *&expr);
-
- // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
- // do not have a prototype. Integer promotions are performed on each
- // argument, and arguments that have type float are promoted to double.
- void DefaultArgumentPromotion(Expr *&Expr);
-
- // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
- // operands and then handles various conversions that are common to binary
- // operators (C99 6.3.1.8). If both operands aren't arithmetic, this
- // routine returns the first non-arithmetic type found. The client is
- // responsible for emitting appropriate error diagnostics.
- QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
- bool isCompAssign = false);
-
- /// AssignConvertType - All of the 'assignment' semantic checks return this
- /// enum to indicate whether the assignment was allowed. These checks are
- /// done for simple assignments, as well as initialization, return from
- /// function, argument passing, etc. The query is phrased in terms of a
- /// source and destination type.
- enum AssignConvertType {
- /// Compatible - the types are compatible according to the standard.
- Compatible,
-
- /// PointerToInt - The assignment converts a pointer to an int, which we
- /// accept as an extension.
- PointerToInt,
-
- /// IntToPointer - The assignment converts an int to a pointer, which we
- /// accept as an extension.
- IntToPointer,
-
- /// FunctionVoidPointer - The assignment is between a function pointer and
- /// void*, which the standard doesn't allow, but we accept as an extension.
- FunctionVoidPointer,
-
- /// IncompatiblePointer - The assignment is between two pointers types that
- /// are not compatible, but we accept them as an extension.
- IncompatiblePointer,
-
- /// CompatiblePointerDiscardsQualifiers - The assignment discards
- /// c/v/r qualifiers, which we accept as an extension.
- CompatiblePointerDiscardsQualifiers,
-
- /// IntToBlockPointer - The assignment converts an int to a block
- /// pointer. We disallow this.
- IntToBlockPointer,
-
- /// IncompatibleBlockPointer - The assignment is between two block
- /// pointers types that are not compatible.
- IncompatibleBlockPointer,
-
- /// BlockVoidPointer - The assignment is between a block pointer and
- /// void*, we accept for now.
- BlockVoidPointer,
-
- /// Incompatible - We reject this conversion outright, it is invalid to
- /// represent it in the AST.
- Incompatible
- };
-
- /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
- /// assignment conversion type specified by ConvTy. This returns true if the
- /// conversion was invalid or false if the conversion was accepted.
- bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
- SourceLocation Loc,
- QualType DstType, QualType SrcType,
- Expr *SrcExpr, const char *Flavor);
-
- /// CheckAssignmentConstraints - Perform type checking for assignment,
- /// argument passing, variable initialization, and function return values.
- /// This routine is only used by the following two methods. C99 6.5.16.
- AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
-
- // CheckSingleAssignmentConstraints - Currently used by ActOnCallExpr,
- // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
- // this routine performs the default function/array converions.
- AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
- Expr *&rExpr);
- // CheckCompoundAssignmentConstraints - Type check without performing any
- // conversions. For compound assignments, the "Check...Operands" methods
- // perform the necessary conversions.
- AssignConvertType CheckCompoundAssignmentConstraints(QualType lhs,
- QualType rhs);
-
- // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
- AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
- QualType rhsType);
-
- // Helper function for CheckAssignmentConstraints involving two
- // blcok pointer types.
- AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
- QualType rhsType);
-
- bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
-
- /// the following "Check" methods will return a valid/converted QualType
- /// or a null QualType (indicating an error diagnostic was issued).
-
- /// type checking binary operators (subroutines of ActOnBinOp).
- inline QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
- inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- inline QualType CheckRemainderOperands( // C99 6.5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- inline QualType CheckAdditionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- inline QualType CheckSubtractionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- inline QualType CheckShiftOperands( // C99 6.5.7
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- inline QualType CheckCompareOperands( // C99 6.5.8/9
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isRelational);
- inline QualType CheckBitwiseOperands( // C99 6.5.[10...12]
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- inline QualType CheckLogicalOperands( // C99 6.5.[13,14]
- Expr *&lex, Expr *&rex, SourceLocation OpLoc);
- // CheckAssignmentOperands is used for both simple and compound assignment.
- // For simple assignment, pass both expressions and a null converted type.
- // For compound assignment, pass both expressions and the converted type.
- inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
- Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
- inline QualType CheckCommaOperands( // C99 6.5.17
- Expr *&lex, Expr *&rex, SourceLocation OpLoc);
- inline QualType CheckConditionalOperands( // C99 6.5.15
- Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
-
- /// type checking for vector binary operators.
- inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
- inline QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
- SourceLocation l, bool isRel);
-
- /// type checking unary operators (subroutines of ActOnUnaryOp).
- /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
- QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc);
- QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
- QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
- QualType CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
- const SourceRange &R, bool isSizeof);
- QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc);
-
- /// type checking primary expressions.
- QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
- IdentifierInfo &Comp, SourceLocation CmpLoc);
-
- /// type checking declaration initializers (C99 6.7.8)
- friend class InitListChecker;
- bool CheckInitializerTypes(Expr *&simpleInit_or_initList, QualType &declType);
- bool CheckSingleInitializer(Expr *&simpleInit, QualType declType);
- bool CheckForConstantInitializer(Expr *e, QualType t);
- bool CheckArithmeticConstantExpression(const Expr* e);
- bool CheckAddressConstantExpression(const Expr* e);
- bool CheckAddressConstantExpressionLValue(const Expr* e);
-
- StringLiteral *IsStringLiteralInit(Expr *Init, QualType DeclType);
- bool CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT);
-
- /// CheckCastTypes - Check type constraints for casting between types.
- bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr);
-
- // CheckVectorCast - check type constraints for vectors.
- // Since vectors are an extension, there are no C standard reference for this.
- // We allow casting between vectors and integer datatypes of the same size.
- // returns true if the cast is invalid
- bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
-
- /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
- /// \param Method - May be null.
- /// \param [out] ReturnType - The return type of the send.
- /// \return true iff there were any incompatible types.
- bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
- ObjCMethodDecl *Method, const char *PrefixStr,
- SourceLocation lbrac, SourceLocation rbrac,
- QualType &ReturnType);
-
- /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
- bool CheckCXXBooleanCondition(Expr *&CondExpr);
-
- /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
- /// the specified width and sign. If an overflow occurs, detect it and emit
- /// the specified diagnostic.
- void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
- unsigned NewWidth, bool NewSign,
- SourceLocation Loc, unsigned DiagID);
-
- bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
- bool ForCompare);
-
-
- void InitBuiltinVaListType();
-
- // Helper method to turn variable array types into
- // constant array types in certain situations which would otherwise
- // be errors
- QualType TryFixInvalidVariablyModifiedType(QualType T);
-
- //===--------------------------------------------------------------------===//
- // Extra semantic analysis beyond the C type system
-private:
- Action::ExprResult CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
- bool CheckBuiltinCFStringArgument(Expr* Arg);
- bool SemaBuiltinVAStart(CallExpr *TheCall);
- bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
- bool SemaBuiltinStackAddress(CallExpr *TheCall);
- Action::ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
- bool SemaBuiltinPrefetch(CallExpr *TheCall);
- bool SemaBuiltinObjectSize(CallExpr *TheCall);
- void CheckPrintfArguments(CallExpr *TheCall,
- bool HasVAListArg, unsigned format_idx);
- void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
- SourceLocation ReturnLoc);
- void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
-};
-
-class InitListChecker {
- Sema *SemaRef;
- bool hadError;
-
- void CheckImplicitInitList(InitListExpr *ParentIList, QualType T,
- unsigned &Index);
- void CheckExplicitInitList(InitListExpr *IList, QualType &T,
- unsigned &Index);
-
- void CheckListElementTypes(InitListExpr *IList, QualType &DeclType,
- unsigned &Index);
- void CheckSubElementType(InitListExpr *IList, QualType ElemType,
- unsigned &Index);
- // FIXME: Does DeclType need to be a reference type?
- void CheckScalarType(InitListExpr *IList, QualType &DeclType,
- unsigned &Index);
- void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index);
- void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType,
- unsigned &Index);
- void CheckArrayType(InitListExpr *IList, QualType &DeclType, unsigned &Index);
-
- int numArrayElements(QualType DeclType);
- int numStructUnionElements(QualType DeclType);
-public:
- InitListChecker(Sema *S, InitListExpr *IL, QualType &T);
- bool HadError() { return hadError; }
-};
-
-/// BlockSemaInfo - When a block is being parsed, this contains information
-/// about the block. It is pointed to from Sema::CurBlock.
-struct BlockSemaInfo {
- llvm::SmallVector<ParmVarDecl*, 8> Params;
- bool hasPrototype;
- bool isVariadic;
-
- /// TheScope - This is the scope for the block itself, which contains
- /// arguments etc.
- Scope *TheScope;
-
- /// ReturnType - This will get set to block result type, by looking at
- /// return types, if any, in the block body.
- Type *ReturnType;
-
- /// PrevBlockInfo - If this is nested inside another block, this points
- /// to the outer block.
- BlockSemaInfo *PrevBlockInfo;
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
deleted file mode 100644
index 27f3abe68a64..000000000000
--- a/clang/lib/Sema/SemaChecking.cpp
+++ /dev/null
@@ -1,999 +0,0 @@
-//===--- SemaChecking.cpp - Extra Semantic Checking -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements extra semantic analysis beyond what is enforced
-// by the C type system.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "SemaUtil.h"
-using namespace clang;
-
-/// CheckFunctionCall - Check a direct function call for various correctness
-/// and safety properties not strictly enforced by the C type system.
-Action::ExprResult
-Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCallRaw) {
- llvm::OwningPtr<CallExpr> TheCall(TheCallRaw);
- // Get the IdentifierInfo* for the called function.
- IdentifierInfo *FnInfo = FDecl->getIdentifier();
-
- switch (FnInfo->getBuiltinID()) {
- case Builtin::BI__builtin___CFStringMakeConstantString:
- assert(TheCall->getNumArgs() == 1 &&
- "Wrong # arguments to builtin CFStringMakeConstantString");
- if (CheckBuiltinCFStringArgument(TheCall->getArg(0)))
- return true;
- return TheCall.take();
- case Builtin::BI__builtin_stdarg_start:
- case Builtin::BI__builtin_va_start:
- if (SemaBuiltinVAStart(TheCall.get()))
- return true;
- return TheCall.take();
- case Builtin::BI__builtin_isgreater:
- case Builtin::BI__builtin_isgreaterequal:
- case Builtin::BI__builtin_isless:
- case Builtin::BI__builtin_islessequal:
- case Builtin::BI__builtin_islessgreater:
- case Builtin::BI__builtin_isunordered:
- if (SemaBuiltinUnorderedCompare(TheCall.get()))
- return true;
- return TheCall.take();
- case Builtin::BI__builtin_return_address:
- case Builtin::BI__builtin_frame_address:
- if (SemaBuiltinStackAddress(TheCall.get()))
- return true;
- return TheCall.take();
- case Builtin::BI__builtin_shufflevector:
- return SemaBuiltinShuffleVector(TheCall.get());
- case Builtin::BI__builtin_prefetch:
- if (SemaBuiltinPrefetch(TheCall.get()))
- return true;
- return TheCall.take();
- case Builtin::BI__builtin_object_size:
- if (SemaBuiltinObjectSize(TheCall.get()))
- return true;
- }
-
- // FIXME: This mechanism should be abstracted to be less fragile and
- // more efficient. For example, just map function ids to custom
- // handlers.
-
- // Search the KnownFunctionIDs for the identifier.
- unsigned i = 0, e = id_num_known_functions;
- for (; i != e; ++i) { if (KnownFunctionIDs[i] == FnInfo) break; }
- if (i == e) return TheCall.take();
-
- // Printf checking.
- if (i <= id_vprintf) {
- // Retrieve the index of the format string parameter and determine
- // if the function is passed a va_arg argument.
- unsigned format_idx = 0;
- bool HasVAListArg = false;
-
- switch (i) {
- default: assert(false && "No format string argument index.");
- case id_NSLog: format_idx = 0; break;
- case id_asprintf: format_idx = 1; break;
- case id_fprintf: format_idx = 1; break;
- case id_printf: format_idx = 0; break;
- case id_snprintf: format_idx = 2; break;
- case id_snprintf_chk: format_idx = 4; break;
- case id_sprintf: format_idx = 1; break;
- case id_sprintf_chk: format_idx = 3; break;
- case id_vasprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vfprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vsnprintf: format_idx = 2; HasVAListArg = true; break;
- case id_vsnprintf_chk: format_idx = 4; HasVAListArg = true; break;
- case id_vsprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vsprintf_chk: format_idx = 3; HasVAListArg = true; break;
- case id_vprintf: format_idx = 0; HasVAListArg = true; break;
- }
-
- CheckPrintfArguments(TheCall.get(), HasVAListArg, format_idx);
- }
-
- return TheCall.take();
-}
-
-/// CheckBuiltinCFStringArgument - Checks that the argument to the builtin
-/// CFString constructor is correct
-bool Sema::CheckBuiltinCFStringArgument(Expr* Arg) {
- Arg = Arg->IgnoreParenCasts();
-
- StringLiteral *Literal = dyn_cast<StringLiteral>(Arg);
-
- if (!Literal || Literal->isWide()) {
- Diag(Arg->getLocStart(),
- diag::err_cfstring_literal_not_string_constant,
- Arg->getSourceRange());
- return true;
- }
-
- const char *Data = Literal->getStrData();
- unsigned Length = Literal->getByteLength();
-
- for (unsigned i = 0; i < Length; ++i) {
- if (!isascii(Data[i])) {
- Diag(PP.AdvanceToTokenCharacter(Arg->getLocStart(), i + 1),
- diag::warn_cfstring_literal_contains_non_ascii_character,
- Arg->getSourceRange());
- break;
- }
-
- if (!Data[i]) {
- Diag(PP.AdvanceToTokenCharacter(Arg->getLocStart(), i + 1),
- diag::warn_cfstring_literal_contains_nul_character,
- Arg->getSourceRange());
- break;
- }
- }
-
- return false;
-}
-
-/// SemaBuiltinVAStart - Check the arguments to __builtin_va_start for validity.
-/// Emit an error and return true on failure, return false on success.
-bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) {
- Expr *Fn = TheCall->getCallee();
- if (TheCall->getNumArgs() > 2) {
- Diag(TheCall->getArg(2)->getLocStart(),
- diag::err_typecheck_call_too_many_args, Fn->getSourceRange(),
- SourceRange(TheCall->getArg(2)->getLocStart(),
- (*(TheCall->arg_end()-1))->getLocEnd()));
- return true;
- }
-
- // Determine whether the current function is variadic or not.
- bool isVariadic;
- if (getCurFunctionDecl())
- isVariadic =
- cast<FunctionTypeProto>(getCurFunctionDecl()->getType())->isVariadic();
- else
- isVariadic = getCurMethodDecl()->isVariadic();
-
- if (!isVariadic) {
- Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function);
- return true;
- }
-
- // Verify that the second argument to the builtin is the last argument of the
- // current function or method.
- bool SecondArgIsLastNamedArgument = false;
- const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
-
- if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
- if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
- // FIXME: This isn't correct for methods (results in bogus warning).
- // Get the last formal in the current function.
- const ParmVarDecl *LastArg;
- if (getCurFunctionDecl())
- LastArg = *(getCurFunctionDecl()->param_end()-1);
- else
- LastArg = *(getCurMethodDecl()->param_end()-1);
- SecondArgIsLastNamedArgument = PV == LastArg;
- }
- }
-
- if (!SecondArgIsLastNamedArgument)
- Diag(TheCall->getArg(1)->getLocStart(),
- diag::warn_second_parameter_of_va_start_not_last_named_argument);
- return false;
-}
-
-/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
-/// friends. This is declared to take (...), so we have to check everything.
-bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
- if (TheCall->getNumArgs() < 2)
- return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args);
- if (TheCall->getNumArgs() > 2)
- return Diag(TheCall->getArg(2)->getLocStart(),
- diag::err_typecheck_call_too_many_args,
- SourceRange(TheCall->getArg(2)->getLocStart(),
- (*(TheCall->arg_end()-1))->getLocEnd()));
-
- Expr *OrigArg0 = TheCall->getArg(0);
- Expr *OrigArg1 = TheCall->getArg(1);
-
- // Do standard promotions between the two arguments, returning their common
- // type.
- QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
-
- // If the common type isn't a real floating type, then the arguments were
- // invalid for this operation.
- if (!Res->isRealFloatingType())
- return Diag(OrigArg0->getLocStart(),
- diag::err_typecheck_call_invalid_ordered_compare,
- OrigArg0->getType().getAsString(),
- OrigArg1->getType().getAsString(),
- SourceRange(OrigArg0->getLocStart(), OrigArg1->getLocEnd()));
-
- return false;
-}
-
-bool Sema::SemaBuiltinStackAddress(CallExpr *TheCall) {
- // The signature for these builtins is exact; the only thing we need
- // to check is that the argument is a constant.
- SourceLocation Loc;
- if (!TheCall->getArg(0)->isIntegerConstantExpr(Context, &Loc))
- return Diag(Loc, diag::err_stack_const_level, TheCall->getSourceRange());
-
- return false;
-}
-
-/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
-// This is declared to take (...), so we have to check everything.
-Action::ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
- if (TheCall->getNumArgs() < 3)
- return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args,
- TheCall->getSourceRange());
-
- QualType FAType = TheCall->getArg(0)->getType();
- QualType SAType = TheCall->getArg(1)->getType();
-
- if (!FAType->isVectorType() || !SAType->isVectorType()) {
- Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector,
- SourceRange(TheCall->getArg(0)->getLocStart(),
- TheCall->getArg(1)->getLocEnd()));
- return true;
- }
-
- if (Context.getCanonicalType(FAType).getUnqualifiedType() !=
- Context.getCanonicalType(SAType).getUnqualifiedType()) {
- Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector,
- SourceRange(TheCall->getArg(0)->getLocStart(),
- TheCall->getArg(1)->getLocEnd()));
- return true;
- }
-
- unsigned numElements = FAType->getAsVectorType()->getNumElements();
- if (TheCall->getNumArgs() != numElements+2) {
- if (TheCall->getNumArgs() < numElements+2)
- return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args,
- TheCall->getSourceRange());
- return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_many_args,
- TheCall->getSourceRange());
- }
-
- for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
- llvm::APSInt Result(32);
- if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))
- return Diag(TheCall->getLocStart(),
- diag::err_shufflevector_nonconstant_argument,
- TheCall->getArg(i)->getSourceRange());
-
- if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
- return Diag(TheCall->getLocStart(),
- diag::err_shufflevector_argument_too_large,
- TheCall->getArg(i)->getSourceRange());
- }
-
- llvm::SmallVector<Expr*, 32> exprs;
-
- for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
- exprs.push_back(TheCall->getArg(i));
- TheCall->setArg(i, 0);
- }
-
- return new ShuffleVectorExpr(exprs.begin(), numElements+2, FAType,
- TheCall->getCallee()->getLocStart(),
- TheCall->getRParenLoc());
-}
-
-/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
-// This is declared to take (const void*, ...) and can take two
-// optional constant int args.
-bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
- unsigned numArgs = TheCall->getNumArgs();
- bool res = false;
-
- if (numArgs > 3) {
- res |= Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_many_args,
- TheCall->getSourceRange());
- }
-
- // Argument 0 is checked for us and the remaining arguments must be
- // constant integers.
- for (unsigned i=1; i<numArgs; ++i) {
- Expr *Arg = TheCall->getArg(i);
- QualType RWType = Arg->getType();
-
- const BuiltinType *BT = RWType->getAsBuiltinType();
- llvm::APSInt Result;
- if (!BT || BT->getKind() != BuiltinType::Int ||
- !Arg->isIntegerConstantExpr(Result, Context)) {
- if (Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument,
- SourceRange(Arg->getLocStart(), Arg->getLocEnd()))) {
- res = true;
- continue;
- }
- }
-
- // FIXME: gcc issues a warning and rewrites these to 0. These
- // seems especially odd for the third argument since the default
- // is 3.
- if (i==1) {
- if (Result.getSExtValue() < 0 || Result.getSExtValue() > 1)
- res |= Diag(TheCall->getLocStart(), diag::err_argument_invalid_range,
- "0", "1",
- SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
- } else {
- if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3)
- res |= Diag(TheCall->getLocStart(), diag::err_argument_invalid_range,
- "0", "3",
- SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
- }
- }
-
- return res;
-}
-
-/// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr,
-/// int type). This simply type checks that type is one of the defined
-/// constants (0-3).
-bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) {
- Expr *Arg = TheCall->getArg(1);
- QualType ArgType = Arg->getType();
- const BuiltinType *BT = ArgType->getAsBuiltinType();
- llvm::APSInt Result(32);
- if (!BT || BT->getKind() != BuiltinType::Int ||
- !Arg->isIntegerConstantExpr(Result, Context)) {
- return Diag(TheCall->getLocStart(), diag::err_object_size_invalid_argument,
- SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
- }
-
- if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) {
- return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range,
- "0", "3",
- SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
- }
-
- return false;
-}
-
-/// CheckPrintfArguments - Check calls to printf (and similar functions) for
-/// correct use of format strings.
-///
-/// HasVAListArg - A predicate indicating whether the printf-like
-/// function is passed an explicit va_arg argument (e.g., vprintf)
-///
-/// format_idx - The index into Args for the format string.
-///
-/// Improper format strings to functions in the printf family can be
-/// the source of bizarre bugs and very serious security holes. A
-/// good source of information is available in the following paper
-/// (which includes additional references):
-///
-/// FormatGuard: Automatic Protection From printf Format String
-/// Vulnerabilities, Proceedings of the 10th USENIX Security Symposium, 2001.
-///
-/// Functionality implemented:
-///
-/// We can statically check the following properties for string
-/// literal format strings for non v.*printf functions (where the
-/// arguments are passed directly):
-//
-/// (1) Are the number of format conversions equal to the number of
-/// data arguments?
-///
-/// (2) Does each format conversion correctly match the type of the
-/// corresponding data argument? (TODO)
-///
-/// Moreover, for all printf functions we can:
-///
-/// (3) Check for a missing format string (when not caught by type checking).
-///
-/// (4) Check for no-operation flags; e.g. using "#" with format
-/// conversion 'c' (TODO)
-///
-/// (5) Check the use of '%n', a major source of security holes.
-///
-/// (6) Check for malformed format conversions that don't specify anything.
-///
-/// (7) Check for empty format strings. e.g: printf("");
-///
-/// (8) Check that the format string is a wide literal.
-///
-/// (9) Also check the arguments of functions with the __format__ attribute.
-/// (TODO).
-///
-/// All of these checks can be done by parsing the format string.
-///
-/// For now, we ONLY do (1), (3), (5), (6), (7), and (8).
-void
-Sema::CheckPrintfArguments(CallExpr *TheCall, bool HasVAListArg,
- unsigned format_idx) {
- Expr *Fn = TheCall->getCallee();
-
- // CHECK: printf-like function is called with no format string.
- if (format_idx >= TheCall->getNumArgs()) {
- Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string,
- Fn->getSourceRange());
- return;
- }
-
- Expr *OrigFormatExpr = TheCall->getArg(format_idx)->IgnoreParenCasts();
-
- // CHECK: format string is not a string literal.
- //
- // Dynamically generated format strings are difficult to
- // automatically vet at compile time. Requiring that format strings
- // are string literals: (1) permits the checking of format strings by
- // the compiler and thereby (2) can practically remove the source of
- // many format string exploits.
-
- // Format string can be either ObjC string (e.g. @"%d") or
- // C string (e.g. "%d")
- // ObjC string uses the same format specifiers as C string, so we can use
- // the same format string checking logic for both ObjC and C strings.
- ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(OrigFormatExpr);
- StringLiteral *FExpr = NULL;
-
- if(ObjCFExpr != NULL)
- FExpr = ObjCFExpr->getString();
- else
- FExpr = dyn_cast<StringLiteral>(OrigFormatExpr);
-
- if (FExpr == NULL) {
- // For vprintf* functions (i.e., HasVAListArg==true), we add a
- // special check to see if the format string is a function parameter
- // of the function calling the printf function. If the function
- // has an attribute indicating it is a printf-like function, then we
- // should suppress warnings concerning non-literals being used in a call
- // to a vprintf function. For example:
- //
- // void
- // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...) {
- // va_list ap;
- // va_start(ap, fmt);
- // vprintf(fmt, ap); // Do NOT emit a warning about "fmt".
- // ...
- //
- //
- // FIXME: We don't have full attribute support yet, so just check to see
- // if the argument is a DeclRefExpr that references a parameter. We'll
- // add proper support for checking the attribute later.
- if (HasVAListArg)
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(OrigFormatExpr))
- if (isa<ParmVarDecl>(DR->getDecl()))
- return;
-
- Diag(TheCall->getArg(format_idx)->getLocStart(),
- diag::warn_printf_not_string_constant,
- OrigFormatExpr->getSourceRange());
- return;
- }
-
- // CHECK: is the format string a wide literal?
- if (FExpr->isWide()) {
- Diag(FExpr->getLocStart(),
- diag::warn_printf_format_string_is_wide_literal,
- OrigFormatExpr->getSourceRange());
- return;
- }
-
- // Str - The format string. NOTE: this is NOT null-terminated!
- const char * const Str = FExpr->getStrData();
-
- // CHECK: empty format string?
- const unsigned StrLen = FExpr->getByteLength();
-
- if (StrLen == 0) {
- Diag(FExpr->getLocStart(), diag::warn_printf_empty_format_string,
- OrigFormatExpr->getSourceRange());
- return;
- }
-
- // We process the format string using a binary state machine. The
- // current state is stored in CurrentState.
- enum {
- state_OrdChr,
- state_Conversion
- } CurrentState = state_OrdChr;
-
- // numConversions - The number of conversions seen so far. This is
- // incremented as we traverse the format string.
- unsigned numConversions = 0;
-
- // numDataArgs - The number of data arguments after the format
- // string. This can only be determined for non vprintf-like
- // functions. For those functions, this value is 1 (the sole
- // va_arg argument).
- unsigned numDataArgs = TheCall->getNumArgs()-(format_idx+1);
-
- // Inspect the format string.
- unsigned StrIdx = 0;
-
- // LastConversionIdx - Index within the format string where we last saw
- // a '%' character that starts a new format conversion.
- unsigned LastConversionIdx = 0;
-
- for (; StrIdx < StrLen; ++StrIdx) {
-
- // Is the number of detected conversion conversions greater than
- // the number of matching data arguments? If so, stop.
- if (!HasVAListArg && numConversions > numDataArgs) break;
-
- // Handle "\0"
- if (Str[StrIdx] == '\0') {
- // The string returned by getStrData() is not null-terminated,
- // so the presence of a null character is likely an error.
- Diag(PP.AdvanceToTokenCharacter(FExpr->getLocStart(), StrIdx+1),
- diag::warn_printf_format_string_contains_null_char,
- OrigFormatExpr->getSourceRange());
- return;
- }
-
- // Ordinary characters (not processing a format conversion).
- if (CurrentState == state_OrdChr) {
- if (Str[StrIdx] == '%') {
- CurrentState = state_Conversion;
- LastConversionIdx = StrIdx;
- }
- continue;
- }
-
- // Seen '%'. Now processing a format conversion.
- switch (Str[StrIdx]) {
- // Handle dynamic precision or width specifier.
- case '*': {
- ++numConversions;
-
- if (!HasVAListArg && numConversions > numDataArgs) {
- SourceLocation Loc = FExpr->getLocStart();
- Loc = PP.AdvanceToTokenCharacter(Loc, StrIdx+1);
-
- if (Str[StrIdx-1] == '.')
- Diag(Loc, diag::warn_printf_asterisk_precision_missing_arg,
- OrigFormatExpr->getSourceRange());
- else
- Diag(Loc, diag::warn_printf_asterisk_width_missing_arg,
- OrigFormatExpr->getSourceRange());
-
- // Don't do any more checking. We'll just emit spurious errors.
- return;
- }
-
- // Perform type checking on width/precision specifier.
- Expr *E = TheCall->getArg(format_idx+numConversions);
- if (const BuiltinType *BT = E->getType()->getAsBuiltinType())
- if (BT->getKind() == BuiltinType::Int)
- break;
-
- SourceLocation Loc =
- PP.AdvanceToTokenCharacter(FExpr->getLocStart(), StrIdx+1);
-
- if (Str[StrIdx-1] == '.')
- Diag(Loc, diag::warn_printf_asterisk_precision_wrong_type,
- E->getType().getAsString(), E->getSourceRange());
- else
- Diag(Loc, diag::warn_printf_asterisk_width_wrong_type,
- E->getType().getAsString(), E->getSourceRange());
-
- break;
- }
-
- // Characters which can terminate a format conversion
- // (e.g. "%d"). Characters that specify length modifiers or
- // other flags are handled by the default case below.
- //
- // FIXME: additional checks will go into the following cases.
- case 'i':
- case 'd':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'D':
- case 'O':
- case 'U':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- case 'a':
- case 'A':
- case 'c':
- case 'C':
- case 'S':
- case 's':
- case 'p':
- ++numConversions;
- CurrentState = state_OrdChr;
- break;
-
- // CHECK: Are we using "%n"? Issue a warning.
- case 'n': {
- ++numConversions;
- CurrentState = state_OrdChr;
- SourceLocation Loc = PP.AdvanceToTokenCharacter(FExpr->getLocStart(),
- LastConversionIdx+1);
-
- Diag(Loc, diag::warn_printf_write_back, OrigFormatExpr->getSourceRange());
- break;
- }
-
- // Handle "%@"
- case '@':
- // %@ is allowed in ObjC format strings only.
- if(ObjCFExpr != NULL)
- CurrentState = state_OrdChr;
- else {
- // Issue a warning: invalid format conversion.
- SourceLocation Loc = PP.AdvanceToTokenCharacter(FExpr->getLocStart(),
- LastConversionIdx+1);
-
- Diag(Loc, diag::warn_printf_invalid_conversion,
- std::string(Str+LastConversionIdx,
- Str+std::min(LastConversionIdx+2, StrLen)),
- OrigFormatExpr->getSourceRange());
- }
- ++numConversions;
- break;
-
- // Handle "%%"
- case '%':
- // Sanity check: Was the first "%" character the previous one?
- // If not, we will assume that we have a malformed format
- // conversion, and that the current "%" character is the start
- // of a new conversion.
- if (StrIdx - LastConversionIdx == 1)
- CurrentState = state_OrdChr;
- else {
- // Issue a warning: invalid format conversion.
- SourceLocation Loc = PP.AdvanceToTokenCharacter(FExpr->getLocStart(),
- LastConversionIdx+1);
-
- Diag(Loc, diag::warn_printf_invalid_conversion,
- std::string(Str+LastConversionIdx, Str+StrIdx),
- OrigFormatExpr->getSourceRange());
-
- // This conversion is broken. Advance to the next format
- // conversion.
- LastConversionIdx = StrIdx;
- ++numConversions;
- }
- break;
-
- default:
- // This case catches all other characters: flags, widths, etc.
- // We should eventually process those as well.
- break;
- }
- }
-
- if (CurrentState == state_Conversion) {
- // Issue a warning: invalid format conversion.
- SourceLocation Loc = PP.AdvanceToTokenCharacter(FExpr->getLocStart(),
- LastConversionIdx+1);
-
- Diag(Loc, diag::warn_printf_invalid_conversion,
- std::string(Str+LastConversionIdx,
- Str+std::min(LastConversionIdx+2, StrLen)),
- OrigFormatExpr->getSourceRange());
- return;
- }
-
- if (!HasVAListArg) {
- // CHECK: Does the number of format conversions exceed the number
- // of data arguments?
- if (numConversions > numDataArgs) {
- SourceLocation Loc = PP.AdvanceToTokenCharacter(FExpr->getLocStart(),
- LastConversionIdx);
-
- Diag(Loc, diag::warn_printf_insufficient_data_args,
- OrigFormatExpr->getSourceRange());
- }
- // CHECK: Does the number of data arguments exceed the number of
- // format conversions in the format string?
- else if (numConversions < numDataArgs)
- Diag(TheCall->getArg(format_idx+numConversions+1)->getLocStart(),
- diag::warn_printf_too_many_data_args,
- OrigFormatExpr->getSourceRange());
- }
-}
-
-//===--- CHECK: Return Address of Stack Variable --------------------------===//
-
-static DeclRefExpr* EvalVal(Expr *E);
-static DeclRefExpr* EvalAddr(Expr* E);
-
-/// CheckReturnStackAddr - Check if a return statement returns the address
-/// of a stack variable.
-void
-Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
- SourceLocation ReturnLoc) {
-
- // Perform checking for returned stack addresses.
- if (lhsType->isPointerType() || lhsType->isBlockPointerType()) {
- if (DeclRefExpr *DR = EvalAddr(RetValExp))
- Diag(DR->getLocStart(), diag::warn_ret_stack_addr,
- DR->getDecl()->getIdentifier()->getName(),
- RetValExp->getSourceRange());
-
- // Skip over implicit cast expressions when checking for block expressions.
- if (ImplicitCastExpr *IcExpr =
- dyn_cast_or_null<ImplicitCastExpr>(RetValExp))
- RetValExp = IcExpr->getSubExpr();
-
- if (BlockExpr *C = dyn_cast_or_null<BlockExpr>(RetValExp))
- Diag(C->getLocStart(), diag::err_ret_local_block,
- C->getSourceRange());
- }
- // Perform checking for stack values returned by reference.
- else if (lhsType->isReferenceType()) {
- // Check for an implicit cast to a reference.
- if (ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(RetValExp))
- if (DeclRefExpr *DR = EvalVal(I->getSubExpr()))
- Diag(DR->getLocStart(), diag::warn_ret_stack_ref,
- DR->getDecl()->getIdentifier()->getName(),
- RetValExp->getSourceRange());
- }
-}
-
-/// EvalAddr - EvalAddr and EvalVal are mutually recursive functions that
-/// check if the expression in a return statement evaluates to an address
-/// to a location on the stack. The recursion is used to traverse the
-/// AST of the return expression, with recursion backtracking when we
-/// encounter a subexpression that (1) clearly does not lead to the address
-/// of a stack variable or (2) is something we cannot determine leads to
-/// the address of a stack variable based on such local checking.
-///
-/// EvalAddr processes expressions that are pointers that are used as
-/// references (and not L-values). EvalVal handles all other values.
-/// At the base case of the recursion is a check for a DeclRefExpr* in
-/// the refers to a stack variable.
-///
-/// This implementation handles:
-///
-/// * pointer-to-pointer casts
-/// * implicit conversions from array references to pointers
-/// * taking the address of fields
-/// * arbitrary interplay between "&" and "*" operators
-/// * pointer arithmetic from an address of a stack variable
-/// * taking the address of an array element where the array is on the stack
-static DeclRefExpr* EvalAddr(Expr *E) {
- // We should only be called for evaluating pointer expressions.
- assert((E->getType()->isPointerType() ||
- E->getType()->isBlockPointerType() ||
- E->getType()->isObjCQualifiedIdType()) &&
- "EvalAddr only works on pointers");
-
- // Our "symbolic interpreter" is just a dispatch off the currently
- // viewed AST node. We then recursively traverse the AST by calling
- // EvalAddr and EvalVal appropriately.
- switch (E->getStmtClass()) {
- case Stmt::ParenExprClass:
- // Ignore parentheses.
- return EvalAddr(cast<ParenExpr>(E)->getSubExpr());
-
- case Stmt::UnaryOperatorClass: {
- // The only unary operator that make sense to handle here
- // is AddrOf. All others don't make sense as pointers.
- UnaryOperator *U = cast<UnaryOperator>(E);
-
- if (U->getOpcode() == UnaryOperator::AddrOf)
- return EvalVal(U->getSubExpr());
- else
- return NULL;
- }
-
- case Stmt::BinaryOperatorClass: {
- // Handle pointer arithmetic. All other binary operators are not valid
- // in this context.
- BinaryOperator *B = cast<BinaryOperator>(E);
- BinaryOperator::Opcode op = B->getOpcode();
-
- if (op != BinaryOperator::Add && op != BinaryOperator::Sub)
- return NULL;
-
- Expr *Base = B->getLHS();
-
- // Determine which argument is the real pointer base. It could be
- // the RHS argument instead of the LHS.
- if (!Base->getType()->isPointerType()) Base = B->getRHS();
-
- assert (Base->getType()->isPointerType());
- return EvalAddr(Base);
- }
-
- // For conditional operators we need to see if either the LHS or RHS are
- // valid DeclRefExpr*s. If one of them is valid, we return it.
- case Stmt::ConditionalOperatorClass: {
- ConditionalOperator *C = cast<ConditionalOperator>(E);
-
- // Handle the GNU extension for missing LHS.
- if (Expr *lhsExpr = C->getLHS())
- if (DeclRefExpr* LHS = EvalAddr(lhsExpr))
- return LHS;
-
- return EvalAddr(C->getRHS());
- }
-
- // For casts, we need to handle conversions from arrays to
- // pointer values, and pointer-to-pointer conversions.
- case Stmt::ExplicitCastExprClass:
- case Stmt::ImplicitCastExprClass: {
-
- Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
- QualType T = SubExpr->getType();
-
- if (SubExpr->getType()->isPointerType() ||
- SubExpr->getType()->isBlockPointerType() ||
- SubExpr->getType()->isObjCQualifiedIdType())
- return EvalAddr(SubExpr);
- else if (T->isArrayType())
- return EvalVal(SubExpr);
- else
- return 0;
- }
-
- // C++ casts. For dynamic casts, static casts, and const casts, we
- // are always converting from a pointer-to-pointer, so we just blow
- // through the cast. In the case the dynamic cast doesn't fail
- // (and return NULL), we take the conservative route and report cases
- // where we return the address of a stack variable. For Reinterpre
- case Stmt::CXXCastExprClass: {
- CXXCastExpr *C = cast<CXXCastExpr>(E);
-
- if (C->getOpcode() == CXXCastExpr::ReinterpretCast) {
- Expr *S = C->getSubExpr();
- if (S->getType()->isPointerType() || S->getType()->isBlockPointerType())
- return EvalAddr(S);
- else
- return NULL;
- }
- else
- return EvalAddr(C->getSubExpr());
- }
-
- // Everything else: we simply don't reason about them.
- default:
- return NULL;
- }
-}
-
-
-/// EvalVal - This function is complements EvalAddr in the mutual recursion.
-/// See the comments for EvalAddr for more details.
-static DeclRefExpr* EvalVal(Expr *E) {
-
- // We should only be called for evaluating non-pointer expressions, or
- // expressions with a pointer type that are not used as references but instead
- // are l-values (e.g., DeclRefExpr with a pointer type).
-
- // Our "symbolic interpreter" is just a dispatch off the currently
- // viewed AST node. We then recursively traverse the AST by calling
- // EvalAddr and EvalVal appropriately.
- switch (E->getStmtClass()) {
- case Stmt::DeclRefExprClass: {
- // DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking
- // at code that refers to a variable's name. We check if it has local
- // storage within the function, and if so, return the expression.
- DeclRefExpr *DR = cast<DeclRefExpr>(E);
-
- if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl()))
- if(V->hasLocalStorage()) return DR;
-
- return NULL;
- }
-
- case Stmt::ParenExprClass:
- // Ignore parentheses.
- return EvalVal(cast<ParenExpr>(E)->getSubExpr());
-
- case Stmt::UnaryOperatorClass: {
- // The only unary operator that make sense to handle here
- // is Deref. All others don't resolve to a "name." This includes
- // handling all sorts of rvalues passed to a unary operator.
- UnaryOperator *U = cast<UnaryOperator>(E);
-
- if (U->getOpcode() == UnaryOperator::Deref)
- return EvalAddr(U->getSubExpr());
-
- return NULL;
- }
-
- case Stmt::ArraySubscriptExprClass: {
- // Array subscripts are potential references to data on the stack. We
- // retrieve the DeclRefExpr* for the array variable if it indeed
- // has local storage.
- return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase());
- }
-
- case Stmt::ConditionalOperatorClass: {
- // For conditional operators we need to see if either the LHS or RHS are
- // non-NULL DeclRefExpr's. If one is non-NULL, we return it.
- ConditionalOperator *C = cast<ConditionalOperator>(E);
-
- // Handle the GNU extension for missing LHS.
- if (Expr *lhsExpr = C->getLHS())
- if (DeclRefExpr *LHS = EvalVal(lhsExpr))
- return LHS;
-
- return EvalVal(C->getRHS());
- }
-
- // Accesses to members are potential references to data on the stack.
- case Stmt::MemberExprClass: {
- MemberExpr *M = cast<MemberExpr>(E);
-
- // Check for indirect access. We only want direct field accesses.
- if (!M->isArrow())
- return EvalVal(M->getBase());
- else
- return NULL;
- }
-
- // Everything else: we simply don't reason about them.
- default:
- return NULL;
- }
-}
-
-//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
-
-/// Check for comparisons of floating point operands using != and ==.
-/// Issue a warning if these are no self-comparisons, as they are not likely
-/// to do what the programmer intended.
-void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) {
- bool EmitWarning = true;
-
- Expr* LeftExprSansParen = lex->IgnoreParens();
- Expr* RightExprSansParen = rex->IgnoreParens();
-
- // Special case: check for x == x (which is OK).
- // Do not emit warnings for such cases.
- if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
- if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
- if (DRL->getDecl() == DRR->getDecl())
- EmitWarning = false;
-
-
- // Special case: check for comparisons against literals that can be exactly
- // represented by APFloat. In such cases, do not emit a warning. This
- // is a heuristic: often comparison against such literals are used to
- // detect if a value in a variable has not changed. This clearly can
- // lead to false negatives.
- if (EmitWarning) {
- if (FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
- if (FLL->isExact())
- EmitWarning = false;
- }
- else
- if (FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen)){
- if (FLR->isExact())
- EmitWarning = false;
- }
- }
-
- // Check for comparisons with builtin types.
- if (EmitWarning)
- if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
- if (isCallBuiltin(CL))
- EmitWarning = false;
-
- if (EmitWarning)
- if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
- if (isCallBuiltin(CR))
- EmitWarning = false;
-
- // Emit the diagnostic.
- if (EmitWarning)
- Diag(loc, diag::warn_floatingpoint_eq,
- lex->getSourceRange(),rex->getSourceRange());
-}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
deleted file mode 100644
index 1b6ff878f57e..000000000000
--- a/clang/lib/Sema/SemaDecl.cpp
+++ /dev/null
@@ -1,2561 +0,0 @@
-//===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for declarations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/SourceManager.h"
-// FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's)
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "llvm/ADT/SmallSet.h"
-using namespace clang;
-
-Sema::TypeTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) {
- Decl *IIDecl = LookupDecl(&II, Decl::IDNS_Ordinary, S, false);
-
- if (IIDecl && (isa<TypedefDecl>(IIDecl) ||
- isa<ObjCInterfaceDecl>(IIDecl) ||
- isa<TagDecl>(IIDecl)))
- return IIDecl;
- return 0;
-}
-
-DeclContext *Sema::getDCParent(DeclContext *DC) {
- // If CurContext is a ObjC method, getParent() will return NULL.
- if (isa<ObjCMethodDecl>(DC))
- return Context.getTranslationUnitDecl();
-
- // A C++ inline method is parsed *after* the topmost class it was declared in
- // is fully parsed (it's "complete").
- // The parsing of a C++ inline method happens at the declaration context of
- // the topmost (non-nested) class it is declared in.
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
- assert(isa<CXXRecordDecl>(MD->getParent()) && "C++ method not in Record.");
- DC = MD->getParent();
- while (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC->getParent()))
- DC = RD;
-
- // Return the declaration context of the topmost class the inline method is
- // declared in.
- return DC;
- }
-
- return DC->getParent();
-}
-
-void Sema::PushDeclContext(DeclContext *DC) {
- assert(getDCParent(DC) == CurContext &&
- "The next DeclContext should be directly contained in the current one.");
- CurContext = DC;
-}
-
-void Sema::PopDeclContext() {
- assert(CurContext && "DeclContext imbalance!");
- CurContext = getDCParent(CurContext);
-}
-
-/// Add this decl to the scope shadowed decl chains.
-void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
- S->AddDecl(D);
-
- // C++ [basic.scope]p4:
- // -- exactly one declaration shall declare a class name or
- // enumeration name that is not a typedef name and the other
- // declarations shall all refer to the same object or
- // enumerator, or all refer to functions and function templates;
- // in this case the class name or enumeration name is hidden.
- if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- // We are pushing the name of a tag (enum or class).
- IdentifierResolver::iterator
- I = IdResolver.begin(TD->getIdentifier(),
- TD->getDeclContext(), false/*LookInParentCtx*/);
- if (I != IdResolver.end() && isDeclInScope(*I, TD->getDeclContext(), S)) {
- // There is already a declaration with the same name in the same
- // scope. It must be found before we find the new declaration,
- // so swap the order on the shadowed declaration chain.
-
- IdResolver.AddShadowedDecl(TD, *I);
- return;
- }
- }
- IdResolver.AddDecl(D);
-}
-
-void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
- if (S->decl_empty()) return;
- assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
-
- for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
- Decl *TmpD = static_cast<Decl*>(*I);
- assert(TmpD && "This decl didn't get pushed??");
-
- if (isa<CXXFieldDecl>(TmpD)) continue;
-
- assert(isa<ScopedDecl>(TmpD) && "Decl isn't ScopedDecl?");
- ScopedDecl *D = cast<ScopedDecl>(TmpD);
-
- IdentifierInfo *II = D->getIdentifier();
- if (!II) continue;
-
- // We only want to remove the decls from the identifier decl chains for
- // local scopes, when inside a function/method.
- if (S->getFnParent() != 0)
- IdResolver.RemoveDecl(D);
-
- // Chain this decl to the containing DeclContext.
- D->setNext(CurContext->getDeclChain());
- CurContext->setDeclChain(D);
- }
-}
-
-/// getObjCInterfaceDecl - Look up a for a class declaration in the scope.
-/// return 0 if one not found.
-ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
- // The third "scope" argument is 0 since we aren't enabling lazy built-in
- // creation from this context.
- Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0, false);
-
- return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
-}
-
-/// LookupDecl - Look up the inner-most declaration in the specified
-/// namespace.
-Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI,
- Scope *S, bool enableLazyBuiltinCreation) {
- if (II == 0) return 0;
- unsigned NS = NSI;
- if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary))
- NS |= Decl::IDNS_Tag;
-
- // Scan up the scope chain looking for a decl that matches this identifier
- // that is in the appropriate namespace. This search should not take long, as
- // shadowing of names is uncommon, and deep shadowing is extremely uncommon.
- for (IdentifierResolver::iterator
- I = IdResolver.begin(II, CurContext), E = IdResolver.end(); I != E; ++I)
- if ((*I)->getIdentifierNamespace() & NS)
- return *I;
-
- // If we didn't find a use of this identifier, and if the identifier
- // corresponds to a compiler builtin, create the decl object for the builtin
- // now, injecting it into translation unit scope, and return it.
- if (NS & Decl::IDNS_Ordinary) {
- if (enableLazyBuiltinCreation) {
- // If this is a builtin on this (or all) targets, create the decl.
- if (unsigned BuiltinID = II->getBuiltinID())
- return LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, S);
- }
- if (getLangOptions().ObjC1) {
- // @interface and @compatibility_alias introduce typedef-like names.
- // Unlike typedef's, they can only be introduced at file-scope (and are
- // therefore not scoped decls). They can, however, be shadowed by
- // other names in IDNS_Ordinary.
- ObjCInterfaceDeclsTy::iterator IDI = ObjCInterfaceDecls.find(II);
- if (IDI != ObjCInterfaceDecls.end())
- return IDI->second;
- ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
- if (I != ObjCAliasDecls.end())
- return I->second->getClassInterface();
- }
- }
- return 0;
-}
-
-void Sema::InitBuiltinVaListType() {
- if (!Context.getBuiltinVaListType().isNull())
- return;
-
- IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
- Decl *VaDecl = LookupDecl(VaIdent, Decl::IDNS_Ordinary, TUScope);
- TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
- Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
-}
-
-/// LazilyCreateBuiltin - The specified Builtin-ID was first used at file scope.
-/// lazily create a decl for it.
-ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
- Scope *S) {
- Builtin::ID BID = (Builtin::ID)bid;
-
- if (Context.BuiltinInfo.hasVAListUse(BID))
- InitBuiltinVaListType();
-
- QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
- FunctionDecl *New = FunctionDecl::Create(Context,
- Context.getTranslationUnitDecl(),
- SourceLocation(), II, R,
- FunctionDecl::Extern, false, 0);
-
- // Create Decl objects for each parameter, adding them to the
- // FunctionDecl.
- if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(R)) {
- llvm::SmallVector<ParmVarDecl*, 16> Params;
- for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
- Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
- FT->getArgType(i), VarDecl::None, 0,
- 0));
- New->setParams(&Params[0], Params.size());
- }
-
-
-
- // TUScope is the translation-unit scope to insert this function into.
- PushOnScopeChains(New, TUScope);
- return New;
-}
-
-/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
-/// and scope as a previous declaration 'Old'. Figure out how to resolve this
-/// situation, merging decls or emitting diagnostics as appropriate.
-///
-TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
- // Allow multiple definitions for ObjC built-in typedefs.
- // FIXME: Verify the underlying types are equivalent!
- if (getLangOptions().ObjC1) {
- const IdentifierInfo *typeIdent = New->getIdentifier();
- if (typeIdent == Ident_id) {
- Context.setObjCIdType(New);
- return New;
- } else if (typeIdent == Ident_Class) {
- Context.setObjCClassType(New);
- return New;
- } else if (typeIdent == Ident_SEL) {
- Context.setObjCSelType(New);
- return New;
- } else if (typeIdent == Ident_Protocol) {
- Context.setObjCProtoType(New->getUnderlyingType());
- return New;
- }
- // Fall through - the typedef name was not a builtin type.
- }
- // Verify the old decl was also a typedef.
- TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
- if (!Old) {
- Diag(New->getLocation(), diag::err_redefinition_different_kind,
- New->getName());
- Diag(OldD->getLocation(), diag::err_previous_definition);
- return New;
- }
-
- // If the typedef types are not identical, reject them in all languages and
- // with any extensions enabled.
- if (Old->getUnderlyingType() != New->getUnderlyingType() &&
- Context.getCanonicalType(Old->getUnderlyingType()) !=
- Context.getCanonicalType(New->getUnderlyingType())) {
- Diag(New->getLocation(), diag::err_redefinition_different_typedef,
- New->getUnderlyingType().getAsString(),
- Old->getUnderlyingType().getAsString());
- Diag(Old->getLocation(), diag::err_previous_definition);
- return Old;
- }
-
- if (getLangOptions().Microsoft) return New;
-
- // Redeclaration of a type is a constraint violation (6.7.2.3p1).
- // Apparently GCC, Intel, and Sun all silently ignore the redeclaration if
- // *either* declaration is in a system header. The code below implements
- // this adhoc compatibility rule. FIXME: The following code will not
- // work properly when compiling ".i" files (containing preprocessed output).
- if (PP.getDiagnostics().getSuppressSystemWarnings()) {
- SourceManager &SrcMgr = Context.getSourceManager();
- if (SrcMgr.isInSystemHeader(Old->getLocation()))
- return New;
- if (SrcMgr.isInSystemHeader(New->getLocation()))
- return New;
- }
-
- Diag(New->getLocation(), diag::err_redefinition, New->getName());
- Diag(Old->getLocation(), diag::err_previous_definition);
- return New;
-}
-
-/// DeclhasAttr - returns true if decl Declaration already has the target
-/// attribute.
-static bool DeclHasAttr(const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
- if (attr->getKind() == target->getKind())
- return true;
-
- return false;
-}
-
-/// MergeAttributes - append attributes from the Old decl to the New one.
-static void MergeAttributes(Decl *New, Decl *Old) {
- Attr *attr = const_cast<Attr*>(Old->getAttrs()), *tmp;
-
- while (attr) {
- tmp = attr;
- attr = attr->getNext();
-
- if (!DeclHasAttr(New, tmp)) {
- New->addAttr(tmp);
- } else {
- tmp->setNext(0);
- delete(tmp);
- }
- }
-
- Old->invalidateAttrs();
-}
-
-/// MergeFunctionDecl - We just parsed a function 'New' from
-/// declarator D which has the same name and scope as a previous
-/// declaration 'Old'. Figure out how to resolve this situation,
-/// merging decls or emitting diagnostics as appropriate.
-/// Redeclaration will be set true if thisNew is a redeclaration OldD.
-FunctionDecl *
-Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
- Redeclaration = false;
- // Verify the old decl was also a function.
- FunctionDecl *Old = dyn_cast<FunctionDecl>(OldD);
- if (!Old) {
- Diag(New->getLocation(), diag::err_redefinition_different_kind,
- New->getName());
- Diag(OldD->getLocation(), diag::err_previous_definition);
- return New;
- }
-
- QualType OldQType = Context.getCanonicalType(Old->getType());
- QualType NewQType = Context.getCanonicalType(New->getType());
-
- // C++ [dcl.fct]p3:
- // All declarations for a function shall agree exactly in both the
- // return type and the parameter-type-list.
- if (getLangOptions().CPlusPlus && OldQType == NewQType) {
- MergeAttributes(New, Old);
- Redeclaration = true;
- return MergeCXXFunctionDecl(New, Old);
- }
-
- // C: Function types need to be compatible, not identical. This handles
- // duplicate function decls like "void f(int); void f(enum X);" properly.
- if (!getLangOptions().CPlusPlus &&
- Context.typesAreCompatible(OldQType, NewQType)) {
- MergeAttributes(New, Old);
- Redeclaration = true;
- return New;
- }
-
- // A function that has already been declared has been redeclared or defined
- // with a different type- show appropriate diagnostic
- diag::kind PrevDiag;
- if (Old->isThisDeclarationADefinition())
- PrevDiag = diag::err_previous_definition;
- else if (Old->isImplicit())
- PrevDiag = diag::err_previous_implicit_declaration;
- else
- PrevDiag = diag::err_previous_declaration;
-
- // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
- // TODO: This is totally simplistic. It should handle merging functions
- // together etc, merging extern int X; int X; ...
- Diag(New->getLocation(), diag::err_conflicting_types, New->getName());
- Diag(Old->getLocation(), PrevDiag);
- return New;
-}
-
-/// Predicate for C "tentative" external object definitions (C99 6.9.2).
-static bool isTentativeDefinition(VarDecl *VD) {
- if (VD->isFileVarDecl())
- return (!VD->getInit() &&
- (VD->getStorageClass() == VarDecl::None ||
- VD->getStorageClass() == VarDecl::Static));
- return false;
-}
-
-/// CheckForFileScopedRedefinitions - Make sure we forgo redefinition errors
-/// when dealing with C "tentative" external object definitions (C99 6.9.2).
-void Sema::CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD) {
- bool VDIsTentative = isTentativeDefinition(VD);
- bool VDIsIncompleteArray = VD->getType()->isIncompleteArrayType();
-
- for (IdentifierResolver::iterator
- I = IdResolver.begin(VD->getIdentifier(),
- VD->getDeclContext(), false/*LookInParentCtx*/),
- E = IdResolver.end(); I != E; ++I) {
- if (*I != VD && isDeclInScope(*I, VD->getDeclContext(), S)) {
- VarDecl *OldDecl = dyn_cast<VarDecl>(*I);
-
- // Handle the following case:
- // int a[10];
- // int a[]; - the code below makes sure we set the correct type.
- // int a[11]; - this is an error, size isn't 10.
- if (OldDecl && VDIsTentative && VDIsIncompleteArray &&
- OldDecl->getType()->isConstantArrayType())
- VD->setType(OldDecl->getType());
-
- // Check for "tentative" definitions. We can't accomplish this in
- // MergeVarDecl since the initializer hasn't been attached.
- if (!OldDecl || isTentativeDefinition(OldDecl) || VDIsTentative)
- continue;
-
- // Handle __private_extern__ just like extern.
- if (OldDecl->getStorageClass() != VarDecl::Extern &&
- OldDecl->getStorageClass() != VarDecl::PrivateExtern &&
- VD->getStorageClass() != VarDecl::Extern &&
- VD->getStorageClass() != VarDecl::PrivateExtern) {
- Diag(VD->getLocation(), diag::err_redefinition, VD->getName());
- Diag(OldDecl->getLocation(), diag::err_previous_definition);
- }
- }
- }
-}
-
-/// MergeVarDecl - We just parsed a variable 'New' which has the same name
-/// and scope as a previous declaration 'Old'. Figure out how to resolve this
-/// situation, merging decls or emitting diagnostics as appropriate.
-///
-/// Tentative definition rules (C99 6.9.2p2) are checked by
-/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
-/// definitions here, since the initializer hasn't been attached.
-///
-VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
- // Verify the old decl was also a variable.
- VarDecl *Old = dyn_cast<VarDecl>(OldD);
- if (!Old) {
- Diag(New->getLocation(), diag::err_redefinition_different_kind,
- New->getName());
- Diag(OldD->getLocation(), diag::err_previous_definition);
- return New;
- }
-
- MergeAttributes(New, Old);
-
- // Verify the types match.
- QualType OldCType = Context.getCanonicalType(Old->getType());
- QualType NewCType = Context.getCanonicalType(New->getType());
- if (OldCType != NewCType && !Context.typesAreCompatible(OldCType, NewCType)) {
- Diag(New->getLocation(), diag::err_redefinition, New->getName());
- Diag(Old->getLocation(), diag::err_previous_definition);
- return New;
- }
- // C99 6.2.2p4: Check if we have a static decl followed by a non-static.
- if (New->getStorageClass() == VarDecl::Static &&
- (Old->getStorageClass() == VarDecl::None ||
- Old->getStorageClass() == VarDecl::Extern)) {
- Diag(New->getLocation(), diag::err_static_non_static, New->getName());
- Diag(Old->getLocation(), diag::err_previous_definition);
- return New;
- }
- // C99 6.2.2p4: Check if we have a non-static decl followed by a static.
- if (New->getStorageClass() != VarDecl::Static &&
- Old->getStorageClass() == VarDecl::Static) {
- Diag(New->getLocation(), diag::err_non_static_static, New->getName());
- Diag(Old->getLocation(), diag::err_previous_definition);
- return New;
- }
- // Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
- if (New->getStorageClass() != VarDecl::Extern && !New->isFileVarDecl()) {
- Diag(New->getLocation(), diag::err_redefinition, New->getName());
- Diag(Old->getLocation(), diag::err_previous_definition);
- }
- return New;
-}
-
-/// CheckParmsForFunctionDef - Check that the parameters of the given
-/// function are appropriate for the definition of a function. This
-/// takes care of any checks that cannot be performed on the
-/// declaration itself, e.g., that the types of each of the function
-/// parameters are complete.
-bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
- bool HasInvalidParm = false;
- for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
-
- // C99 6.7.5.3p4: the parameters in a parameter type list in a
- // function declarator that is part of a function definition of
- // that function shall not have incomplete type.
- if (Param->getType()->isIncompleteType() &&
- !Param->isInvalidDecl()) {
- Diag(Param->getLocation(), diag::err_typecheck_decl_incomplete_type,
- Param->getType().getAsString());
- Param->setInvalidDecl();
- HasInvalidParm = true;
- }
- }
-
- return HasInvalidParm;
-}
-
-/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
-/// no declarator (e.g. "struct foo;") is parsed.
-Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
- // TODO: emit error on 'int;' or 'const enum foo;'.
- // TODO: emit error on 'typedef int;'
- // if (!DS.isMissingDeclaratorOk()) Diag(...);
-
- return dyn_cast_or_null<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
-}
-
-bool Sema::CheckSingleInitializer(Expr *&Init, QualType DeclType) {
- // Get the type before calling CheckSingleAssignmentConstraints(), since
- // it can promote the expression.
- QualType InitType = Init->getType();
-
- AssignConvertType ConvTy = CheckSingleAssignmentConstraints(DeclType, Init);
- return DiagnoseAssignmentResult(ConvTy, Init->getLocStart(), DeclType,
- InitType, Init, "initializing");
-}
-
-bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) {
- const ArrayType *AT = Context.getAsArrayType(DeclT);
-
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
- // C99 6.7.8p14. We have an array of character type with unknown size
- // being initialized to a string literal.
- llvm::APSInt ConstVal(32);
- ConstVal = strLiteral->getByteLength() + 1;
- // Return a new array type (C99 6.7.8p22).
- DeclT = Context.getConstantArrayType(IAT->getElementType(), ConstVal,
- ArrayType::Normal, 0);
- } else {
- const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
- // C99 6.7.8p14. We have an array of character type with known size.
- // FIXME: Avoid truncation for 64-bit length strings.
- if (strLiteral->getByteLength() > (unsigned)CAT->getSize().getZExtValue())
- Diag(strLiteral->getSourceRange().getBegin(),
- diag::warn_initializer_string_for_char_array_too_long,
- strLiteral->getSourceRange());
- }
- // Set type from "char *" to "constant array of char".
- strLiteral->setType(DeclT);
- // For now, we always return false (meaning success).
- return false;
-}
-
-StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) {
- const ArrayType *AT = Context.getAsArrayType(DeclType);
- if (AT && AT->getElementType()->isCharType()) {
- return dyn_cast<StringLiteral>(Init);
- }
- return 0;
-}
-
-bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {
- // C99 6.7.8p3: The type of the entity to be initialized shall be an array
- // of unknown size ("[]") or an object type that is not a variable array type.
- if (const VariableArrayType *VAT = Context.getAsVariableArrayType(DeclType))
- return Diag(VAT->getSizeExpr()->getLocStart(),
- diag::err_variable_object_no_init,
- VAT->getSizeExpr()->getSourceRange());
-
- InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
- if (!InitList) {
- // FIXME: Handle wide strings
- if (StringLiteral *strLiteral = IsStringLiteralInit(Init, DeclType))
- return CheckStringLiteralInit(strLiteral, DeclType);
-
- // C99 6.7.8p16.
- if (DeclType->isArrayType())
- return Diag(Init->getLocStart(),
- diag::err_array_init_list_required,
- Init->getSourceRange());
-
- return CheckSingleInitializer(Init, DeclType);
- }
-
- InitListChecker CheckInitList(this, InitList, DeclType);
- return CheckInitList.HadError();
-}
-
-Sema::DeclTy *
-Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
- ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
- IdentifierInfo *II = D.getIdentifier();
-
- // All of these full declarators require an identifier. If it doesn't have
- // one, the ParsedFreeStandingDeclSpec action should be used.
- if (II == 0) {
- Diag(D.getDeclSpec().getSourceRange().getBegin(),
- diag::err_declarator_need_ident,
- D.getDeclSpec().getSourceRange(), D.getSourceRange());
- return 0;
- }
-
- // The scope passed in may not be a decl scope. Zip up the scope tree until
- // we find one that is.
- while ((S->getFlags() & Scope::DeclScope) == 0)
- S = S->getParent();
-
- // See if this is a redefinition of a variable in the same scope.
- Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S);
- ScopedDecl *New;
- bool InvalidDecl = false;
-
- // In C++, the previous declaration we find might be a tag type
- // (class or enum). In this case, the new declaration will hide the
- // tag type.
- if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
- PrevDecl = 0;
-
- QualType R = GetTypeForDeclarator(D, S);
- assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
-
- if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
- // Check that there are no default arguments (C++ only).
- if (getLangOptions().CPlusPlus)
- CheckExtraCXXDefaultArguments(D);
-
- TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, LastDeclarator);
- if (!NewTD) return 0;
-
- // Handle attributes prior to checking for duplicates in MergeVarDecl
- ProcessDeclAttributes(NewTD, D);
- // Merge the decl with the existing one if appropriate. If the decl is
- // in an outer scope, it isn't the same thing.
- if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)) {
- NewTD = MergeTypeDefDecl(NewTD, PrevDecl);
- if (NewTD == 0) return 0;
- }
- New = NewTD;
- if (S->getFnParent() == 0) {
- // C99 6.7.7p2: If a typedef name specifies a variably modified type
- // then it shall have block scope.
- if (NewTD->getUnderlyingType()->isVariablyModifiedType()) {
- // FIXME: Diagnostic needs to be fixed.
- Diag(D.getIdentifierLoc(), diag::err_typecheck_illegal_vla);
- InvalidDecl = true;
- }
- }
- } else if (R.getTypePtr()->isFunctionType()) {
- FunctionDecl::StorageClass SC = FunctionDecl::None;
- switch (D.getDeclSpec().getStorageClassSpec()) {
- default: assert(0 && "Unknown storage class!");
- case DeclSpec::SCS_auto:
- case DeclSpec::SCS_register:
- Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_func,
- R.getAsString());
- InvalidDecl = true;
- break;
- case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
- case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break;
- case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
- case DeclSpec::SCS_private_extern: SC = FunctionDecl::PrivateExtern;break;
- }
-
- bool isInline = D.getDeclSpec().isInlineSpecified();
- FunctionDecl *NewFD;
- if (D.getContext() == Declarator::MemberContext) {
- // This is a C++ method declaration.
- NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
- D.getIdentifierLoc(), II, R,
- (SC == FunctionDecl::Static), isInline,
- LastDeclarator);
- } else {
- NewFD = FunctionDecl::Create(Context, CurContext,
- D.getIdentifierLoc(),
- II, R, SC, isInline, LastDeclarator,
- // FIXME: Move to DeclGroup...
- D.getDeclSpec().getSourceRange().getBegin());
- }
- // Handle attributes.
- ProcessDeclAttributes(NewFD, D);
-
- // Handle GNU asm-label extension (encoded as an attribute).
- if (Expr *E = (Expr*) D.getAsmLabel()) {
- // The parser guarantees this is a string.
- StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
- SE->getByteLength())));
- }
-
- // Copy the parameter declarations from the declarator D to
- // the function declaration NewFD, if they are available.
- if (D.getNumTypeObjects() > 0) {
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
-
- // Create Decl objects for each parameter, adding them to the
- // FunctionDecl.
- llvm::SmallVector<ParmVarDecl*, 16> Params;
-
- // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs
- // function that takes no arguments, not a function that takes a
- // single void argument.
- // We let through "const void" here because Sema::GetTypeForDeclarator
- // already checks for that case.
- if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
- FTI.ArgInfo[0].Param &&
- ((ParmVarDecl*)FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
- // empty arg list, don't push any params.
- ParmVarDecl *Param = (ParmVarDecl*)FTI.ArgInfo[0].Param;
-
- // In C++, the empty parameter-type-list must be spelled "void"; a
- // typedef of void is not permitted.
- if (getLangOptions().CPlusPlus &&
- Param->getType().getUnqualifiedType() != Context.VoidTy) {
- Diag(Param->getLocation(), diag::ext_param_typedef_of_void);
- }
-
- } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
- for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
- Params.push_back((ParmVarDecl *)FTI.ArgInfo[i].Param);
- }
-
- NewFD->setParams(&Params[0], Params.size());
- }
-
- // Merge the decl with the existing one if appropriate. Since C functions
- // are in a flat namespace, make sure we consider decls in outer scopes.
- if (PrevDecl &&
- (!getLangOptions().CPlusPlus||isDeclInScope(PrevDecl, CurContext, S))) {
- bool Redeclaration = false;
- NewFD = MergeFunctionDecl(NewFD, PrevDecl, Redeclaration);
- if (NewFD == 0) return 0;
- if (Redeclaration) {
- NewFD->setPreviousDeclaration(cast<FunctionDecl>(PrevDecl));
- }
- }
- New = NewFD;
-
- // In C++, check default arguments now that we have merged decls.
- if (getLangOptions().CPlusPlus)
- CheckCXXDefaultArguments(NewFD);
- } else {
- // Check that there are no default arguments (C++ only).
- if (getLangOptions().CPlusPlus)
- CheckExtraCXXDefaultArguments(D);
-
- if (R.getTypePtr()->isObjCInterfaceType()) {
- Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object,
- D.getIdentifier()->getName());
- InvalidDecl = true;
- }
-
- VarDecl *NewVD;
- VarDecl::StorageClass SC;
- switch (D.getDeclSpec().getStorageClassSpec()) {
- default: assert(0 && "Unknown storage class!");
- case DeclSpec::SCS_unspecified: SC = VarDecl::None; break;
- case DeclSpec::SCS_extern: SC = VarDecl::Extern; break;
- case DeclSpec::SCS_static: SC = VarDecl::Static; break;
- case DeclSpec::SCS_auto: SC = VarDecl::Auto; break;
- case DeclSpec::SCS_register: SC = VarDecl::Register; break;
- case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
- }
- if (D.getContext() == Declarator::MemberContext) {
- assert(SC == VarDecl::Static && "Invalid storage class for member!");
- // This is a static data member for a C++ class.
- NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
- D.getIdentifierLoc(), II,
- R, LastDeclarator);
- } else {
- bool ThreadSpecified = D.getDeclSpec().isThreadSpecified();
- if (S->getFnParent() == 0) {
- // C99 6.9p2: The storage-class specifiers auto and register shall not
- // appear in the declaration specifiers in an external declaration.
- if (SC == VarDecl::Auto || SC == VarDecl::Register) {
- Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope,
- R.getAsString());
- InvalidDecl = true;
- }
- }
- NewVD = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
- II, R, SC, LastDeclarator,
- // FIXME: Move to DeclGroup...
- D.getDeclSpec().getSourceRange().getBegin());
- NewVD->setThreadSpecified(ThreadSpecified);
- }
- // Handle attributes prior to checking for duplicates in MergeVarDecl
- ProcessDeclAttributes(NewVD, D);
-
- // Handle GNU asm-label extension (encoded as an attribute).
- if (Expr *E = (Expr*) D.getAsmLabel()) {
- // The parser guarantees this is a string.
- StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
- SE->getByteLength())));
- }
-
- // Emit an error if an address space was applied to decl with local storage.
- // This includes arrays of objects with address space qualifiers, but not
- // automatic variables that point to other address spaces.
- // ISO/IEC TR 18037 S5.1.2
- if (NewVD->hasLocalStorage() && (NewVD->getType().getAddressSpace() != 0)) {
- Diag(D.getIdentifierLoc(), diag::err_as_qualified_auto_decl);
- InvalidDecl = true;
- }
- // Merge the decl with the existing one if appropriate. If the decl is
- // in an outer scope, it isn't the same thing.
- if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)) {
- NewVD = MergeVarDecl(NewVD, PrevDecl);
- if (NewVD == 0) return 0;
- }
- New = NewVD;
- }
-
- // If this has an identifier, add it to the scope stack.
- if (II)
- PushOnScopeChains(New, S);
- // If any semantic error occurred, mark the decl as invalid.
- if (D.getInvalidType() || InvalidDecl)
- New->setInvalidDecl();
-
- return New;
-}
-
-bool Sema::CheckAddressConstantExpressionLValue(const Expr* Init) {
- switch (Init->getStmtClass()) {
- default:
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- case Expr::ParenExprClass: {
- const ParenExpr* PE = cast<ParenExpr>(Init);
- return CheckAddressConstantExpressionLValue(PE->getSubExpr());
- }
- case Expr::CompoundLiteralExprClass:
- return cast<CompoundLiteralExpr>(Init)->isFileScope();
- case Expr::DeclRefExprClass: {
- const Decl *D = cast<DeclRefExpr>(Init)->getDecl();
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (VD->hasGlobalStorage())
- return false;
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- if (isa<FunctionDecl>(D))
- return false;
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::MemberExprClass: {
- const MemberExpr *M = cast<MemberExpr>(Init);
- if (M->isArrow())
- return CheckAddressConstantExpression(M->getBase());
- return CheckAddressConstantExpressionLValue(M->getBase());
- }
- case Expr::ArraySubscriptExprClass: {
- // FIXME: Should we pedwarn for "x[0+0]" (where x is a pointer)?
- const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(Init);
- return CheckAddressConstantExpression(ASE->getBase()) ||
- CheckArithmeticConstantExpression(ASE->getIdx());
- }
- case Expr::StringLiteralClass:
- case Expr::PredefinedExprClass:
- return false;
- case Expr::UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(Init);
-
- // C99 6.6p9
- if (Exp->getOpcode() == UnaryOperator::Deref)
- return CheckAddressConstantExpression(Exp->getSubExpr());
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- }
-}
-
-bool Sema::CheckAddressConstantExpression(const Expr* Init) {
- switch (Init->getStmtClass()) {
- default:
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- case Expr::ParenExprClass:
- return CheckAddressConstantExpression(cast<ParenExpr>(Init)->getSubExpr());
- case Expr::StringLiteralClass:
- case Expr::ObjCStringLiteralClass:
- return false;
- case Expr::CallExprClass:
- // __builtin___CFStringMakeConstantString is a valid constant l-value.
- if (cast<CallExpr>(Init)->isBuiltinCall() ==
- Builtin::BI__builtin___CFStringMakeConstantString)
- return false;
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
-
- case Expr::UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(Init);
-
- // C99 6.6p9
- if (Exp->getOpcode() == UnaryOperator::AddrOf)
- return CheckAddressConstantExpressionLValue(Exp->getSubExpr());
-
- if (Exp->getOpcode() == UnaryOperator::Extension)
- return CheckAddressConstantExpression(Exp->getSubExpr());
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::BinaryOperatorClass: {
- // FIXME: Should we pedwarn for expressions like "a + 1 + 2"?
- const BinaryOperator *Exp = cast<BinaryOperator>(Init);
-
- Expr *PExp = Exp->getLHS();
- Expr *IExp = Exp->getRHS();
- if (IExp->getType()->isPointerType())
- std::swap(PExp, IExp);
-
- // FIXME: Should we pedwarn if IExp isn't an integer constant expression?
- return CheckAddressConstantExpression(PExp) ||
- CheckArithmeticConstantExpression(IExp);
- }
- case Expr::ImplicitCastExprClass:
- case Expr::ExplicitCastExprClass: {
- const Expr* SubExpr = cast<CastExpr>(Init)->getSubExpr();
- if (Init->getStmtClass() == Expr::ImplicitCastExprClass) {
- // Check for implicit promotion
- if (SubExpr->getType()->isFunctionType() ||
- SubExpr->getType()->isArrayType())
- return CheckAddressConstantExpressionLValue(SubExpr);
- }
-
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType())
- return CheckAddressConstantExpression(SubExpr);
-
- if (SubExpr->getType()->isIntegralType()) {
- // Check for the special-case of a pointer->int->pointer cast;
- // this isn't standard, but some code requires it. See
- // PR2720 for an example.
- if (const CastExpr* SubCast = dyn_cast<CastExpr>(SubExpr)) {
- if (SubCast->getSubExpr()->getType()->isPointerType()) {
- unsigned IntWidth = Context.getIntWidth(SubCast->getType());
- unsigned PointerWidth = Context.getTypeSize(Context.VoidPtrTy);
- if (IntWidth >= PointerWidth) {
- return CheckAddressConstantExpression(SubCast->getSubExpr());
- }
- }
- }
- }
- if (SubExpr->getType()->isArithmeticType()) {
- return CheckArithmeticConstantExpression(SubExpr);
- }
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::ConditionalOperatorClass: {
- // FIXME: Should we pedwarn here?
- const ConditionalOperator *Exp = cast<ConditionalOperator>(Init);
- if (!Exp->getCond()->getType()->isArithmeticType()) {
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- if (CheckArithmeticConstantExpression(Exp->getCond()))
- return true;
- if (Exp->getLHS() &&
- CheckAddressConstantExpression(Exp->getLHS()))
- return true;
- return CheckAddressConstantExpression(Exp->getRHS());
- }
- case Expr::AddrLabelExprClass:
- return false;
- }
-}
-
-static const Expr* FindExpressionBaseAddress(const Expr* E);
-
-static const Expr* FindExpressionBaseAddressLValue(const Expr* E) {
- switch (E->getStmtClass()) {
- default:
- return E;
- case Expr::ParenExprClass: {
- const ParenExpr* PE = cast<ParenExpr>(E);
- return FindExpressionBaseAddressLValue(PE->getSubExpr());
- }
- case Expr::MemberExprClass: {
- const MemberExpr *M = cast<MemberExpr>(E);
- if (M->isArrow())
- return FindExpressionBaseAddress(M->getBase());
- return FindExpressionBaseAddressLValue(M->getBase());
- }
- case Expr::ArraySubscriptExprClass: {
- const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(E);
- return FindExpressionBaseAddress(ASE->getBase());
- }
- case Expr::UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(E);
-
- if (Exp->getOpcode() == UnaryOperator::Deref)
- return FindExpressionBaseAddress(Exp->getSubExpr());
-
- return E;
- }
- }
-}
-
-static const Expr* FindExpressionBaseAddress(const Expr* E) {
- switch (E->getStmtClass()) {
- default:
- return E;
- case Expr::ParenExprClass: {
- const ParenExpr* PE = cast<ParenExpr>(E);
- return FindExpressionBaseAddress(PE->getSubExpr());
- }
- case Expr::UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(E);
-
- // C99 6.6p9
- if (Exp->getOpcode() == UnaryOperator::AddrOf)
- return FindExpressionBaseAddressLValue(Exp->getSubExpr());
-
- if (Exp->getOpcode() == UnaryOperator::Extension)
- return FindExpressionBaseAddress(Exp->getSubExpr());
-
- return E;
- }
- case Expr::BinaryOperatorClass: {
- const BinaryOperator *Exp = cast<BinaryOperator>(E);
-
- Expr *PExp = Exp->getLHS();
- Expr *IExp = Exp->getRHS();
- if (IExp->getType()->isPointerType())
- std::swap(PExp, IExp);
-
- return FindExpressionBaseAddress(PExp);
- }
- case Expr::ImplicitCastExprClass: {
- const Expr* SubExpr = cast<ImplicitCastExpr>(E)->getSubExpr();
-
- // Check for implicit promotion
- if (SubExpr->getType()->isFunctionType() ||
- SubExpr->getType()->isArrayType())
- return FindExpressionBaseAddressLValue(SubExpr);
-
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType())
- return FindExpressionBaseAddress(SubExpr);
-
- // We assume that we have an arithmetic expression here;
- // if we don't, we'll figure it out later
- return 0;
- }
- case Expr::ExplicitCastExprClass: {
- const Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
-
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType())
- return FindExpressionBaseAddress(SubExpr);
-
- // We assume that we have an arithmetic expression here;
- // if we don't, we'll figure it out later
- return 0;
- }
- }
-}
-
-bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
- switch (Init->getStmtClass()) {
- default:
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- case Expr::ParenExprClass: {
- const ParenExpr* PE = cast<ParenExpr>(Init);
- return CheckArithmeticConstantExpression(PE->getSubExpr());
- }
- case Expr::FloatingLiteralClass:
- case Expr::IntegerLiteralClass:
- case Expr::CharacterLiteralClass:
- case Expr::ImaginaryLiteralClass:
- case Expr::TypesCompatibleExprClass:
- case Expr::CXXBoolLiteralExprClass:
- return false;
- case Expr::CallExprClass: {
- const CallExpr *CE = cast<CallExpr>(Init);
-
- // Allow any constant foldable calls to builtins.
- if (CE->isBuiltinCall() && CE->isEvaluatable(Context))
- return false;
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::DeclRefExprClass: {
- const Decl *D = cast<DeclRefExpr>(Init)->getDecl();
- if (isa<EnumConstantDecl>(D))
- return false;
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::CompoundLiteralExprClass:
- // Allow "(vector type){2,4}"; normal C constraints don't allow this,
- // but vectors are allowed to be magic.
- if (Init->getType()->isVectorType())
- return false;
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- case Expr::UnaryOperatorClass: {
- const UnaryOperator *Exp = cast<UnaryOperator>(Init);
-
- switch (Exp->getOpcode()) {
- // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
- // See C99 6.6p3.
- default:
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- case UnaryOperator::SizeOf:
- case UnaryOperator::AlignOf:
- case UnaryOperator::OffsetOf:
- // sizeof(E) is a constantexpr if and only if E is not evaluted.
- // See C99 6.5.3.4p2 and 6.6p3.
- if (Exp->getSubExpr()->getType()->isConstantSizeType())
- return false;
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- case UnaryOperator::Extension:
- case UnaryOperator::LNot:
- case UnaryOperator::Plus:
- case UnaryOperator::Minus:
- case UnaryOperator::Not:
- return CheckArithmeticConstantExpression(Exp->getSubExpr());
- }
- }
- case Expr::SizeOfAlignOfTypeExprClass: {
- const SizeOfAlignOfTypeExpr *Exp = cast<SizeOfAlignOfTypeExpr>(Init);
- // Special check for void types, which are allowed as an extension
- if (Exp->getArgumentType()->isVoidType())
- return false;
- // alignof always evaluates to a constant.
- // FIXME: is sizeof(int[3.0]) a constant expression?
- if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) {
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- return false;
- }
- case Expr::BinaryOperatorClass: {
- const BinaryOperator *Exp = cast<BinaryOperator>(Init);
-
- if (Exp->getLHS()->getType()->isArithmeticType() &&
- Exp->getRHS()->getType()->isArithmeticType()) {
- return CheckArithmeticConstantExpression(Exp->getLHS()) ||
- CheckArithmeticConstantExpression(Exp->getRHS());
- }
-
- if (Exp->getLHS()->getType()->isPointerType() &&
- Exp->getRHS()->getType()->isPointerType()) {
- const Expr* LHSBase = FindExpressionBaseAddress(Exp->getLHS());
- const Expr* RHSBase = FindExpressionBaseAddress(Exp->getRHS());
-
- // Only allow a null (constant integer) base; we could
- // allow some additional cases if necessary, but this
- // is sufficient to cover offsetof-like constructs.
- if (!LHSBase && !RHSBase) {
- return CheckAddressConstantExpression(Exp->getLHS()) ||
- CheckAddressConstantExpression(Exp->getRHS());
- }
- }
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::ImplicitCastExprClass:
- case Expr::ExplicitCastExprClass: {
- const Expr *SubExpr = cast<CastExpr>(Init)->getSubExpr();
- if (SubExpr->getType()->isArithmeticType())
- return CheckArithmeticConstantExpression(SubExpr);
-
- if (SubExpr->getType()->isPointerType()) {
- const Expr* Base = FindExpressionBaseAddress(SubExpr);
- // If the pointer has a null base, this is an offsetof-like construct
- if (!Base)
- return CheckAddressConstantExpression(SubExpr);
- }
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- case Expr::ConditionalOperatorClass: {
- const ConditionalOperator *Exp = cast<ConditionalOperator>(Init);
-
- // If GNU extensions are disabled, we require all operands to be arithmetic
- // constant expressions.
- if (getLangOptions().NoExtensions) {
- return CheckArithmeticConstantExpression(Exp->getCond()) ||
- (Exp->getLHS() && CheckArithmeticConstantExpression(Exp->getLHS())) ||
- CheckArithmeticConstantExpression(Exp->getRHS());
- }
-
- // Otherwise, we have to emulate some of the behavior of fold here.
- // Basically GCC treats things like "4 ? 1 : somefunc()" as a constant
- // because it can constant fold things away. To retain compatibility with
- // GCC code, we see if we can fold the condition to a constant (which we
- // should always be able to do in theory). If so, we only require the
- // specified arm of the conditional to be a constant. This is a horrible
- // hack, but is require by real world code that uses __builtin_constant_p.
- APValue Val;
- if (!Exp->getCond()->tryEvaluate(Val, Context)) {
- // If the tryEvaluate couldn't fold it, CheckArithmeticConstantExpression
- // won't be able to either. Use it to emit the diagnostic though.
- bool Res = CheckArithmeticConstantExpression(Exp->getCond());
- assert(Res && "tryEvaluate couldn't evaluate this constant?");
- return Res;
- }
-
- // Verify that the side following the condition is also a constant.
- const Expr *TrueSide = Exp->getLHS(), *FalseSide = Exp->getRHS();
- if (Val.getInt() == 0)
- std::swap(TrueSide, FalseSide);
-
- if (TrueSide && CheckArithmeticConstantExpression(TrueSide))
- return true;
-
- // Okay, the evaluated side evaluates to a constant, so we accept this.
- // Check to see if the other side is obviously not a constant. If so,
- // emit a warning that this is a GNU extension.
- if (FalseSide && !FalseSide->isEvaluatable(Context))
- Diag(Init->getExprLoc(),
- diag::ext_typecheck_expression_not_constant_but_accepted,
- FalseSide->getSourceRange());
- return false;
- }
- }
-}
-
-bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
- Init = Init->IgnoreParens();
-
- // Look through CXXDefaultArgExprs; they have no meaning in this context.
- if (CXXDefaultArgExpr* DAE = dyn_cast<CXXDefaultArgExpr>(Init))
- return CheckForConstantInitializer(DAE->getExpr(), DclT);
-
- if (CompoundLiteralExpr *e = dyn_cast<CompoundLiteralExpr>(Init))
- return CheckForConstantInitializer(e->getInitializer(), DclT);
-
- if (Init->getType()->isReferenceType()) {
- // FIXME: Work out how the heck references work.
- return false;
- }
-
- if (InitListExpr *Exp = dyn_cast<InitListExpr>(Init)) {
- unsigned numInits = Exp->getNumInits();
- for (unsigned i = 0; i < numInits; i++) {
- // FIXME: Need to get the type of the declaration for C++,
- // because it could be a reference?
- if (CheckForConstantInitializer(Exp->getInit(i),
- Exp->getInit(i)->getType()))
- return true;
- }
- return false;
- }
-
- if (Init->isNullPointerConstant(Context))
- return false;
- if (Init->getType()->isArithmeticType()) {
- QualType InitTy = Context.getCanonicalType(Init->getType())
- .getUnqualifiedType();
- if (InitTy == Context.BoolTy) {
- // Special handling for pointers implicitly cast to bool;
- // (e.g. "_Bool rr = &rr;"). This is only legal at the top level.
- if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(Init)) {
- Expr* SubE = ICE->getSubExpr();
- if (SubE->getType()->isPointerType() ||
- SubE->getType()->isArrayType() ||
- SubE->getType()->isFunctionType()) {
- return CheckAddressConstantExpression(Init);
- }
- }
- } else if (InitTy->isIntegralType()) {
- Expr* SubE = 0;
- if (CastExpr* CE = dyn_cast<CastExpr>(Init))
- SubE = CE->getSubExpr();
- // Special check for pointer cast to int; we allow as an extension
- // an address constant cast to an integer if the integer
- // is of an appropriate width (this sort of code is apparently used
- // in some places).
- // FIXME: Add pedwarn?
- // FIXME: Don't allow bitfields here! Need the FieldDecl for that.
- if (SubE && (SubE->getType()->isPointerType() ||
- SubE->getType()->isArrayType() ||
- SubE->getType()->isFunctionType())) {
- unsigned IntWidth = Context.getTypeSize(Init->getType());
- unsigned PointerWidth = Context.getTypeSize(Context.VoidPtrTy);
- if (IntWidth >= PointerWidth)
- return CheckAddressConstantExpression(Init);
- }
- }
-
- return CheckArithmeticConstantExpression(Init);
- }
-
- if (Init->getType()->isPointerType())
- return CheckAddressConstantExpression(Init);
-
- // An array type at the top level that isn't an init-list must
- // be a string literal
- if (Init->getType()->isArrayType())
- return false;
-
- if (Init->getType()->isFunctionType())
- return false;
-
- // Allow block exprs at top level.
- if (Init->getType()->isBlockPointerType())
- return false;
-
- Diag(Init->getExprLoc(), diag::err_init_element_not_constant,
- Init->getSourceRange());
- return true;
-}
-
-void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
- Decl *RealDecl = static_cast<Decl *>(dcl);
- Expr *Init = static_cast<Expr *>(init);
- assert(Init && "missing initializer");
-
- // If there is no declaration, there was an error parsing it. Just ignore
- // the initializer.
- if (RealDecl == 0) {
- delete Init;
- return;
- }
-
- VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
- if (!VDecl) {
- Diag(dyn_cast<ScopedDecl>(RealDecl)->getLocation(),
- diag::err_illegal_initializer);
- RealDecl->setInvalidDecl();
- return;
- }
- // Get the decls type and save a reference for later, since
- // CheckInitializerTypes may change it.
- QualType DclT = VDecl->getType(), SavT = DclT;
- if (VDecl->isBlockVarDecl()) {
- VarDecl::StorageClass SC = VDecl->getStorageClass();
- if (SC == VarDecl::Extern) { // C99 6.7.8p5
- Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
- VDecl->setInvalidDecl();
- } else if (!VDecl->isInvalidDecl()) {
- if (CheckInitializerTypes(Init, DclT))
- VDecl->setInvalidDecl();
-
- // C++ 3.6.2p2, allow dynamic initialization of static initializers.
- if (!getLangOptions().CPlusPlus) {
- if (SC == VarDecl::Static) // C99 6.7.8p4.
- CheckForConstantInitializer(Init, DclT);
- }
- }
- } else if (VDecl->isFileVarDecl()) {
- if (VDecl->getStorageClass() == VarDecl::Extern)
- Diag(VDecl->getLocation(), diag::warn_extern_init);
- if (!VDecl->isInvalidDecl())
- if (CheckInitializerTypes(Init, DclT))
- VDecl->setInvalidDecl();
-
- // C++ 3.6.2p2, allow dynamic initialization of static initializers.
- if (!getLangOptions().CPlusPlus) {
- // C99 6.7.8p4. All file scoped initializers need to be constant.
- CheckForConstantInitializer(Init, DclT);
- }
- }
- // If the type changed, it means we had an incomplete type that was
- // completed by the initializer. For example:
- // int ary[] = { 1, 3, 5 };
- // "ary" transitions from a VariableArrayType to a ConstantArrayType.
- if (!VDecl->isInvalidDecl() && (DclT != SavT)) {
- VDecl->setType(DclT);
- Init->setType(DclT);
- }
-
- // Attach the initializer to the decl.
- VDecl->setInit(Init);
- return;
-}
-
-/// The declarators are chained together backwards, reverse the list.
-Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
- // Often we have single declarators, handle them quickly.
- Decl *GroupDecl = static_cast<Decl*>(group);
- if (GroupDecl == 0)
- return 0;
-
- ScopedDecl *Group = dyn_cast<ScopedDecl>(GroupDecl);
- ScopedDecl *NewGroup = 0;
- if (Group->getNextDeclarator() == 0)
- NewGroup = Group;
- else { // reverse the list.
- while (Group) {
- ScopedDecl *Next = Group->getNextDeclarator();
- Group->setNextDeclarator(NewGroup);
- NewGroup = Group;
- Group = Next;
- }
- }
- // Perform semantic analysis that depends on having fully processed both
- // the declarator and initializer.
- for (ScopedDecl *ID = NewGroup; ID; ID = ID->getNextDeclarator()) {
- VarDecl *IDecl = dyn_cast<VarDecl>(ID);
- if (!IDecl)
- continue;
- QualType T = IDecl->getType();
-
- // C99 6.7.5.2p2: If an identifier is declared to be an object with
- // static storage duration, it shall not have a variable length array.
- if ((IDecl->isFileVarDecl() || IDecl->isBlockVarDecl()) &&
- IDecl->getStorageClass() == VarDecl::Static) {
- if (T->isVariableArrayType()) {
- Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
- IDecl->setInvalidDecl();
- }
- }
- // Block scope. C99 6.7p7: If an identifier for an object is declared with
- // no linkage (C99 6.2.2p6), the type for the object shall be complete...
- if (IDecl->isBlockVarDecl() &&
- IDecl->getStorageClass() != VarDecl::Extern) {
- if (T->isIncompleteType() && !IDecl->isInvalidDecl()) {
- Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type,
- T.getAsString());
- IDecl->setInvalidDecl();
- }
- }
- // File scope. C99 6.9.2p2: A declaration of an identifier for and
- // object that has file scope without an initializer, and without a
- // storage-class specifier or with the storage-class specifier "static",
- // constitutes a tentative definition. Note: A tentative definition with
- // external linkage is valid (C99 6.2.2p5).
- if (isTentativeDefinition(IDecl)) {
- if (T->isIncompleteArrayType()) {
- // C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete
- // array to be completed. Don't issue a diagnostic.
- } else if (T->isIncompleteType() && !IDecl->isInvalidDecl()) {
- // C99 6.9.2p3: If the declaration of an identifier for an object is
- // a tentative definition and has internal linkage (C99 6.2.2p3), the
- // declared type shall not be an incomplete type.
- Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type,
- T.getAsString());
- IDecl->setInvalidDecl();
- }
- }
- if (IDecl->isFileVarDecl())
- CheckForFileScopedRedefinitions(S, IDecl);
- }
- return NewGroup;
-}
-
-/// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
-/// to introduce parameters into function prototype scope.
-Sema::DeclTy *
-Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
- const DeclSpec &DS = D.getDeclSpec();
-
- // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
- VarDecl::StorageClass StorageClass = VarDecl::None;
- if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
- StorageClass = VarDecl::Register;
- } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
- Diag(DS.getStorageClassSpecLoc(),
- diag::err_invalid_storage_class_in_func_decl);
- D.getMutableDeclSpec().ClearStorageClassSpecs();
- }
- if (DS.isThreadSpecified()) {
- Diag(DS.getThreadSpecLoc(),
- diag::err_invalid_storage_class_in_func_decl);
- D.getMutableDeclSpec().ClearStorageClassSpecs();
- }
-
- // Check that there are no default arguments inside the type of this
- // parameter (C++ only).
- if (getLangOptions().CPlusPlus)
- CheckExtraCXXDefaultArguments(D);
-
- // In this context, we *do not* check D.getInvalidType(). If the declarator
- // type was invalid, GetTypeForDeclarator() still returns a "valid" type,
- // though it will not reflect the user specified type.
- QualType parmDeclType = GetTypeForDeclarator(D, S);
-
- assert(!parmDeclType.isNull() && "GetTypeForDeclarator() returned null type");
-
- // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
- // Can this happen for params? We already checked that they don't conflict
- // among each other. Here they can only shadow globals, which is ok.
- IdentifierInfo *II = D.getIdentifier();
- if (Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S)) {
- if (S->isDeclScope(PrevDecl)) {
- Diag(D.getIdentifierLoc(), diag::err_param_redefinition,
- dyn_cast<NamedDecl>(PrevDecl)->getName());
-
- // Recover by removing the name
- II = 0;
- D.SetIdentifier(0, D.getIdentifierLoc());
- }
- }
-
- // Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
- // Doing the promotion here has a win and a loss. The win is the type for
- // both Decl's and DeclRefExpr's will match (a convenient invariant for the
- // code generator). The loss is the orginal type isn't preserved. For example:
- //
- // void func(int parmvardecl[5]) { // convert "int [5]" to "int *"
- // int blockvardecl[5];
- // sizeof(parmvardecl); // size == 4
- // sizeof(blockvardecl); // size == 20
- // }
- //
- // For expressions, all implicit conversions are captured using the
- // ImplicitCastExpr AST node (we have no such mechanism for Decl's).
- //
- // FIXME: If a source translation tool needs to see the original type, then
- // we need to consider storing both types (in ParmVarDecl)...
- //
- if (parmDeclType->isArrayType()) {
- // int x[restrict 4] -> int *restrict
- parmDeclType = Context.getArrayDecayedType(parmDeclType);
- } else if (parmDeclType->isFunctionType())
- parmDeclType = Context.getPointerType(parmDeclType);
-
- ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext,
- D.getIdentifierLoc(), II,
- parmDeclType, StorageClass,
- 0, 0);
-
- if (D.getInvalidType())
- New->setInvalidDecl();
-
- if (II)
- PushOnScopeChains(New, S);
-
- ProcessDeclAttributes(New, D);
- return New;
-
-}
-
-Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
- assert(getCurFunctionDecl() == 0 && "Function parsing confused");
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
-
- // Verify 6.9.1p6: 'every identifier in the identifier list shall be declared'
- // for a K&R function.
- if (!FTI.hasPrototype) {
- for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- if (FTI.ArgInfo[i].Param == 0) {
- Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared,
- FTI.ArgInfo[i].Ident->getName());
- // Implicitly declare the argument as type 'int' for lack of a better
- // type.
- DeclSpec DS;
- const char* PrevSpec; // unused
- DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
- PrevSpec);
- Declarator ParamD(DS, Declarator::KNRTypeListContext);
- ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc);
- FTI.ArgInfo[i].Param = ActOnParamDeclarator(FnBodyScope, ParamD);
- }
- }
- } else {
- // FIXME: Diagnose arguments without names in C.
- }
-
- Scope *GlobalScope = FnBodyScope->getParent();
-
- // See if this is a redefinition.
- Decl *PrevDcl = LookupDecl(D.getIdentifier(), Decl::IDNS_Ordinary,
- GlobalScope);
- if (PrevDcl && isDeclInScope(PrevDcl, CurContext)) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PrevDcl)) {
- const FunctionDecl *Definition;
- if (FD->getBody(Definition)) {
- Diag(D.getIdentifierLoc(), diag::err_redefinition,
- D.getIdentifier()->getName());
- Diag(Definition->getLocation(), diag::err_previous_definition);
- }
- }
- }
-
- return ActOnStartOfFunctionDef(FnBodyScope,
- ActOnDeclarator(GlobalScope, D, 0));
-}
-
-Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
- Decl *decl = static_cast<Decl*>(D);
- FunctionDecl *FD = cast<FunctionDecl>(decl);
- PushDeclContext(FD);
-
- // Check the validity of our function parameters
- CheckParmsForFunctionDef(FD);
-
- // Introduce our parameters into the function scope
- for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
- // If this has an identifier, add it to the scope stack.
- if (Param->getIdentifier())
- PushOnScopeChains(Param, FnBodyScope);
- }
-
- return FD;
-}
-
-Sema::DeclTy *Sema::ActOnFinishFunctionBody(DeclTy *D, StmtTy *Body) {
- Decl *dcl = static_cast<Decl *>(D);
- if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(dcl)) {
- FD->setBody((Stmt*)Body);
- assert(FD == getCurFunctionDecl() && "Function parsing confused");
- } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
- MD->setBody((Stmt*)Body);
- } else
- return 0;
- PopDeclContext();
- // Verify and clean out per-function state.
-
- // Check goto/label use.
- for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
- I = LabelMap.begin(), E = LabelMap.end(); I != E; ++I) {
- // Verify that we have no forward references left. If so, there was a goto
- // or address of a label taken, but no definition of it. Label fwd
- // definitions are indicated with a null substmt.
- if (I->second->getSubStmt() == 0) {
- LabelStmt *L = I->second;
- // Emit error.
- Diag(L->getIdentLoc(), diag::err_undeclared_label_use, L->getName());
-
- // At this point, we have gotos that use the bogus label. Stitch it into
- // the function body so that they aren't leaked and that the AST is well
- // formed.
- if (Body) {
- L->setSubStmt(new NullStmt(L->getIdentLoc()));
- cast<CompoundStmt>((Stmt*)Body)->push_back(L);
- } else {
- // The whole function wasn't parsed correctly, just delete this.
- delete L;
- }
- }
- }
- LabelMap.clear();
-
- return D;
-}
-
-/// ImplicitlyDefineFunction - An undeclared identifier was used in a function
-/// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
-ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
- IdentifierInfo &II, Scope *S) {
- // Extension in C99. Legal in C90, but warn about it.
- if (getLangOptions().C99)
- Diag(Loc, diag::ext_implicit_function_decl, II.getName());
- else
- Diag(Loc, diag::warn_implicit_function_decl, II.getName());
-
- // FIXME: handle stuff like:
- // void foo() { extern float X(); }
- // void bar() { X(); } <-- implicit decl for X in another scope.
-
- // Set a Declarator for the implicit definition: int foo();
- const char *Dummy;
- DeclSpec DS;
- bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
- Error = Error; // Silence warning.
- assert(!Error && "Error setting up implicit decl!");
- Declarator D(DS, Declarator::BlockContext);
- D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, Loc));
- D.SetIdentifier(&II, Loc);
-
- // Insert this function into translation-unit scope.
-
- DeclContext *PrevDC = CurContext;
- CurContext = Context.getTranslationUnitDecl();
-
- FunctionDecl *FD =
- dyn_cast<FunctionDecl>(static_cast<Decl*>(ActOnDeclarator(TUScope, D, 0)));
- FD->setImplicit();
-
- CurContext = PrevDC;
-
- return FD;
-}
-
-
-TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
- ScopedDecl *LastDeclarator) {
- assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
- assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
-
- // Scope manipulation handled by caller.
- TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
- D.getIdentifierLoc(),
- D.getIdentifier(),
- T, LastDeclarator);
- if (D.getInvalidType())
- NewTD->setInvalidDecl();
- return NewTD;
-}
-
-/// ActOnTag - This is invoked when we see 'struct foo' or 'struct {'. In the
-/// former case, Name will be non-null. In the later case, Name will be null.
-/// TagType indicates what kind of tag this is. TK indicates whether this is a
-/// reference/declaration/definition of a tag.
-Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
- SourceLocation KWLoc, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr) {
- // If this is a use of an existing tag, it must have a name.
- assert((Name != 0 || TK == TK_Definition) &&
- "Nameless record must be a definition!");
-
- TagDecl::TagKind Kind;
- switch (TagType) {
- default: assert(0 && "Unknown tag type!");
- case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
- case DeclSpec::TST_union: Kind = TagDecl::TK_union; break;
- case DeclSpec::TST_class: Kind = TagDecl::TK_class; break;
- case DeclSpec::TST_enum: Kind = TagDecl::TK_enum; break;
- }
-
- // Two code paths: a new one for structs/unions/classes where we create
- // separate decls for forward declarations, and an old (eventually to
- // be removed) code path for enums.
- if (Kind != TagDecl::TK_enum)
- return ActOnTagStruct(S, Kind, TK, KWLoc, Name, NameLoc, Attr);
-
- // If this is a named struct, check to see if there was a previous forward
- // declaration or definition.
- // Use ScopedDecl instead of TagDecl, because a NamespaceDecl may come up.
- ScopedDecl *PrevDecl =
- dyn_cast_or_null<ScopedDecl>(LookupDecl(Name, Decl::IDNS_Tag, S));
-
- if (PrevDecl) {
- assert((isa<TagDecl>(PrevDecl) || isa<NamespaceDecl>(PrevDecl)) &&
- "unexpected Decl type");
- if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
- // If this is a use of a previous tag, or if the tag is already declared
- // in the same scope (so that the definition/declaration completes or
- // rementions the tag), reuse the decl.
- if (TK == TK_Reference || isDeclInScope(PrevDecl, CurContext, S)) {
- // Make sure that this wasn't declared as an enum and now used as a
- // struct or something similar.
- if (PrevTagDecl->getTagKind() != Kind) {
- Diag(KWLoc, diag::err_use_with_wrong_tag, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_use);
- // Recover by making this an anonymous redefinition.
- Name = 0;
- PrevDecl = 0;
- } else {
- // If this is a use or a forward declaration, we're good.
- if (TK != TK_Definition)
- return PrevDecl;
-
- // Diagnose attempts to redefine a tag.
- if (PrevTagDecl->isDefinition()) {
- Diag(NameLoc, diag::err_redefinition, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- // If this is a redefinition, recover by making this struct be
- // anonymous, which will make any later references get the previous
- // definition.
- Name = 0;
- } else {
- // Okay, this is definition of a previously declared or referenced
- // tag. Move the location of the decl to be the definition site.
- PrevDecl->setLocation(NameLoc);
- return PrevDecl;
- }
- }
- }
- // If we get here, this is a definition of a new struct type in a nested
- // scope, e.g. "struct foo; void bar() { struct foo; }", just create a new
- // type.
- } else {
- // PrevDecl is a namespace.
- if (isDeclInScope(PrevDecl, CurContext, S)) {
- // The tag name clashes with a namespace name, issue an error and
- // recover by making this tag be anonymous.
- Diag(NameLoc, diag::err_redefinition_different_kind, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- Name = 0;
- }
- }
- }
-
- // If there is an identifier, use the location of the identifier as the
- // location of the decl, otherwise use the location of the struct/union
- // keyword.
- SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
-
- // Otherwise, if this is the first time we've seen this tag, create the decl.
- TagDecl *New;
- if (Kind == TagDecl::TK_enum) {
- // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
- // enum X { A, B, C } D; D should chain to X.
- New = EnumDecl::Create(Context, CurContext, Loc, Name, 0);
- // If this is an undefined enum, warn.
- if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
- } else {
- // struct/union/class
-
- // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
- // struct X { int A; } D; D should chain to X.
- if (getLangOptions().CPlusPlus)
- // FIXME: Look for a way to use RecordDecl for simple structs.
- New = CXXRecordDecl::Create(Context, Kind, CurContext, Loc, Name);
- else
- New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name);
- }
-
- // If this has an identifier, add it to the scope stack.
- if (Name) {
- // The scope passed in may not be a decl scope. Zip up the scope tree until
- // we find one that is.
- while ((S->getFlags() & Scope::DeclScope) == 0)
- S = S->getParent();
-
- // Add it to the decl chain.
- PushOnScopeChains(New, S);
- }
-
- if (Attr)
- ProcessDeclAttributeList(New, Attr);
- return New;
-}
-
-/// ActOnTagStruct - New "ActOnTag" logic for structs/unions/classes. Unlike
-/// the logic for enums, we create separate decls for forward declarations.
-/// This is called by ActOnTag, but eventually will replace its logic.
-Sema::DeclTy *Sema::ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK,
- SourceLocation KWLoc, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr) {
-
- // If this is a named struct, check to see if there was a previous forward
- // declaration or definition.
- // Use ScopedDecl instead of TagDecl, because a NamespaceDecl may come up.
- ScopedDecl *PrevDecl =
- dyn_cast_or_null<ScopedDecl>(LookupDecl(Name, Decl::IDNS_Tag, S));
-
- if (PrevDecl) {
- assert((isa<TagDecl>(PrevDecl) || isa<NamespaceDecl>(PrevDecl)) &&
- "unexpected Decl type");
-
- if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
- // If this is a use of a previous tag, or if the tag is already declared
- // in the same scope (so that the definition/declaration completes or
- // rementions the tag), reuse the decl.
- if (TK == TK_Reference || isDeclInScope(PrevDecl, CurContext, S)) {
- // Make sure that this wasn't declared as an enum and now used as a
- // struct or something similar.
- if (PrevTagDecl->getTagKind() != Kind) {
- Diag(KWLoc, diag::err_use_with_wrong_tag, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_use);
- // Recover by making this an anonymous redefinition.
- Name = 0;
- PrevDecl = 0;
- } else {
- // If this is a use, return the original decl.
-
- // FIXME: In the future, return a variant or some other clue
- // for the consumer of this Decl to know it doesn't own it.
- // For our current ASTs this shouldn't be a problem, but will
- // need to be changed with DeclGroups.
- if (TK == TK_Reference)
- return PrevDecl;
-
- // The new decl is a definition?
- if (TK == TK_Definition) {
- // Diagnose attempts to redefine a tag.
- if (RecordDecl* DefRecord =
- cast<RecordDecl>(PrevTagDecl)->getDefinition(Context)) {
- Diag(NameLoc, diag::err_redefinition, Name->getName());
- Diag(DefRecord->getLocation(), diag::err_previous_definition);
- // If this is a redefinition, recover by making this struct be
- // anonymous, which will make any later references get the previous
- // definition.
- Name = 0;
- PrevDecl = 0;
- }
- // Okay, this is definition of a previously declared or referenced
- // tag. We're going to create a new Decl.
- }
- }
- // If we get here we have (another) forward declaration. Just create
- // a new decl.
- }
- else {
- // If we get here, this is a definition of a new struct type in a nested
- // scope, e.g. "struct foo; void bar() { struct foo; }", just create a
- // new decl/type. We set PrevDecl to NULL so that the Records
- // have distinct types.
- PrevDecl = 0;
- }
- } else {
- // PrevDecl is a namespace.
- if (isDeclInScope(PrevDecl, CurContext, S)) {
- // The tag name clashes with a namespace name, issue an error and
- // recover by making this tag be anonymous.
- Diag(NameLoc, diag::err_redefinition_different_kind, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- Name = 0;
- }
- }
- }
-
- // If there is an identifier, use the location of the identifier as the
- // location of the decl, otherwise use the location of the struct/union
- // keyword.
- SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
-
- // Otherwise, if this is the first time we've seen this tag, create the decl.
- TagDecl *New;
-
- // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
- // struct X { int A; } D; D should chain to X.
- if (getLangOptions().CPlusPlus)
- // FIXME: Look for a way to use RecordDecl for simple structs.
- New = CXXRecordDecl::Create(Context, Kind, CurContext, Loc, Name,
- dyn_cast_or_null<CXXRecordDecl>(PrevDecl));
- else
- New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name,
- dyn_cast_or_null<RecordDecl>(PrevDecl));
-
- // If this has an identifier, add it to the scope stack.
- if ((TK == TK_Definition || !PrevDecl) && Name) {
- // The scope passed in may not be a decl scope. Zip up the scope tree until
- // we find one that is.
- while ((S->getFlags() & Scope::DeclScope) == 0)
- S = S->getParent();
-
- // Add it to the decl chain.
- PushOnScopeChains(New, S);
- }
-
- if (Attr)
- ProcessDeclAttributeList(New, Attr);
-
- return New;
-}
-
-
-/// Collect the instance variables declared in an Objective-C object. Used in
-/// the creation of structures from objects using the @defs directive.
-static void CollectIvars(ObjCInterfaceDecl *Class, ASTContext& Ctx,
- llvm::SmallVectorImpl<Sema::DeclTy*> &ivars) {
- if (Class->getSuperClass())
- CollectIvars(Class->getSuperClass(), Ctx, ivars);
-
- // For each ivar, create a fresh ObjCAtDefsFieldDecl.
- for (ObjCInterfaceDecl::ivar_iterator
- I=Class->ivar_begin(), E=Class->ivar_end(); I!=E; ++I) {
-
- ObjCIvarDecl* ID = *I;
- ivars.push_back(ObjCAtDefsFieldDecl::Create(Ctx, ID->getLocation(),
- ID->getIdentifier(),
- ID->getType(),
- ID->getBitWidth()));
- }
-}
-
-/// Called whenever @defs(ClassName) is encountered in the source. Inserts the
-/// instance variables of ClassName into Decls.
-void Sema::ActOnDefs(Scope *S, SourceLocation DeclStart,
- IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclTy*> &Decls) {
- // Check that ClassName is a valid class
- ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName);
- if (!Class) {
- Diag(DeclStart, diag::err_undef_interface, ClassName->getName());
- return;
- }
- // Collect the instance variables
- CollectIvars(Class, Context, Decls);
-}
-
-QualType Sema::TryFixInvalidVariablyModifiedType(QualType T) {
- // This method tries to turn a variable array into a constant
- // array even when the size isn't an ICE. This is necessary
- // for compatibility with code that depends on gcc's buggy
- // constant expression folding, like struct {char x[(int)(char*)2];}
- if (const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T)) {
- APValue Result;
- if (VLATy->getSizeExpr() &&
- VLATy->getSizeExpr()->tryEvaluate(Result, Context) && Result.isInt()) {
- llvm::APSInt &Res = Result.getInt();
- if (Res > llvm::APSInt(Res.getBitWidth(), Res.isUnsigned()))
- return Context.getConstantArrayType(VLATy->getElementType(),
- Res, ArrayType::Normal, 0);
- }
- }
- return QualType();
-}
-
-/// ActOnField - Each field of a struct/union/class is passed into this in order
-/// to create a FieldDecl object for it.
-Sema::DeclTy *Sema::ActOnField(Scope *S,
- SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth) {
- IdentifierInfo *II = D.getIdentifier();
- Expr *BitWidth = (Expr*)BitfieldWidth;
- SourceLocation Loc = DeclStart;
- if (II) Loc = D.getIdentifierLoc();
-
- // FIXME: Unnamed fields can be handled in various different ways, for
- // example, unnamed unions inject all members into the struct namespace!
-
- if (BitWidth) {
- // TODO: Validate.
- //printf("WARNING: BITFIELDS IGNORED!\n");
-
- // 6.7.2.1p3
- // 6.7.2.1p4
-
- } else {
- // Not a bitfield.
-
- // validate II.
-
- }
-
- QualType T = GetTypeForDeclarator(D, S);
- assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
- bool InvalidDecl = false;
-
- // C99 6.7.2.1p8: A member of a structure or union may have any type other
- // than a variably modified type.
- if (T->isVariablyModifiedType()) {
- QualType FixedTy = TryFixInvalidVariablyModifiedType(T);
- if (!FixedTy.isNull()) {
- Diag(Loc, diag::warn_illegal_constant_array_size, Loc);
- T = FixedTy;
- } else {
- // FIXME: This diagnostic needs work
- Diag(Loc, diag::err_typecheck_illegal_vla, Loc);
- InvalidDecl = true;
- }
- }
- // FIXME: Chain fielddecls together.
- FieldDecl *NewFD;
-
- if (getLangOptions().CPlusPlus) {
- // FIXME: Replace CXXFieldDecls with FieldDecls for simple structs.
- NewFD = CXXFieldDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
- Loc, II, T, BitWidth);
- if (II)
- PushOnScopeChains(NewFD, S);
- }
- else
- NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
-
- ProcessDeclAttributes(NewFD, D);
-
- if (D.getInvalidType() || InvalidDecl)
- NewFD->setInvalidDecl();
- return NewFD;
-}
-
-/// TranslateIvarVisibility - Translate visibility from a token ID to an
-/// AST enum value.
-static ObjCIvarDecl::AccessControl
-TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) {
- switch (ivarVisibility) {
- case tok::objc_private: return ObjCIvarDecl::Private;
- case tok::objc_public: return ObjCIvarDecl::Public;
- case tok::objc_protected: return ObjCIvarDecl::Protected;
- case tok::objc_package: return ObjCIvarDecl::Package;
- default: assert(false && "Unknown visitibility kind");
- }
-}
-
-/// ActOnIvar - Each ivar field of an objective-c class is passed into this
-/// in order to create an IvarDecl object for it.
-Sema::DeclTy *Sema::ActOnIvar(Scope *S,
- SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth,
- tok::ObjCKeywordKind Visibility) {
- IdentifierInfo *II = D.getIdentifier();
- Expr *BitWidth = (Expr*)BitfieldWidth;
- SourceLocation Loc = DeclStart;
- if (II) Loc = D.getIdentifierLoc();
-
- // FIXME: Unnamed fields can be handled in various different ways, for
- // example, unnamed unions inject all members into the struct namespace!
-
-
- if (BitWidth) {
- // TODO: Validate.
- //printf("WARNING: BITFIELDS IGNORED!\n");
-
- // 6.7.2.1p3
- // 6.7.2.1p4
-
- } else {
- // Not a bitfield.
-
- // validate II.
-
- }
-
- QualType T = GetTypeForDeclarator(D, S);
- assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
- bool InvalidDecl = false;
-
- // C99 6.7.2.1p8: A member of a structure or union may have any type other
- // than a variably modified type.
- if (T->isVariablyModifiedType()) {
- // FIXME: This diagnostic needs work
- Diag(Loc, diag::err_typecheck_illegal_vla, Loc);
- InvalidDecl = true;
- }
-
- // Get the visibility (access control) for this ivar.
- ObjCIvarDecl::AccessControl ac =
- Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
- : ObjCIvarDecl::None;
-
- // Construct the decl.
- ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context, Loc, II, T, ac,
- (Expr *)BitfieldWidth);
-
- // Process attributes attached to the ivar.
- ProcessDeclAttributes(NewID, D);
-
- if (D.getInvalidType() || InvalidDecl)
- NewID->setInvalidDecl();
-
- return NewID;
-}
-
-void Sema::ActOnFields(Scope* S,
- SourceLocation RecLoc, DeclTy *RecDecl,
- DeclTy **Fields, unsigned NumFields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *Attr) {
- Decl *EnclosingDecl = static_cast<Decl*>(RecDecl);
- assert(EnclosingDecl && "missing record or interface decl");
- RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
-
- if (Record)
- if (RecordDecl* DefRecord = Record->getDefinition(Context)) {
- // Diagnose code like:
- // struct S { struct S {} X; };
- // We discover this when we complete the outer S. Reject and ignore the
- // outer S.
- Diag(DefRecord->getLocation(), diag::err_nested_redefinition,
- DefRecord->getKindName());
- Diag(RecLoc, diag::err_previous_definition);
- Record->setInvalidDecl();
- return;
- }
-
- // Verify that all the fields are okay.
- unsigned NumNamedMembers = 0;
- llvm::SmallVector<FieldDecl*, 32> RecFields;
- llvm::SmallSet<const IdentifierInfo*, 32> FieldIDs;
-
- for (unsigned i = 0; i != NumFields; ++i) {
-
- FieldDecl *FD = cast_or_null<FieldDecl>(static_cast<Decl*>(Fields[i]));
- assert(FD && "missing field decl");
-
- // Remember all fields.
- RecFields.push_back(FD);
-
- // Get the type for the field.
- Type *FDTy = FD->getType().getTypePtr();
-
- // C99 6.7.2.1p2 - A field may not be a function type.
- if (FDTy->isFunctionType()) {
- Diag(FD->getLocation(), diag::err_field_declared_as_function,
- FD->getName());
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- // C99 6.7.2.1p2 - A field may not be an incomplete type except...
- if (FDTy->isIncompleteType()) {
- if (!Record) { // Incomplete ivar type is always an error.
- Diag(FD->getLocation(), diag::err_field_incomplete, FD->getName());
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- if (i != NumFields-1 || // ... that the last member ...
- !Record->isStruct() || // ... of a structure ...
- !FDTy->isArrayType()) { //... may have incomplete array type.
- Diag(FD->getLocation(), diag::err_field_incomplete, FD->getName());
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- if (NumNamedMembers < 1) { //... must have more than named member ...
- Diag(FD->getLocation(), diag::err_flexible_array_empty_struct,
- FD->getName());
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- // Okay, we have a legal flexible array member at the end of the struct.
- if (Record)
- Record->setHasFlexibleArrayMember(true);
- }
- /// C99 6.7.2.1p2 - a struct ending in a flexible array member cannot be the
- /// field of another structure or the element of an array.
- if (const RecordType *FDTTy = FDTy->getAsRecordType()) {
- if (FDTTy->getDecl()->hasFlexibleArrayMember()) {
- // If this is a member of a union, then entire union becomes "flexible".
- if (Record && Record->isUnion()) {
- Record->setHasFlexibleArrayMember(true);
- } else {
- // If this is a struct/class and this is not the last element, reject
- // it. Note that GCC supports variable sized arrays in the middle of
- // structures.
- if (i != NumFields-1) {
- Diag(FD->getLocation(), diag::err_variable_sized_type_in_struct,
- FD->getName());
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- // We support flexible arrays at the end of structs in other structs
- // as an extension.
- Diag(FD->getLocation(), diag::ext_flexible_array_in_struct,
- FD->getName());
- if (Record)
- Record->setHasFlexibleArrayMember(true);
- }
- }
- }
- /// A field cannot be an Objective-c object
- if (FDTy->isObjCInterfaceType()) {
- Diag(FD->getLocation(), diag::err_statically_allocated_object,
- FD->getName());
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- // Keep track of the number of named members.
- if (IdentifierInfo *II = FD->getIdentifier()) {
- // Detect duplicate member names.
- if (!FieldIDs.insert(II)) {
- Diag(FD->getLocation(), diag::err_duplicate_member, II->getName());
- // Find the previous decl.
- SourceLocation PrevLoc;
- for (unsigned i = 0, e = RecFields.size(); ; ++i) {
- assert(i != e && "Didn't find previous def!");
- if (RecFields[i]->getIdentifier() == II) {
- PrevLoc = RecFields[i]->getLocation();
- break;
- }
- }
- Diag(PrevLoc, diag::err_previous_definition);
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
- ++NumNamedMembers;
- }
- }
-
- // Okay, we successfully defined 'Record'.
- if (Record) {
- Record->defineBody(Context, &RecFields[0], RecFields.size());
- // If this is a C++ record, HandleTagDeclDefinition will be invoked in
- // Sema::ActOnFinishCXXClassDef.
- if (!isa<CXXRecordDecl>(Record))
- Consumer.HandleTagDeclDefinition(Record);
- } else {
- ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(&RecFields[0]);
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl))
- ID->addInstanceVariablesToClass(ClsFields, RecFields.size(), RBrac);
- else if (ObjCImplementationDecl *IMPDecl =
- dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
- assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");
- IMPDecl->ObjCAddInstanceVariablesToClassImpl(ClsFields, RecFields.size());
- CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac);
- }
- }
-
- if (Attr)
- ProcessDeclAttributeList(Record, Attr);
-}
-
-Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
- DeclTy *lastEnumConst,
- SourceLocation IdLoc, IdentifierInfo *Id,
- SourceLocation EqualLoc, ExprTy *val) {
- EnumDecl *TheEnumDecl = cast<EnumDecl>(static_cast<Decl*>(theEnumDecl));
- EnumConstantDecl *LastEnumConst =
- cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
- Expr *Val = static_cast<Expr*>(val);
-
- // The scope passed in may not be a decl scope. Zip up the scope tree until
- // we find one that is.
- while ((S->getFlags() & Scope::DeclScope) == 0)
- S = S->getParent();
-
- // Verify that there isn't already something declared with this name in this
- // scope.
- if (Decl *PrevDecl = LookupDecl(Id, Decl::IDNS_Ordinary, S)) {
- // When in C++, we may get a TagDecl with the same name; in this case the
- // enum constant will 'hide' the tag.
- assert((getLangOptions().CPlusPlus || !isa<TagDecl>(PrevDecl)) &&
- "Received TagDecl when not in C++!");
- if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)) {
- if (isa<EnumConstantDecl>(PrevDecl))
- Diag(IdLoc, diag::err_redefinition_of_enumerator, Id->getName());
- else
- Diag(IdLoc, diag::err_redefinition, Id->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- delete Val;
- return 0;
- }
- }
-
- llvm::APSInt EnumVal(32);
- QualType EltTy;
- if (Val) {
- // Make sure to promote the operand type to int.
- UsualUnaryConversions(Val);
-
- // C99 6.7.2.2p2: Make sure we have an integer constant expression.
- SourceLocation ExpLoc;
- if (!Val->isIntegerConstantExpr(EnumVal, Context, &ExpLoc)) {
- Diag(ExpLoc, diag::err_enum_value_not_integer_constant_expr,
- Id->getName());
- delete Val;
- Val = 0; // Just forget about it.
- } else {
- EltTy = Val->getType();
- }
- }
-
- if (!Val) {
- if (LastEnumConst) {
- // Assign the last value + 1.
- EnumVal = LastEnumConst->getInitVal();
- ++EnumVal;
-
- // Check for overflow on increment.
- if (EnumVal < LastEnumConst->getInitVal())
- Diag(IdLoc, diag::warn_enum_value_overflow);
-
- EltTy = LastEnumConst->getType();
- } else {
- // First value, set to zero.
- EltTy = Context.IntTy;
- EnumVal.zextOrTrunc(static_cast<uint32_t>(Context.getTypeSize(EltTy)));
- }
- }
-
- EnumConstantDecl *New =
- EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy,
- Val, EnumVal,
- LastEnumConst);
-
- // Register this decl in the current scope stack.
- PushOnScopeChains(New, S);
- return New;
-}
-
-// FIXME: For consistency with ActOnFields(), we should have the parser
-// pass in the source location for the left/right braces.
-void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX,
- DeclTy **Elements, unsigned NumElements) {
- EnumDecl *Enum = cast<EnumDecl>(static_cast<Decl*>(EnumDeclX));
-
- if (Enum && Enum->isDefinition()) {
- // Diagnose code like:
- // enum e0 {
- // E0 = sizeof(enum e0 { E1 })
- // };
- Diag(Enum->getLocation(), diag::err_nested_redefinition,
- Enum->getName());
- Diag(EnumLoc, diag::err_previous_definition);
- Enum->setInvalidDecl();
- return;
- }
- // TODO: If the result value doesn't fit in an int, it must be a long or long
- // long value. ISO C does not support this, but GCC does as an extension,
- // emit a warning.
- unsigned IntWidth = Context.Target.getIntWidth();
-
- // Verify that all the values are okay, compute the size of the values, and
- // reverse the list.
- unsigned NumNegativeBits = 0;
- unsigned NumPositiveBits = 0;
-
- // Keep track of whether all elements have type int.
- bool AllElementsInt = true;
-
- EnumConstantDecl *EltList = 0;
- for (unsigned i = 0; i != NumElements; ++i) {
- EnumConstantDecl *ECD =
- cast_or_null<EnumConstantDecl>(static_cast<Decl*>(Elements[i]));
- if (!ECD) continue; // Already issued a diagnostic.
-
- // If the enum value doesn't fit in an int, emit an extension warning.
- const llvm::APSInt &InitVal = ECD->getInitVal();
- assert(InitVal.getBitWidth() >= IntWidth &&
- "Should have promoted value to int");
- if (InitVal.getBitWidth() > IntWidth) {
- llvm::APSInt V(InitVal);
- V.trunc(IntWidth);
- V.extend(InitVal.getBitWidth());
- if (V != InitVal)
- Diag(ECD->getLocation(), diag::ext_enum_value_not_int,
- InitVal.toString(10));
- }
-
- // Keep track of the size of positive and negative values.
- if (InitVal.isUnsigned() || InitVal.isNonNegative())
- NumPositiveBits = std::max(NumPositiveBits,
- (unsigned)InitVal.getActiveBits());
- else
- NumNegativeBits = std::max(NumNegativeBits,
- (unsigned)InitVal.getMinSignedBits());
-
- // Keep track of whether every enum element has type int (very commmon).
- if (AllElementsInt)
- AllElementsInt = ECD->getType() == Context.IntTy;
-
- ECD->setNextDeclarator(EltList);
- EltList = ECD;
- }
-
- // Figure out the type that should be used for this enum.
- // FIXME: Support attribute(packed) on enums and -fshort-enums.
- QualType BestType;
- unsigned BestWidth;
-
- if (NumNegativeBits) {
- // If there is a negative value, figure out the smallest integer type (of
- // int/long/longlong) that fits.
- if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) {
- BestType = Context.IntTy;
- BestWidth = IntWidth;
- } else {
- BestWidth = Context.Target.getLongWidth();
-
- if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth)
- BestType = Context.LongTy;
- else {
- BestWidth = Context.Target.getLongLongWidth();
-
- if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
- Diag(Enum->getLocation(), diag::warn_enum_too_large);
- BestType = Context.LongLongTy;
- }
- }
- } else {
- // If there is no negative value, figure out which of uint, ulong, ulonglong
- // fits.
- if (NumPositiveBits <= IntWidth) {
- BestType = Context.UnsignedIntTy;
- BestWidth = IntWidth;
- } else if (NumPositiveBits <=
- (BestWidth = Context.Target.getLongWidth())) {
- BestType = Context.UnsignedLongTy;
- } else {
- BestWidth = Context.Target.getLongLongWidth();
- assert(NumPositiveBits <= BestWidth &&
- "How could an initializer get larger than ULL?");
- BestType = Context.UnsignedLongLongTy;
- }
- }
-
- // Loop over all of the enumerator constants, changing their types to match
- // the type of the enum if needed.
- for (unsigned i = 0; i != NumElements; ++i) {
- EnumConstantDecl *ECD =
- cast_or_null<EnumConstantDecl>(static_cast<Decl*>(Elements[i]));
- if (!ECD) continue; // Already issued a diagnostic.
-
- // Standard C says the enumerators have int type, but we allow, as an
- // extension, the enumerators to be larger than int size. If each
- // enumerator value fits in an int, type it as an int, otherwise type it the
- // same as the enumerator decl itself. This means that in "enum { X = 1U }"
- // that X has type 'int', not 'unsigned'.
- if (ECD->getType() == Context.IntTy) {
- // Make sure the init value is signed.
- llvm::APSInt IV = ECD->getInitVal();
- IV.setIsSigned(true);
- ECD->setInitVal(IV);
- continue; // Already int type.
- }
-
- // Determine whether the value fits into an int.
- llvm::APSInt InitVal = ECD->getInitVal();
- bool FitsInInt;
- if (InitVal.isUnsigned() || !InitVal.isNegative())
- FitsInInt = InitVal.getActiveBits() < IntWidth;
- else
- FitsInInt = InitVal.getMinSignedBits() <= IntWidth;
-
- // If it fits into an integer type, force it. Otherwise force it to match
- // the enum decl type.
- QualType NewTy;
- unsigned NewWidth;
- bool NewSign;
- if (FitsInInt) {
- NewTy = Context.IntTy;
- NewWidth = IntWidth;
- NewSign = true;
- } else if (ECD->getType() == BestType) {
- // Already the right type!
- continue;
- } else {
- NewTy = BestType;
- NewWidth = BestWidth;
- NewSign = BestType->isSignedIntegerType();
- }
-
- // Adjust the APSInt value.
- InitVal.extOrTrunc(NewWidth);
- InitVal.setIsSigned(NewSign);
- ECD->setInitVal(InitVal);
-
- // Adjust the Expr initializer and type.
- ECD->setInitExpr(new ImplicitCastExpr(NewTy, ECD->getInitExpr()));
- ECD->setType(NewTy);
- }
-
- Enum->defineElements(EltList, BestType);
- Consumer.HandleTagDeclDefinition(Enum);
-}
-
-Sema::DeclTy *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
- ExprTy *expr) {
- StringLiteral *AsmString = cast<StringLiteral>((Expr*)expr);
-
- return FileScopeAsmDecl::Create(Context, Loc, AsmString);
-}
-
-Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
- SourceLocation LBrace,
- SourceLocation RBrace,
- const char *Lang,
- unsigned StrSize,
- DeclTy *D) {
- LinkageSpecDecl::LanguageIDs Language;
- Decl *dcl = static_cast<Decl *>(D);
- if (strncmp(Lang, "\"C\"", StrSize) == 0)
- Language = LinkageSpecDecl::lang_c;
- else if (strncmp(Lang, "\"C++\"", StrSize) == 0)
- Language = LinkageSpecDecl::lang_cxx;
- else {
- Diag(Loc, diag::err_bad_language);
- return 0;
- }
-
- // FIXME: Add all the various semantics of linkage specifications
- return LinkageSpecDecl::Create(Context, Loc, Language, dcl);
-}
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
deleted file mode 100644
index 3ab0c91cb9c6..000000000000
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ /dev/null
@@ -1,1185 +0,0 @@
-//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements decl-related attribute processing.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Parse/DeclSpec.h"
-#include <llvm/ADT/StringExtras.h>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Helper functions
-//===----------------------------------------------------------------------===//
-
-static const FunctionTypeProto *getFunctionProto(Decl *d) {
- QualType Ty;
- if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
- Ty = decl->getType();
- else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
- Ty = decl->getType();
- else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
- Ty = decl->getUnderlyingType();
- else
- return 0;
-
- if (Ty->isFunctionPointerType())
- Ty = Ty->getAsPointerType()->getPointeeType();
-
- if (const FunctionType *FnTy = Ty->getAsFunctionType())
- return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
-
- return 0;
-}
-
-// FIXME: We should provide an abstraction around a method or function
-// to provide the following bits of information.
-
-/// isFunctionOrMethod - Return true if the given decl is a (non-K&R)
-/// function or an Objective-C method.
-static bool isFunctionOrMethod(Decl *d) {
- return getFunctionProto(d) || isa<ObjCMethodDecl>(d);
-
-}
-
-static unsigned getFunctionOrMethodNumArgs(Decl *d) {
- if (const FunctionTypeProto *proto = getFunctionProto(d)) {
- return proto->getNumArgs();
- } else {
- return cast<ObjCMethodDecl>(d)->getNumParams();
- }
-}
-
-static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
- if (const FunctionTypeProto *proto = getFunctionProto(d)) {
- return proto->getArgType(Idx);
- } else {
- return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType();
- }
-}
-
-static bool isFunctionOrMethodVariadic(Decl *d) {
- if (const FunctionTypeProto *proto = getFunctionProto(d)) {
- return proto->isVariadic();
- } else {
- return cast<ObjCMethodDecl>(d)->isVariadic();
- }
-}
-
-static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
- const PointerType *PT = T->getAsPointerType();
- if (!PT)
- return false;
-
- const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
- if (!ClsT)
- return false;
-
- IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
-
- // FIXME: Should we walk the chain of classes?
- return ClsName == &Ctx.Idents.get("NSString") ||
- ClsName == &Ctx.Idents.get("NSMutableString");
-}
-
-static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
- const PointerType *PT = T->getAsPointerType();
- if (!PT)
- return false;
-
- const RecordType *RT = PT->getPointeeType()->getAsRecordType();
- if (!RT)
- return false;
-
- const RecordDecl *RD = RT->getDecl();
- if (RD->getTagKind() != TagDecl::TK_struct)
- return false;
-
- return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
-}
-
-//===----------------------------------------------------------------------===//
-// Attribute Implementations
-//===----------------------------------------------------------------------===//
-
-// FIXME: All this manual attribute parsing code is gross. At the
-// least add some helper functions to check most argument patterns (#
-// and types of args).
-
-static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
- TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
- if (tDecl == 0) {
- S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
- return;
- }
-
- QualType curType = tDecl->getUnderlyingType();
- // check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt vecSize(32);
- if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
- "ext_vector_type", sizeExpr->getSourceRange());
- return;
- }
- // unlike gcc's vector_size attribute, we do not allow vectors to be defined
- // in conjunction with complex types (pointers, arrays, functions, etc.).
- if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
- curType.getAsString());
- return;
- }
- // unlike gcc's vector_size attribute, the size is specified as the
- // number of elements, not the number of bytes.
- unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
-
- if (vectorSize == 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
- sizeExpr->getSourceRange());
- return;
- }
- // Instantiate/Install the vector type, the number of elements is > 0.
- tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
- // Remember this typedef decl, we will need it later for diagnostics.
- S.ExtVectorDecls.push_back(tDecl);
-}
-
-
-/// HandleVectorSizeAttribute - this attribute is only applicable to
-/// integral and float scalars, although arrays, pointers, and function
-/// return values are allowed in conjunction with this construct. Aggregates
-/// with this attribute are invalid, even if they are of the same size as a
-/// corresponding scalar.
-/// The raw attribute should contain precisely 1 argument, the vector size
-/// for the variable, measured in bytes. If curType and rawAttr are well
-/// formed, this routine will return a new vector type.
-static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
- QualType CurType;
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
- CurType = VD->getType();
- else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
- CurType = TD->getUnderlyingType();
- else {
- S.Diag(D->getLocation(), diag::err_attr_wrong_decl,
- std::string("vector_size"),
- SourceRange(Attr.getLoc(), Attr.getLoc()));
- return;
- }
-
- // Check the attribute arugments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt vecSize(32);
- if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
- "vector_size", sizeExpr->getSourceRange());
- return;
- }
- // navigate to the base type - we need to provide for vector pointers,
- // vector arrays, and functions returning vectors.
- if (CurType->isPointerType() || CurType->isArrayType() ||
- CurType->isFunctionType()) {
- assert(0 && "HandleVector(): Complex type construction unimplemented");
- /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
- do {
- if (PointerType *PT = dyn_cast<PointerType>(canonType))
- canonType = PT->getPointeeType().getTypePtr();
- else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
- canonType = AT->getElementType().getTypePtr();
- else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
- canonType = FT->getResultType().getTypePtr();
- } while (canonType->isPointerType() || canonType->isArrayType() ||
- canonType->isFunctionType());
- */
- }
- // the base type must be integer or float.
- if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
- CurType.getAsString());
- return;
- }
- unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
- // vecSize is specified in bytes - convert to bits.
- unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
-
- // the vector size needs to be an integral multiple of the type size.
- if (vectorSize % typeSize) {
- S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
- sizeExpr->getSourceRange());
- return;
- }
- if (vectorSize == 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
- sizeExpr->getSourceRange());
- return;
- }
-
- // Success! Instantiate the vector type, the number of elements is > 0, and
- // not required to be a power of 2, unlike GCC.
- CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
-
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
- VD->setType(CurType);
- else
- cast<TypedefDecl>(D)->setUnderlyingType(CurType);
-}
-
-static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() > 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- if (TagDecl *TD = dyn_cast<TagDecl>(d))
- TD->addAttr(new PackedAttr());
- else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
- // If the alignment is less than or equal to 8 bits, the packed attribute
- // has no effect.
- if (!FD->getType()->isIncompleteType() &&
- S.Context.getTypeAlign(FD->getType()) <= 8)
- S.Diag(Attr.getLoc(),
- diag::warn_attribute_ignored_for_field_of_type,
- Attr.getName()->getName(), FD->getType().getAsString());
- else
- FD->addAttr(new PackedAttr());
- } else
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored,
- Attr.getName()->getName());
-}
-
-static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() > 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- // The IBOutlet attribute only applies to instance variables of Objective-C
- // classes.
- if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
- ID->addAttr(new IBOutletAttr());
- else
- S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
-}
-
-static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
-
- // GCC ignores the nonnull attribute on K&R style function
- // prototypes, so we ignore it as well
- const FunctionTypeProto *proto = getFunctionProto(d);
- if (!proto) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "nonnull", "function");
- return;
- }
-
- unsigned NumArgs = proto->getNumArgs();
-
- // The nonnull attribute only applies to pointers.
- llvm::SmallVector<unsigned, 10> NonNullArgs;
-
- for (AttributeList::arg_iterator I=Attr.arg_begin(),
- E=Attr.arg_end(); I!=E; ++I) {
-
-
- // The argument must be an integer constant expression.
- Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt ArgNum(32);
- if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
- "nonnull", Ex->getSourceRange());
- return;
- }
-
- unsigned x = (unsigned) ArgNum.getZExtValue();
-
- if (x < 1 || x > NumArgs) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
- "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange());
- return;
- }
-
- --x;
-
- // Is the function argument a pointer type?
- if (!proto->getArgType(x)->isPointerType()) {
- // FIXME: Should also highlight argument in decl.
- S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
- "nonnull", Ex->getSourceRange());
- continue;
- }
-
- NonNullArgs.push_back(x);
- }
-
- // If no arguments were specified to __attribute__((nonnull)) then all
- // pointer arguments have a nonnull attribute.
- if (NonNullArgs.empty()) {
- unsigned idx = 0;
-
- for (FunctionTypeProto::arg_type_iterator
- I=proto->arg_type_begin(), E=proto->arg_type_end(); I!=E; ++I, ++idx)
- if ((*I)->isPointerType())
- NonNullArgs.push_back(idx);
-
- if (NonNullArgs.empty()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
- return;
- }
- }
-
- unsigned* start = &NonNullArgs[0];
- unsigned size = NonNullArgs.size();
- std::sort(start, start + size);
- d->addAttr(new NonNullAttr(start, size));
-}
-
-static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
-
- Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
- Arg = Arg->IgnoreParenCasts();
- StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-
- if (Str == 0 || Str->isWide()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
- "alias", std::string("1"));
- return;
- }
-
- const char *Alias = Str->getStrData();
- unsigned AliasLen = Str->getByteLength();
-
- // FIXME: check if target symbol exists in current file
-
- d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
-}
-
-static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- if (!isa<FunctionDecl>(d) && !isa<ObjCMethodDecl>(d)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "noreturn", "function");
- return;
- }
-
- d->addAttr(new NoReturnAttr());
-}
-
-static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- if (!isa<VarDecl>(d) && !getFunctionProto(d)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "unused", "variable and function");
- return;
- }
-
- d->addAttr(new UnusedAttr());
-}
-
-static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
- return;
- }
-
- int priority = 65535; // FIXME: Do not hardcode such constants.
- if (Attr.getNumArgs() > 0) {
- Expr *E = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt Idx(32);
- if (!E->isIntegerConstantExpr(Idx, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
- "constructor", "1", E->getSourceRange());
- return;
- }
- priority = Idx.getZExtValue();
- }
-
- FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
- if (!Fn) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "constructor", "function");
- return;
- }
-
- d->addAttr(new ConstructorAttr(priority));
-}
-
-static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
- return;
- }
-
- int priority = 65535; // FIXME: Do not hardcode such constants.
- if (Attr.getNumArgs() > 0) {
- Expr *E = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt Idx(32);
- if (!E->isIntegerConstantExpr(Idx, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
- "destructor", "1", E->getSourceRange());
- return;
- }
- priority = Idx.getZExtValue();
- }
-
- if (!isa<FunctionDecl>(d)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "destructor", "function");
- return;
- }
-
- d->addAttr(new DestructorAttr(priority));
-}
-
-static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new DeprecatedAttr());
-}
-
-static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
-
- Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
- Arg = Arg->IgnoreParenCasts();
- StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-
- if (Str == 0 || Str->isWide()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
- "visibility", std::string("1"));
- return;
- }
-
- const char *TypeStr = Str->getStrData();
- unsigned TypeLen = Str->getByteLength();
- VisibilityAttr::VisibilityTypes type;
-
- if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
- type = VisibilityAttr::DefaultVisibility;
- else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
- type = VisibilityAttr::HiddenVisibility;
- else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
- type = VisibilityAttr::HiddenVisibility; // FIXME
- else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
- type = VisibilityAttr::ProtectedVisibility;
- else {
- S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
- "visibility", TypeStr);
- return;
- }
-
- d->addAttr(new VisibilityAttr(type));
-}
-
-static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- if (!Attr.getParameterName()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
- "objc_gc", std::string("1"));
- return;
- }
-
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
-
- const char *TypeStr = Attr.getParameterName()->getName();
- unsigned TypeLen = Attr.getParameterName()->getLength();
-
- ObjCGCAttr::GCAttrTypes type;
-
- if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4))
- type = ObjCGCAttr::Weak;
- else if (TypeLen == 6 && !memcmp(TypeStr, "strong", 6))
- type = ObjCGCAttr::Strong;
- else {
- S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
- "objc_gc", TypeStr);
- return;
- }
-
- d->addAttr(new ObjCGCAttr(type));
-}
-
-static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- if (!Attr.getParameterName()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
- "blocks", std::string("1"));
- return;
- }
-
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- const char *TypeStr = Attr.getParameterName()->getName();
- unsigned TypeLen = Attr.getParameterName()->getLength();
-
- BlocksAttr::BlocksAttrTypes type;
-
- if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5))
- type = BlocksAttr::ByRef;
- else {
- S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
- "blocks", TypeStr);
- return;
- }
-
- d->addAttr(new BlocksAttr(type));
-}
-
-static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() > 2) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0, 1 or 2");
- return;
- }
-
- int sentinel = 0;
- if (Attr.getNumArgs() > 0) {
- Expr *E = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt Idx(32);
- if (!E->isIntegerConstantExpr(Idx, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
- "sentinel", "1", E->getSourceRange());
- return;
- }
- sentinel = Idx.getZExtValue();
-
- if (sentinel < 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero,
- E->getSourceRange());
- return;
- }
- }
-
- int nullPos = 0;
- if (Attr.getNumArgs() > 1) {
- Expr *E = static_cast<Expr *>(Attr.getArg(1));
- llvm::APSInt Idx(32);
- if (!E->isIntegerConstantExpr(Idx, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
- "sentinel", "2", E->getSourceRange());
- return;
- }
- nullPos = Idx.getZExtValue();
-
- if (nullPos > 1 || nullPos < 0) {
- // FIXME: This error message could be improved, it would be nice
- // to say what the bounds actually are.
- S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one,
- E->getSourceRange());
- return;
- }
- }
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
- QualType FT = FD->getType();
- if (!FT->getAsFunctionTypeProto()->isVariadic()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
- return;
- }
- } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
- if (!MD->isVariadic()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
- return;
- }
- } else {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "sentinel", "function or method");
- return;
- }
-
- // FIXME: Actually create the attribute.
-}
-
-static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new WeakAttr());
-}
-
-static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new DLLImportAttr());
-}
-
-static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new DLLExportAttr());
-}
-
-static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new StdCallAttr());
-}
-
-static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new FastCallAttr());
-}
-
-static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new NoThrowAttr());
-}
-
-static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new ConstAttr());
-}
-
-static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new PureAttr());
-}
-
-/// Handle __attribute__((format(type,idx,firstarg))) attributes
-/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
-static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
-
- if (!Attr.getParameterName()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
- "format", std::string("1"));
- return;
- }
-
- if (Attr.getNumArgs() != 2) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("3"));
- return;
- }
-
- // GCC ignores the format attribute on K&R style function
- // prototypes, so we ignore it as well
- if (!isFunctionOrMethod(d)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "format", "function");
- return;
- }
-
- // FIXME: in C++ the implicit 'this' function parameter also counts.
- // this is needed in order to be compatible with GCC
- // the index must start in 1 and the limit is numargs+1
- unsigned NumArgs = getFunctionOrMethodNumArgs(d);
- unsigned FirstIdx = 1;
-
- const char *Format = Attr.getParameterName()->getName();
- unsigned FormatLen = Attr.getParameterName()->getLength();
-
- // Normalize the argument, __foo__ becomes foo.
- if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
- Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
- Format += 2;
- FormatLen -= 4;
- }
-
- bool Supported = false;
- bool is_NSString = false;
- bool is_strftime = false;
- bool is_CFString = false;
-
- switch (FormatLen) {
- default: break;
- case 5: Supported = !memcmp(Format, "scanf", 5); break;
- case 6: Supported = !memcmp(Format, "printf", 6); break;
- case 7: Supported = !memcmp(Format, "strfmon", 7); break;
- case 8:
- Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
- (is_NSString = !memcmp(Format, "NSString", 8)) ||
- (is_CFString = !memcmp(Format, "CFString", 8));
- break;
- }
-
- if (!Supported) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
- "format", Attr.getParameterName()->getName());
- return;
- }
-
- // checks for the 2nd argument
- Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt Idx(32);
- if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
- "format", std::string("2"), IdxExpr->getSourceRange());
- return;
- }
-
- if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
- "format", std::string("2"), IdxExpr->getSourceRange());
- return;
- }
-
- // FIXME: Do we need to bounds check?
- unsigned ArgIdx = Idx.getZExtValue() - 1;
-
- // make sure the format string is really a string
- QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
-
- if (is_CFString) {
- if (!isCFStringType(Ty, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
- "a CFString", IdxExpr->getSourceRange());
- return;
- }
- } else if (is_NSString) {
- // FIXME: do we need to check if the type is NSString*? What are
- // the semantics?
- if (!isNSStringType(Ty, S.Context)) {
- // FIXME: Should highlight the actual expression that has the
- // wrong type.
- S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
- "an NSString", IdxExpr->getSourceRange());
- return;
- }
- } else if (!Ty->isPointerType() ||
- !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
- // FIXME: Should highlight the actual expression that has the
- // wrong type.
- S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
- "a string type", IdxExpr->getSourceRange());
- return;
- }
-
- // check the 3rd argument
- Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
- llvm::APSInt FirstArg(32);
- if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
- "format", std::string("3"), FirstArgExpr->getSourceRange());
- return;
- }
-
- // check if the function is variadic if the 3rd argument non-zero
- if (FirstArg != 0) {
- if (isFunctionOrMethodVariadic(d)) {
- ++NumArgs; // +1 for ...
- } else {
- S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
- return;
- }
- }
-
- // strftime requires FirstArg to be 0 because it doesn't read from any variable
- // the input is just the current time + the format string
- if (is_strftime) {
- if (FirstArg != 0) {
- S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
- FirstArgExpr->getSourceRange());
- return;
- }
- // if 0 it disables parameter checking (to use with e.g. va_list)
- } else if (FirstArg != 0 && FirstArg != NumArgs) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
- "format", std::string("3"), FirstArgExpr->getSourceRange());
- return;
- }
-
- d->addAttr(new FormatAttr(std::string(Format, FormatLen),
- Idx.getZExtValue(), FirstArg.getZExtValue()));
-}
-
-static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- // FIXME: This shouldn't be restricted to typedefs
- TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
- if (!TD || !TD->getUnderlyingType()->isUnionType()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
- "transparent_union", "union");
- return;
- }
-
- RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
-
- // FIXME: Should we do a check for RD->isDefinition()?
-
- // FIXME: This isn't supposed to be restricted to pointers, but otherwise
- // we might silently generate incorrect code; see following code
- for (int i = 0; i < RD->getNumMembers(); i++) {
- if (!RD->getMember(i)->getType()->isPointerType()) {
- S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
- return;
- }
- }
-
- // FIXME: This is a complete hack; we should be properly propagating
- // transparent_union through Sema. That said, this is close enough to
- // correctly compile all the common cases of transparent_union without
- // errors or warnings
- QualType NewTy = S.Context.VoidPtrTy;
- NewTy.addConst();
- TD->setUnderlyingType(NewTy);
-}
-
-static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
- StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
-
- // Make sure that there is a string literal as the annotation's single
- // argument.
- if (!SE) {
- S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
- return;
- }
- d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
- SE->getByteLength())));
-}
-
-static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // check the attribute arguments.
- if (Attr.getNumArgs() > 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
-
- unsigned Align = 0;
- if (Attr.getNumArgs() == 0) {
- // FIXME: This should be the target specific maximum alignment.
- // (For now we just use 128 bits which is the maximum on X86.
- Align = 128;
- return;
- }
-
- Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt Alignment(32);
- if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
- "aligned", alignmentExpr->getSourceRange());
- return;
- }
- d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
-}
-
-/// HandleModeAttr - This attribute modifies the width of a decl with
-/// primitive type.
-///
-/// Despite what would be logical, the mode attribute is a decl attribute,
-/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
-/// 'G' be HImode, not an intermediate pointer.
-///
-static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
- // This attribute isn't documented, but glibc uses it. It changes
- // the width of an int or unsigned int to the specified size.
-
- // Check that there aren't any arguments
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- IdentifierInfo *Name = Attr.getParameterName();
- if (!Name) {
- S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
- return;
- }
- const char *Str = Name->getName();
- unsigned Len = Name->getLength();
-
- // Normalize the attribute name, __foo__ becomes foo.
- if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
- Str[Len - 2] == '_' && Str[Len - 1] == '_') {
- Str += 2;
- Len -= 4;
- }
-
- unsigned DestWidth = 0;
- bool IntegerMode = true;
- switch (Len) {
- case 2:
- if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; }
- if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
- if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
- if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
- if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
- if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
- if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
- if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
- if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
- break;
- case 4:
- // FIXME: glibc uses 'word' to define register_t; this is narrower than a
- // pointer on PIC16 and other embedded platforms.
- if (!memcmp(Str, "word", 4))
- DestWidth = S.Context.Target.getPointerWidth(0);
- if (!memcmp(Str, "byte", 4))
- DestWidth = S.Context.Target.getCharWidth();
- break;
- case 7:
- if (!memcmp(Str, "pointer", 7))
- DestWidth = S.Context.Target.getPointerWidth(0);
- break;
- }
-
- QualType OldTy;
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
- OldTy = TD->getUnderlyingType();
- else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
- OldTy = VD->getType();
- else {
- S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
- SourceRange(Attr.getLoc(), Attr.getLoc()));
- return;
- }
-
- // FIXME: Need proper fixed-width types
- QualType NewTy;
- switch (DestWidth) {
- case 0:
- S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
- return;
- default:
- S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
- return;
- case 8:
- assert(IntegerMode);
- if (OldTy->isSignedIntegerType())
- NewTy = S.Context.SignedCharTy;
- else
- NewTy = S.Context.UnsignedCharTy;
- break;
- case 16:
- assert(IntegerMode);
- if (OldTy->isSignedIntegerType())
- NewTy = S.Context.ShortTy;
- else
- NewTy = S.Context.UnsignedShortTy;
- break;
- case 32:
- if (!IntegerMode)
- NewTy = S.Context.FloatTy;
- else if (OldTy->isSignedIntegerType())
- NewTy = S.Context.IntTy;
- else
- NewTy = S.Context.UnsignedIntTy;
- break;
- case 64:
- if (!IntegerMode)
- NewTy = S.Context.DoubleTy;
- else if (OldTy->isSignedIntegerType())
- NewTy = S.Context.LongLongTy;
- else
- NewTy = S.Context.UnsignedLongLongTy;
- break;
- }
-
- if (!OldTy->getAsBuiltinType())
- S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
- else if (!(IntegerMode && OldTy->isIntegerType()) &&
- !(!IntegerMode && OldTy->isFloatingType())) {
- S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
- }
-
- // Install the new type.
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
- TD->setUnderlyingType(NewTy);
- else
- cast<ValueDecl>(D)->setType(NewTy);
-}
-
-//===----------------------------------------------------------------------===//
-// Top Level Sema Entry Points
-//===----------------------------------------------------------------------===//
-
-/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
-/// the attribute applies to decls. If the attribute is a type attribute, just
-/// silently ignore it.
-static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
- switch (Attr.getKind()) {
- case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break;
- case AttributeList::AT_address_space:
- // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
- break;
- case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
- case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
- case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
- case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
- case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break;
- case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break;
- case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
- case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
- case AttributeList::AT_ext_vector_type:
- HandleExtVectorTypeAttr(D, Attr, S);
- break;
- case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break;
- case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
- case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
- case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
- case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
- case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
- case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
- case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
- case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
- case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
- case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
- case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
- case AttributeList::AT_transparent_union:
- HandleTransparentUnionAttr(D, Attr, S);
- break;
- case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break;
- case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
- case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
- case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
- case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
- default:
-#if 0
- // TODO: when we have the full set of attributes, warn about unknown ones.
- S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
- Attr->getName()->getName());
-#endif
- break;
- }
-}
-
-/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
-/// attribute list to the specified decl, ignoring any type attributes.
-void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
- while (AttrList) {
- ProcessDeclAttribute(D, *AttrList, *this);
- AttrList = AttrList->getNext();
- }
-}
-
-
-/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
-/// it, apply them to D. This is a bit tricky because PD can have attributes
-/// specified in many different places, and we need to find and apply them all.
-void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
- // Apply decl attributes from the DeclSpec if present.
- if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
- ProcessDeclAttributeList(D, Attrs);
-
- // Walk the declarator structure, applying decl attributes that were in a type
- // position to the decl itself. This handles cases like:
- // int *__attr__(x)** D;
- // when X is a decl attribute.
- for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
- if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
- ProcessDeclAttributeList(D, Attrs);
-
- // Finally, apply any attributes on the decl itself.
- if (const AttributeList *Attrs = PD.getAttributes())
- ProcessDeclAttributeList(D, Attrs);
-}
-
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
deleted file mode 100644
index 4d8c16bf53e5..000000000000
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ /dev/null
@@ -1,617 +0,0 @@
-//===------ SemaDeclCXX.cpp - Semantic Analysis for C++ Declarations ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for C++ declarations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/DeclSpec.h"
-#include "llvm/Support/Compiler.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// CheckDefaultArgumentVisitor
-//===----------------------------------------------------------------------===//
-
-namespace {
- /// CheckDefaultArgumentVisitor - C++ [dcl.fct.default] Traverses
- /// the default argument of a parameter to determine whether it
- /// contains any ill-formed subexpressions. For example, this will
- /// diagnose the use of local variables or parameters within the
- /// default argument expression.
- class VISIBILITY_HIDDEN CheckDefaultArgumentVisitor
- : public StmtVisitor<CheckDefaultArgumentVisitor, bool> {
- Expr *DefaultArg;
- Sema *S;
-
- public:
- CheckDefaultArgumentVisitor(Expr *defarg, Sema *s)
- : DefaultArg(defarg), S(s) {}
-
- bool VisitExpr(Expr *Node);
- bool VisitDeclRefExpr(DeclRefExpr *DRE);
- };
-
- /// VisitExpr - Visit all of the children of this expression.
- bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) {
- bool IsInvalid = false;
- for (Stmt::child_iterator I = Node->child_begin(),
- E = Node->child_end(); I != E; ++I)
- IsInvalid |= Visit(*I);
- return IsInvalid;
- }
-
- /// VisitDeclRefExpr - Visit a reference to a declaration, to
- /// determine whether this declaration can be used in the default
- /// argument expression.
- bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(DeclRefExpr *DRE) {
- ValueDecl *Decl = DRE->getDecl();
- if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Decl)) {
- // C++ [dcl.fct.default]p9
- // Default arguments are evaluated each time the function is
- // called. The order of evaluation of function arguments is
- // unspecified. Consequently, parameters of a function shall not
- // be used in default argument expressions, even if they are not
- // evaluated. Parameters of a function declared before a default
- // argument expression are in scope and can hide namespace and
- // class member names.
- return S->Diag(DRE->getSourceRange().getBegin(),
- diag::err_param_default_argument_references_param,
- Param->getName(), DefaultArg->getSourceRange());
- } else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) {
- // C++ [dcl.fct.default]p7
- // Local variables shall not be used in default argument
- // expressions.
- if (VDecl->isBlockVarDecl())
- return S->Diag(DRE->getSourceRange().getBegin(),
- diag::err_param_default_argument_references_local,
- VDecl->getName(), DefaultArg->getSourceRange());
- }
-
- // FIXME: when Clang has support for member functions, "this"
- // will also need to be diagnosed.
-
- return false;
- }
-}
-
-/// ActOnParamDefaultArgument - Check whether the default argument
-/// provided for a function parameter is well-formed. If so, attach it
-/// to the parameter declaration.
-void
-Sema::ActOnParamDefaultArgument(DeclTy *param, SourceLocation EqualLoc,
- ExprTy *defarg) {
- ParmVarDecl *Param = (ParmVarDecl *)param;
- llvm::OwningPtr<Expr> DefaultArg((Expr *)defarg);
- QualType ParamType = Param->getType();
-
- // Default arguments are only permitted in C++
- if (!getLangOptions().CPlusPlus) {
- Diag(EqualLoc, diag::err_param_default_argument,
- DefaultArg->getSourceRange());
- return;
- }
-
- // C++ [dcl.fct.default]p5
- // A default argument expression is implicitly converted (clause
- // 4) to the parameter type. The default argument expression has
- // the same semantic constraints as the initializer expression in
- // a declaration of a variable of the parameter type, using the
- // copy-initialization semantics (8.5).
- //
- // FIXME: CheckSingleAssignmentConstraints has the wrong semantics
- // for C++ (since we want copy-initialization, not copy-assignment),
- // but we don't have the right semantics implemented yet. Because of
- // this, our error message is also very poor.
- QualType DefaultArgType = DefaultArg->getType();
- Expr *DefaultArgPtr = DefaultArg.get();
- AssignConvertType ConvTy = CheckSingleAssignmentConstraints(ParamType,
- DefaultArgPtr);
- if (DefaultArgPtr != DefaultArg.get()) {
- DefaultArg.take();
- DefaultArg.reset(DefaultArgPtr);
- }
- if (DiagnoseAssignmentResult(ConvTy, DefaultArg->getLocStart(),
- ParamType, DefaultArgType, DefaultArg.get(),
- "in default argument")) {
- return;
- }
-
- // Check that the default argument is well-formed
- CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
- if (DefaultArgChecker.Visit(DefaultArg.get()))
- return;
-
- // Okay: add the default argument to the parameter
- Param->setDefaultArg(DefaultArg.take());
-}
-
-/// CheckExtraCXXDefaultArguments - Check for any extra default
-/// arguments in the declarator, which is not a function declaration
-/// or definition and therefore is not permitted to have default
-/// arguments. This routine should be invoked for every declarator
-/// that is not a function declaration or definition.
-void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
- // C++ [dcl.fct.default]p3
- // A default argument expression shall be specified only in the
- // parameter-declaration-clause of a function declaration or in a
- // template-parameter (14.1). It shall not be specified for a
- // parameter pack. If it is specified in a
- // parameter-declaration-clause, it shall not occur within a
- // declarator or abstract-declarator of a parameter-declaration.
- for (unsigned i = 0; i < D.getNumTypeObjects(); ++i) {
- DeclaratorChunk &chunk = D.getTypeObject(i);
- if (chunk.Kind == DeclaratorChunk::Function) {
- for (unsigned argIdx = 0; argIdx < chunk.Fun.NumArgs; ++argIdx) {
- ParmVarDecl *Param = (ParmVarDecl *)chunk.Fun.ArgInfo[argIdx].Param;
- if (Param->getDefaultArg()) {
- Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc,
- Param->getDefaultArg()->getSourceRange());
- Param->setDefaultArg(0);
- }
- }
- }
- }
-}
-
-// MergeCXXFunctionDecl - Merge two declarations of the same C++
-// function, once we already know that they have the same
-// type. Subroutine of MergeFunctionDecl.
-FunctionDecl *
-Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
- // C++ [dcl.fct.default]p4:
- //
- // For non-template functions, default arguments can be added in
- // later declarations of a function in the same
- // scope. Declarations in different scopes have completely
- // distinct sets of default arguments. That is, declarations in
- // inner scopes do not acquire default arguments from
- // declarations in outer scopes, and vice versa. In a given
- // function declaration, all parameters subsequent to a
- // parameter with a default argument shall have default
- // arguments supplied in this or previous declarations. A
- // default argument shall not be redefined by a later
- // declaration (not even to the same value).
- for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams; ++p) {
- ParmVarDecl *OldParam = Old->getParamDecl(p);
- ParmVarDecl *NewParam = New->getParamDecl(p);
-
- if(OldParam->getDefaultArg() && NewParam->getDefaultArg()) {
- Diag(NewParam->getLocation(),
- diag::err_param_default_argument_redefinition,
- NewParam->getDefaultArg()->getSourceRange());
- Diag(OldParam->getLocation(), diag::err_previous_definition);
- } else if (OldParam->getDefaultArg()) {
- // Merge the old default argument into the new parameter
- NewParam->setDefaultArg(OldParam->getDefaultArg());
- }
- }
-
- return New;
-}
-
-/// CheckCXXDefaultArguments - Verify that the default arguments for a
-/// function declaration are well-formed according to C++
-/// [dcl.fct.default].
-void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
- unsigned NumParams = FD->getNumParams();
- unsigned p;
-
- // Find first parameter with a default argument
- for (p = 0; p < NumParams; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
- if (Param->getDefaultArg())
- break;
- }
-
- // C++ [dcl.fct.default]p4:
- // In a given function declaration, all parameters
- // subsequent to a parameter with a default argument shall
- // have default arguments supplied in this or previous
- // declarations. A default argument shall not be redefined
- // by a later declaration (not even to the same value).
- unsigned LastMissingDefaultArg = 0;
- for(; p < NumParams; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
- if (!Param->getDefaultArg()) {
- if (Param->getIdentifier())
- Diag(Param->getLocation(),
- diag::err_param_default_argument_missing_name,
- Param->getIdentifier()->getName());
- else
- Diag(Param->getLocation(),
- diag::err_param_default_argument_missing);
-
- LastMissingDefaultArg = p;
- }
- }
-
- if (LastMissingDefaultArg > 0) {
- // Some default arguments were missing. Clear out all of the
- // default arguments up to (and including) the last missing
- // default argument, so that we leave the function parameters
- // in a semantically valid state.
- for (p = 0; p <= LastMissingDefaultArg; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
- if (Param->getDefaultArg()) {
- delete Param->getDefaultArg();
- Param->setDefaultArg(0);
- }
- }
- }
-}
-
-/// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
-/// one entry in the base class list of a class specifier, for
-/// example:
-/// class foo : public bar, virtual private baz {
-/// 'public bar' and 'virtual private baz' are each base-specifiers.
-void Sema::ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- TypeTy *basetype, SourceLocation BaseLoc) {
- RecordDecl *Decl = (RecordDecl*)classdecl;
- QualType BaseType = Context.getTypeDeclType((TypeDecl*)basetype);
-
- // Base specifiers must be record types.
- if (!BaseType->isRecordType()) {
- Diag(BaseLoc, diag::err_base_must_be_class, SpecifierRange);
- return;
- }
-
- // C++ [class.union]p1:
- // A union shall not be used as a base class.
- if (BaseType->isUnionType()) {
- Diag(BaseLoc, diag::err_union_as_base_class, SpecifierRange);
- return;
- }
-
- // C++ [class.union]p1:
- // A union shall not have base classes.
- if (Decl->isUnion()) {
- Diag(Decl->getLocation(), diag::err_base_clause_on_union,
- SpecifierRange);
- Decl->setInvalidDecl();
- return;
- }
-
- // C++ [class.derived]p2:
- // The class-name in a base-specifier shall not be an incompletely
- // defined class.
- if (BaseType->isIncompleteType()) {
- Diag(BaseLoc, diag::err_incomplete_base_class, SpecifierRange);
- return;
- }
-
- // FIXME: C++ [class.mi]p3:
- // A class shall not be specified as a direct base class of a
- // derived class more than once.
-
- // FIXME: Attach base class to the record.
-}
-
-//===----------------------------------------------------------------------===//
-// C++ class member Handling
-//===----------------------------------------------------------------------===//
-
-/// ActOnStartCXXClassDef - This is called at the start of a class/struct/union
-/// definition, when on C++.
-void Sema::ActOnStartCXXClassDef(Scope *S, DeclTy *D, SourceLocation LBrace) {
- Decl *Dcl = static_cast<Decl *>(D);
- PushDeclContext(cast<CXXRecordDecl>(Dcl));
- FieldCollector->StartClass();
-}
-
-/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
-/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
-/// bitfield width if there is one and 'InitExpr' specifies the initializer if
-/// any. 'LastInGroup' is non-null for cases where one declspec has multiple
-/// declarators on it.
-///
-/// NOTE: Because of CXXFieldDecl's inability to be chained like ScopedDecls, if
-/// an instance field is declared, a new CXXFieldDecl is created but the method
-/// does *not* return it; it returns LastInGroup instead. The other C++ members
-/// (which are all ScopedDecls) are returned after appending them to
-/// LastInGroup.
-Sema::DeclTy *
-Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
- ExprTy *BW, ExprTy *InitExpr,
- DeclTy *LastInGroup) {
- const DeclSpec &DS = D.getDeclSpec();
- IdentifierInfo *II = D.getIdentifier();
- Expr *BitWidth = static_cast<Expr*>(BW);
- Expr *Init = static_cast<Expr*>(InitExpr);
- SourceLocation Loc = D.getIdentifierLoc();
-
- // C++ 9.2p6: A member shall not be declared to have automatic storage
- // duration (auto, register) or with the extern storage-class-specifier.
- switch (DS.getStorageClassSpec()) {
- case DeclSpec::SCS_unspecified:
- case DeclSpec::SCS_typedef:
- case DeclSpec::SCS_static:
- // FALL THROUGH.
- break;
- default:
- if (DS.getStorageClassSpecLoc().isValid())
- Diag(DS.getStorageClassSpecLoc(),
- diag::err_storageclass_invalid_for_member);
- else
- Diag(DS.getThreadSpecLoc(), diag::err_storageclass_invalid_for_member);
- D.getMutableDeclSpec().ClearStorageClassSpecs();
- }
-
- QualType T = GetTypeForDeclarator(D, S);
-
- // T->isFunctionType() is used instead of D.isFunctionDeclarator() to cover
- // this case:
- //
- // typedef int f();
- // f a;
- bool isInstField = (DS.getStorageClassSpec() == DeclSpec::SCS_unspecified &&
- !T->isFunctionType());
-
- Decl *Member;
- bool InvalidDecl = false;
-
- if (isInstField)
- Member = static_cast<Decl*>(ActOnField(S, Loc, D, BitWidth));
- else
- Member = static_cast<Decl*>(ActOnDeclarator(S, D, LastInGroup));
-
- if (!Member) return LastInGroup;
-
- assert(II || isInstField && "No identifier for non-field ?");
-
- // set/getAccess is not part of Decl's interface to avoid bloating it with C++
- // specific methods. Use a wrapper class that can be used with all C++ class
- // member decls.
- CXXClassMemberWrapper(Member).setAccess(AS);
-
- if (BitWidth) {
- // C++ 9.6p2: Only when declaring an unnamed bit-field may the
- // constant-expression be a value equal to zero.
- // FIXME: Check this.
-
- if (D.isFunctionDeclarator()) {
- // FIXME: Emit diagnostic about only constructors taking base initializers
- // or something similar, when constructor support is in place.
- Diag(Loc, diag::err_not_bitfield_type,
- II->getName(), BitWidth->getSourceRange());
- InvalidDecl = true;
-
- } else if (isInstField || isa<FunctionDecl>(Member)) {
- // An instance field or a function typedef ("typedef int f(); f a;").
- // C++ 9.6p3: A bit-field shall have integral or enumeration type.
- if (!T->isIntegralType()) {
- Diag(Loc, diag::err_not_integral_type_bitfield,
- II->getName(), BitWidth->getSourceRange());
- InvalidDecl = true;
- }
-
- } else if (isa<TypedefDecl>(Member)) {
- // "cannot declare 'A' to be a bit-field type"
- Diag(Loc, diag::err_not_bitfield_type, II->getName(),
- BitWidth->getSourceRange());
- InvalidDecl = true;
-
- } else {
- assert(isa<CXXClassVarDecl>(Member) &&
- "Didn't we cover all member kinds?");
- // C++ 9.6p3: A bit-field shall not be a static member.
- // "static member 'A' cannot be a bit-field"
- Diag(Loc, diag::err_static_not_bitfield, II->getName(),
- BitWidth->getSourceRange());
- InvalidDecl = true;
- }
- }
-
- if (Init) {
- // C++ 9.2p4: A member-declarator can contain a constant-initializer only
- // if it declares a static member of const integral or const enumeration
- // type.
- if (CXXClassVarDecl *CVD = dyn_cast<CXXClassVarDecl>(Member)) {
- // ...static member of...
- CVD->setInit(Init);
- // ...const integral or const enumeration type.
- if (Context.getCanonicalType(CVD->getType()).isConstQualified() &&
- CVD->getType()->isIntegralType()) {
- // constant-initializer
- if (CheckForConstantInitializer(Init, CVD->getType()))
- InvalidDecl = true;
-
- } else {
- // not const integral.
- Diag(Loc, diag::err_member_initialization,
- II->getName(), Init->getSourceRange());
- InvalidDecl = true;
- }
-
- } else {
- // not static member.
- Diag(Loc, diag::err_member_initialization,
- II->getName(), Init->getSourceRange());
- InvalidDecl = true;
- }
- }
-
- if (InvalidDecl)
- Member->setInvalidDecl();
-
- if (isInstField) {
- FieldCollector->Add(cast<CXXFieldDecl>(Member));
- return LastInGroup;
- }
- return Member;
-}
-
-void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- DeclTy *TagDecl,
- SourceLocation LBrac,
- SourceLocation RBrac) {
- ActOnFields(S, RLoc, TagDecl,
- (DeclTy**)FieldCollector->getCurFields(),
- FieldCollector->getCurNumFields(), LBrac, RBrac, 0);
-}
-
-void Sema::ActOnFinishCXXClassDef(DeclTy *D) {
- CXXRecordDecl *Rec = cast<CXXRecordDecl>(static_cast<Decl *>(D));
- FieldCollector->FinishClass();
- PopDeclContext();
-
- // Everything, including inline method definitions, have been parsed.
- // Let the consumer know of the new TagDecl definition.
- Consumer.HandleTagDeclDefinition(Rec);
-}
-
-//===----------------------------------------------------------------------===//
-// Namespace Handling
-//===----------------------------------------------------------------------===//
-
-/// ActOnStartNamespaceDef - This is called at the start of a namespace
-/// definition.
-Sema::DeclTy *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
- SourceLocation IdentLoc,
- IdentifierInfo *II,
- SourceLocation LBrace) {
- NamespaceDecl *Namespc =
- NamespaceDecl::Create(Context, CurContext, IdentLoc, II);
- Namespc->setLBracLoc(LBrace);
-
- Scope *DeclRegionScope = NamespcScope->getParent();
-
- if (II) {
- // C++ [namespace.def]p2:
- // The identifier in an original-namespace-definition shall not have been
- // previously defined in the declarative region in which the
- // original-namespace-definition appears. The identifier in an
- // original-namespace-definition is the name of the namespace. Subsequently
- // in that declarative region, it is treated as an original-namespace-name.
-
- Decl *PrevDecl =
- LookupDecl(II, Decl::IDNS_Tag | Decl::IDNS_Ordinary, DeclRegionScope,
- /*enableLazyBuiltinCreation=*/false);
-
- if (PrevDecl && isDeclInScope(PrevDecl, CurContext, DeclRegionScope)) {
- if (NamespaceDecl *OrigNS = dyn_cast<NamespaceDecl>(PrevDecl)) {
- // This is an extended namespace definition.
- // Attach this namespace decl to the chain of extended namespace
- // definitions.
- NamespaceDecl *NextNS = OrigNS;
- while (NextNS->getNextNamespace())
- NextNS = NextNS->getNextNamespace();
-
- NextNS->setNextNamespace(Namespc);
- Namespc->setOriginalNamespace(OrigNS);
-
- // We won't add this decl to the current scope. We want the namespace
- // name to return the original namespace decl during a name lookup.
- } else {
- // This is an invalid name redefinition.
- Diag(Namespc->getLocation(), diag::err_redefinition_different_kind,
- Namespc->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- Namespc->setInvalidDecl();
- // Continue on to push Namespc as current DeclContext and return it.
- }
- } else {
- // This namespace name is declared for the first time.
- PushOnScopeChains(Namespc, DeclRegionScope);
- }
- }
- else {
- // FIXME: Handle anonymous namespaces
- }
-
- // Although we could have an invalid decl (i.e. the namespace name is a
- // redefinition), push it as current DeclContext and try to continue parsing.
- PushDeclContext(Namespc->getOriginalNamespace());
- return Namespc;
-}
-
-/// ActOnFinishNamespaceDef - This callback is called after a namespace is
-/// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef.
-void Sema::ActOnFinishNamespaceDef(DeclTy *D, SourceLocation RBrace) {
- Decl *Dcl = static_cast<Decl *>(D);
- NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl);
- assert(Namespc && "Invalid parameter, expected NamespaceDecl");
- Namespc->setRBracLoc(RBrace);
- PopDeclContext();
-}
-
-
-/// AddCXXDirectInitializerToDecl - This action is called immediately after
-/// ActOnDeclarator, when a C++ direct initializer is present.
-/// e.g: "int x(1);"
-void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
- ExprTy **ExprTys, unsigned NumExprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc) {
- assert(NumExprs != 0 && ExprTys && "missing expressions");
- Decl *RealDecl = static_cast<Decl *>(Dcl);
-
- // If there is no declaration, there was an error parsing it. Just ignore
- // the initializer.
- if (RealDecl == 0) {
- for (unsigned i = 0; i != NumExprs; ++i)
- delete static_cast<Expr *>(ExprTys[i]);
- return;
- }
-
- VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
- if (!VDecl) {
- Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
- RealDecl->setInvalidDecl();
- return;
- }
-
- // We will treat direct-initialization as a copy-initialization:
- // int x(1); -as-> int x = 1;
- // ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
- //
- // Clients that want to distinguish between the two forms, can check for
- // direct initializer using VarDecl::hasCXXDirectInitializer().
- // A major benefit is that clients that don't particularly care about which
- // exactly form was it (like the CodeGen) can handle both cases without
- // special case code.
-
- // C++ 8.5p11:
- // The form of initialization (using parentheses or '=') is generally
- // insignificant, but does matter when the entity being initialized has a
- // class type.
-
- if (VDecl->getType()->isRecordType()) {
- // FIXME: When constructors for class types are supported, determine how
- // exactly semantic checking will be done for direct initializers.
- unsigned DiagID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error,
- "initialization for class types is not handled yet");
- Diag(VDecl->getLocation(), DiagID);
- RealDecl->setInvalidDecl();
- return;
- }
-
- if (NumExprs > 1) {
- Diag(CommaLocs[0], diag::err_builtin_direct_init_more_than_one_arg,
- SourceRange(VDecl->getLocation(), RParenLoc));
- RealDecl->setInvalidDecl();
- return;
- }
-
- // Let clients know that initialization was done with a direct initializer.
- VDecl->setCXXDirectInitializer(true);
-
- assert(NumExprs == 1 && "Expected 1 expression");
- // Set the init expression, handles conversions.
- AddInitializerToDecl(Dcl, ExprTys[0]);
-}
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
deleted file mode 100644
index 05c3bc78b31e..000000000000
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ /dev/null
@@ -1,1303 +0,0 @@
-//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for Objective C declarations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/DeclSpec.h"
-
-using namespace clang;
-
-/// ObjCActOnStartOfMethodDef - This routine sets up parameters; invisible
-/// and user declared, in the method definition's AST.
-void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
- assert(getCurMethodDecl() == 0 && "Method parsing confused");
- ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>((Decl *)D);
-
- // If we don't have a valid method decl, simply return.
- if (!MDecl)
- return;
-
- // Allow the rest of sema to find private method decl implementations.
- if (MDecl->isInstance())
- AddInstanceMethodToGlobalPool(MDecl);
- else
- AddFactoryMethodToGlobalPool(MDecl);
-
- // Allow all of Sema to see that we are entering a method definition.
- PushDeclContext(MDecl);
-
- // Create Decl objects for each parameter, entrring them in the scope for
- // binding to their use.
-
- // Insert the invisible arguments, self and _cmd!
- MDecl->createImplicitParams(Context);
-
- PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
- PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
-
- // Introduce all of the other parameters into this scope.
- for (unsigned i = 0, e = MDecl->getNumParams(); i != e; ++i) {
- ParmVarDecl *PDecl = MDecl->getParamDecl(i);
- IdentifierInfo *II = PDecl->getIdentifier();
- if (II)
- PushOnScopeChains(PDecl, FnBodyScope);
- }
-}
-
-Sema::DeclTy *Sema::
-ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperName, SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs, unsigned NumProtoRefs,
- SourceLocation EndProtoLoc, AttributeList *AttrList) {
- assert(ClassName && "Missing class identifier");
-
- // Check for another declaration kind with the same name.
- Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
- if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
- Diag(ClassLoc, diag::err_redefinition_different_kind,
- ClassName->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- }
-
- ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
- if (IDecl) {
- // Class already seen. Is it a forward declaration?
- if (!IDecl->isForwardDecl())
- Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
- else {
- IDecl->setLocation(AtInterfaceLoc);
- IDecl->setForwardDecl(false);
- }
- } else {
- IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc,
- ClassName, ClassLoc);
- if (AttrList)
- ProcessDeclAttributeList(IDecl, AttrList);
-
- ObjCInterfaceDecls[ClassName] = IDecl;
- // Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IDecl);
- }
-
- if (SuperName) {
- ObjCInterfaceDecl* SuperClassEntry = 0;
- // Check if a different kind of symbol declared in this scope.
- PrevDecl = LookupDecl(SuperName, Decl::IDNS_Ordinary, TUScope);
- if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
- Diag(SuperLoc, diag::err_redefinition_different_kind,
- SuperName->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- }
- else {
- // Check that super class is previously defined
- SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
-
- if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
- Diag(SuperLoc, diag::err_undef_superclass,
- SuperClassEntry ? SuperClassEntry->getName()
- : SuperName->getName(),
- ClassName->getName(), SourceRange(AtInterfaceLoc, ClassLoc));
- }
- }
- IDecl->setSuperClass(SuperClassEntry);
- IDecl->setSuperClassLoc(SuperLoc);
- IDecl->setLocEnd(SuperLoc);
- } else { // we have a root class.
- IDecl->setLocEnd(ClassLoc);
- }
-
- /// Check then save referenced protocols
- if (NumProtoRefs) {
- IDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
- IDecl->setLocEnd(EndProtoLoc);
- }
- return IDecl;
-}
-
-/// ActOnCompatiblityAlias - this action is called after complete parsing of
-/// @compatibility_alias declaration. It sets up the alias relationships.
-Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
- IdentifierInfo *AliasName,
- SourceLocation AliasLocation,
- IdentifierInfo *ClassName,
- SourceLocation ClassLocation) {
- // Look for previous declaration of alias name
- Decl *ADecl = LookupDecl(AliasName, Decl::IDNS_Ordinary, TUScope);
- if (ADecl) {
- if (isa<ObjCCompatibleAliasDecl>(ADecl)) {
- Diag(AliasLocation, diag::warn_previous_alias_decl);
- Diag(ADecl->getLocation(), diag::warn_previous_declaration);
- }
- else {
- Diag(AliasLocation, diag::err_conflicting_aliasing_type,
- AliasName->getName());
- Diag(ADecl->getLocation(), diag::err_previous_declaration);
- }
- return 0;
- }
- // Check for class declaration
- Decl *CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
- ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
- if (CDecl == 0) {
- Diag(ClassLocation, diag::warn_undef_interface, ClassName->getName());
- if (CDeclU)
- Diag(CDeclU->getLocation(), diag::warn_previous_declaration);
- return 0;
- }
-
- // Everything checked out, instantiate a new alias declaration AST.
- ObjCCompatibleAliasDecl *AliasDecl =
- ObjCCompatibleAliasDecl::Create(Context, AtLoc, AliasName, CDecl);
-
- ObjCAliasDecls[AliasName] = AliasDecl;
- TUScope->AddDecl(AliasDecl);
- return AliasDecl;
-}
-
-Sema::DeclTy *
-Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName,
- SourceLocation ProtocolLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList) {
- // FIXME: Deal with AttrList.
- assert(ProtocolName && "Missing protocol identifier");
- ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName];
- if (PDecl) {
- // Protocol already seen. Better be a forward protocol declaration
- if (!PDecl->isForwardDecl()) {
- Diag(ProtocolLoc, diag::err_duplicate_protocol_def,
- ProtocolName->getName());
- // Just return the protocol we already had.
- // FIXME: don't leak the objects passed in!
- return PDecl;
- }
- // Make sure the cached decl gets a valid start location.
- PDecl->setLocation(AtProtoInterfaceLoc);
- PDecl->setForwardDecl(false);
- } else {
- PDecl = ObjCProtocolDecl::Create(Context, AtProtoInterfaceLoc,ProtocolName);
- PDecl->setForwardDecl(false);
- ObjCProtocols[ProtocolName] = PDecl;
- }
-
- if (NumProtoRefs) {
- /// Check then save referenced protocols.
- PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
- PDecl->setLocEnd(EndProtoLoc);
- }
- return PDecl;
-}
-
-/// FindProtocolDeclaration - This routine looks up protocols and
-/// issues an error if they are not declared. It returns list of
-/// protocol declarations in its 'Protocols' argument.
-void
-Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
- const IdentifierLocPair *ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVectorImpl<DeclTy*> &Protocols) {
- for (unsigned i = 0; i != NumProtocols; ++i) {
- ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i].first];
- if (!PDecl) {
- Diag(ProtocolId[i].second, diag::err_undeclared_protocol,
- ProtocolId[i].first->getName());
- continue;
- }
-
- // If this is a forward declaration and we are supposed to warn in this
- // case, do it.
- if (WarnOnDeclarations && PDecl->isForwardDecl())
- Diag(ProtocolId[i].second, diag::warn_undef_protocolref,
- ProtocolId[i].first->getName());
- Protocols.push_back(PDecl);
- }
-}
-
-/// DiagnosePropertyMismatch - Compares two properties for their
-/// attributes and types and warns on a variety of inconsistencies.
-///
-void
-Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
- ObjCPropertyDecl *SuperProperty,
- const char *inheritedName) {
- ObjCPropertyDecl::PropertyAttributeKind CAttr =
- Property->getPropertyAttributes();
- ObjCPropertyDecl::PropertyAttributeKind SAttr =
- SuperProperty->getPropertyAttributes();
- if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
- && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
- Diag(Property->getLocation(), diag::warn_readonly_property,
- Property->getName(), inheritedName);
- if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
- != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
- Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "copy", inheritedName,
- SourceRange());
- else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
- != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
- Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "retain", inheritedName,
- SourceRange());
-
- if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
- != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
- Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "atomic", inheritedName,
- SourceRange());
- if (Property->getSetterName() != SuperProperty->getSetterName())
- Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "setter", inheritedName,
- SourceRange());
- if (Property->getGetterName() != SuperProperty->getGetterName())
- Diag(Property->getLocation(), diag::warn_property_attribute,
- Property->getName(), "getter", inheritedName,
- SourceRange());
-
- if (Context.getCanonicalType(Property->getType()) !=
- Context.getCanonicalType(SuperProperty->getType()))
- Diag(Property->getLocation(), diag::warn_property_type,
- Property->getType().getAsString(),
- inheritedName);
-
-}
-
-/// ComparePropertiesInBaseAndSuper - This routine compares property
-/// declarations in base and its super class, if any, and issues
-/// diagnostics in a variety of inconsistant situations.
-///
-void
-Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
- ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
- if (!SDecl)
- return;
- // FIXME: O(N^2)
- for (ObjCInterfaceDecl::classprop_iterator S = SDecl->classprop_begin(),
- E = SDecl->classprop_end(); S != E; ++S) {
- ObjCPropertyDecl *SuperPDecl = (*S);
- // Does property in super class has declaration in current class?
- for (ObjCInterfaceDecl::classprop_iterator I = IDecl->classprop_begin(),
- E = IDecl->classprop_end(); I != E; ++I) {
- ObjCPropertyDecl *PDecl = (*I);
- if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
- DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl->getName());
- }
- }
-}
-
-/// MergeOneProtocolPropertiesIntoClass - This routine goes thru the list
-/// of properties declared in a protocol and adds them to the list
-/// of properties for current class if it is not there already.
-void
-Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
- ObjCProtocolDecl *PDecl)
-{
- llvm::SmallVector<ObjCPropertyDecl*, 16> mergeProperties;
- for (ObjCProtocolDecl::classprop_iterator P = PDecl->classprop_begin(),
- E = PDecl->classprop_end(); P != E; ++P) {
- ObjCPropertyDecl *Pr = (*P);
- ObjCInterfaceDecl::classprop_iterator CP, CE;
- // Is this property already in class's list of properties?
- for (CP = IDecl->classprop_begin(), CE = IDecl->classprop_end();
- CP != CE; ++CP)
- if ((*CP)->getIdentifier() == Pr->getIdentifier())
- break;
- if (CP == CE)
- // Add this property to list of properties for thie class.
- mergeProperties.push_back(Pr);
- else
- // Property protocol already exist in class. Diagnose any mismatch.
- DiagnosePropertyMismatch((*CP), Pr, PDecl->getName());
- }
- IDecl->mergeProperties(&mergeProperties[0], mergeProperties.size());
-}
-
-/// MergeProtocolPropertiesIntoClass - This routine merges properties
-/// declared in 'MergeItsProtocols' objects (which can be a class or an
-/// inherited protocol into the list of properties for class 'IDecl'
-///
-
-void
-Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
- DeclTy *MergeItsProtocols) {
- Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols);
- if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
- for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
- E = MDecl->protocol_end(); P != E; ++P)
- // Merge properties of class (*P) into IDECL's
- MergeOneProtocolPropertiesIntoClass(IDecl, *P);
-
- // Go thru the list of protocols for this class and recursively merge
- // their properties into this class as well.
- for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
- E = IDecl->protocol_end(); P != E; ++P)
- MergeProtocolPropertiesIntoClass(IDecl, *P);
- } else {
- ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
- for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
- E = MD->protocol_end(); P != E; ++P)
- MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
- }
-}
-
-/// ActOnForwardProtocolDeclaration -
-Action::DeclTy *
-Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
- const IdentifierLocPair *IdentList,
- unsigned NumElts) {
- llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
-
- for (unsigned i = 0; i != NumElts; ++i) {
- IdentifierInfo *Ident = IdentList[i].first;
- ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident];
- if (PDecl == 0) // Not already seen?
- PDecl = ObjCProtocolDecl::Create(Context, IdentList[i].second, Ident);
-
- Protocols.push_back(PDecl);
- }
- return ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
- &Protocols[0], Protocols.size());
-}
-
-Sema::DeclTy *Sema::
-ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- DeclTy * const *ProtoRefs,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc) {
- ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
-
- ObjCCategoryDecl *CDecl =
- ObjCCategoryDecl::Create(Context, AtInterfaceLoc, CategoryName);
- CDecl->setClassInterface(IDecl);
-
- /// Check that class of this category is already completely declared.
- if (!IDecl || IDecl->isForwardDecl())
- Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
- else {
- /// Check for duplicate interface declaration for this category
- ObjCCategoryDecl *CDeclChain;
- for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
- CDeclChain = CDeclChain->getNextClassCategory()) {
- if (CategoryName && CDeclChain->getIdentifier() == CategoryName) {
- Diag(CategoryLoc, diag::warn_dup_category_def, ClassName->getName(),
- CategoryName->getName());
- break;
- }
- }
- if (!CDeclChain)
- CDecl->insertNextClassCategory();
- }
-
- if (NumProtoRefs) {
- CDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
- CDecl->setLocEnd(EndProtoLoc);
- }
- return CDecl;
-}
-
-/// ActOnStartCategoryImplementation - Perform semantic checks on the
-/// category implementation declaration and build an ObjCCategoryImplDecl
-/// object.
-Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
- SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *CatName, SourceLocation CatLoc) {
- ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
- ObjCCategoryImplDecl *CDecl =
- ObjCCategoryImplDecl::Create(Context, AtCatImplLoc, CatName, IDecl);
- /// Check that class of this category is already completely declared.
- if (!IDecl || IDecl->isForwardDecl())
- Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
-
- /// TODO: Check that CatName, category name, is not used in another
- // implementation.
- ObjCCategoryImpls.push_back(CDecl);
- return CDecl;
-}
-
-Sema::DeclTy *Sema::ActOnStartClassImplementation(
- SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc) {
- ObjCInterfaceDecl* IDecl = 0;
- // Check for another declaration kind with the same name.
- Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
- if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
- Diag(ClassLoc, diag::err_redefinition_different_kind,
- ClassName->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- }
- else {
- // Is there an interface declaration of this class; if not, warn!
- IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
- if (!IDecl)
- Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
- }
-
- // Check that super class name is valid class name
- ObjCInterfaceDecl* SDecl = 0;
- if (SuperClassname) {
- // Check if a different kind of symbol declared in this scope.
- PrevDecl = LookupDecl(SuperClassname, Decl::IDNS_Ordinary, TUScope);
- if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
- Diag(SuperClassLoc, diag::err_redefinition_different_kind,
- SuperClassname->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- }
- else {
- SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
- if (!SDecl)
- Diag(SuperClassLoc, diag::err_undef_superclass,
- SuperClassname->getName(), ClassName->getName());
- else if (IDecl && IDecl->getSuperClass() != SDecl) {
- // This implementation and its interface do not have the same
- // super class.
- Diag(SuperClassLoc, diag::err_conflicting_super_class,
- SDecl->getName());
- Diag(SDecl->getLocation(), diag::err_previous_definition);
- }
- }
- }
-
- if (!IDecl) {
- // Legacy case of @implementation with no corresponding @interface.
- // Build, chain & install the interface decl into the identifier.
-
- // FIXME: Do we support attributes on the @implementation? If so
- // we should copy them over.
- IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, ClassName,
- ClassLoc, false, true);
- ObjCInterfaceDecls[ClassName] = IDecl;
- IDecl->setSuperClass(SDecl);
- IDecl->setLocEnd(ClassLoc);
-
- // Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IDecl);
- }
-
- ObjCImplementationDecl* IMPDecl =
- ObjCImplementationDecl::Create(Context, AtClassImplLoc, ClassName,
- IDecl, SDecl);
-
- // Check that there is no duplicate implementation of this class.
- if (ObjCImplementations[ClassName])
- // FIXME: Don't leak everything!
- Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
- else // add it to the list.
- ObjCImplementations[ClassName] = IMPDecl;
- return IMPDecl;
-}
-
-void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
- ObjCIvarDecl **ivars, unsigned numIvars,
- SourceLocation RBrace) {
- assert(ImpDecl && "missing implementation decl");
- ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(ImpDecl->getIdentifier());
- if (!IDecl)
- return;
- /// Check case of non-existing @interface decl.
- /// (legacy objective-c @implementation decl without an @interface decl).
- /// Add implementations's ivar to the synthesize class's ivar list.
- if (IDecl->ImplicitInterfaceDecl()) {
- IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace);
- return;
- }
- // If implementation has empty ivar list, just return.
- if (numIvars == 0)
- return;
-
- assert(ivars && "missing @implementation ivars");
-
- // Check interface's Ivar list against those in the implementation.
- // names and types must match.
- //
- unsigned j = 0;
- ObjCInterfaceDecl::ivar_iterator
- IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
- for (; numIvars > 0 && IVI != IVE; ++IVI) {
- ObjCIvarDecl* ImplIvar = ivars[j++];
- ObjCIvarDecl* ClsIvar = *IVI;
- assert (ImplIvar && "missing implementation ivar");
- assert (ClsIvar && "missing class ivar");
- if (Context.getCanonicalType(ImplIvar->getType()) !=
- Context.getCanonicalType(ClsIvar->getType())) {
- Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type,
- ImplIvar->getIdentifier()->getName());
- Diag(ClsIvar->getLocation(), diag::err_previous_definition,
- ClsIvar->getIdentifier()->getName());
- }
- // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed
- // as error.
- else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
- Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name,
- ImplIvar->getIdentifier()->getName());
- Diag(ClsIvar->getLocation(), diag::err_previous_definition,
- ClsIvar->getIdentifier()->getName());
- return;
- }
- --numIvars;
- }
-
- if (numIvars > 0)
- Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
- else if (IVI != IVE)
- Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
-}
-
-void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
- bool &IncompleteImpl) {
- if (!IncompleteImpl) {
- Diag(ImpLoc, diag::warn_incomplete_impl);
- IncompleteImpl = true;
- }
- Diag(ImpLoc, diag::warn_undef_method_impl, method->getSelector().getName());
-}
-
-/// FIXME: Type hierarchies in Objective-C can be deep. We could most
-/// likely improve the efficiency of selector lookups and type
-/// checking by associating with each protocol / interface / category
-/// the flattened instance tables. If we used an immutable set to keep
-/// the table then it wouldn't add significant memory cost and it
-/// would be handy for lookups.
-
-/// CheckProtocolMethodDefs - This routine checks unimplemented methods
-/// Declared in protocol, and those referenced by it.
-void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
- ObjCProtocolDecl *PDecl,
- bool& IncompleteImpl,
- const llvm::DenseSet<Selector> &InsMap,
- const llvm::DenseSet<Selector> &ClsMap,
- ObjCInterfaceDecl *IDecl) {
- ObjCInterfaceDecl *Super = IDecl->getSuperClass();
-
- // If a method lookup fails locally we still need to look and see if
- // the method was implemented by a base class or an inherited
- // protocol. This lookup is slow, but occurs rarely in correct code
- // and otherwise would terminate in a warning.
-
- // check unimplemented instance methods.
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
- E = PDecl->instmeth_end(); I != E; ++I) {
- ObjCMethodDecl *method = *I;
- if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
- !InsMap.count(method->getSelector()) &&
- (!Super || !Super->lookupInstanceMethod(method->getSelector())))
- WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
- }
- // check unimplemented class methods
- for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
- E = PDecl->classmeth_end(); I != E; ++I) {
- ObjCMethodDecl *method = *I;
- if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
- !ClsMap.count(method->getSelector()) &&
- (!Super || !Super->lookupClassMethod(method->getSelector())))
- WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
- }
- // Check on this protocols's referenced protocols, recursively.
- for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
- E = PDecl->protocol_end(); PI != E; ++PI)
- CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
-}
-
-void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
- ObjCInterfaceDecl* IDecl) {
- llvm::DenseSet<Selector> InsMap;
- // Check and see if instance methods in class interface have been
- // implemented in the implementation class.
- for (ObjCImplementationDecl::instmeth_iterator I = IMPDecl->instmeth_begin(),
- E = IMPDecl->instmeth_end(); I != E; ++I)
- InsMap.insert((*I)->getSelector());
-
- bool IncompleteImpl = false;
- for (ObjCInterfaceDecl::instmeth_iterator I = IDecl->instmeth_begin(),
- E = IDecl->instmeth_end(); I != E; ++I)
- if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector()))
- WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
-
- llvm::DenseSet<Selector> ClsMap;
- // Check and see if class methods in class interface have been
- // implemented in the implementation class.
- for (ObjCImplementationDecl::classmeth_iterator I =IMPDecl->classmeth_begin(),
- E = IMPDecl->classmeth_end(); I != E; ++I)
- ClsMap.insert((*I)->getSelector());
-
- for (ObjCInterfaceDecl::classmeth_iterator I = IDecl->classmeth_begin(),
- E = IDecl->classmeth_end(); I != E; ++I)
- if (!ClsMap.count((*I)->getSelector()))
- WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
-
- // Check the protocol list for unimplemented methods in the @implementation
- // class.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- IDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end(); I != E; ++I)
- CheckProtocolMethodDefs(IMPDecl->getLocation(), *I,
- IncompleteImpl, InsMap, ClsMap, IDecl);
-}
-
-/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
-/// category interface are implemented in the category @implementation.
-void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
- ObjCCategoryDecl *CatClassDecl) {
- llvm::DenseSet<Selector> InsMap;
- // Check and see if instance methods in category interface have been
- // implemented in its implementation class.
- for (ObjCCategoryImplDecl::instmeth_iterator I =CatImplDecl->instmeth_begin(),
- E = CatImplDecl->instmeth_end(); I != E; ++I)
- InsMap.insert((*I)->getSelector());
-
- bool IncompleteImpl = false;
- for (ObjCCategoryDecl::instmeth_iterator I = CatClassDecl->instmeth_begin(),
- E = CatClassDecl->instmeth_end(); I != E; ++I)
- if (!InsMap.count((*I)->getSelector()))
- WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
-
- llvm::DenseSet<Selector> ClsMap;
- // Check and see if class methods in category interface have been
- // implemented in its implementation class.
- for (ObjCCategoryImplDecl::classmeth_iterator
- I = CatImplDecl->classmeth_begin(), E = CatImplDecl->classmeth_end();
- I != E; ++I)
- ClsMap.insert((*I)->getSelector());
-
- for (ObjCCategoryDecl::classmeth_iterator I = CatClassDecl->classmeth_begin(),
- E = CatClassDecl->classmeth_end(); I != E; ++I)
- if (!ClsMap.count((*I)->getSelector()))
- WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
-
- // Check the protocol list for unimplemented methods in the @implementation
- // class.
- for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),
- E = CatClassDecl->protocol_end(); PI != E; ++PI)
- CheckProtocolMethodDefs(CatImplDecl->getLocation(), *PI, IncompleteImpl,
- InsMap, ClsMap, CatClassDecl->getClassInterface());
-}
-
-/// ActOnForwardClassDeclaration -
-Action::DeclTy *
-Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
- IdentifierInfo **IdentList, unsigned NumElts)
-{
- llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
-
- for (unsigned i = 0; i != NumElts; ++i) {
- // Check for another declaration kind with the same name.
- Decl *PrevDecl = LookupDecl(IdentList[i], Decl::IDNS_Ordinary, TUScope);
- if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
- // GCC apparently allows the following idiom:
- //
- // typedef NSObject < XCElementTogglerP > XCElementToggler;
- // @class XCElementToggler;
- //
- // FIXME: Make an extension?
- TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
- if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
- Diag(AtClassLoc, diag::err_redefinition_different_kind,
- IdentList[i]->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_definition);
- }
- }
- ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
- if (!IDecl) { // Not already seen? Make a forward decl.
- IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, IdentList[i],
- SourceLocation(), true);
- ObjCInterfaceDecls[IdentList[i]] = IDecl;
-
- // Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IDecl);
- }
-
- Interfaces.push_back(IDecl);
- }
-
- return ObjCClassDecl::Create(Context, AtClassLoc,
- &Interfaces[0], Interfaces.size());
-}
-
-
-/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
-/// returns true, or false, accordingly.
-/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
-bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
- const ObjCMethodDecl *PrevMethod) {
- if (Context.getCanonicalType(Method->getResultType()) !=
- Context.getCanonicalType(PrevMethod->getResultType()))
- return false;
- for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) {
- ParmVarDecl *ParamDecl = Method->getParamDecl(i);
- ParmVarDecl *PrevParamDecl = PrevMethod->getParamDecl(i);
- if (Context.getCanonicalType(ParamDecl->getType()) !=
- Context.getCanonicalType(PrevParamDecl->getType()))
- return false;
- }
- return true;
-}
-
-void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
- ObjCMethodList &FirstMethod = InstanceMethodPool[Method->getSelector()];
- if (!FirstMethod.Method) {
- // Haven't seen a method with this selector name yet - add it.
- FirstMethod.Method = Method;
- FirstMethod.Next = 0;
- } else {
- // We've seen a method with this name, now check the type signature(s).
- bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-
- for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
- Next = Next->Next)
- match = MatchTwoMethodDeclarations(Method, Next->Method);
-
- if (!match) {
- // We have a new signature for an existing method - add it.
- // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
- struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
- FirstMethod.Next = OMI;
- }
- }
-}
-
-ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
- SourceRange R) {
- ObjCMethodList &MethList = InstanceMethodPool[Sel];
-
- if (MethList.Method && MethList.Next) {
- Diag(R.getBegin(), diag::warn_multiple_method_decl, Sel.getName(), R);
- Diag(MethList.Method->getLocStart(), diag::warn_using_decl,
- MethList.Method->getSourceRange());
- for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
- Diag(Next->Method->getLocStart(), diag::warn_also_found_decl,
- Next->Method->getSourceRange());
- }
- return MethList.Method;
-}
-
-void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
- ObjCMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
- if (!FirstMethod.Method) {
- // Haven't seen a method with this selector name yet - add it.
- FirstMethod.Method = Method;
- FirstMethod.Next = 0;
- } else {
- // We've seen a method with this name, now check the type signature(s).
- bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-
- for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
- Next = Next->Next)
- match = MatchTwoMethodDeclarations(Method, Next->Method);
-
- if (!match) {
- // We have a new signature for an existing method - add it.
- // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
- struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
- FirstMethod.Next = OMI;
- }
- }
-}
-
-// Note: For class/category implemenations, allMethods/allProperties is
-// always null.
-void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
- DeclTy **allMethods, unsigned allNum,
- DeclTy **allProperties, unsigned pNum) {
- Decl *ClassDecl = static_cast<Decl *>(classDecl);
-
- // FIXME: If we don't have a ClassDecl, we have an error. We should consider
- // always passing in a decl. If the decl has an error, isInvalidDecl()
- // should be true.
- if (!ClassDecl)
- return;
-
- llvm::SmallVector<ObjCMethodDecl*, 32> insMethods;
- llvm::SmallVector<ObjCMethodDecl*, 16> clsMethods;
-
- llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
- llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
-
- bool isInterfaceDeclKind =
- isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
- || isa<ObjCProtocolDecl>(ClassDecl);
- bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
-
- if (pNum != 0) {
- if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
- IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
- else if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
- CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
- else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(ClassDecl))
- PDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
- else
- assert(false && "ActOnAtEnd - property declaration misplaced");
- }
-
- for (unsigned i = 0; i < allNum; i++ ) {
- ObjCMethodDecl *Method =
- cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i]));
-
- if (!Method) continue; // Already issued a diagnostic.
- if (Method->isInstance()) {
- /// Check for instance method of the same name with incompatible types
- const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
- bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
- : false;
- if (isInterfaceDeclKind && PrevMethod && !match
- || checkIdenticalMethods && match) {
- Diag(Method->getLocation(), diag::error_duplicate_method_decl,
- Method->getSelector().getName());
- Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
- } else {
- insMethods.push_back(Method);
- InsMap[Method->getSelector()] = Method;
- /// The following allows us to typecheck messages to "id".
- AddInstanceMethodToGlobalPool(Method);
- }
- }
- else {
- /// Check for class method of the same name with incompatible types
- const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
- bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
- : false;
- if (isInterfaceDeclKind && PrevMethod && !match
- || checkIdenticalMethods && match) {
- Diag(Method->getLocation(), diag::error_duplicate_method_decl,
- Method->getSelector().getName());
- Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
- } else {
- clsMethods.push_back(Method);
- ClsMap[Method->getSelector()] = Method;
- /// The following allows us to typecheck messages to "Class".
- AddFactoryMethodToGlobalPool(Method);
- }
- }
- }
- // Save the size so we can detect if we've added any property methods.
- unsigned int insMethodsSizePriorToPropAdds = insMethods.size();
- unsigned int clsMethodsSizePriorToPropAdds = clsMethods.size();
-
- if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
- // Compares properties declared in this class to those of its
- // super class.
- ComparePropertiesInBaseAndSuper(I);
- MergeProtocolPropertiesIntoClass(I, I);
- for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
- e = I->classprop_end(); i != e; ++i)
- I->addPropertyMethods(Context, *i, insMethods);
- I->addMethods(&insMethods[0], insMethods.size(),
- &clsMethods[0], clsMethods.size(), AtEndLoc);
-
- } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
- for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
- e = P->classprop_end(); i != e; ++i)
- P->addPropertyMethods(Context, *i, insMethods);
- P->addMethods(&insMethods[0], insMethods.size(),
- &clsMethods[0], clsMethods.size(), AtEndLoc);
- }
- else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
- // FIXME: Need to compare properties to those in interface?
-
- // FIXME: If we merge properties into class we should probably
- // merge them into category as well?
- for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
- e = C->classprop_end(); i != e; ++i)
- C->addPropertyMethods(Context, *i, insMethods);
- C->addMethods(&insMethods[0], insMethods.size(),
- &clsMethods[0], clsMethods.size(), AtEndLoc);
- }
- else if (ObjCImplementationDecl *IC =
- dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
- IC->setLocEnd(AtEndLoc);
- if (ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
- ImplMethodsVsClassMethods(IC, IDecl);
- } else {
- ObjCCategoryImplDecl* CatImplClass = cast<ObjCCategoryImplDecl>(ClassDecl);
- CatImplClass->setLocEnd(AtEndLoc);
- ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface();
- // Find category interface decl and then check that all methods declared
- // in this interface are implemented in the category @implementation.
- if (IDecl) {
- for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
- Categories; Categories = Categories->getNextClassCategory()) {
- if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
- ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories);
- break;
- }
- }
- }
- }
- // Add any synthesized methods to the global pool. This allows us to
- // handle the following, which is supported by GCC (and part of the design).
- //
- // @interface Foo
- // @property double bar;
- // @end
- //
- // void thisIsUnfortunate() {
- // id foo;
- // double bar = [foo bar];
- // }
- //
- if (insMethodsSizePriorToPropAdds < insMethods.size())
- for (unsigned i = insMethodsSizePriorToPropAdds; i < insMethods.size(); i++)
- AddInstanceMethodToGlobalPool(insMethods[i]);
- if (clsMethodsSizePriorToPropAdds < clsMethods.size())
- for (unsigned i = clsMethodsSizePriorToPropAdds; i < clsMethods.size(); i++)
- AddFactoryMethodToGlobalPool(clsMethods[i]);
-}
-
-
-/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
-/// objective-c's type qualifier from the parser version of the same info.
-static Decl::ObjCDeclQualifier
-CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
- Decl::ObjCDeclQualifier ret = Decl::OBJC_TQ_None;
- if (PQTVal & ObjCDeclSpec::DQ_In)
- ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_In);
- if (PQTVal & ObjCDeclSpec::DQ_Inout)
- ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
- if (PQTVal & ObjCDeclSpec::DQ_Out)
- ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Out);
- if (PQTVal & ObjCDeclSpec::DQ_Bycopy)
- ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
- if (PQTVal & ObjCDeclSpec::DQ_Byref)
- ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
- if (PQTVal & ObjCDeclSpec::DQ_Oneway)
- ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
-
- return ret;
-}
-
-Sema::DeclTy *Sema::ActOnMethodDeclaration(
- SourceLocation MethodLoc, SourceLocation EndLoc,
- tok::TokenKind MethodType, DeclTy *classDecl,
- ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
- Selector Sel,
- // optional arguments. The number of types/arguments is obtained
- // from the Sel.getNumArgs().
- ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
- AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
- bool isVariadic) {
- Decl *ClassDecl = static_cast<Decl*>(classDecl);
-
- // Make sure we can establish a context for the method.
- if (!ClassDecl) {
- Diag(MethodLoc, diag::error_missing_method_context);
- return 0;
- }
- QualType resultDeclType;
-
- if (ReturnType)
- resultDeclType = QualType::getFromOpaquePtr(ReturnType);
- else // get the type for "id".
- resultDeclType = Context.getObjCIdType();
-
- ObjCMethodDecl* ObjCMethod =
- ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
- ClassDecl,
- MethodType == tok::minus, isVariadic,
- false,
- MethodDeclKind == tok::objc_optional ?
- ObjCMethodDecl::Optional :
- ObjCMethodDecl::Required);
-
- llvm::SmallVector<ParmVarDecl*, 16> Params;
-
- for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
- // FIXME: arg->AttrList must be stored too!
- QualType argType;
-
- if (ArgTypes[i])
- argType = QualType::getFromOpaquePtr(ArgTypes[i]);
- else
- argType = Context.getObjCIdType();
- ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
- SourceLocation(/*FIXME*/),
- ArgNames[i], argType,
- VarDecl::None, 0, 0);
- Param->setObjCDeclQualifier(
- CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
- Params.push_back(Param);
- }
-
- ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
- ObjCMethod->setObjCDeclQualifier(
- CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
- const ObjCMethodDecl *PrevMethod = 0;
-
- if (AttrList)
- ProcessDeclAttributeList(ObjCMethod, AttrList);
-
- // For implementations (which can be very "coarse grain"), we add the
- // method now. This allows the AST to implement lookup methods that work
- // incrementally (without waiting until we parse the @end). It also allows
- // us to flag multiple declaration errors as they occur.
- if (ObjCImplementationDecl *ImpDecl =
- dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
- if (MethodType == tok::minus) {
- PrevMethod = ImpDecl->getInstanceMethod(Sel);
- ImpDecl->addInstanceMethod(ObjCMethod);
- } else {
- PrevMethod = ImpDecl->getClassMethod(Sel);
- ImpDecl->addClassMethod(ObjCMethod);
- }
- }
- else if (ObjCCategoryImplDecl *CatImpDecl =
- dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
- if (MethodType == tok::minus) {
- PrevMethod = CatImpDecl->getInstanceMethod(Sel);
- CatImpDecl->addInstanceMethod(ObjCMethod);
- } else {
- PrevMethod = CatImpDecl->getClassMethod(Sel);
- CatImpDecl->addClassMethod(ObjCMethod);
- }
- }
- if (PrevMethod) {
- // You can never have two method definitions with the same name.
- Diag(ObjCMethod->getLocation(), diag::error_duplicate_method_decl,
- ObjCMethod->getSelector().getName());
- Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
- }
- return ObjCMethod;
-}
-
-void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
- SourceLocation Loc,
- unsigned &Attributes) {
- // FIXME: Improve the reported location.
-
- // readonly and readwrite conflict.
- if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
- (Attributes & ObjCDeclSpec::DQ_PR_readwrite)) {
- Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
- "readonly", "readwrite");
- Attributes ^= ObjCDeclSpec::DQ_PR_readonly;
- }
-
- // Check for copy or retain on non-object types.
- if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
- !Context.isObjCObjectPointerType(PropertyTy)) {
- Diag(Loc, diag::err_objc_property_requires_object,
- Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
- Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
- }
-
- // Check for more than one of { assign, copy, retain }.
- if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
- if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
- Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
- "assign", "copy");
- Attributes ^= ObjCDeclSpec::DQ_PR_copy;
- }
- if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
- Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
- "assign", "retain");
- Attributes ^= ObjCDeclSpec::DQ_PR_retain;
- }
- } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
- if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
- Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
- "copy", "retain");
- Attributes ^= ObjCDeclSpec::DQ_PR_retain;
- }
- }
-
- // Warn if user supplied no assignment attribute, property is
- // readwrite, and this is an object type.
- if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
- ObjCDeclSpec::DQ_PR_retain)) &&
- !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
- Context.isObjCObjectPointerType(PropertyTy)) {
- // Skip this warning in gc-only mode.
- if (getLangOptions().getGCMode() != LangOptions::GCOnly)
- Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
-
- // If non-gc code warn that this is likely inappropriate.
- if (getLangOptions().getGCMode() == LangOptions::NonGC)
- Diag(Loc, diag::warn_objc_property_default_assign_on_object);
-
- // FIXME: Implement warning dependent on NSCopying being
- // implemented. See also:
- // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
- // (please trim this list while you are at it).
- }
-}
-
-Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
- FieldDeclarator &FD,
- ObjCDeclSpec &ODS,
- Selector GetterSel,
- Selector SetterSel,
- tok::ObjCKeywordKind MethodImplKind) {
- QualType T = GetTypeForDeclarator(FD.D, S);
- unsigned Attributes = ODS.getPropertyAttributes();
-
- // May modify Attributes.
- CheckObjCPropertyAttributes(T, AtLoc, Attributes);
-
- ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, AtLoc,
- FD.D.getIdentifier(), T);
- // Regardless of setter/getter attribute, we save the default getter/setter
- // selector names in anticipation of declaration of setter/getter methods.
- PDecl->setGetterName(GetterSel);
- PDecl->setSetterName(SetterSel);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_getter)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_setter)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_assign)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_retain)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_copy)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
-
- if (MethodImplKind == tok::objc_required)
- PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
- else if (MethodImplKind == tok::objc_optional)
- PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
-
- return PDecl;
-}
-
-/// ActOnPropertyImplDecl - This routine performs semantic checks and
-/// builds the AST node for a property implementation declaration; declared
-/// as @synthesize or @dynamic.
-///
-Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
- SourceLocation PropertyLoc,
- bool Synthesize,
- DeclTy *ClassCatImpDecl,
- IdentifierInfo *PropertyId,
- IdentifierInfo *PropertyIvar) {
- Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
- // Make sure we have a context for the property implementation declaration.
- if (!ClassImpDecl) {
- Diag(AtLoc, diag::error_missing_property_context);
- return 0;
- }
- ObjCPropertyDecl *property = 0;
- ObjCInterfaceDecl* IDecl = 0;
- // Find the class or category class where this property must have
- // a declaration.
- ObjCImplementationDecl *IC = 0;
- ObjCCategoryImplDecl* CatImplClass = 0;
- if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
- IDecl = getObjCInterfaceDecl(IC->getIdentifier());
- // We always synthesize an interface for an implementation
- // without an interface decl. So, IDecl is always non-zero.
- assert(IDecl &&
- "ActOnPropertyImplDecl - @implementation without @interface");
-
- // Look for this property declaration in the @implementation's @interface
- property = IDecl->FindPropertyDeclaration(PropertyId);
- if (!property) {
- Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName());
- return 0;
- }
- }
- else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
- if (Synthesize) {
- Diag(AtLoc, diag::error_synthesize_category_decl);
- return 0;
- }
- IDecl = CatImplClass->getClassInterface();
- if (!IDecl) {
- Diag(AtLoc, diag::error_missing_property_interface);
- return 0;
- }
- ObjCCategoryDecl *Category =
- IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
-
- // If category for this implementation not found, it is an error which
- // has already been reported eralier.
- if (!Category)
- return 0;
- // Look for this property declaration in @implementation's category
- property = Category->FindPropertyDeclaration(PropertyId);
- if (!property) {
- Diag(PropertyLoc, diag::error_bad_category_property_decl,
- Category->getName());
- return 0;
- }
- }
- else {
- Diag(AtLoc, diag::error_bad_property_context);
- return 0;
- }
- ObjCIvarDecl *Ivar = 0;
- // Check that we have a valid, previously declared ivar for @synthesize
- if (Synthesize) {
- // @synthesize
- if (!PropertyIvar)
- PropertyIvar = PropertyId;
- // Check that this is a previously declared 'ivar' in 'IDecl' interface
- Ivar = IDecl->FindIvarDeclaration(PropertyIvar);
- if (!Ivar) {
- Diag(PropertyLoc, diag::error_missing_property_ivar_decl,
- PropertyId->getName());
- return 0;
- }
- QualType PropType = Context.getCanonicalType(property->getType());
- QualType IvarType = Context.getCanonicalType(Ivar->getType());
-
- // Check that type of property and its ivar are type compatible.
- if (PropType != IvarType) {
- // A readonly property is allowed to be a sub-class of the ivar type.
- if (!property->isReadOnly() ||
- CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
- Diag(PropertyLoc, diag::error_property_ivar_type, property->getName(),
- Ivar->getName());
- return 0;
- }
- }
- } else if (PropertyIvar) {
- // @dynamic
- Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
- return 0;
- }
- assert (property && "ActOnPropertyImplDecl - property declaration missing");
- ObjCPropertyImplDecl *PIDecl =
- ObjCPropertyImplDecl::Create(Context, AtLoc, PropertyLoc, property,
- (Synthesize ?
- ObjCPropertyImplDecl::Synthesize
- : ObjCPropertyImplDecl::Dynamic),
- Ivar);
- if (IC)
- IC->addPropertyImplementation(PIDecl);
- else
- CatImplClass->addPropertyImplementation(PIDecl);
-
- return PIDecl;
-}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
deleted file mode 100644
index fa18ce313e43..000000000000
--- a/clang/lib/Sema/SemaExpr.cpp
+++ /dev/null
@@ -1,3116 +0,0 @@
-//===--- SemaExpr.cpp - Semantic Analysis for Expressions -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/LiteralSupport.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Standard Promotions and Conversions
-//===----------------------------------------------------------------------===//
-
-/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
-void Sema::DefaultFunctionArrayConversion(Expr *&E) {
- QualType Ty = E->getType();
- assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
-
- if (const ReferenceType *ref = Ty->getAsReferenceType()) {
- ImpCastExprToType(E, ref->getPointeeType()); // C++ [expr]
- Ty = E->getType();
- }
- if (Ty->isFunctionType())
- ImpCastExprToType(E, Context.getPointerType(Ty));
- else if (Ty->isArrayType()) {
- // In C90 mode, arrays only promote to pointers if the array expression is
- // an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
- // type 'array of type' is converted to an expression that has type 'pointer
- // to type'...". In C99 this was changed to: C99 6.3.2.1p3: "an expression
- // that has type 'array of type' ...". The relevant change is "an lvalue"
- // (C90) to "an expression" (C99).
- //
- // C++ 4.2p1:
- // An lvalue or rvalue of type "array of N T" or "array of unknown bound of
- // T" can be converted to an rvalue of type "pointer to T".
- //
- if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
- E->isLvalue(Context) == Expr::LV_Valid)
- ImpCastExprToType(E, Context.getArrayDecayedType(Ty));
- }
-}
-
-/// UsualUnaryConversions - Performs various conversions that are common to most
-/// operators (C99 6.3). The conversions of array and function types are
-/// sometimes surpressed. For example, the array->pointer conversion doesn't
-/// apply if the array is an argument to the sizeof or address (&) operators.
-/// In these instances, this routine should *not* be called.
-Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
- QualType Ty = Expr->getType();
- assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
-
- if (const ReferenceType *Ref = Ty->getAsReferenceType()) {
- ImpCastExprToType(Expr, Ref->getPointeeType()); // C++ [expr]
- Ty = Expr->getType();
- }
- if (Ty->isPromotableIntegerType()) // C99 6.3.1.1p2
- ImpCastExprToType(Expr, Context.IntTy);
- else
- DefaultFunctionArrayConversion(Expr);
-
- return Expr;
-}
-
-/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
-/// do not have a prototype. Arguments that have type float are promoted to
-/// double. All other argument types are converted by UsualUnaryConversions().
-void Sema::DefaultArgumentPromotion(Expr *&Expr) {
- QualType Ty = Expr->getType();
- assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
-
- // If this is a 'float' (CVR qualified or typedef) promote to double.
- if (const BuiltinType *BT = Ty->getAsBuiltinType())
- if (BT->getKind() == BuiltinType::Float)
- return ImpCastExprToType(Expr, Context.DoubleTy);
-
- UsualUnaryConversions(Expr);
-}
-
-/// UsualArithmeticConversions - Performs various conversions that are common to
-/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
-/// routine returns the first non-arithmetic type found. The client is
-/// responsible for emitting appropriate error diagnostics.
-/// FIXME: verify the conversion rules for "complex int" are consistent with
-/// GCC.
-QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
- bool isCompAssign) {
- if (!isCompAssign) {
- UsualUnaryConversions(lhsExpr);
- UsualUnaryConversions(rhsExpr);
- }
- // For conversion purposes, we ignore any qualifiers.
- // For example, "const float" and "float" are equivalent.
- QualType lhs =
- Context.getCanonicalType(lhsExpr->getType()).getUnqualifiedType();
- QualType rhs =
- Context.getCanonicalType(rhsExpr->getType()).getUnqualifiedType();
-
- // If both types are identical, no conversion is needed.
- if (lhs == rhs)
- return lhs;
-
- // If either side is a non-arithmetic type (e.g. a pointer), we are done.
- // The caller can deal with this (e.g. pointer + int).
- if (!lhs->isArithmeticType() || !rhs->isArithmeticType())
- return lhs;
-
- // At this point, we have two different arithmetic types.
-
- // Handle complex types first (C99 6.3.1.8p1).
- if (lhs->isComplexType() || rhs->isComplexType()) {
- // if we have an integer operand, the result is the complex type.
- if (rhs->isIntegerType() || rhs->isComplexIntegerType()) {
- // convert the rhs to the lhs complex type.
- if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- }
- if (lhs->isIntegerType() || lhs->isComplexIntegerType()) {
- // convert the lhs to the rhs complex type.
- if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
- return rhs;
- }
- // This handles complex/complex, complex/float, or float/complex.
- // When both operands are complex, the shorter operand is converted to the
- // type of the longer, and that is the type of the result. This corresponds
- // to what is done when combining two real floating-point operands.
- // The fun begins when size promotion occur across type domains.
- // From H&S 6.3.4: When one operand is complex and the other is a real
- // floating-point type, the less precise type is converted, within it's
- // real or complex domain, to the precision of the other type. For example,
- // when combining a "long double" with a "double _Complex", the
- // "double _Complex" is promoted to "long double _Complex".
- int result = Context.getFloatingTypeOrder(lhs, rhs);
-
- if (result > 0) { // The left side is bigger, convert rhs.
- rhs = Context.getFloatingTypeOfSizeWithinDomain(lhs, rhs);
- if (!isCompAssign)
- ImpCastExprToType(rhsExpr, rhs);
- } else if (result < 0) { // The right side is bigger, convert lhs.
- lhs = Context.getFloatingTypeOfSizeWithinDomain(rhs, lhs);
- if (!isCompAssign)
- ImpCastExprToType(lhsExpr, lhs);
- }
- // At this point, lhs and rhs have the same rank/size. Now, make sure the
- // domains match. This is a requirement for our implementation, C99
- // does not require this promotion.
- if (lhs != rhs) { // Domains don't match, we have complex/float mix.
- if (lhs->isRealFloatingType()) { // handle "double, _Complex double".
- if (!isCompAssign)
- ImpCastExprToType(lhsExpr, rhs);
- return rhs;
- } else { // handle "_Complex double, double".
- if (!isCompAssign)
- ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- }
- }
- return lhs; // The domain/size match exactly.
- }
- // Now handle "real" floating types (i.e. float, double, long double).
- if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
- // if we have an integer operand, the result is the real floating type.
- if (rhs->isIntegerType() || rhs->isComplexIntegerType()) {
- // convert rhs to the lhs floating point type.
- if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- }
- if (lhs->isIntegerType() || lhs->isComplexIntegerType()) {
- // convert lhs to the rhs floating point type.
- if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
- return rhs;
- }
- // We have two real floating types, float/complex combos were handled above.
- // Convert the smaller operand to the bigger result.
- int result = Context.getFloatingTypeOrder(lhs, rhs);
-
- if (result > 0) { // convert the rhs
- if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- }
- if (result < 0) { // convert the lhs
- if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
- return rhs;
- }
- assert(0 && "Sema::UsualArithmeticConversions(): illegal float comparison");
- }
- if (lhs->isComplexIntegerType() || rhs->isComplexIntegerType()) {
- // Handle GCC complex int extension.
- const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
- const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
-
- if (lhsComplexInt && rhsComplexInt) {
- if (Context.getIntegerTypeOrder(lhsComplexInt->getElementType(),
- rhsComplexInt->getElementType()) >= 0) {
- // convert the rhs
- if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- }
- if (!isCompAssign)
- ImpCastExprToType(lhsExpr, rhs); // convert the lhs
- return rhs;
- } else if (lhsComplexInt && rhs->isIntegerType()) {
- // convert the rhs to the lhs complex type.
- if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- } else if (rhsComplexInt && lhs->isIntegerType()) {
- // convert the lhs to the rhs complex type.
- if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
- return rhs;
- }
- }
- // Finally, we have two differing integer types.
- // The rules for this case are in C99 6.3.1.8
- int compare = Context.getIntegerTypeOrder(lhs, rhs);
- bool lhsSigned = lhs->isSignedIntegerType(),
- rhsSigned = rhs->isSignedIntegerType();
- QualType destType;
- if (lhsSigned == rhsSigned) {
- // Same signedness; use the higher-ranked type
- destType = compare >= 0 ? lhs : rhs;
- } else if (compare != (lhsSigned ? 1 : -1)) {
- // The unsigned type has greater than or equal rank to the
- // signed type, so use the unsigned type
- destType = lhsSigned ? rhs : lhs;
- } else if (Context.getIntWidth(lhs) != Context.getIntWidth(rhs)) {
- // The two types are different widths; if we are here, that
- // means the signed type is larger than the unsigned type, so
- // use the signed type.
- destType = lhsSigned ? lhs : rhs;
- } else {
- // The signed type is higher-ranked than the unsigned type,
- // but isn't actually any bigger (like unsigned int and long
- // on most 32-bit systems). Use the unsigned type corresponding
- // to the signed type.
- destType = Context.getCorrespondingUnsignedType(lhsSigned ? lhs : rhs);
- }
- if (!isCompAssign) {
- ImpCastExprToType(lhsExpr, destType);
- ImpCastExprToType(rhsExpr, destType);
- }
- return destType;
-}
-
-//===----------------------------------------------------------------------===//
-// Semantic Analysis for various Expression Types
-//===----------------------------------------------------------------------===//
-
-
-/// ActOnStringLiteral - The specified tokens were lexed as pasted string
-/// fragments (e.g. "foo" "bar" L"baz"). The result string has to handle string
-/// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from
-/// multiple tokens. However, the common case is that StringToks points to one
-/// string.
-///
-Action::ExprResult
-Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
- assert(NumStringToks && "Must have at least one string!");
-
- StringLiteralParser Literal(StringToks, NumStringToks, PP, Context.Target);
- if (Literal.hadError)
- return ExprResult(true);
-
- llvm::SmallVector<SourceLocation, 4> StringTokLocs;
- for (unsigned i = 0; i != NumStringToks; ++i)
- StringTokLocs.push_back(StringToks[i].getLocation());
-
- // Verify that pascal strings aren't too large.
- if (Literal.Pascal && Literal.GetStringLength() > 256)
- return Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long,
- SourceRange(StringToks[0].getLocation(),
- StringToks[NumStringToks-1].getLocation()));
-
- QualType StrTy = Context.CharTy;
- if (Literal.AnyWide) StrTy = Context.getWCharType();
- if (Literal.Pascal) StrTy = Context.UnsignedCharTy;
-
- // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
- if (getLangOptions().CPlusPlus)
- StrTy.addConst();
-
- // Get an array type for the string, according to C99 6.4.5. This includes
- // the nul terminator character as well as the string length for pascal
- // strings.
- StrTy = Context.getConstantArrayType(StrTy,
- llvm::APInt(32, Literal.GetStringLength()+1),
- ArrayType::Normal, 0);
-
- // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
- return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
- Literal.AnyWide, StrTy,
- StringToks[0].getLocation(),
- StringToks[NumStringToks-1].getLocation());
-}
-
-/// DeclDefinedWithinScope - Return true if the specified decl is defined at or
-/// within the 'Within' scope. The current Scope is CurScope.
-///
-/// FIXME: This method is extremely inefficient (linear scan), this should not
-/// be used in common cases. Replace with the more modern DeclContext. We need
-/// to make sure both assignments below produce an error.
-///
-/// int main(int argc) {
-/// int xx;
-/// ^(int X) {
-/// xx = 4; // error (variable is not assignable)
-/// argc = 3; // no error.
-/// };
-/// }
-///
-static bool DeclDefinedWithinScope(ScopedDecl *D, Scope *Within,
- Scope *CurScope) {
- while (1) {
- assert(CurScope && "CurScope not nested within 'Within'?");
-
- // Check this scope for the decl.
- if (CurScope->isDeclScope(D)) return true;
-
- if (CurScope == Within) return false;
- CurScope = CurScope->getParent();
- }
-}
-
-/// ActOnIdentifierExpr - The parser read an identifier in expression context,
-/// validate it per-C99 6.5.1. HasTrailingLParen indicates whether this
-/// identifier is used in a function call context.
-Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
- IdentifierInfo &II,
- bool HasTrailingLParen) {
- // Could be enum-constant, value decl, instance variable, etc.
- Decl *D = LookupDecl(&II, Decl::IDNS_Ordinary, S);
-
- // If this reference is in an Objective-C method, then ivar lookup happens as
- // well.
- if (getCurMethodDecl()) {
- ScopedDecl *SD = dyn_cast_or_null<ScopedDecl>(D);
- // There are two cases to handle here. 1) scoped lookup could have failed,
- // in which case we should look for an ivar. 2) scoped lookup could have
- // found a decl, but that decl is outside the current method (i.e. a global
- // variable). In these two cases, we do a lookup for an ivar with this
- // name, if the lookup suceeds, we replace it our current decl.
- if (SD == 0 || SD->isDefinedOutsideFunctionOrMethod()) {
- ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&II)) {
- // FIXME: This should use a new expr for a direct reference, don't turn
- // this into Self->ivar, just return a BareIVarExpr or something.
- IdentifierInfo &II = Context.Idents.get("self");
- ExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false);
- return new ObjCIvarRefExpr(IV, IV->getType(), Loc,
- static_cast<Expr*>(SelfExpr.Val), true, true);
- }
- }
- // Needed to implement property "super.method" notation.
- if (SD == 0 && &II == SuperID) {
- QualType T = Context.getPointerType(Context.getObjCInterfaceType(
- getCurMethodDecl()->getClassInterface()));
- return new PredefinedExpr(Loc, T, PredefinedExpr::ObjCSuper);
- }
- }
- // If we are parsing a block, check the block parameter list.
- if (CurBlock) {
- BlockSemaInfo *BLK = CurBlock;
- do {
- for (unsigned i = 0, e = BLK->Params.size(); i != e && D == 0; ++i)
- if (BLK->Params[i]->getIdentifier() == &II)
- D = BLK->Params[i];
- if (D)
- break; // Found!
- } while ((BLK = BLK->PrevBlockInfo)); // Look through any enclosing blocks.
- }
- if (D == 0) {
- // Otherwise, this could be an implicitly declared function reference (legal
- // in C90, extension in C99).
- if (HasTrailingLParen &&
- !getLangOptions().CPlusPlus) // Not in C++.
- D = ImplicitlyDefineFunction(Loc, II, S);
- else {
- // If this name wasn't predeclared and if this is not a function call,
- // diagnose the problem.
- return Diag(Loc, diag::err_undeclared_var_use, II.getName());
- }
- }
-
- if (CXXFieldDecl *FD = dyn_cast<CXXFieldDecl>(D)) {
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
- if (MD->isStatic())
- // "invalid use of member 'x' in static member function"
- return Diag(Loc, diag::err_invalid_member_use_in_static_method,
- FD->getName());
- if (cast<CXXRecordDecl>(MD->getParent()) != FD->getParent())
- // "invalid use of nonstatic data member 'x'"
- return Diag(Loc, diag::err_invalid_non_static_member_use,
- FD->getName());
-
- if (FD->isInvalidDecl())
- return true;
-
- // FIXME: Use DeclRefExpr or a new Expr for a direct CXXField reference.
- ExprResult ThisExpr = ActOnCXXThis(SourceLocation());
- return new MemberExpr(static_cast<Expr*>(ThisExpr.Val),
- true, FD, Loc, FD->getType());
- }
-
- return Diag(Loc, diag::err_invalid_non_static_member_use, FD->getName());
- }
- if (isa<TypedefDecl>(D))
- return Diag(Loc, diag::err_unexpected_typedef, II.getName());
- if (isa<ObjCInterfaceDecl>(D))
- return Diag(Loc, diag::err_unexpected_interface, II.getName());
- if (isa<NamespaceDecl>(D))
- return Diag(Loc, diag::err_unexpected_namespace, II.getName());
-
- // Make the DeclRefExpr or BlockDeclRefExpr for the decl.
- ValueDecl *VD = cast<ValueDecl>(D);
-
- // check if referencing an identifier with __attribute__((deprecated)).
- if (VD->getAttr<DeprecatedAttr>())
- Diag(Loc, diag::warn_deprecated, VD->getName());
-
- // Only create DeclRefExpr's for valid Decl's.
- if (VD->isInvalidDecl())
- return true;
-
- // If this reference is not in a block or if the referenced variable is
- // within the block, create a normal DeclRefExpr.
- //
- // FIXME: This will create BlockDeclRefExprs for global variables,
- // function references, etc which is suboptimal :) and breaks
- // things like "integer constant expression" tests.
- //
- if (!CurBlock || DeclDefinedWithinScope(VD, CurBlock->TheScope, S) ||
- isa<EnumConstantDecl>(VD) || isa<ParmVarDecl>(VD))
- return new DeclRefExpr(VD, VD->getType(), Loc);
-
- // If we are in a block and the variable is outside the current block,
- // bind the variable reference with a BlockDeclRefExpr.
-
- // The BlocksAttr indicates the variable is bound by-reference.
- if (VD->getAttr<BlocksAttr>())
- return new BlockDeclRefExpr(VD, VD->getType(), Loc, true);
-
- // Variable will be bound by-copy, make it const within the closure.
- VD->getType().addConst();
- return new BlockDeclRefExpr(VD, VD->getType(), Loc, false);
-}
-
-Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
- tok::TokenKind Kind) {
- PredefinedExpr::IdentType IT;
-
- switch (Kind) {
- default: assert(0 && "Unknown simple primary expr!");
- case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
- case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
- case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
- }
-
- // Verify that this is in a function context.
- if (getCurFunctionDecl() == 0 && getCurMethodDecl() == 0)
- return Diag(Loc, diag::err_predef_outside_function);
-
- // Pre-defined identifiers are of type char[x], where x is the length of the
- // string.
- unsigned Length;
- if (getCurFunctionDecl())
- Length = getCurFunctionDecl()->getIdentifier()->getLength();
- else
- Length = getCurMethodDecl()->getSynthesizedMethodSize();
-
- llvm::APInt LengthI(32, Length + 1);
- QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const);
- ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
- return new PredefinedExpr(Loc, ResTy, IT);
-}
-
-Sema::ExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
- llvm::SmallString<16> CharBuffer;
- CharBuffer.resize(Tok.getLength());
- const char *ThisTokBegin = &CharBuffer[0];
- unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
-
- CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
- Tok.getLocation(), PP);
- if (Literal.hadError())
- return ExprResult(true);
-
- QualType type = getLangOptions().CPlusPlus ? Context.CharTy : Context.IntTy;
-
- return new CharacterLiteral(Literal.getValue(), Literal.isWide(), type,
- Tok.getLocation());
-}
-
-Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
- // fast path for a single digit (which is quite common). A single digit
- // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
- if (Tok.getLength() == 1) {
- const char *Ty = PP.getSourceManager().getCharacterData(Tok.getLocation());
-
- unsigned IntSize =static_cast<unsigned>(Context.getTypeSize(Context.IntTy));
- return ExprResult(new IntegerLiteral(llvm::APInt(IntSize, *Ty-'0'),
- Context.IntTy,
- Tok.getLocation()));
- }
- llvm::SmallString<512> IntegerBuffer;
- // Add padding so that NumericLiteralParser can overread by one character.
- IntegerBuffer.resize(Tok.getLength()+1);
- const char *ThisTokBegin = &IntegerBuffer[0];
-
- // Get the spelling of the token, which eliminates trigraphs, etc.
- unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
-
- NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
- Tok.getLocation(), PP);
- if (Literal.hadError)
- return ExprResult(true);
-
- Expr *Res;
-
- if (Literal.isFloatingLiteral()) {
- QualType Ty;
- if (Literal.isFloat)
- Ty = Context.FloatTy;
- else if (!Literal.isLong)
- Ty = Context.DoubleTy;
- else
- Ty = Context.LongDoubleTy;
-
- const llvm::fltSemantics &Format = Context.getFloatTypeSemantics(Ty);
-
- // isExact will be set by GetFloatValue().
- bool isExact = false;
- Res = new FloatingLiteral(Literal.GetFloatValue(Format, &isExact), &isExact,
- Ty, Tok.getLocation());
-
- } else if (!Literal.isIntegerLiteral()) {
- return ExprResult(true);
- } else {
- QualType Ty;
-
- // long long is a C99 feature.
- if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
- Literal.isLongLong)
- Diag(Tok.getLocation(), diag::ext_longlong);
-
- // Get the value in the widest-possible width.
- llvm::APInt ResultVal(Context.Target.getIntMaxTWidth(), 0);
-
- if (Literal.GetIntegerValue(ResultVal)) {
- // If this value didn't fit into uintmax_t, warn and force to ull.
- Diag(Tok.getLocation(), diag::warn_integer_too_large);
- Ty = Context.UnsignedLongLongTy;
- assert(Context.getTypeSize(Ty) == ResultVal.getBitWidth() &&
- "long long is not intmax_t?");
- } else {
- // If this value fits into a ULL, try to figure out what else it fits into
- // according to the rules of C99 6.4.4.1p5.
-
- // Octal, Hexadecimal, and integers with a U suffix are allowed to
- // be an unsigned int.
- bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10;
-
- // Check from smallest to largest, picking the smallest type we can.
- unsigned Width = 0;
- if (!Literal.isLong && !Literal.isLongLong) {
- // Are int/unsigned possibilities?
- unsigned IntSize = Context.Target.getIntWidth();
-
- // Does it fit in a unsigned int?
- if (ResultVal.isIntN(IntSize)) {
- // Does it fit in a signed int?
- if (!Literal.isUnsigned && ResultVal[IntSize-1] == 0)
- Ty = Context.IntTy;
- else if (AllowUnsigned)
- Ty = Context.UnsignedIntTy;
- Width = IntSize;
- }
- }
-
- // Are long/unsigned long possibilities?
- if (Ty.isNull() && !Literal.isLongLong) {
- unsigned LongSize = Context.Target.getLongWidth();
-
- // Does it fit in a unsigned long?
- if (ResultVal.isIntN(LongSize)) {
- // Does it fit in a signed long?
- if (!Literal.isUnsigned && ResultVal[LongSize-1] == 0)
- Ty = Context.LongTy;
- else if (AllowUnsigned)
- Ty = Context.UnsignedLongTy;
- Width = LongSize;
- }
- }
-
- // Finally, check long long if needed.
- if (Ty.isNull()) {
- unsigned LongLongSize = Context.Target.getLongLongWidth();
-
- // Does it fit in a unsigned long long?
- if (ResultVal.isIntN(LongLongSize)) {
- // Does it fit in a signed long long?
- if (!Literal.isUnsigned && ResultVal[LongLongSize-1] == 0)
- Ty = Context.LongLongTy;
- else if (AllowUnsigned)
- Ty = Context.UnsignedLongLongTy;
- Width = LongLongSize;
- }
- }
-
- // If we still couldn't decide a type, we probably have something that
- // does not fit in a signed long long, but has no U suffix.
- if (Ty.isNull()) {
- Diag(Tok.getLocation(), diag::warn_integer_too_large_for_signed);
- Ty = Context.UnsignedLongLongTy;
- Width = Context.Target.getLongLongWidth();
- }
-
- if (ResultVal.getBitWidth() != Width)
- ResultVal.trunc(Width);
- }
-
- Res = new IntegerLiteral(ResultVal, Ty, Tok.getLocation());
- }
-
- // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
- if (Literal.isImaginary)
- Res = new ImaginaryLiteral(Res, Context.getComplexType(Res->getType()));
-
- return Res;
-}
-
-Action::ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R,
- ExprTy *Val) {
- Expr *E = (Expr *)Val;
- assert((E != 0) && "ActOnParenExpr() missing expr");
- return new ParenExpr(L, R, E);
-}
-
-/// The UsualUnaryConversions() function is *not* called by this routine.
-/// See C99 6.3.2.1p[2-4] for more details.
-QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType,
- SourceLocation OpLoc,
- const SourceRange &ExprRange,
- bool isSizeof) {
- // C99 6.5.3.4p1:
- if (isa<FunctionType>(exprType) && isSizeof)
- // alignof(function) is allowed.
- Diag(OpLoc, diag::ext_sizeof_function_type, ExprRange);
- else if (exprType->isVoidType())
- Diag(OpLoc, diag::ext_sizeof_void_type, isSizeof ? "sizeof" : "__alignof",
- ExprRange);
- else if (exprType->isIncompleteType()) {
- Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type :
- diag::err_alignof_incomplete_type,
- exprType.getAsString(), ExprRange);
- return QualType(); // error
- }
- // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
- return Context.getSizeType();
-}
-
-Action::ExprResult Sema::
-ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
- SourceLocation LPLoc, TypeTy *Ty,
- SourceLocation RPLoc) {
- // If error parsing type, ignore.
- if (Ty == 0) return true;
-
- // Verify that this is a valid expression.
- QualType ArgTy = QualType::getFromOpaquePtr(Ty);
-
- QualType resultType =
- CheckSizeOfAlignOfOperand(ArgTy, OpLoc, SourceRange(LPLoc, RPLoc),isSizeof);
-
- if (resultType.isNull())
- return true;
- return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, resultType, OpLoc, RPLoc);
-}
-
-QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc) {
- DefaultFunctionArrayConversion(V);
-
- // These operators return the element type of a complex type.
- if (const ComplexType *CT = V->getType()->getAsComplexType())
- return CT->getElementType();
-
- // Otherwise they pass through real integer and floating point types here.
- if (V->getType()->isArithmeticType())
- return V->getType();
-
- // Reject anything else.
- Diag(Loc, diag::err_realimag_invalid_type, V->getType().getAsString());
- return QualType();
-}
-
-
-
-Action::ExprResult Sema::ActOnPostfixUnaryOp(SourceLocation OpLoc,
- tok::TokenKind Kind,
- ExprTy *Input) {
- UnaryOperator::Opcode Opc;
- switch (Kind) {
- default: assert(0 && "Unknown unary op!");
- case tok::plusplus: Opc = UnaryOperator::PostInc; break;
- case tok::minusminus: Opc = UnaryOperator::PostDec; break;
- }
- QualType result = CheckIncrementDecrementOperand((Expr *)Input, OpLoc);
- if (result.isNull())
- return true;
- return new UnaryOperator((Expr *)Input, Opc, result, OpLoc);
-}
-
-Action::ExprResult Sema::
-ActOnArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
- ExprTy *Idx, SourceLocation RLoc) {
- Expr *LHSExp = static_cast<Expr*>(Base), *RHSExp = static_cast<Expr*>(Idx);
-
- // Perform default conversions.
- DefaultFunctionArrayConversion(LHSExp);
- DefaultFunctionArrayConversion(RHSExp);
-
- QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
-
- // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent
- // to the expression *((e1)+(e2)). This means the array "Base" may actually be
- // in the subscript position. As a result, we need to derive the array base
- // and index from the expression types.
- Expr *BaseExpr, *IndexExpr;
- QualType ResultType;
- if (const PointerType *PTy = LHSTy->getAsPointerType()) {
- BaseExpr = LHSExp;
- IndexExpr = RHSExp;
- // FIXME: need to deal with const...
- ResultType = PTy->getPointeeType();
- } else if (const PointerType *PTy = RHSTy->getAsPointerType()) {
- // Handle the uncommon case of "123[Ptr]".
- BaseExpr = RHSExp;
- IndexExpr = LHSExp;
- // FIXME: need to deal with const...
- ResultType = PTy->getPointeeType();
- } else if (const VectorType *VTy = LHSTy->getAsVectorType()) {
- BaseExpr = LHSExp; // vectors: V[123]
- IndexExpr = RHSExp;
-
- // Component access limited to variables (reject vec4.rg[1]).
- if (!isa<DeclRefExpr>(BaseExpr) && !isa<ArraySubscriptExpr>(BaseExpr) &&
- !isa<ExtVectorElementExpr>(BaseExpr))
- return Diag(LLoc, diag::err_ext_vector_component_access,
- SourceRange(LLoc, RLoc));
- // FIXME: need to deal with const...
- ResultType = VTy->getElementType();
- } else {
- return Diag(LHSExp->getLocStart(), diag::err_typecheck_subscript_value,
- RHSExp->getSourceRange());
- }
- // C99 6.5.2.1p1
- if (!IndexExpr->getType()->isIntegerType())
- return Diag(IndexExpr->getLocStart(), diag::err_typecheck_subscript,
- IndexExpr->getSourceRange());
-
- // C99 6.5.2.1p1: "shall have type "pointer to *object* type". In practice,
- // the following check catches trying to index a pointer to a function (e.g.
- // void (*)(int)) and pointers to incomplete types. Functions are not
- // objects in C99.
- if (!ResultType->isObjectType())
- return Diag(BaseExpr->getLocStart(),
- diag::err_typecheck_subscript_not_object,
- BaseExpr->getType().getAsString(), BaseExpr->getSourceRange());
-
- return new ArraySubscriptExpr(LHSExp, RHSExp, ResultType, RLoc);
-}
-
-QualType Sema::
-CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
- IdentifierInfo &CompName, SourceLocation CompLoc) {
- const ExtVectorType *vecType = baseType->getAsExtVectorType();
-
- // This flag determines whether or not the component is to be treated as a
- // special name, or a regular GLSL-style component access.
- bool SpecialComponent = false;
-
- // The vector accessor can't exceed the number of elements.
- const char *compStr = CompName.getName();
- if (strlen(compStr) > vecType->getNumElements()) {
- Diag(OpLoc, diag::err_ext_vector_component_exceeds_length,
- baseType.getAsString(), SourceRange(CompLoc));
- return QualType();
- }
-
- // Check that we've found one of the special components, or that the component
- // names must come from the same set.
- if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
- !strcmp(compStr, "e") || !strcmp(compStr, "o")) {
- SpecialComponent = true;
- } else if (vecType->getPointAccessorIdx(*compStr) != -1) {
- do
- compStr++;
- while (*compStr && vecType->getPointAccessorIdx(*compStr) != -1);
- } else if (vecType->getColorAccessorIdx(*compStr) != -1) {
- do
- compStr++;
- while (*compStr && vecType->getColorAccessorIdx(*compStr) != -1);
- } else if (vecType->getTextureAccessorIdx(*compStr) != -1) {
- do
- compStr++;
- while (*compStr && vecType->getTextureAccessorIdx(*compStr) != -1);
- }
-
- if (!SpecialComponent && *compStr) {
- // We didn't get to the end of the string. This means the component names
- // didn't come from the same set *or* we encountered an illegal name.
- Diag(OpLoc, diag::err_ext_vector_component_name_illegal,
- std::string(compStr,compStr+1), SourceRange(CompLoc));
- return QualType();
- }
- // Each component accessor can't exceed the vector type.
- compStr = CompName.getName();
- while (*compStr) {
- if (vecType->isAccessorWithinNumElements(*compStr))
- compStr++;
- else
- break;
- }
- if (!SpecialComponent && *compStr) {
- // We didn't get to the end of the string. This means a component accessor
- // exceeds the number of elements in the vector.
- Diag(OpLoc, diag::err_ext_vector_component_exceeds_length,
- baseType.getAsString(), SourceRange(CompLoc));
- return QualType();
- }
-
- // If we have a special component name, verify that the current vector length
- // is an even number, since all special component names return exactly half
- // the elements.
- if (SpecialComponent && (vecType->getNumElements() & 1U)) {
- Diag(OpLoc, diag::err_ext_vector_component_requires_even,
- baseType.getAsString(), SourceRange(CompLoc));
- return QualType();
- }
-
- // The component accessor looks fine - now we need to compute the actual type.
- // The vector type is implied by the component accessor. For example,
- // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
- // vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2.
- unsigned CompSize = SpecialComponent ? vecType->getNumElements() / 2
- : strlen(CompName.getName());
- if (CompSize == 1)
- return vecType->getElementType();
-
- QualType VT = Context.getExtVectorType(vecType->getElementType(), CompSize);
- // Now look up the TypeDefDecl from the vector type. Without this,
- // diagostics look bad. We want extended vector types to appear built-in.
- for (unsigned i = 0, E = ExtVectorDecls.size(); i != E; ++i) {
- if (ExtVectorDecls[i]->getUnderlyingType() == VT)
- return Context.getTypedefType(ExtVectorDecls[i]);
- }
- return VT; // should never get here (a typedef type should always be found).
-}
-
-/// constructSetterName - Return the setter name for the given
-/// identifier, i.e. "set" + Name where the initial character of Name
-/// has been capitalized.
-// FIXME: Merge with same routine in Parser. But where should this
-// live?
-static IdentifierInfo *constructSetterName(IdentifierTable &Idents,
- const IdentifierInfo *Name) {
- unsigned N = Name->getLength();
- char *SelectorName = new char[3 + N];
- memcpy(SelectorName, "set", 3);
- memcpy(&SelectorName[3], Name->getName(), N);
- SelectorName[3] = toupper(SelectorName[3]);
-
- IdentifierInfo *Setter =
- &Idents.get(SelectorName, &SelectorName[3 + N]);
- delete[] SelectorName;
- return Setter;
-}
-
-Action::ExprResult Sema::
-ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
- tok::TokenKind OpKind, SourceLocation MemberLoc,
- IdentifierInfo &Member) {
- Expr *BaseExpr = static_cast<Expr *>(Base);
- assert(BaseExpr && "no record expression");
-
- // Perform default conversions.
- DefaultFunctionArrayConversion(BaseExpr);
-
- QualType BaseType = BaseExpr->getType();
- assert(!BaseType.isNull() && "no type for member expression");
-
- // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
- // must have pointer type, and the accessed type is the pointee.
- if (OpKind == tok::arrow) {
- if (const PointerType *PT = BaseType->getAsPointerType())
- BaseType = PT->getPointeeType();
- else
- return Diag(MemberLoc, diag::err_typecheck_member_reference_arrow,
- BaseType.getAsString(), BaseExpr->getSourceRange());
- }
-
- // Handle field access to simple records. This also handles access to fields
- // of the ObjC 'id' struct.
- if (const RecordType *RTy = BaseType->getAsRecordType()) {
- RecordDecl *RDecl = RTy->getDecl();
- if (RTy->isIncompleteType())
- return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RDecl->getName(),
- BaseExpr->getSourceRange());
- // The record definition is complete, now make sure the member is valid.
- FieldDecl *MemberDecl = RDecl->getMember(&Member);
- if (!MemberDecl)
- return Diag(MemberLoc, diag::err_typecheck_no_member, Member.getName(),
- BaseExpr->getSourceRange());
-
- // Figure out the type of the member; see C99 6.5.2.3p3
- // FIXME: Handle address space modifiers
- QualType MemberType = MemberDecl->getType();
- unsigned combinedQualifiers =
- MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers();
- MemberType = MemberType.getQualifiedType(combinedQualifiers);
-
- return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl,
- MemberLoc, MemberType);
- }
-
- // Handle access to Objective-C instance variables, such as "Obj->ivar" and
- // (*Obj).ivar.
- if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) {
- if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member))
- return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr,
- OpKind == tok::arrow);
- return Diag(MemberLoc, diag::err_typecheck_member_reference_ivar,
- IFTy->getDecl()->getName(), Member.getName(),
- BaseExpr->getSourceRange());
- }
-
- // Handle Objective-C property access, which is "Obj.property" where Obj is a
- // pointer to a (potentially qualified) interface type.
- const PointerType *PTy;
- const ObjCInterfaceType *IFTy;
- if (OpKind == tok::period && (PTy = BaseType->getAsPointerType()) &&
- (IFTy = PTy->getPointeeType()->getAsObjCInterfaceType())) {
- ObjCInterfaceDecl *IFace = IFTy->getDecl();
-
- // Search for a declared property first.
- if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member))
- return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr);
-
- // Check protocols on qualified interfaces.
- for (ObjCInterfaceType::qual_iterator I = IFTy->qual_begin(),
- E = IFTy->qual_end(); I != E; ++I)
- if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member))
- return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr);
-
- // If that failed, look for an "implicit" property by seeing if the nullary
- // selector is implemented.
-
- // FIXME: The logic for looking up nullary and unary selectors should be
- // shared with the code in ActOnInstanceMessage.
-
- Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
-
- // If this reference is in an @implementation, check for 'private' methods.
- if (!Getter)
- if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
- if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Getter = ImpDecl->getInstanceMethod(Sel);
-
- if (Getter) {
- // If we found a getter then this may be a valid dot-reference, we
- // need to also look for the matching setter.
- IdentifierInfo *SetterName = constructSetterName(PP.getIdentifierTable(),
- &Member);
- Selector SetterSel = PP.getSelectorTable().getUnarySelector(SetterName);
- ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
-
- if (!Setter) {
- if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
- if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Setter = ImpDecl->getInstanceMethod(SetterSel);
- }
-
- // FIXME: There are some issues here. First, we are not
- // diagnosing accesses to read-only properties because we do not
- // know if this is a getter or setter yet. Second, we are
- // checking that the type of the setter matches the type we
- // expect.
- return new ObjCPropertyRefExpr(Getter, Setter, Getter->getResultType(),
- MemberLoc, BaseExpr);
- }
- }
-
- // Handle 'field access' to vectors, such as 'V.xx'.
- if (BaseType->isExtVectorType() && OpKind == tok::period) {
- // Component access limited to variables (reject vec4.rg.g).
- if (!isa<DeclRefExpr>(BaseExpr) && !isa<ArraySubscriptExpr>(BaseExpr) &&
- !isa<ExtVectorElementExpr>(BaseExpr))
- return Diag(MemberLoc, diag::err_ext_vector_component_access,
- BaseExpr->getSourceRange());
- QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc);
- if (ret.isNull())
- return true;
- return new ExtVectorElementExpr(ret, BaseExpr, Member, MemberLoc);
- }
-
- return Diag(MemberLoc, diag::err_typecheck_member_reference_struct_union,
- BaseType.getAsString(), BaseExpr->getSourceRange());
-}
-
-/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
-/// This provides the location of the left/right parens and a list of comma
-/// locations.
-Action::ExprResult Sema::
-ActOnCallExpr(ExprTy *fn, SourceLocation LParenLoc,
- ExprTy **args, unsigned NumArgs,
- SourceLocation *CommaLocs, SourceLocation RParenLoc) {
- Expr *Fn = static_cast<Expr *>(fn);
- Expr **Args = reinterpret_cast<Expr**>(args);
- assert(Fn && "no function call expression");
- FunctionDecl *FDecl = NULL;
-
- // Promote the function operand.
- UsualUnaryConversions(Fn);
-
- // If we're directly calling a function, get the declaration for
- // that function.
- if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
- if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr()))
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
-
- // Make the call expr early, before semantic checks. This guarantees cleanup
- // of arguments and function on error.
- llvm::OwningPtr<CallExpr> TheCall(new CallExpr(Fn, Args, NumArgs,
- Context.BoolTy, RParenLoc));
- const FunctionType *FuncT;
- if (!Fn->getType()->isBlockPointerType()) {
- // C99 6.5.2.2p1 - "The expression that denotes the called function shall
- // have type pointer to function".
- const PointerType *PT = Fn->getType()->getAsPointerType();
- if (PT == 0)
- return Diag(LParenLoc, diag::err_typecheck_call_not_function,
- Fn->getSourceRange());
- FuncT = PT->getPointeeType()->getAsFunctionType();
- } else { // This is a block call.
- FuncT = Fn->getType()->getAsBlockPointerType()->getPointeeType()->
- getAsFunctionType();
- }
- if (FuncT == 0)
- return Diag(LParenLoc, diag::err_typecheck_call_not_function,
- Fn->getSourceRange());
-
- // We know the result type of the call, set it.
- TheCall->setType(FuncT->getResultType());
-
- if (const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(FuncT)) {
- // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by
- // assignment, to the types of the corresponding parameter, ...
- unsigned NumArgsInProto = Proto->getNumArgs();
- unsigned NumArgsToCheck = NumArgs;
-
- // If too few arguments are available (and we don't have default
- // arguments for the remaining parameters), don't make the call.
- if (NumArgs < NumArgsInProto) {
- if (FDecl && NumArgs >= FDecl->getMinRequiredArguments()) {
- // Use default arguments for missing arguments
- NumArgsToCheck = NumArgsInProto;
- TheCall->setNumArgs(NumArgsInProto);
- } else
- return Diag(RParenLoc,
- !Fn->getType()->isBlockPointerType()
- ? diag::err_typecheck_call_too_few_args
- : diag::err_typecheck_block_too_few_args,
- Fn->getSourceRange());
- }
-
- // If too many are passed and not variadic, error on the extras and drop
- // them.
- if (NumArgs > NumArgsInProto) {
- if (!Proto->isVariadic()) {
- Diag(Args[NumArgsInProto]->getLocStart(),
- !Fn->getType()->isBlockPointerType()
- ? diag::err_typecheck_call_too_many_args
- : diag::err_typecheck_block_too_many_args,
- Fn->getSourceRange(),
- SourceRange(Args[NumArgsInProto]->getLocStart(),
- Args[NumArgs-1]->getLocEnd()));
- // This deletes the extra arguments.
- TheCall->setNumArgs(NumArgsInProto);
- }
- NumArgsToCheck = NumArgsInProto;
- }
-
- // Continue to check argument types (even if we have too few/many args).
- for (unsigned i = 0; i != NumArgsToCheck; i++) {
- QualType ProtoArgType = Proto->getArgType(i);
-
- Expr *Arg;
- if (i < NumArgs)
- Arg = Args[i];
- else
- Arg = new CXXDefaultArgExpr(FDecl->getParamDecl(i));
- QualType ArgType = Arg->getType();
-
- // Compute implicit casts from the operand to the formal argument type.
- AssignConvertType ConvTy =
- CheckSingleAssignmentConstraints(ProtoArgType, Arg);
- TheCall->setArg(i, Arg);
-
- if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), ProtoArgType,
- ArgType, Arg, "passing"))
- return true;
- }
-
- // If this is a variadic call, handle args passed through "...".
- if (Proto->isVariadic()) {
- // Promote the arguments (C99 6.5.2.2p7).
- for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
- Expr *Arg = Args[i];
- DefaultArgumentPromotion(Arg);
- TheCall->setArg(i, Arg);
- }
- }
- } else {
- assert(isa<FunctionTypeNoProto>(FuncT) && "Unknown FunctionType!");
-
- // Promote the arguments (C99 6.5.2.2p6).
- for (unsigned i = 0; i != NumArgs; i++) {
- Expr *Arg = Args[i];
- DefaultArgumentPromotion(Arg);
- TheCall->setArg(i, Arg);
- }
- }
-
- // Do special checking on direct calls to functions.
- if (FDecl)
- return CheckFunctionCall(FDecl, TheCall.take());
-
- return TheCall.take();
-}
-
-Action::ExprResult Sema::
-ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprTy *InitExpr) {
- assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
- QualType literalType = QualType::getFromOpaquePtr(Ty);
- // FIXME: put back this assert when initializers are worked out.
- //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
- Expr *literalExpr = static_cast<Expr*>(InitExpr);
-
- if (literalType->isArrayType()) {
- if (literalType->isVariableArrayType())
- return Diag(LParenLoc,
- diag::err_variable_object_no_init,
- SourceRange(LParenLoc,
- literalExpr->getSourceRange().getEnd()));
- } else if (literalType->isIncompleteType()) {
- return Diag(LParenLoc,
- diag::err_typecheck_decl_incomplete_type,
- literalType.getAsString(),
- SourceRange(LParenLoc,
- literalExpr->getSourceRange().getEnd()));
- }
-
- if (CheckInitializerTypes(literalExpr, literalType))
- return true;
-
- bool isFileScope = !getCurFunctionDecl() && !getCurMethodDecl();
- if (isFileScope) { // 6.5.2.5p3
- if (CheckForConstantInitializer(literalExpr, literalType))
- return true;
- }
- return new CompoundLiteralExpr(LParenLoc, literalType, literalExpr, isFileScope);
-}
-
-Action::ExprResult Sema::
-ActOnInitList(SourceLocation LBraceLoc, ExprTy **initlist, unsigned NumInit,
- SourceLocation RBraceLoc) {
- Expr **InitList = reinterpret_cast<Expr**>(initlist);
-
- // Semantic analysis for initializers is done by ActOnDeclarator() and
- // CheckInitializer() - it requires knowledge of the object being intialized.
-
- InitListExpr *E = new InitListExpr(LBraceLoc, InitList, NumInit, RBraceLoc);
- E->setType(Context.VoidTy); // FIXME: just a place holder for now.
- return E;
-}
-
-/// CheckCastTypes - Check type constraints for casting between types.
-bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) {
- UsualUnaryConversions(castExpr);
-
- // C99 6.5.4p2: the cast type needs to be void or scalar and the expression
- // type needs to be scalar.
- if (castType->isVoidType()) {
- // Cast to void allows any expr type.
- } else if (!castType->isScalarType() && !castType->isVectorType()) {
- // GCC struct/union extension: allow cast to self.
- if (Context.getCanonicalType(castType) !=
- Context.getCanonicalType(castExpr->getType()) ||
- (!castType->isStructureType() && !castType->isUnionType())) {
- // Reject any other conversions to non-scalar types.
- return Diag(TyR.getBegin(), diag::err_typecheck_cond_expect_scalar,
- castType.getAsString(), castExpr->getSourceRange());
- }
-
- // accept this, but emit an ext-warn.
- Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar,
- castType.getAsString(), castExpr->getSourceRange());
- } else if (!castExpr->getType()->isScalarType() &&
- !castExpr->getType()->isVectorType()) {
- return Diag(castExpr->getLocStart(),
- diag::err_typecheck_expect_scalar_operand,
- castExpr->getType().getAsString(),castExpr->getSourceRange());
- } else if (castExpr->getType()->isVectorType()) {
- if (CheckVectorCast(TyR, castExpr->getType(), castType))
- return true;
- } else if (castType->isVectorType()) {
- if (CheckVectorCast(TyR, castType, castExpr->getType()))
- return true;
- }
- return false;
-}
-
-bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) {
- assert(VectorTy->isVectorType() && "Not a vector type!");
-
- if (Ty->isVectorType() || Ty->isIntegerType()) {
- if (Context.getTypeSize(VectorTy) != Context.getTypeSize(Ty))
- return Diag(R.getBegin(),
- Ty->isVectorType() ?
- diag::err_invalid_conversion_between_vectors :
- diag::err_invalid_conversion_between_vector_and_integer,
- VectorTy.getAsString().c_str(),
- Ty.getAsString().c_str(), R);
- } else
- return Diag(R.getBegin(),
- diag::err_invalid_conversion_between_vector_and_scalar,
- VectorTy.getAsString().c_str(),
- Ty.getAsString().c_str(), R);
-
- return false;
-}
-
-Action::ExprResult Sema::
-ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprTy *Op) {
- assert((Ty != 0) && (Op != 0) && "ActOnCastExpr(): missing type or expr");
-
- Expr *castExpr = static_cast<Expr*>(Op);
- QualType castType = QualType::getFromOpaquePtr(Ty);
-
- if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr))
- return true;
- return new ExplicitCastExpr(castType, castExpr, LParenLoc);
-}
-
-/// Note that lex is not null here, even if this is the gnu "x ?: y" extension.
-/// In that case, lex = cond.
-inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
- Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) {
- UsualUnaryConversions(cond);
- UsualUnaryConversions(lex);
- UsualUnaryConversions(rex);
- QualType condT = cond->getType();
- QualType lexT = lex->getType();
- QualType rexT = rex->getType();
-
- // first, check the condition.
- if (!condT->isScalarType()) { // C99 6.5.15p2
- Diag(cond->getLocStart(), diag::err_typecheck_cond_expect_scalar,
- condT.getAsString());
- return QualType();
- }
-
- // Now check the two expressions.
-
- // If both operands have arithmetic type, do the usual arithmetic conversions
- // to find a common type: C99 6.5.15p3,5.
- if (lexT->isArithmeticType() && rexT->isArithmeticType()) {
- UsualArithmeticConversions(lex, rex);
- return lex->getType();
- }
-
- // If both operands are the same structure or union type, the result is that
- // type.
- if (const RecordType *LHSRT = lexT->getAsRecordType()) { // C99 6.5.15p3
- if (const RecordType *RHSRT = rexT->getAsRecordType())
- if (LHSRT->getDecl() == RHSRT->getDecl())
- // "If both the operands have structure or union type, the result has
- // that type." This implies that CV qualifiers are dropped.
- return lexT.getUnqualifiedType();
- }
-
- // C99 6.5.15p5: "If both operands have void type, the result has void type."
- // The following || allows only one side to be void (a GCC-ism).
- if (lexT->isVoidType() || rexT->isVoidType()) {
- if (!lexT->isVoidType())
- Diag(rex->getLocStart(), diag::ext_typecheck_cond_one_void,
- rex->getSourceRange());
- if (!rexT->isVoidType())
- Diag(lex->getLocStart(), diag::ext_typecheck_cond_one_void,
- lex->getSourceRange());
- ImpCastExprToType(lex, Context.VoidTy);
- ImpCastExprToType(rex, Context.VoidTy);
- return Context.VoidTy;
- }
- // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
- // the type of the other operand."
- if ((lexT->isPointerType() || lexT->isBlockPointerType() ||
- Context.isObjCObjectPointerType(lexT)) &&
- rex->isNullPointerConstant(Context)) {
- ImpCastExprToType(rex, lexT); // promote the null to a pointer.
- return lexT;
- }
- if ((rexT->isPointerType() || rexT->isBlockPointerType() ||
- Context.isObjCObjectPointerType(rexT)) &&
- lex->isNullPointerConstant(Context)) {
- ImpCastExprToType(lex, rexT); // promote the null to a pointer.
- return rexT;
- }
- // Handle the case where both operands are pointers before we handle null
- // pointer constants in case both operands are null pointer constants.
- if (const PointerType *LHSPT = lexT->getAsPointerType()) { // C99 6.5.15p3,6
- if (const PointerType *RHSPT = rexT->getAsPointerType()) {
- // get the "pointed to" types
- QualType lhptee = LHSPT->getPointeeType();
- QualType rhptee = RHSPT->getPointeeType();
-
- // ignore qualifiers on void (C99 6.5.15p3, clause 6)
- if (lhptee->isVoidType() &&
- rhptee->isIncompleteOrObjectType()) {
- // Figure out necessary qualifiers (C99 6.5.15p6)
- QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers());
- QualType destType = Context.getPointerType(destPointee);
- ImpCastExprToType(lex, destType); // add qualifiers if necessary
- ImpCastExprToType(rex, destType); // promote to void*
- return destType;
- }
- if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
- QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers());
- QualType destType = Context.getPointerType(destPointee);
- ImpCastExprToType(lex, destType); // add qualifiers if necessary
- ImpCastExprToType(rex, destType); // promote to void*
- return destType;
- }
-
- QualType compositeType = lexT;
-
- // If either type is an Objective-C object type then check
- // compatibility according to Objective-C.
- if (Context.isObjCObjectPointerType(lexT) ||
- Context.isObjCObjectPointerType(rexT)) {
- // If both operands are interfaces and either operand can be
- // assigned to the other, use that type as the composite
- // type. This allows
- // xxx ? (A*) a : (B*) b
- // where B is a subclass of A.
- //
- // Additionally, as for assignment, if either type is 'id'
- // allow silent coercion. Finally, if the types are
- // incompatible then make sure to use 'id' as the composite
- // type so the result is acceptable for sending messages to.
-
- // FIXME: This code should not be localized to here. Also this
- // should use a compatible check instead of abusing the
- // canAssignObjCInterfaces code.
- const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
- const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
- if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
- compositeType = lexT;
- } else if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
- compositeType = rexT;
- } else if (Context.isObjCIdType(lhptee) ||
- Context.isObjCIdType(rhptee)) {
- // FIXME: This code looks wrong, because isObjCIdType checks
- // the struct but getObjCIdType returns the pointer to
- // struct. This is horrible and should be fixed.
- compositeType = Context.getObjCIdType();
- } else {
- QualType incompatTy = Context.getObjCIdType();
- ImpCastExprToType(lex, incompatTy);
- ImpCastExprToType(rex, incompatTy);
- return incompatTy;
- }
- } else if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType())) {
- Diag(questionLoc, diag::warn_typecheck_cond_incompatible_pointers,
- lexT.getAsString(), rexT.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- // In this situation, we assume void* type. No especially good
- // reason, but this is what gcc does, and we do have to pick
- // to get a consistent AST.
- QualType incompatTy = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(lex, incompatTy);
- ImpCastExprToType(rex, incompatTy);
- return incompatTy;
- }
- // The pointer types are compatible.
- // C99 6.5.15p6: If both operands are pointers to compatible types *or* to
- // differently qualified versions of compatible types, the result type is
- // a pointer to an appropriately qualified version of the *composite*
- // type.
- // FIXME: Need to calculate the composite type.
- // FIXME: Need to add qualifiers
- ImpCastExprToType(lex, compositeType);
- ImpCastExprToType(rex, compositeType);
- return compositeType;
- }
- }
- // Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
- // evaluates to "struct objc_object *" (and is handled above when comparing
- // id with statically typed objects).
- if (lexT->isObjCQualifiedIdType() || rexT->isObjCQualifiedIdType()) {
- // GCC allows qualified id and any Objective-C type to devolve to
- // id. Currently localizing to here until clear this should be
- // part of ObjCQualifiedIdTypesAreCompatible.
- if (ObjCQualifiedIdTypesAreCompatible(lexT, rexT, true) ||
- (lexT->isObjCQualifiedIdType() &&
- Context.isObjCObjectPointerType(rexT)) ||
- (rexT->isObjCQualifiedIdType() &&
- Context.isObjCObjectPointerType(lexT))) {
- // FIXME: This is not the correct composite type. This only
- // happens to work because id can more or less be used anywhere,
- // however this may change the type of method sends.
- // FIXME: gcc adds some type-checking of the arguments and emits
- // (confusing) incompatible comparison warnings in some
- // cases. Investigate.
- QualType compositeType = Context.getObjCIdType();
- ImpCastExprToType(lex, compositeType);
- ImpCastExprToType(rex, compositeType);
- return compositeType;
- }
- }
-
- // Selection between block pointer types is ok as long as they are the same.
- if (lexT->isBlockPointerType() && rexT->isBlockPointerType() &&
- Context.getCanonicalType(lexT) == Context.getCanonicalType(rexT))
- return lexT;
-
- // Otherwise, the operands are not compatible.
- Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
- lexT.getAsString(), rexT.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- return QualType();
-}
-
-/// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
-/// in the case of a the GNU conditional expr extension.
-Action::ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
- SourceLocation ColonLoc,
- ExprTy *Cond, ExprTy *LHS,
- ExprTy *RHS) {
- Expr *CondExpr = (Expr *) Cond;
- Expr *LHSExpr = (Expr *) LHS, *RHSExpr = (Expr *) RHS;
-
- // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
- // was the condition.
- bool isLHSNull = LHSExpr == 0;
- if (isLHSNull)
- LHSExpr = CondExpr;
-
- QualType result = CheckConditionalOperands(CondExpr, LHSExpr,
- RHSExpr, QuestionLoc);
- if (result.isNull())
- return true;
- return new ConditionalOperator(CondExpr, isLHSNull ? 0 : LHSExpr,
- RHSExpr, result);
-}
-
-
-// CheckPointerTypesForAssignment - This is a very tricky routine (despite
-// being closely modeled after the C99 spec:-). The odd characteristic of this
-// routine is it effectively iqnores the qualifiers on the top level pointee.
-// This circumvents the usual type rules specified in 6.2.7p1 & 6.7.5.[1-3].
-// FIXME: add a couple examples in this comment.
-Sema::AssignConvertType
-Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
- QualType lhptee, rhptee;
-
- // get the "pointed to" type (ignoring qualifiers at the top level)
- lhptee = lhsType->getAsPointerType()->getPointeeType();
- rhptee = rhsType->getAsPointerType()->getPointeeType();
-
- // make sure we operate on the canonical type
- lhptee = Context.getCanonicalType(lhptee);
- rhptee = Context.getCanonicalType(rhptee);
-
- AssignConvertType ConvTy = Compatible;
-
- // C99 6.5.16.1p1: This following citation is common to constraints
- // 3 & 4 (below). ...and the type *pointed to* by the left has all the
- // qualifiers of the type *pointed to* by the right;
- // FIXME: Handle ASQualType
- if ((lhptee.getCVRQualifiers() & rhptee.getCVRQualifiers()) !=
- rhptee.getCVRQualifiers())
- ConvTy = CompatiblePointerDiscardsQualifiers;
-
- // C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or
- // incomplete type and the other is a pointer to a qualified or unqualified
- // version of void...
- if (lhptee->isVoidType()) {
- if (rhptee->isIncompleteOrObjectType())
- return ConvTy;
-
- // As an extension, we allow cast to/from void* to function pointer.
- assert(rhptee->isFunctionType());
- return FunctionVoidPointer;
- }
-
- if (rhptee->isVoidType()) {
- if (lhptee->isIncompleteOrObjectType())
- return ConvTy;
-
- // As an extension, we allow cast to/from void* to function pointer.
- assert(lhptee->isFunctionType());
- return FunctionVoidPointer;
- }
-
- // Check for ObjC interfaces
- const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
- const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
- if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(LHSIface, RHSIface))
- return ConvTy;
-
- // ID acts sort of like void* for ObjC interfaces
- if (LHSIface && Context.isObjCIdType(rhptee))
- return ConvTy;
- if (RHSIface && Context.isObjCIdType(lhptee))
- return ConvTy;
-
- // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
- // unqualified versions of compatible types, ...
- if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType()))
- return IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
- return ConvTy;
-}
-
-/// CheckBlockPointerTypesForAssignment - This routine determines whether two
-/// block pointer types are compatible or whether a block and normal pointer
-/// are compatible. It is more restrict than comparing two function pointer
-// types.
-Sema::AssignConvertType
-Sema::CheckBlockPointerTypesForAssignment(QualType lhsType,
- QualType rhsType) {
- QualType lhptee, rhptee;
-
- // get the "pointed to" type (ignoring qualifiers at the top level)
- lhptee = lhsType->getAsBlockPointerType()->getPointeeType();
- rhptee = rhsType->getAsBlockPointerType()->getPointeeType();
-
- // make sure we operate on the canonical type
- lhptee = Context.getCanonicalType(lhptee);
- rhptee = Context.getCanonicalType(rhptee);
-
- AssignConvertType ConvTy = Compatible;
-
- // For blocks we enforce that qualifiers are identical.
- if (lhptee.getCVRQualifiers() != rhptee.getCVRQualifiers())
- ConvTy = CompatiblePointerDiscardsQualifiers;
-
- if (!Context.typesAreBlockCompatible(lhptee, rhptee))
- return IncompatibleBlockPointer;
- return ConvTy;
-}
-
-/// CheckAssignmentConstraints (C99 6.5.16) - This routine currently
-/// has code to accommodate several GCC extensions when type checking
-/// pointers. Here are some objectionable examples that GCC considers warnings:
-///
-/// int a, *pint;
-/// short *pshort;
-/// struct foo *pfoo;
-///
-/// pint = pshort; // warning: assignment from incompatible pointer type
-/// a = pint; // warning: assignment makes integer from pointer without a cast
-/// pint = a; // warning: assignment makes pointer from integer without a cast
-/// pint = pfoo; // warning: assignment from incompatible pointer type
-///
-/// As a result, the code for dealing with pointers is more complex than the
-/// C99 spec dictates.
-///
-Sema::AssignConvertType
-Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
- // Get canonical types. We're not formatting these types, just comparing
- // them.
- lhsType = Context.getCanonicalType(lhsType).getUnqualifiedType();
- rhsType = Context.getCanonicalType(rhsType).getUnqualifiedType();
-
- if (lhsType == rhsType)
- return Compatible; // Common case: fast path an exact match.
-
- if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
- if (Context.typesAreCompatible(lhsType, rhsType))
- return Compatible;
- return Incompatible;
- }
-
- if (lhsType->isObjCQualifiedIdType() || rhsType->isObjCQualifiedIdType()) {
- if (ObjCQualifiedIdTypesAreCompatible(lhsType, rhsType, false))
- return Compatible;
- // Relax integer conversions like we do for pointers below.
- if (rhsType->isIntegerType())
- return IntToPointer;
- if (lhsType->isIntegerType())
- return PointerToInt;
- return Incompatible;
- }
-
- if (lhsType->isVectorType() || rhsType->isVectorType()) {
- // For ExtVector, allow vector splats; float -> <n x float>
- if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
- if (LV->getElementType() == rhsType)
- return Compatible;
-
- // If we are allowing lax vector conversions, and LHS and RHS are both
- // vectors, the total size only needs to be the same. This is a bitcast;
- // no bits are changed but the result type is different.
- if (getLangOptions().LaxVectorConversions &&
- lhsType->isVectorType() && rhsType->isVectorType()) {
- if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
- return Compatible;
- }
- return Incompatible;
- }
-
- if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
- return Compatible;
-
- if (isa<PointerType>(lhsType)) {
- if (rhsType->isIntegerType())
- return IntToPointer;
-
- if (isa<PointerType>(rhsType))
- return CheckPointerTypesForAssignment(lhsType, rhsType);
-
- if (rhsType->getAsBlockPointerType()) {
- if (lhsType->getAsPointerType()->getPointeeType()->isVoidType())
- return BlockVoidPointer;
-
- // Treat block pointers as objects.
- if (getLangOptions().ObjC1 &&
- lhsType == Context.getCanonicalType(Context.getObjCIdType()))
- return Compatible;
- }
- return Incompatible;
- }
-
- if (isa<BlockPointerType>(lhsType)) {
- if (rhsType->isIntegerType())
- return IntToPointer;
-
- // Treat block pointers as objects.
- if (getLangOptions().ObjC1 &&
- rhsType == Context.getCanonicalType(Context.getObjCIdType()))
- return Compatible;
-
- if (rhsType->isBlockPointerType())
- return CheckBlockPointerTypesForAssignment(lhsType, rhsType);
-
- if (const PointerType *RHSPT = rhsType->getAsPointerType()) {
- if (RHSPT->getPointeeType()->isVoidType())
- return BlockVoidPointer;
- }
- return Incompatible;
- }
-
- if (isa<PointerType>(rhsType)) {
- // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
- if (lhsType == Context.BoolTy)
- return Compatible;
-
- if (lhsType->isIntegerType())
- return PointerToInt;
-
- if (isa<PointerType>(lhsType))
- return CheckPointerTypesForAssignment(lhsType, rhsType);
-
- if (isa<BlockPointerType>(lhsType) &&
- rhsType->getAsPointerType()->getPointeeType()->isVoidType())
- return BlockVoidPointer;
- return Incompatible;
- }
-
- if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
- if (Context.typesAreCompatible(lhsType, rhsType))
- return Compatible;
- }
- return Incompatible;
-}
-
-Sema::AssignConvertType
-Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
- // C99 6.5.16.1p1: the left operand is a pointer and the right is
- // a null pointer constant.
- if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() ||
- lhsType->isBlockPointerType())
- && rExpr->isNullPointerConstant(Context)) {
- ImpCastExprToType(rExpr, lhsType);
- return Compatible;
- }
-
- // We don't allow conversion of non-null-pointer constants to integers.
- if (lhsType->isBlockPointerType() && rExpr->getType()->isIntegerType())
- return IntToBlockPointer;
-
- // This check seems unnatural, however it is necessary to ensure the proper
- // conversion of functions/arrays. If the conversion were done for all
- // DeclExpr's (created by ActOnIdentifierExpr), it would mess up the unary
- // expressions that surpress this implicit conversion (&, sizeof).
- //
- // Suppress this for references: C99 8.5.3p5. FIXME: revisit when references
- // are better understood.
- if (!lhsType->isReferenceType())
- DefaultFunctionArrayConversion(rExpr);
-
- Sema::AssignConvertType result =
- CheckAssignmentConstraints(lhsType, rExpr->getType());
-
- // C99 6.5.16.1p2: The value of the right operand is converted to the
- // type of the assignment expression.
- if (rExpr->getType() != lhsType)
- ImpCastExprToType(rExpr, lhsType);
- return result;
-}
-
-Sema::AssignConvertType
-Sema::CheckCompoundAssignmentConstraints(QualType lhsType, QualType rhsType) {
- return CheckAssignmentConstraints(lhsType, rhsType);
-}
-
-QualType Sema::InvalidOperands(SourceLocation loc, Expr *&lex, Expr *&rex) {
- Diag(loc, diag::err_typecheck_invalid_operands,
- lex->getType().getAsString(), rex->getType().getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- return QualType();
-}
-
-inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex,
- Expr *&rex) {
- // For conversion purposes, we ignore any qualifiers.
- // For example, "const float" and "float" are equivalent.
- QualType lhsType =
- Context.getCanonicalType(lex->getType()).getUnqualifiedType();
- QualType rhsType =
- Context.getCanonicalType(rex->getType()).getUnqualifiedType();
-
- // If the vector types are identical, return.
- if (lhsType == rhsType)
- return lhsType;
-
- // Handle the case of a vector & extvector type of the same size and element
- // type. It would be nice if we only had one vector type someday.
- if (getLangOptions().LaxVectorConversions)
- if (const VectorType *LV = lhsType->getAsVectorType())
- if (const VectorType *RV = rhsType->getAsVectorType())
- if (LV->getElementType() == RV->getElementType() &&
- LV->getNumElements() == RV->getNumElements())
- return lhsType->isExtVectorType() ? lhsType : rhsType;
-
- // If the lhs is an extended vector and the rhs is a scalar of the same type
- // or a literal, promote the rhs to the vector type.
- if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
- ImpCastExprToType(rex, lhsType);
- return lhsType;
- }
- }
-
- // If the rhs is an extended vector and the lhs is a scalar of the same type,
- // promote the lhs to the vector type.
- if (const ExtVectorType *V = rhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
- ImpCastExprToType(lex, rhsType);
- return rhsType;
- }
- }
-
- // You cannot convert between vector values of different size.
- Diag(loc, diag::err_typecheck_vector_not_convertable,
- lex->getType().getAsString(), rex->getType().getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- return QualType();
-}
-
-inline QualType Sema::CheckMultiplyDivideOperands(
- Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign)
-{
- QualType lhsType = lex->getType(), rhsType = rex->getType();
-
- if (lhsType->isVectorType() || rhsType->isVectorType())
- return CheckVectorOperands(loc, lex, rex);
-
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
-
- if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
- return compType;
- return InvalidOperands(loc, lex, rex);
-}
-
-inline QualType Sema::CheckRemainderOperands(
- Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign)
-{
- QualType lhsType = lex->getType(), rhsType = rex->getType();
-
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
-
- if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
- return compType;
- return InvalidOperands(loc, lex, rex);
-}
-
-inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign)
-{
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(loc, lex, rex);
-
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
-
- // handle the common case first (both operands are arithmetic).
- if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
- return compType;
-
- // Put any potential pointer into PExp
- Expr* PExp = lex, *IExp = rex;
- if (IExp->getType()->isPointerType())
- std::swap(PExp, IExp);
-
- if (const PointerType* PTy = PExp->getType()->getAsPointerType()) {
- if (IExp->getType()->isIntegerType()) {
- // Check for arithmetic on pointers to incomplete types
- if (!PTy->getPointeeType()->isObjectType()) {
- if (PTy->getPointeeType()->isVoidType()) {
- Diag(loc, diag::ext_gnu_void_ptr,
- lex->getSourceRange(), rex->getSourceRange());
- } else {
- Diag(loc, diag::err_typecheck_arithmetic_incomplete_type,
- lex->getType().getAsString(), lex->getSourceRange());
- return QualType();
- }
- }
- return PExp->getType();
- }
- }
-
- return InvalidOperands(loc, lex, rex);
-}
-
-// C99 6.5.6
-QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
- SourceLocation loc, bool isCompAssign) {
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(loc, lex, rex);
-
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
-
- // Enforce type constraints: C99 6.5.6p3.
-
- // Handle the common case first (both operands are arithmetic).
- if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
- return compType;
-
- // Either ptr - int or ptr - ptr.
- if (const PointerType *LHSPTy = lex->getType()->getAsPointerType()) {
- QualType lpointee = LHSPTy->getPointeeType();
-
- // The LHS must be an object type, not incomplete, function, etc.
- if (!lpointee->isObjectType()) {
- // Handle the GNU void* extension.
- if (lpointee->isVoidType()) {
- Diag(loc, diag::ext_gnu_void_ptr,
- lex->getSourceRange(), rex->getSourceRange());
- } else {
- Diag(loc, diag::err_typecheck_sub_ptr_object,
- lex->getType().getAsString(), lex->getSourceRange());
- return QualType();
- }
- }
-
- // The result type of a pointer-int computation is the pointer type.
- if (rex->getType()->isIntegerType())
- return lex->getType();
-
- // Handle pointer-pointer subtractions.
- if (const PointerType *RHSPTy = rex->getType()->getAsPointerType()) {
- QualType rpointee = RHSPTy->getPointeeType();
-
- // RHS must be an object type, unless void (GNU).
- if (!rpointee->isObjectType()) {
- // Handle the GNU void* extension.
- if (rpointee->isVoidType()) {
- if (!lpointee->isVoidType())
- Diag(loc, diag::ext_gnu_void_ptr,
- lex->getSourceRange(), rex->getSourceRange());
- } else {
- Diag(loc, diag::err_typecheck_sub_ptr_object,
- rex->getType().getAsString(), rex->getSourceRange());
- return QualType();
- }
- }
-
- // Pointee types must be compatible.
- if (!Context.typesAreCompatible(
- Context.getCanonicalType(lpointee).getUnqualifiedType(),
- Context.getCanonicalType(rpointee).getUnqualifiedType())) {
- Diag(loc, diag::err_typecheck_sub_ptr_compatible,
- lex->getType().getAsString(), rex->getType().getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- return QualType();
- }
-
- return Context.getPointerDiffType();
- }
- }
-
- return InvalidOperands(loc, lex, rex);
-}
-
-// C99 6.5.7
-QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
- bool isCompAssign) {
- // C99 6.5.7p2: Each of the operands shall have integer type.
- if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
- return InvalidOperands(loc, lex, rex);
-
- // Shifts don't perform usual arithmetic conversions, they just do integer
- // promotions on each operand. C99 6.5.7p3
- if (!isCompAssign)
- UsualUnaryConversions(lex);
- UsualUnaryConversions(rex);
-
- // "The type of the result is that of the promoted left operand."
- return lex->getType();
-}
-
-static bool areComparableObjCInterfaces(QualType LHS, QualType RHS,
- ASTContext& Context) {
- const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType();
- const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType();
- // ID acts sort of like void* for ObjC interfaces
- if (LHSIface && Context.isObjCIdType(RHS))
- return true;
- if (RHSIface && Context.isObjCIdType(LHS))
- return true;
- if (!LHSIface || !RHSIface)
- return false;
- return Context.canAssignObjCInterfaces(LHSIface, RHSIface) ||
- Context.canAssignObjCInterfaces(RHSIface, LHSIface);
-}
-
-// C99 6.5.8
-QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
- bool isRelational) {
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorCompareOperands(lex, rex, loc, isRelational);
-
- // C99 6.5.8p3 / C99 6.5.9p4
- if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
- UsualArithmeticConversions(lex, rex);
- else {
- UsualUnaryConversions(lex);
- UsualUnaryConversions(rex);
- }
- QualType lType = lex->getType();
- QualType rType = rex->getType();
-
- // For non-floating point types, check for self-comparisons of the form
- // x == x, x != x, x < x, etc. These always evaluate to a constant, and
- // often indicate logic errors in the program.
- if (!lType->isFloatingType()) {
- if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
- if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
- if (DRL->getDecl() == DRR->getDecl())
- Diag(loc, diag::warn_selfcomparison);
- }
-
- if (isRelational) {
- if (lType->isRealType() && rType->isRealType())
- return Context.IntTy;
- } else {
- // Check for comparisons of floating point operands using != and ==.
- if (lType->isFloatingType()) {
- assert (rType->isFloatingType());
- CheckFloatComparison(loc,lex,rex);
- }
-
- if (lType->isArithmeticType() && rType->isArithmeticType())
- return Context.IntTy;
- }
-
- bool LHSIsNull = lex->isNullPointerConstant(Context);
- bool RHSIsNull = rex->isNullPointerConstant(Context);
-
- // All of the following pointer related warnings are GCC extensions, except
- // when handling null pointer constants. One day, we can consider making them
- // errors (when -pedantic-errors is enabled).
- if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2
- QualType LCanPointeeTy =
- Context.getCanonicalType(lType->getAsPointerType()->getPointeeType());
- QualType RCanPointeeTy =
- Context.getCanonicalType(rType->getAsPointerType()->getPointeeType());
-
- if (!LHSIsNull && !RHSIsNull && // C99 6.5.9p2
- !LCanPointeeTy->isVoidType() && !RCanPointeeTy->isVoidType() &&
- !Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
- RCanPointeeTy.getUnqualifiedType()) &&
- !areComparableObjCInterfaces(LCanPointeeTy, RCanPointeeTy, Context)) {
- Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- }
- ImpCastExprToType(rex, lType); // promote the pointer to pointer
- return Context.IntTy;
- }
- // Handle block pointer types.
- if (lType->isBlockPointerType() && rType->isBlockPointerType()) {
- QualType lpointee = lType->getAsBlockPointerType()->getPointeeType();
- QualType rpointee = rType->getAsBlockPointerType()->getPointeeType();
-
- if (!LHSIsNull && !RHSIsNull &&
- !Context.typesAreBlockCompatible(lpointee, rpointee)) {
- Diag(loc, diag::err_typecheck_comparison_of_distinct_blocks,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- }
- ImpCastExprToType(rex, lType); // promote the pointer to pointer
- return Context.IntTy;
- }
- // Allow block pointers to be compared with null pointer constants.
- if ((lType->isBlockPointerType() && rType->isPointerType()) ||
- (lType->isPointerType() && rType->isBlockPointerType())) {
- if (!LHSIsNull && !RHSIsNull) {
- Diag(loc, diag::err_typecheck_comparison_of_distinct_blocks,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- }
- ImpCastExprToType(rex, lType); // promote the pointer to pointer
- return Context.IntTy;
- }
-
- if ((lType->isObjCQualifiedIdType() || rType->isObjCQualifiedIdType())) {
- if (ObjCQualifiedIdTypesAreCompatible(lType, rType, true)) {
- ImpCastExprToType(rex, lType);
- return Context.IntTy;
- }
- }
- if ((lType->isPointerType() || lType->isObjCQualifiedIdType()) &&
- rType->isIntegerType()) {
- if (!RHSIsNull)
- Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- ImpCastExprToType(rex, lType); // promote the integer to pointer
- return Context.IntTy;
- }
- if (lType->isIntegerType() &&
- (rType->isPointerType() || rType->isObjCQualifiedIdType())) {
- if (!LHSIsNull)
- Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- ImpCastExprToType(lex, rType); // promote the integer to pointer
- return Context.IntTy;
- }
- // Handle block pointers.
- if (lType->isBlockPointerType() && rType->isIntegerType()) {
- if (!RHSIsNull)
- Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- ImpCastExprToType(rex, lType); // promote the integer to pointer
- return Context.IntTy;
- }
- if (lType->isIntegerType() && rType->isBlockPointerType()) {
- if (!LHSIsNull)
- Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
- lType.getAsString(), rType.getAsString(),
- lex->getSourceRange(), rex->getSourceRange());
- ImpCastExprToType(lex, rType); // promote the integer to pointer
- return Context.IntTy;
- }
- return InvalidOperands(loc, lex, rex);
-}
-
-/// CheckVectorCompareOperands - vector comparisons are a clang extension that
-/// operates on extended vector types. Instead of producing an IntTy result,
-/// like a scalar comparison, a vector comparison produces a vector of integer
-/// types.
-QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
- SourceLocation loc,
- bool isRelational) {
- // Check to make sure we're operating on vectors of the same type and width,
- // Allowing one side to be a scalar of element type.
- QualType vType = CheckVectorOperands(loc, lex, rex);
- if (vType.isNull())
- return vType;
-
- QualType lType = lex->getType();
- QualType rType = rex->getType();
-
- // For non-floating point types, check for self-comparisons of the form
- // x == x, x != x, x < x, etc. These always evaluate to a constant, and
- // often indicate logic errors in the program.
- if (!lType->isFloatingType()) {
- if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
- if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
- if (DRL->getDecl() == DRR->getDecl())
- Diag(loc, diag::warn_selfcomparison);
- }
-
- // Check for comparisons of floating point operands using != and ==.
- if (!isRelational && lType->isFloatingType()) {
- assert (rType->isFloatingType());
- CheckFloatComparison(loc,lex,rex);
- }
-
- // Return the type for the comparison, which is the same as vector type for
- // integer vectors, or an integer type of identical size and number of
- // elements for floating point vectors.
- if (lType->isIntegerType())
- return lType;
-
- const VectorType *VTy = lType->getAsVectorType();
-
- // FIXME: need to deal with non-32b int / non-64b long long
- unsigned TypeSize = Context.getTypeSize(VTy->getElementType());
- if (TypeSize == 32) {
- return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
- }
- assert(TypeSize == 64 && "Unhandled vector element size in vector compare");
- return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements());
-}
-
-inline QualType Sema::CheckBitwiseOperands(
- Expr *&lex, Expr *&rex, SourceLocation loc, bool isCompAssign)
-{
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(loc, lex, rex);
-
- QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
-
- if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
- return compType;
- return InvalidOperands(loc, lex, rex);
-}
-
-inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
- Expr *&lex, Expr *&rex, SourceLocation loc)
-{
- UsualUnaryConversions(lex);
- UsualUnaryConversions(rex);
-
- if (lex->getType()->isScalarType() && rex->getType()->isScalarType())
- return Context.IntTy;
- return InvalidOperands(loc, lex, rex);
-}
-
-inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1
- Expr *lex, Expr *&rex, SourceLocation loc, QualType compoundType)
-{
- QualType lhsType = lex->getType();
- QualType rhsType = compoundType.isNull() ? rex->getType() : compoundType;
- Expr::isModifiableLvalueResult mlval = lex->isModifiableLvalue(Context);
-
- switch (mlval) { // C99 6.5.16p2
- case Expr::MLV_Valid:
- break;
- case Expr::MLV_ConstQualified:
- Diag(loc, diag::err_typecheck_assign_const, lex->getSourceRange());
- return QualType();
- case Expr::MLV_ArrayType:
- Diag(loc, diag::err_typecheck_array_not_modifiable_lvalue,
- lhsType.getAsString(), lex->getSourceRange());
- return QualType();
- case Expr::MLV_NotObjectType:
- Diag(loc, diag::err_typecheck_non_object_not_modifiable_lvalue,
- lhsType.getAsString(), lex->getSourceRange());
- return QualType();
- case Expr::MLV_InvalidExpression:
- Diag(loc, diag::err_typecheck_expression_not_modifiable_lvalue,
- lex->getSourceRange());
- return QualType();
- case Expr::MLV_IncompleteType:
- case Expr::MLV_IncompleteVoidType:
- Diag(loc, diag::err_typecheck_incomplete_type_not_modifiable_lvalue,
- lhsType.getAsString(), lex->getSourceRange());
- return QualType();
- case Expr::MLV_DuplicateVectorComponents:
- Diag(loc, diag::err_typecheck_duplicate_vector_components_not_mlvalue,
- lex->getSourceRange());
- return QualType();
- case Expr::MLV_NotBlockQualified:
- Diag(loc, diag::err_block_decl_ref_not_modifiable_lvalue,
- lex->getSourceRange());
- return QualType();
- }
-
- AssignConvertType ConvTy;
- if (compoundType.isNull()) {
- // Simple assignment "x = y".
- ConvTy = CheckSingleAssignmentConstraints(lhsType, rex);
-
- // If the RHS is a unary plus or minus, check to see if they = and + are
- // right next to each other. If so, the user may have typo'd "x =+ 4"
- // instead of "x += 4".
- Expr *RHSCheck = rex;
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
- RHSCheck = ICE->getSubExpr();
- if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
- if ((UO->getOpcode() == UnaryOperator::Plus ||
- UO->getOpcode() == UnaryOperator::Minus) &&
- loc.isFileID() && UO->getOperatorLoc().isFileID() &&
- // Only if the two operators are exactly adjacent.
- loc.getFileLocWithOffset(1) == UO->getOperatorLoc())
- Diag(loc, diag::warn_not_compound_assign,
- UO->getOpcode() == UnaryOperator::Plus ? "+" : "-",
- SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc()));
- }
- } else {
- // Compound assignment "x += y"
- ConvTy = CheckCompoundAssignmentConstraints(lhsType, rhsType);
- }
-
- if (DiagnoseAssignmentResult(ConvTy, loc, lhsType, rhsType,
- rex, "assigning"))
- return QualType();
-
- // C99 6.5.16p3: The type of an assignment expression is the type of the
- // left operand unless the left operand has qualified type, in which case
- // it is the unqualified version of the type of the left operand.
- // C99 6.5.16.1p2: In simple assignment, the value of the right operand
- // is converted to the type of the assignment expression (above).
- // C++ 5.17p1: the type of the assignment expression is that of its left
- // oprdu.
- return lhsType.getUnqualifiedType();
-}
-
-inline QualType Sema::CheckCommaOperands( // C99 6.5.17
- Expr *&lex, Expr *&rex, SourceLocation loc) {
-
- // Comma performs lvalue conversion (C99 6.3.2.1), but not unary conversions.
- DefaultFunctionArrayConversion(rex);
- return rex->getType();
-}
-
-/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
-/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
-QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) {
- QualType resType = op->getType();
- assert(!resType.isNull() && "no type for increment/decrement expression");
-
- // C99 6.5.2.4p1: We allow complex as a GCC extension.
- if (const PointerType *pt = resType->getAsPointerType()) {
- if (pt->getPointeeType()->isVoidType()) {
- Diag(OpLoc, diag::ext_gnu_void_ptr, op->getSourceRange());
- } else if (!pt->getPointeeType()->isObjectType()) {
- // C99 6.5.2.4p2, 6.5.6p2
- Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type,
- resType.getAsString(), op->getSourceRange());
- return QualType();
- }
- } else if (!resType->isRealType()) {
- if (resType->isComplexType())
- // C99 does not support ++/-- on complex types.
- Diag(OpLoc, diag::ext_integer_increment_complex,
- resType.getAsString(), op->getSourceRange());
- else {
- Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement,
- resType.getAsString(), op->getSourceRange());
- return QualType();
- }
- }
- // At this point, we know we have a real, complex or pointer type.
- // Now make sure the operand is a modifiable lvalue.
- Expr::isModifiableLvalueResult mlval = op->isModifiableLvalue(Context);
- if (mlval != Expr::MLV_Valid) {
- // FIXME: emit a more precise diagnostic...
- Diag(OpLoc, diag::err_typecheck_invalid_lvalue_incr_decr,
- op->getSourceRange());
- return QualType();
- }
- return resType;
-}
-
-/// getPrimaryDecl - Helper function for CheckAddressOfOperand().
-/// This routine allows us to typecheck complex/recursive expressions
-/// where the declaration is needed for type checking. We only need to
-/// handle cases when the expression references a function designator
-/// or is an lvalue. Here are some examples:
-/// - &(x) => x
-/// - &*****f => f for f a function designator.
-/// - &s.xx => s
-/// - &s.zz[1].yy -> s, if zz is an array
-/// - *(x + 1) -> x, if x is an array
-/// - &"123"[2] -> 0
-/// - & __real__ x -> x
-static ValueDecl *getPrimaryDecl(Expr *E) {
- switch (E->getStmtClass()) {
- case Stmt::DeclRefExprClass:
- return cast<DeclRefExpr>(E)->getDecl();
- case Stmt::MemberExprClass:
- // Fields cannot be declared with a 'register' storage class.
- // &X->f is always ok, even if X is declared register.
- if (cast<MemberExpr>(E)->isArrow())
- return 0;
- return getPrimaryDecl(cast<MemberExpr>(E)->getBase());
- case Stmt::ArraySubscriptExprClass: {
- // &X[4] and &4[X] refers to X if X is not a pointer.
-
- ValueDecl *VD = getPrimaryDecl(cast<ArraySubscriptExpr>(E)->getBase());
- if (!VD || VD->getType()->isPointerType())
- return 0;
- else
- return VD;
- }
- case Stmt::UnaryOperatorClass: {
- UnaryOperator *UO = cast<UnaryOperator>(E);
-
- switch(UO->getOpcode()) {
- case UnaryOperator::Deref: {
- // *(X + 1) refers to X if X is not a pointer.
- ValueDecl *VD = getPrimaryDecl(UO->getSubExpr());
- if (!VD || VD->getType()->isPointerType())
- return 0;
- return VD;
- }
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- case UnaryOperator::Extension:
- return getPrimaryDecl(UO->getSubExpr());
- default:
- return 0;
- }
- }
- case Stmt::BinaryOperatorClass: {
- BinaryOperator *BO = cast<BinaryOperator>(E);
-
- // Handle cases involving pointer arithmetic. The result of an
- // Assign or AddAssign is not an lvalue so they can be ignored.
-
- // (x + n) or (n + x) => x
- if (BO->getOpcode() == BinaryOperator::Add) {
- if (BO->getLHS()->getType()->isPointerType()) {
- return getPrimaryDecl(BO->getLHS());
- } else if (BO->getRHS()->getType()->isPointerType()) {
- return getPrimaryDecl(BO->getRHS());
- }
- }
-
- return 0;
- }
- case Stmt::ParenExprClass:
- return getPrimaryDecl(cast<ParenExpr>(E)->getSubExpr());
- case Stmt::ImplicitCastExprClass:
- // &X[4] when X is an array, has an implicit cast from array to pointer.
- return getPrimaryDecl(cast<ImplicitCastExpr>(E)->getSubExpr());
- default:
- return 0;
- }
-}
-
-/// CheckAddressOfOperand - The operand of & must be either a function
-/// designator or an lvalue designating an object. If it is an lvalue, the
-/// object cannot be declared with storage class register or be a bit field.
-/// Note: The usual conversions are *not* applied to the operand of the &
-/// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue.
-QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
- if (getLangOptions().C99) {
- // Implement C99-only parts of addressof rules.
- if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
- if (uOp->getOpcode() == UnaryOperator::Deref)
- // Per C99 6.5.3.2, the address of a deref always returns a valid result
- // (assuming the deref expression is valid).
- return uOp->getSubExpr()->getType();
- }
- // Technically, there should be a check for array subscript
- // expressions here, but the result of one is always an lvalue anyway.
- }
- ValueDecl *dcl = getPrimaryDecl(op);
- Expr::isLvalueResult lval = op->isLvalue(Context);
-
- if (lval != Expr::LV_Valid) { // C99 6.5.3.2p1
- if (!dcl || !isa<FunctionDecl>(dcl)) {// allow function designators
- // FIXME: emit more specific diag...
- Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof,
- op->getSourceRange());
- return QualType();
- }
- } else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(op)) { // C99 6.5.3.2p1
- if (MemExpr->getMemberDecl()->isBitField()) {
- Diag(OpLoc, diag::err_typecheck_address_of,
- std::string("bit-field"), op->getSourceRange());
- return QualType();
- }
- // Check for Apple extension for accessing vector components.
- } else if (isa<ArraySubscriptExpr>(op) &&
- cast<ArraySubscriptExpr>(op)->getBase()->getType()->isVectorType()) {
- Diag(OpLoc, diag::err_typecheck_address_of,
- std::string("vector"), op->getSourceRange());
- return QualType();
- } else if (dcl) { // C99 6.5.3.2p1
- // We have an lvalue with a decl. Make sure the decl is not declared
- // with the register storage-class specifier.
- if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
- if (vd->getStorageClass() == VarDecl::Register) {
- Diag(OpLoc, diag::err_typecheck_address_of,
- std::string("register variable"), op->getSourceRange());
- return QualType();
- }
- } else
- assert(0 && "Unknown/unexpected decl type");
- }
-
- // If the operand has type "type", the result has type "pointer to type".
- return Context.getPointerType(op->getType());
-}
-
-QualType Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) {
- UsualUnaryConversions(op);
- QualType qType = op->getType();
-
- if (const PointerType *PT = qType->getAsPointerType()) {
- // Note that per both C89 and C99, this is always legal, even
- // if ptype is an incomplete type or void.
- // It would be possible to warn about dereferencing a
- // void pointer, but it's completely well-defined,
- // and such a warning is unlikely to catch any mistakes.
- return PT->getPointeeType();
- }
- Diag(OpLoc, diag::err_typecheck_indirection_requires_pointer,
- qType.getAsString(), op->getSourceRange());
- return QualType();
-}
-
-static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode(
- tok::TokenKind Kind) {
- BinaryOperator::Opcode Opc;
- switch (Kind) {
- default: assert(0 && "Unknown binop!");
- case tok::star: Opc = BinaryOperator::Mul; break;
- case tok::slash: Opc = BinaryOperator::Div; break;
- case tok::percent: Opc = BinaryOperator::Rem; break;
- case tok::plus: Opc = BinaryOperator::Add; break;
- case tok::minus: Opc = BinaryOperator::Sub; break;
- case tok::lessless: Opc = BinaryOperator::Shl; break;
- case tok::greatergreater: Opc = BinaryOperator::Shr; break;
- case tok::lessequal: Opc = BinaryOperator::LE; break;
- case tok::less: Opc = BinaryOperator::LT; break;
- case tok::greaterequal: Opc = BinaryOperator::GE; break;
- case tok::greater: Opc = BinaryOperator::GT; break;
- case tok::exclaimequal: Opc = BinaryOperator::NE; break;
- case tok::equalequal: Opc = BinaryOperator::EQ; break;
- case tok::amp: Opc = BinaryOperator::And; break;
- case tok::caret: Opc = BinaryOperator::Xor; break;
- case tok::pipe: Opc = BinaryOperator::Or; break;
- case tok::ampamp: Opc = BinaryOperator::LAnd; break;
- case tok::pipepipe: Opc = BinaryOperator::LOr; break;
- case tok::equal: Opc = BinaryOperator::Assign; break;
- case tok::starequal: Opc = BinaryOperator::MulAssign; break;
- case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
- case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
- case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
- case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
- case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
- case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
- case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
- case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
- case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
- case tok::comma: Opc = BinaryOperator::Comma; break;
- }
- return Opc;
-}
-
-static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
- tok::TokenKind Kind) {
- UnaryOperator::Opcode Opc;
- switch (Kind) {
- default: assert(0 && "Unknown unary op!");
- case tok::plusplus: Opc = UnaryOperator::PreInc; break;
- case tok::minusminus: Opc = UnaryOperator::PreDec; break;
- case tok::amp: Opc = UnaryOperator::AddrOf; break;
- case tok::star: Opc = UnaryOperator::Deref; break;
- case tok::plus: Opc = UnaryOperator::Plus; break;
- case tok::minus: Opc = UnaryOperator::Minus; break;
- case tok::tilde: Opc = UnaryOperator::Not; break;
- case tok::exclaim: Opc = UnaryOperator::LNot; break;
- case tok::kw_sizeof: Opc = UnaryOperator::SizeOf; break;
- case tok::kw___alignof: Opc = UnaryOperator::AlignOf; break;
- case tok::kw___real: Opc = UnaryOperator::Real; break;
- case tok::kw___imag: Opc = UnaryOperator::Imag; break;
- case tok::kw___extension__: Opc = UnaryOperator::Extension; break;
- }
- return Opc;
-}
-
-// Binary Operators. 'Tok' is the token for the operator.
-Action::ExprResult Sema::ActOnBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
- ExprTy *LHS, ExprTy *RHS) {
- BinaryOperator::Opcode Opc = ConvertTokenKindToBinaryOpcode(Kind);
- Expr *lhs = (Expr *)LHS, *rhs = (Expr*)RHS;
-
- assert((lhs != 0) && "ActOnBinOp(): missing left expression");
- assert((rhs != 0) && "ActOnBinOp(): missing right expression");
-
- QualType ResultTy; // Result type of the binary operator.
- QualType CompTy; // Computation type for compound assignments (e.g. '+=')
-
- switch (Opc) {
- default:
- assert(0 && "Unknown binary expr!");
- case BinaryOperator::Assign:
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, QualType());
- break;
- case BinaryOperator::Mul:
- case BinaryOperator::Div:
- ResultTy = CheckMultiplyDivideOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::Rem:
- ResultTy = CheckRemainderOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::Add:
- ResultTy = CheckAdditionOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::Sub:
- ResultTy = CheckSubtractionOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::Shl:
- case BinaryOperator::Shr:
- ResultTy = CheckShiftOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::LE:
- case BinaryOperator::LT:
- case BinaryOperator::GE:
- case BinaryOperator::GT:
- ResultTy = CheckCompareOperands(lhs, rhs, TokLoc, true);
- break;
- case BinaryOperator::EQ:
- case BinaryOperator::NE:
- ResultTy = CheckCompareOperands(lhs, rhs, TokLoc, false);
- break;
- case BinaryOperator::And:
- case BinaryOperator::Xor:
- case BinaryOperator::Or:
- ResultTy = CheckBitwiseOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::LAnd:
- case BinaryOperator::LOr:
- ResultTy = CheckLogicalOperands(lhs, rhs, TokLoc);
- break;
- case BinaryOperator::MulAssign:
- case BinaryOperator::DivAssign:
- CompTy = CheckMultiplyDivideOperands(lhs, rhs, TokLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
- break;
- case BinaryOperator::RemAssign:
- CompTy = CheckRemainderOperands(lhs, rhs, TokLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
- break;
- case BinaryOperator::AddAssign:
- CompTy = CheckAdditionOperands(lhs, rhs, TokLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
- break;
- case BinaryOperator::SubAssign:
- CompTy = CheckSubtractionOperands(lhs, rhs, TokLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
- break;
- case BinaryOperator::ShlAssign:
- case BinaryOperator::ShrAssign:
- CompTy = CheckShiftOperands(lhs, rhs, TokLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
- break;
- case BinaryOperator::AndAssign:
- case BinaryOperator::XorAssign:
- case BinaryOperator::OrAssign:
- CompTy = CheckBitwiseOperands(lhs, rhs, TokLoc, true);
- if (!CompTy.isNull())
- ResultTy = CheckAssignmentOperands(lhs, rhs, TokLoc, CompTy);
- break;
- case BinaryOperator::Comma:
- ResultTy = CheckCommaOperands(lhs, rhs, TokLoc);
- break;
- }
- if (ResultTy.isNull())
- return true;
- if (CompTy.isNull())
- return new BinaryOperator(lhs, rhs, Opc, ResultTy, TokLoc);
- else
- return new CompoundAssignOperator(lhs, rhs, Opc, ResultTy, CompTy, TokLoc);
-}
-
-// Unary Operators. 'Tok' is the token for the operator.
-Action::ExprResult Sema::ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
- ExprTy *input) {
- Expr *Input = (Expr*)input;
- UnaryOperator::Opcode Opc = ConvertTokenKindToUnaryOpcode(Op);
- QualType resultType;
- switch (Opc) {
- default:
- assert(0 && "Unimplemented unary expr!");
- case UnaryOperator::PreInc:
- case UnaryOperator::PreDec:
- resultType = CheckIncrementDecrementOperand(Input, OpLoc);
- break;
- case UnaryOperator::AddrOf:
- resultType = CheckAddressOfOperand(Input, OpLoc);
- break;
- case UnaryOperator::Deref:
- DefaultFunctionArrayConversion(Input);
- resultType = CheckIndirectionOperand(Input, OpLoc);
- break;
- case UnaryOperator::Plus:
- case UnaryOperator::Minus:
- UsualUnaryConversions(Input);
- resultType = Input->getType();
- if (!resultType->isArithmeticType()) // C99 6.5.3.3p1
- return Diag(OpLoc, diag::err_typecheck_unary_expr,
- resultType.getAsString());
- break;
- case UnaryOperator::Not: // bitwise complement
- UsualUnaryConversions(Input);
- resultType = Input->getType();
- // C99 6.5.3.3p1. We allow complex int and float as a GCC extension.
- if (resultType->isComplexType() || resultType->isComplexIntegerType())
- // C99 does not support '~' for complex conjugation.
- Diag(OpLoc, diag::ext_integer_complement_complex,
- resultType.getAsString(), Input->getSourceRange());
- else if (!resultType->isIntegerType())
- return Diag(OpLoc, diag::err_typecheck_unary_expr,
- resultType.getAsString(), Input->getSourceRange());
- break;
- case UnaryOperator::LNot: // logical negation
- // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
- DefaultFunctionArrayConversion(Input);
- resultType = Input->getType();
- if (!resultType->isScalarType()) // C99 6.5.3.3p1
- return Diag(OpLoc, diag::err_typecheck_unary_expr,
- resultType.getAsString());
- // LNot always has type int. C99 6.5.3.3p5.
- resultType = Context.IntTy;
- break;
- case UnaryOperator::SizeOf:
- resultType = CheckSizeOfAlignOfOperand(Input->getType(), OpLoc,
- Input->getSourceRange(), true);
- break;
- case UnaryOperator::AlignOf:
- resultType = CheckSizeOfAlignOfOperand(Input->getType(), OpLoc,
- Input->getSourceRange(), false);
- break;
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- resultType = CheckRealImagOperand(Input, OpLoc);
- break;
- case UnaryOperator::Extension:
- resultType = Input->getType();
- break;
- }
- if (resultType.isNull())
- return true;
- return new UnaryOperator(Input, Opc, resultType, OpLoc);
-}
-
-/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-Sema::ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
- SourceLocation LabLoc,
- IdentifierInfo *LabelII) {
- // Look up the record for this label identifier.
- LabelStmt *&LabelDecl = LabelMap[LabelII];
-
- // If we haven't seen this label yet, create a forward reference. It
- // will be validated and/or cleaned up in ActOnFinishFunctionBody.
- if (LabelDecl == 0)
- LabelDecl = new LabelStmt(LabLoc, LabelII, 0);
-
- // Create the AST node. The address of a label always has type 'void*'.
- return new AddrLabelExpr(OpLoc, LabLoc, LabelDecl,
- Context.getPointerType(Context.VoidTy));
-}
-
-Sema::ExprResult Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtTy *substmt,
- SourceLocation RPLoc) { // "({..})"
- Stmt *SubStmt = static_cast<Stmt*>(substmt);
- assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
- CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
-
- // FIXME: there are a variety of strange constraints to enforce here, for
- // example, it is not possible to goto into a stmt expression apparently.
- // More semantic analysis is needed.
-
- // FIXME: the last statement in the compount stmt has its value used. We
- // should not warn about it being unused.
-
- // If there are sub stmts in the compound stmt, take the type of the last one
- // as the type of the stmtexpr.
- QualType Ty = Context.VoidTy;
-
- if (!Compound->body_empty()) {
- Stmt *LastStmt = Compound->body_back();
- // If LastStmt is a label, skip down through into the body.
- while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt))
- LastStmt = Label->getSubStmt();
-
- if (Expr *LastExpr = dyn_cast<Expr>(LastStmt))
- Ty = LastExpr->getType();
- }
-
- return new StmtExpr(Compound, Ty, LPLoc, RPLoc);
-}
-
-Sema::ExprResult Sema::ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
- SourceLocation TypeLoc,
- TypeTy *argty,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RPLoc) {
- QualType ArgTy = QualType::getFromOpaquePtr(argty);
- assert(!ArgTy.isNull() && "Missing type argument!");
-
- // We must have at least one component that refers to the type, and the first
- // one is known to be a field designator. Verify that the ArgTy represents
- // a struct/union/class.
- if (!ArgTy->isRecordType())
- return Diag(TypeLoc, diag::err_offsetof_record_type,ArgTy.getAsString());
-
- // Otherwise, create a compound literal expression as the base, and
- // iteratively process the offsetof designators.
- Expr *Res = new CompoundLiteralExpr(SourceLocation(), ArgTy, 0, false);
-
- // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
- // GCC extension, diagnose them.
- if (NumComponents != 1)
- Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator,
- SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd));
-
- for (unsigned i = 0; i != NumComponents; ++i) {
- const OffsetOfComponent &OC = CompPtr[i];
- if (OC.isBrackets) {
- // Offset of an array sub-field. TODO: Should we allow vector elements?
- const ArrayType *AT = Context.getAsArrayType(Res->getType());
- if (!AT) {
- delete Res;
- return Diag(OC.LocEnd, diag::err_offsetof_array_type,
- Res->getType().getAsString());
- }
-
- // FIXME: C++: Verify that operator[] isn't overloaded.
-
- // C99 6.5.2.1p1
- Expr *Idx = static_cast<Expr*>(OC.U.E);
- if (!Idx->getType()->isIntegerType())
- return Diag(Idx->getLocStart(), diag::err_typecheck_subscript,
- Idx->getSourceRange());
-
- Res = new ArraySubscriptExpr(Res, Idx, AT->getElementType(), OC.LocEnd);
- continue;
- }
-
- const RecordType *RC = Res->getType()->getAsRecordType();
- if (!RC) {
- delete Res;
- return Diag(OC.LocEnd, diag::err_offsetof_record_type,
- Res->getType().getAsString());
- }
-
- // Get the decl corresponding to this.
- RecordDecl *RD = RC->getDecl();
- FieldDecl *MemberDecl = RD->getMember(OC.U.IdentInfo);
- if (!MemberDecl)
- return Diag(BuiltinLoc, diag::err_typecheck_no_member,
- OC.U.IdentInfo->getName(),
- SourceRange(OC.LocStart, OC.LocEnd));
-
- // FIXME: C++: Verify that MemberDecl isn't a static field.
- // FIXME: Verify that MemberDecl isn't a bitfield.
- // MemberDecl->getType() doesn't get the right qualifiers, but it doesn't
- // matter here.
- Res = new MemberExpr(Res, false, MemberDecl, OC.LocEnd, MemberDecl->getType());
- }
-
- return new UnaryOperator(Res, UnaryOperator::OffsetOf, Context.getSizeType(),
- BuiltinLoc);
-}
-
-
-Sema::ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1, TypeTy *arg2,
- SourceLocation RPLoc) {
- QualType argT1 = QualType::getFromOpaquePtr(arg1);
- QualType argT2 = QualType::getFromOpaquePtr(arg2);
-
- assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
-
- return new TypesCompatibleExpr(Context.IntTy, BuiltinLoc, argT1, argT2,RPLoc);
-}
-
-Sema::ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, ExprTy *cond,
- ExprTy *expr1, ExprTy *expr2,
- SourceLocation RPLoc) {
- Expr *CondExpr = static_cast<Expr*>(cond);
- Expr *LHSExpr = static_cast<Expr*>(expr1);
- Expr *RHSExpr = static_cast<Expr*>(expr2);
-
- assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
-
- // The conditional expression is required to be a constant expression.
- llvm::APSInt condEval(32);
- SourceLocation ExpLoc;
- if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc))
- return Diag(ExpLoc, diag::err_typecheck_choose_expr_requires_constant,
- CondExpr->getSourceRange());
-
- // If the condition is > zero, then the AST type is the same as the LSHExpr.
- QualType resType = condEval.getZExtValue() ? LHSExpr->getType() :
- RHSExpr->getType();
- return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
-}
-
-//===----------------------------------------------------------------------===//
-// Clang Extensions.
-//===----------------------------------------------------------------------===//
-
-/// ActOnBlockStart - This callback is invoked when a block literal is started.
-void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope,
- Declarator &ParamInfo) {
- // Analyze block parameters.
- BlockSemaInfo *BSI = new BlockSemaInfo();
-
- // Add BSI to CurBlock.
- BSI->PrevBlockInfo = CurBlock;
- CurBlock = BSI;
-
- BSI->ReturnType = 0;
- BSI->TheScope = BlockScope;
-
- // Analyze arguments to block.
- assert(ParamInfo.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
- DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getTypeObject(0).Fun;
-
- BSI->hasPrototype = FTI.hasPrototype;
- BSI->isVariadic = true;
-
- // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs function that takes
- // no arguments, not a function that takes a single void argument.
- if (FTI.hasPrototype &&
- FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
- (!((ParmVarDecl *)FTI.ArgInfo[0].Param)->getType().getCVRQualifiers() &&
- ((ParmVarDecl *)FTI.ArgInfo[0].Param)->getType()->isVoidType())) {
- // empty arg list, don't push any params.
- BSI->isVariadic = false;
- } else if (FTI.hasPrototype) {
- for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
- BSI->Params.push_back((ParmVarDecl *)FTI.ArgInfo[i].Param);
- BSI->isVariadic = FTI.isVariadic;
- }
-}
-
-/// ActOnBlockError - If there is an error parsing a block, this callback
-/// is invoked to pop the information about the block from the action impl.
-void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
- // Ensure that CurBlock is deleted.
- llvm::OwningPtr<BlockSemaInfo> CC(CurBlock);
-
- // Pop off CurBlock, handle nested blocks.
- CurBlock = CurBlock->PrevBlockInfo;
-
- // FIXME: Delete the ParmVarDecl objects as well???
-
-}
-
-/// ActOnBlockStmtExpr - This is called when the body of a block statement
-/// literal was successfully completed. ^(int x){...}
-Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body,
- Scope *CurScope) {
- // Ensure that CurBlock is deleted.
- llvm::OwningPtr<BlockSemaInfo> BSI(CurBlock);
- llvm::OwningPtr<CompoundStmt> Body(static_cast<CompoundStmt*>(body));
-
- // Pop off CurBlock, handle nested blocks.
- CurBlock = CurBlock->PrevBlockInfo;
-
- QualType RetTy = Context.VoidTy;
- if (BSI->ReturnType)
- RetTy = QualType(BSI->ReturnType, 0);
-
- llvm::SmallVector<QualType, 8> ArgTypes;
- for (unsigned i = 0, e = BSI->Params.size(); i != e; ++i)
- ArgTypes.push_back(BSI->Params[i]->getType());
-
- QualType BlockTy;
- if (!BSI->hasPrototype)
- BlockTy = Context.getFunctionTypeNoProto(RetTy);
- else
- BlockTy = Context.getFunctionType(RetTy, &ArgTypes[0], ArgTypes.size(),
- BSI->isVariadic);
-
- BlockTy = Context.getBlockPointerType(BlockTy);
- return new BlockExpr(CaretLoc, BlockTy, &BSI->Params[0], BSI->Params.size(),
- Body.take());
-}
-
-/// ExprsMatchFnType - return true if the Exprs in array Args have
-/// QualTypes that match the QualTypes of the arguments of the FnType.
-/// The number of arguments has already been validated to match the number of
-/// arguments in FnType.
-static bool ExprsMatchFnType(Expr **Args, const FunctionTypeProto *FnType,
- ASTContext &Context) {
- unsigned NumParams = FnType->getNumArgs();
- for (unsigned i = 0; i != NumParams; ++i) {
- QualType ExprTy = Context.getCanonicalType(Args[i]->getType());
- QualType ParmTy = Context.getCanonicalType(FnType->getArgType(i));
-
- if (ExprTy.getUnqualifiedType() != ParmTy.getUnqualifiedType())
- return false;
- }
- return true;
-}
-
-Sema::ExprResult Sema::ActOnOverloadExpr(ExprTy **args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation BuiltinLoc,
- SourceLocation RParenLoc) {
- // __builtin_overload requires at least 2 arguments
- if (NumArgs < 2)
- return Diag(RParenLoc, diag::err_typecheck_call_too_few_args,
- SourceRange(BuiltinLoc, RParenLoc));
-
- // The first argument is required to be a constant expression. It tells us
- // the number of arguments to pass to each of the functions to be overloaded.
- Expr **Args = reinterpret_cast<Expr**>(args);
- Expr *NParamsExpr = Args[0];
- llvm::APSInt constEval(32);
- SourceLocation ExpLoc;
- if (!NParamsExpr->isIntegerConstantExpr(constEval, Context, &ExpLoc))
- return Diag(ExpLoc, diag::err_overload_expr_requires_non_zero_constant,
- NParamsExpr->getSourceRange());
-
- // Verify that the number of parameters is > 0
- unsigned NumParams = constEval.getZExtValue();
- if (NumParams == 0)
- return Diag(ExpLoc, diag::err_overload_expr_requires_non_zero_constant,
- NParamsExpr->getSourceRange());
- // Verify that we have at least 1 + NumParams arguments to the builtin.
- if ((NumParams + 1) > NumArgs)
- return Diag(RParenLoc, diag::err_typecheck_call_too_few_args,
- SourceRange(BuiltinLoc, RParenLoc));
-
- // Figure out the return type, by matching the args to one of the functions
- // listed after the parameters.
- OverloadExpr *OE = 0;
- for (unsigned i = NumParams + 1; i < NumArgs; ++i) {
- // UsualUnaryConversions will convert the function DeclRefExpr into a
- // pointer to function.
- Expr *Fn = UsualUnaryConversions(Args[i]);
- const FunctionTypeProto *FnType = 0;
- if (const PointerType *PT = Fn->getType()->getAsPointerType())
- FnType = PT->getPointeeType()->getAsFunctionTypeProto();
-
- // The Expr type must be FunctionTypeProto, since FunctionTypeProto has no
- // parameters, and the number of parameters must match the value passed to
- // the builtin.
- if (!FnType || (FnType->getNumArgs() != NumParams))
- return Diag(Fn->getExprLoc(), diag::err_overload_incorrect_fntype,
- Fn->getSourceRange());
-
- // Scan the parameter list for the FunctionType, checking the QualType of
- // each parameter against the QualTypes of the arguments to the builtin.
- // If they match, return a new OverloadExpr.
- if (ExprsMatchFnType(Args+1, FnType, Context)) {
- if (OE)
- return Diag(Fn->getExprLoc(), diag::err_overload_multiple_match,
- OE->getFn()->getSourceRange());
- // Remember our match, and continue processing the remaining arguments
- // to catch any errors.
- OE = new OverloadExpr(Args, NumArgs, i, FnType->getResultType(),
- BuiltinLoc, RParenLoc);
- }
- }
- // Return the newly created OverloadExpr node, if we succeded in matching
- // exactly one of the candidate functions.
- if (OE)
- return OE;
-
- // If we didn't find a matching function Expr in the __builtin_overload list
- // the return an error.
- std::string typeNames;
- for (unsigned i = 0; i != NumParams; ++i) {
- if (i != 0) typeNames += ", ";
- typeNames += Args[i+1]->getType().getAsString();
- }
-
- return Diag(BuiltinLoc, diag::err_overload_no_match, typeNames,
- SourceRange(BuiltinLoc, RParenLoc));
-}
-
-Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
- ExprTy *expr, TypeTy *type,
- SourceLocation RPLoc) {
- Expr *E = static_cast<Expr*>(expr);
- QualType T = QualType::getFromOpaquePtr(type);
-
- InitBuiltinVaListType();
-
- // Get the va_list type
- QualType VaListType = Context.getBuiltinVaListType();
- // Deal with implicit array decay; for example, on x86-64,
- // va_list is an array, but it's supposed to decay to
- // a pointer for va_arg.
- if (VaListType->isArrayType())
- VaListType = Context.getArrayDecayedType(VaListType);
- // Make sure the input expression also decays appropriately.
- UsualUnaryConversions(E);
-
- if (CheckAssignmentConstraints(VaListType, E->getType()) != Compatible)
- return Diag(E->getLocStart(),
- diag::err_first_argument_to_va_arg_not_of_type_va_list,
- E->getType().getAsString(),
- E->getSourceRange());
-
- // FIXME: Warn if a non-POD type is passed in.
-
- return new VAArgExpr(BuiltinLoc, E, T, RPLoc);
-}
-
-bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
- SourceLocation Loc,
- QualType DstType, QualType SrcType,
- Expr *SrcExpr, const char *Flavor) {
- // Decode the result (notice that AST's are still created for extensions).
- bool isInvalid = false;
- unsigned DiagKind;
- switch (ConvTy) {
- default: assert(0 && "Unknown conversion type");
- case Compatible: return false;
- case PointerToInt:
- DiagKind = diag::ext_typecheck_convert_pointer_int;
- break;
- case IntToPointer:
- DiagKind = diag::ext_typecheck_convert_int_pointer;
- break;
- case IncompatiblePointer:
- DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
- break;
- case FunctionVoidPointer:
- DiagKind = diag::ext_typecheck_convert_pointer_void_func;
- break;
- case CompatiblePointerDiscardsQualifiers:
- // If the qualifiers lost were because we were applying the
- // (deprecated) C++ conversion from a string literal to a char*
- // (or wchar_t*), then there was no error (C++ 4.2p2). FIXME:
- // Ideally, this check would be performed in
- // CheckPointerTypesForAssignment. However, that would require a
- // bit of refactoring (so that the second argument is an
- // expression, rather than a type), which should be done as part
- // of a larger effort to fix CheckPointerTypesForAssignment for
- // C++ semantics.
- if (getLangOptions().CPlusPlus &&
- IsStringLiteralToNonConstPointerConversion(SrcExpr, DstType))
- return false;
- DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
- break;
- case IntToBlockPointer:
- DiagKind = diag::err_int_to_block_pointer;
- break;
- case IncompatibleBlockPointer:
- DiagKind = diag::ext_typecheck_convert_incompatible_block_pointer;
- break;
- case BlockVoidPointer:
- DiagKind = diag::ext_typecheck_convert_pointer_void_block;
- break;
- case Incompatible:
- DiagKind = diag::err_typecheck_convert_incompatible;
- isInvalid = true;
- break;
- }
-
- Diag(Loc, DiagKind, DstType.getAsString(), SrcType.getAsString(), Flavor,
- SrcExpr->getSourceRange());
- return isInvalid;
-}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
deleted file mode 100644
index 540d92dbae27..000000000000
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for C++ expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-using namespace clang;
-
-/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
-Action::ExprResult
-Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
- SourceLocation LAngleBracketLoc, TypeTy *Ty,
- SourceLocation RAngleBracketLoc,
- SourceLocation LParenLoc, ExprTy *E,
- SourceLocation RParenLoc) {
- CXXCastExpr::Opcode Op;
-
- switch (Kind) {
- default: assert(0 && "Unknown C++ cast!");
- case tok::kw_const_cast: Op = CXXCastExpr::ConstCast; break;
- case tok::kw_dynamic_cast: Op = CXXCastExpr::DynamicCast; break;
- case tok::kw_reinterpret_cast: Op = CXXCastExpr::ReinterpretCast; break;
- case tok::kw_static_cast: Op = CXXCastExpr::StaticCast; break;
- }
-
- return new CXXCastExpr(Op, QualType::getFromOpaquePtr(Ty), (Expr*)E, OpLoc);
-}
-
-/// ActOnCXXBoolLiteral - Parse {true,false} literals.
-Action::ExprResult
-Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
- assert((Kind != tok::kw_true || Kind != tok::kw_false) &&
- "Unknown C++ Boolean value!");
- return new CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
-}
-
-/// ActOnCXXThrow - Parse throw expressions.
-Action::ExprResult
-Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprTy *E) {
- return new CXXThrowExpr((Expr*)E, Context.VoidTy, OpLoc);
-}
-
-Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
- /// C++ 9.3.2: In the body of a non-static member function, the keyword this
- /// is a non-lvalue expression whose value is the address of the object for
- /// which the function is called.
-
- if (!isa<FunctionDecl>(CurContext)) {
- Diag(ThisLoc, diag::err_invalid_this_use);
- return ExprResult(true);
- }
-
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
- if (MD->isInstance())
- return new PredefinedExpr(ThisLoc, MD->getThisType(Context),
- PredefinedExpr::CXXThis);
-
- return Diag(ThisLoc, diag::err_invalid_this_use);
-}
-
-/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
-/// Can be interpreted either as function-style casting ("int(x)")
-/// or class type construction ("ClassType(x,y,z)")
-/// or creation of a value-initialized type ("int()").
-Action::ExprResult
-Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
- SourceLocation LParenLoc,
- ExprTy **ExprTys, unsigned NumExprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc) {
- assert(TypeRep && "Missing type!");
- QualType Ty = QualType::getFromOpaquePtr(TypeRep);
- Expr **Exprs = (Expr**)ExprTys;
- SourceLocation TyBeginLoc = TypeRange.getBegin();
- SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
-
- if (const RecordType *RT = Ty->getAsRecordType()) {
- // C++ 5.2.3p1:
- // If the simple-type-specifier specifies a class type, the class type shall
- // be complete.
- //
- if (!RT->getDecl()->isDefinition())
- return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
- Ty.getAsString(), FullRange);
-
- unsigned DiagID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error,
- "class constructors are not supported yet");
- return Diag(TyBeginLoc, DiagID);
- }
-
- // C++ 5.2.3p1:
- // If the expression list is a single expression, the type conversion
- // expression is equivalent (in definedness, and if defined in meaning) to the
- // corresponding cast expression.
- //
- if (NumExprs == 1) {
- if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
- return true;
- return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc);
- }
-
- // C++ 5.2.3p1:
- // If the expression list specifies more than a single value, the type shall
- // be a class with a suitably declared constructor.
- //
- if (NumExprs > 1)
- return Diag(CommaLocs[0], diag::err_builtin_func_cast_more_than_one_arg,
- FullRange);
-
- assert(NumExprs == 0 && "Expected 0 expressions");
-
- // C++ 5.2.3p2:
- // The expression T(), where T is a simple-type-specifier for a non-array
- // complete object type or the (possibly cv-qualified) void type, creates an
- // rvalue of the specified type, which is value-initialized.
- //
- if (Ty->isArrayType())
- return Diag(TyBeginLoc, diag::err_value_init_for_array_type, FullRange);
- if (Ty->isIncompleteType() && !Ty->isVoidType())
- return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
- Ty.getAsString(), FullRange);
-
- return new CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc);
-}
-
-
-/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
-/// C++ if/switch/while/for statement.
-/// e.g: "if (int x = f()) {...}"
-Action::ExprResult
-Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
- Declarator &D,
- SourceLocation EqualLoc,
- ExprTy *AssignExprVal) {
- assert(AssignExprVal && "Null assignment expression");
-
- // C++ 6.4p2:
- // The declarator shall not specify a function or an array.
- // The type-specifier-seq shall not contain typedef and shall not declare a
- // new class or enumeration.
-
- assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
- "Parser allowed 'typedef' as storage class of condition decl.");
-
- QualType Ty = GetTypeForDeclarator(D, S);
-
- if (Ty->isFunctionType()) { // The declarator shall not specify a function...
- // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
- // would be created and CXXConditionDeclExpr wants a VarDecl.
- return Diag(StartLoc, diag::err_invalid_use_of_function_type,
- SourceRange(StartLoc, EqualLoc));
- } else if (Ty->isArrayType()) { // ...or an array.
- Diag(StartLoc, diag::err_invalid_use_of_array_type,
- SourceRange(StartLoc, EqualLoc));
- } else if (const RecordType *RT = Ty->getAsRecordType()) {
- RecordDecl *RD = RT->getDecl();
- // The type-specifier-seq shall not declare a new class...
- if (RD->isDefinition() && (RD->getIdentifier() == 0 || S->isDeclScope(RD)))
- Diag(RD->getLocation(), diag::err_type_defined_in_condition);
- } else if (const EnumType *ET = Ty->getAsEnumType()) {
- EnumDecl *ED = ET->getDecl();
- // ...or enumeration.
- if (ED->isDefinition() && (ED->getIdentifier() == 0 || S->isDeclScope(ED)))
- Diag(ED->getLocation(), diag::err_type_defined_in_condition);
- }
-
- DeclTy *Dcl = ActOnDeclarator(S, D, 0);
- if (!Dcl)
- return true;
- AddInitializerToDecl(Dcl, AssignExprVal);
-
- return new CXXConditionDeclExpr(StartLoc, EqualLoc,
- cast<VarDecl>(static_cast<Decl *>(Dcl)));
-}
-
-/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
-bool Sema::CheckCXXBooleanCondition(Expr *&CondExpr) {
- // C++ 6.4p4:
- // The value of a condition that is an initialized declaration in a statement
- // other than a switch statement is the value of the declared variable
- // implicitly converted to type bool. If that conversion is ill-formed, the
- // program is ill-formed.
- // The value of a condition that is an expression is the value of the
- // expression, implicitly converted to bool.
- //
- QualType Ty = CondExpr->getType(); // Save the type.
- AssignConvertType
- ConvTy = CheckSingleAssignmentConstraints(Context.BoolTy, CondExpr);
- if (ConvTy == Incompatible)
- return Diag(CondExpr->getLocStart(), diag::err_typecheck_bool_condition,
- Ty.getAsString(), CondExpr->getSourceRange());
- return false;
-}
-
-/// Helper function to determine whether this is the (deprecated) C++
-/// conversion from a string literal to a pointer to non-const char or
-/// non-const wchar_t (for narrow and wide string literals,
-/// respectively).
-bool
-Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
- // Look inside the implicit cast, if it exists.
- if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From))
- From = Cast->getSubExpr();
-
- // A string literal (2.13.4) that is not a wide string literal can
- // be converted to an rvalue of type "pointer to char"; a wide
- // string literal can be converted to an rvalue of type "pointer
- // to wchar_t" (C++ 4.2p2).
- if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From))
- if (const PointerType *ToPtrType = ToType->getAsPointerType())
- if (const BuiltinType *ToPointeeType
- = ToPtrType->getPointeeType()->getAsBuiltinType()) {
- // This conversion is considered only when there is an
- // explicit appropriate pointer target type (C++ 4.2p2).
- if (ToPtrType->getPointeeType().getCVRQualifiers() == 0 &&
- ((StrLit->isWide() && ToPointeeType->isWideCharType()) ||
- (!StrLit->isWide() &&
- (ToPointeeType->getKind() == BuiltinType::Char_U ||
- ToPointeeType->getKind() == BuiltinType::Char_S))))
- return true;
- }
-
- return false;
-}
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
deleted file mode 100644
index a474b7eee786..000000000000
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for Objective-C expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/Basic/Diagnostic.h"
-using namespace clang;
-
-Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
- ExprTy **Strings,
- unsigned NumStrings) {
- SourceLocation AtLoc = AtLocs[0];
- StringLiteral* S = static_cast<StringLiteral *>(Strings[0]);
- if (NumStrings > 1) {
- // Concatenate objc strings.
- StringLiteral* ES = static_cast<StringLiteral *>(Strings[NumStrings-1]);
- SourceLocation EndLoc = ES->getSourceRange().getEnd();
- unsigned Length = 0;
- for (unsigned i = 0; i < NumStrings; i++)
- Length += static_cast<StringLiteral *>(Strings[i])->getByteLength();
- char *strBuf = new char [Length];
- char *p = strBuf;
- bool isWide = false;
- for (unsigned i = 0; i < NumStrings; i++) {
- S = static_cast<StringLiteral *>(Strings[i]);
- if (S->isWide())
- isWide = true;
- memcpy(p, S->getStrData(), S->getByteLength());
- p += S->getByteLength();
- delete S;
- }
- S = new StringLiteral(strBuf, Length,
- isWide, Context.getPointerType(Context.CharTy),
- AtLoc, EndLoc);
- }
-
- if (CheckBuiltinCFStringArgument(S))
- return true;
-
- if (Context.getObjCConstantStringInterface().isNull()) {
- // Initialize the constant string interface lazily. This assumes
- // the NSConstantString interface is seen in this translation unit.
- IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
- Decl *IFace = LookupDecl(NSIdent, Decl::IDNS_Ordinary, TUScope);
- ObjCInterfaceDecl *strIFace = dyn_cast_or_null<ObjCInterfaceDecl>(IFace);
- if (strIFace)
- Context.setObjCConstantStringInterface(strIFace);
- }
- QualType t = Context.getObjCConstantStringInterface();
- // If there is no NSConstantString interface defined then treat constant
- // strings as untyped objects and let the runtime figure it out later.
- if (t == QualType()) {
- t = Context.getObjCIdType();
- } else {
- t = Context.getPointerType(t);
- }
- return new ObjCStringLiteral(S, t, AtLoc);
-}
-
-Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
- SourceLocation EncodeLoc,
- SourceLocation LParenLoc,
- TypeTy *Ty,
- SourceLocation RParenLoc) {
- QualType EncodedType = QualType::getFromOpaquePtr(Ty);
-
- QualType t = Context.getPointerType(Context.CharTy);
- return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
-}
-
-Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
- SourceLocation AtLoc,
- SourceLocation SelLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- QualType t = Context.getObjCSelType();
- return new ObjCSelectorExpr(t, Sel, AtLoc, RParenLoc);
-}
-
-Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
- SourceLocation AtLoc,
- SourceLocation ProtoLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- ObjCProtocolDecl* PDecl = ObjCProtocols[ProtocolId];
- if (!PDecl) {
- Diag(ProtoLoc, diag::err_undeclared_protocol, ProtocolId->getName());
- return true;
- }
-
- QualType t = Context.getObjCProtoType();
- if (t.isNull())
- return true;
- t = Context.getPointerType(t);
- return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc);
-}
-
-bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
- Selector Sel, ObjCMethodDecl *Method,
- const char *PrefixStr,
- SourceLocation lbrac, SourceLocation rbrac,
- QualType &ReturnType) {
- if (!Method) {
- // Apply default argument promotion as for (C99 6.5.2.2p6).
- for (unsigned i = 0; i != NumArgs; i++)
- DefaultArgumentPromotion(Args[i]);
-
- Diag(lbrac, diag::warn_method_not_found, std::string(PrefixStr),
- Sel.getName(), SourceRange(lbrac, rbrac));
- ReturnType = Context.getObjCIdType();
- return false;
- } else {
- ReturnType = Method->getResultType();
- }
-
- unsigned NumNamedArgs = Sel.getNumArgs();
- assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
-
- bool anyIncompatibleArgs = false;
- for (unsigned i = 0; i < NumNamedArgs; i++) {
- Expr *argExpr = Args[i];
- assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
-
- QualType lhsType = Method->getParamDecl(i)->getType();
- QualType rhsType = argExpr->getType();
-
- // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
- if (lhsType->isArrayType())
- lhsType = Context.getArrayDecayedType(lhsType);
- else if (lhsType->isFunctionType())
- lhsType = Context.getPointerType(lhsType);
-
- AssignConvertType Result =
- CheckSingleAssignmentConstraints(lhsType, argExpr);
- if (Args[i] != argExpr) // The expression was converted.
- Args[i] = argExpr; // Make sure we store the converted expression.
-
- anyIncompatibleArgs |=
- DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
- argExpr, "sending");
- }
-
- // Promote additional arguments to variadic methods.
- if (Method->isVariadic()) {
- for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
- DefaultArgumentPromotion(Args[i]);
- } else {
- // Check for extra arguments to non-variadic methods.
- if (NumArgs != NumNamedArgs) {
- Diag(Args[NumNamedArgs]->getLocStart(),
- diag::err_typecheck_call_too_many_args,
- Method->getSourceRange(),
- SourceRange(Args[NumNamedArgs]->getLocStart(),
- Args[NumArgs-1]->getLocEnd()));
- }
- }
-
- return anyIncompatibleArgs;
-}
-
-// ActOnClassMessage - used for both unary and keyword messages.
-// ArgExprs is optional - if it is present, the number of expressions
-// is obtained from Sel.getNumArgs().
-Sema::ExprResult Sema::ActOnClassMessage(
- Scope *S,
- IdentifierInfo *receiverName, Selector Sel,
- SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs)
-{
- assert(receiverName && "missing receiver class name");
-
- Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
- ObjCInterfaceDecl* ClassDecl = 0;
- bool isSuper = false;
-
- if (receiverName == SuperID && getCurMethodDecl()) {
- isSuper = true;
- ClassDecl = getCurMethodDecl()->getClassInterface()->getSuperClass();
- if (!ClassDecl)
- return Diag(lbrac, diag::error_no_super_class,
- getCurMethodDecl()->getClassInterface()->getName());
- if (getCurMethodDecl()->isInstance()) {
- QualType superTy = Context.getObjCInterfaceType(ClassDecl);
- superTy = Context.getPointerType(superTy);
- ExprResult ReceiverExpr = new PredefinedExpr(SourceLocation(), superTy,
- PredefinedExpr::ObjCSuper);
- // We are really in an instance method, redirect.
- return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac,
- Args, NumArgs);
- }
- // We are sending a message to 'super' within a class method. Do nothing,
- // the receiver will pass through as 'super' (how convenient:-).
- } else
- ClassDecl = getObjCInterfaceDecl(receiverName);
-
- // The following code allows for the following GCC-ism:
- //
- // typedef XCElementDisplayRect XCElementGraphicsRect;
- //
- // @implementation XCRASlice
- // - whatever { // Note that XCElementGraphicsRect is a typedef name.
- // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
- // }
- //
- // If necessary, the following lookup could move to getObjCInterfaceDecl().
- if (!ClassDecl) {
- Decl *IDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, 0, false);
- if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
- const ObjCInterfaceType *OCIT;
- OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
- if (OCIT)
- ClassDecl = OCIT->getDecl();
- }
- }
- assert(ClassDecl && "missing interface declaration");
- ObjCMethodDecl *Method = 0;
- QualType returnType;
- Method = ClassDecl->lookupClassMethod(Sel);
-
- // If we have an implementation in scope, check "private" methods.
- if (!Method) {
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getClassMethod(Sel);
-
- // Look through local category implementations associated with the class.
- if (!Method) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
- }
- }
- }
- // Before we give up, check if the selector is an instance method.
- if (!Method)
- Method = ClassDecl->lookupInstanceMethod(Sel);
-
- if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "+",
- lbrac, rbrac, returnType))
- return true;
-
- // If we have the ObjCInterfaceDecl* for the class that is receiving
- // the message, use that to construct the ObjCMessageExpr. Otherwise
- // pass on the IdentifierInfo* for the class.
- // FIXME: need to do a better job handling 'super' usage within a class
- // For now, we simply pass the "super" identifier through (which isn't
- // consistent with instance methods.
- if (isSuper)
- return new ObjCMessageExpr(receiverName, Sel, returnType, Method,
- lbrac, rbrac, ArgExprs, NumArgs);
- else
- return new ObjCMessageExpr(ClassDecl, Sel, returnType, Method,
- lbrac, rbrac, ArgExprs, NumArgs);
-}
-
-// ActOnInstanceMessage - used for both unary and keyword messages.
-// ArgExprs is optional - if it is present, the number of expressions
-// is obtained from Sel.getNumArgs().
-Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
- SourceLocation lbrac,
- SourceLocation rbrac,
- ExprTy **Args, unsigned NumArgs) {
- assert(receiver && "missing receiver expression");
-
- Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
- Expr *RExpr = static_cast<Expr *>(receiver);
- QualType returnType;
-
- QualType ReceiverCType =
- Context.getCanonicalType(RExpr->getType()).getUnqualifiedType();
-
- // Handle messages to id.
- if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
- ReceiverCType->getAsBlockPointerType()) {
- ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
- Sel, SourceRange(lbrac,rbrac));
- if (!Method)
- Method = FactoryMethodPool[Sel].Method;
- if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
- lbrac, rbrac, returnType))
- return true;
- return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac,
- ArgExprs, NumArgs);
- }
-
- // Handle messages to Class.
- if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
- ObjCMethodDecl *Method = 0;
- if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
- // If we have an implementation in scope, check "private" methods.
- if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getClassMethod(Sel);
- }
- if (!Method)
- Method = FactoryMethodPool[Sel].Method;
- if (!Method)
- Method = LookupInstanceMethodInGlobalPool(
- Sel, SourceRange(lbrac,rbrac));
- if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
- lbrac, rbrac, returnType))
- return true;
- return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac,
- ArgExprs, NumArgs);
- }
-
- ObjCMethodDecl *Method = 0;
- ObjCInterfaceDecl* ClassDecl = 0;
-
- // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
- // long as one of the protocols implements the selector (if not, warn).
- if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
- // Search protocols
- for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
- ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
- if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
- break;
- }
- if (!Method)
- Diag(lbrac, diag::warn_method_not_found_in_protocol,
- std::string("-"), Sel.getName(),
- RExpr->getSourceRange());
- } else if (const ObjCInterfaceType *OCIReceiver =
- ReceiverCType->getAsPointerToObjCInterfaceType()) {
- // We allow sending a message to a pointer to an interface (an object).
-
- ClassDecl = OCIReceiver->getDecl();
- // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
- // faster than the following method (which can do *many* linear searches).
- // The idea is to add class info to InstanceMethodPool.
- Method = ClassDecl->lookupInstanceMethod(Sel);
-
- if (!Method) {
- // Search protocol qualifiers.
- for (ObjCQualifiedIdType::qual_iterator QI = OCIReceiver->qual_begin(),
- E = OCIReceiver->qual_end(); QI != E; ++QI) {
- if ((Method = (*QI)->lookupInstanceMethod(Sel)))
- break;
- }
- }
-
- if (!Method && !OCIReceiver->qual_empty())
- Diag(lbrac, diag::warn_method_not_found_in_protocol,
- std::string("-"), Sel.getName(),
- SourceRange(lbrac, rbrac));
- } else {
- Diag(lbrac, diag::error_bad_receiver_type,
- RExpr->getType().getAsString(), RExpr->getSourceRange());
- return true;
- }
-
- if (!Method) {
- // If we have an implementation in scope, check "private" methods.
- if (ClassDecl)
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getInstanceMethod(Sel);
- // If we still haven't found a method, look in the global pool. This
- // behavior isn't very desirable, however we need it for GCC
- // compatibility.
- if (!Method)
- Method = LookupInstanceMethodInGlobalPool(
- Sel, SourceRange(lbrac,rbrac));
- }
- if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
- lbrac, rbrac, returnType))
- return true;
- return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac,
- ArgExprs, NumArgs);
-}
-
-//===----------------------------------------------------------------------===//
-// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
-//===----------------------------------------------------------------------===//
-
-/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
-/// inheritance hierarchy of 'rProto'.
-static bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
- ObjCProtocolDecl *rProto) {
- if (lProto == rProto)
- return true;
- for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
- E = rProto->protocol_end(); PI != E; ++PI)
- if (ProtocolCompatibleWithProtocol(lProto, *PI))
- return true;
- return false;
-}
-
-/// ClassImplementsProtocol - Checks that 'lProto' protocol
-/// has been implemented in IDecl class, its super class or categories (if
-/// lookupCategory is true).
-static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
- ObjCInterfaceDecl *IDecl,
- bool lookupCategory,
- bool RHSIsQualifiedID = false) {
-
- // 1st, look up the class.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- IDecl->getReferencedProtocols();
-
- for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
- E = Protocols.end(); PI != E; ++PI) {
- if (ProtocolCompatibleWithProtocol(lProto, *PI))
- return true;
- // This is dubious and is added to be compatible with gcc.
- // In gcc, it is also allowed assigning a protocol-qualified 'id'
- // type to a LHS object when protocol in qualified LHS is in list
- // of protocols in the rhs 'id' object. This IMO, should be a bug.
- // FIXME: Treat this as an extension, and flag this as an error when
- // GCC extensions are not enabled.
- if (RHSIsQualifiedID && ProtocolCompatibleWithProtocol(*PI, lProto))
- return true;
- }
-
- // 2nd, look up the category.
- if (lookupCategory)
- for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
- CDecl = CDecl->getNextClassCategory()) {
- for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
- E = CDecl->protocol_end(); PI != E; ++PI)
- if (ProtocolCompatibleWithProtocol(lProto, *PI))
- return true;
- }
-
- // 3rd, look up the super class(s)
- if (IDecl->getSuperClass())
- return
- ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory,
- RHSIsQualifiedID);
-
- return false;
-}
-
-/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
-/// ObjCQualifiedIDType.
-bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
- bool compare) {
- // Allow id<P..> and an 'id' or void* type in all cases.
- if (const PointerType *PT = lhs->getAsPointerType()) {
- QualType PointeeTy = PT->getPointeeType();
- if (Context.isObjCIdType(PointeeTy) || PointeeTy->isVoidType())
- return true;
- } else if (const PointerType *PT = rhs->getAsPointerType()) {
- QualType PointeeTy = PT->getPointeeType();
- if (Context.isObjCIdType(PointeeTy) || PointeeTy->isVoidType())
- return true;
- }
-
- if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
- const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
- const ObjCQualifiedInterfaceType *rhsQI = 0;
- QualType rtype;
-
- if (!rhsQID) {
- // Not comparing two ObjCQualifiedIdType's?
- if (!rhs->isPointerType()) return false;
-
- rtype = rhs->getAsPointerType()->getPointeeType();
- rhsQI = rtype->getAsObjCQualifiedInterfaceType();
- if (rhsQI == 0) {
- // If the RHS is a unqualified interface pointer "NSString*",
- // make sure we check the class hierarchy.
- if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
- ObjCInterfaceDecl *rhsID = IT->getDecl();
- for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
- // when comparing an id<P> on lhs with a static type on rhs,
- // see if static class implements all of id's protocols, directly or
- // through its super class and categories.
- if (!ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true))
- return false;
- }
- return true;
- }
- }
- }
-
- ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE;
- if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *").
- RHSProtoI = rhsQI->qual_begin();
- RHSProtoE = rhsQI->qual_end();
- } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *").
- RHSProtoI = rhsQID->qual_begin();
- RHSProtoE = rhsQID->qual_end();
- } else {
- return false;
- }
-
- for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) {
- ObjCProtocolDecl *lhsProto = lhsQID->getProtocols(i);
- bool match = false;
-
- // when comparing an id<P> on lhs with a static type on rhs,
- // see if static class implements all of id's protocols, directly or
- // through its super class and categories.
- for (; RHSProtoI != RHSProtoE; ++RHSProtoI) {
- ObjCProtocolDecl *rhsProto = *RHSProtoI;
- if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
- compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) {
- match = true;
- break;
- }
- }
- if (rhsQI) {
- // If the RHS is a qualified interface pointer "NSString<P>*",
- // make sure we check the class hierarchy.
- if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
- ObjCInterfaceDecl *rhsID = IT->getDecl();
- for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
- // when comparing an id<P> on lhs with a static type on rhs,
- // see if static class implements all of id's protocols, directly or
- // through its super class and categories.
- if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) {
- match = true;
- break;
- }
- }
- }
- }
- if (!match)
- return false;
- }
-
- return true;
- }
-
- const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
- assert(rhsQID && "One of the LHS/RHS should be id<x>");
-
- if (!lhs->isPointerType())
- return false;
-
- QualType ltype = lhs->getAsPointerType()->getPointeeType();
- if (const ObjCQualifiedInterfaceType *lhsQI =
- ltype->getAsObjCQualifiedInterfaceType()) {
- ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin();
- ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end();
- for (; LHSProtoI != LHSProtoE; ++LHSProtoI) {
- bool match = false;
- ObjCProtocolDecl *lhsProto = *LHSProtoI;
- for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
- ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
- if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
- compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) {
- match = true;
- break;
- }
- }
- if (!match)
- return false;
- }
- return true;
- }
-
- if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) {
- // for static type vs. qualified 'id' type, check that class implements
- // all of 'id's protocols.
- ObjCInterfaceDecl *lhsID = IT->getDecl();
- for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
- ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
- if (!ClassImplementsProtocol(rhsProto, lhsID, compare, true))
- return false;
- }
- return true;
- }
- return false;
-}
-
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
deleted file mode 100644
index 12ca3820dd49..000000000000
--- a/clang/lib/Sema/SemaInit.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-//===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for initializers.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
-
-InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
- hadError = false;
- SemaRef = S;
-
- unsigned newIndex = 0;
-
- CheckExplicitInitList(IL, T, newIndex);
-}
-
-int InitListChecker::numArrayElements(QualType DeclType) {
- // FIXME: use a proper constant
- int maxElements = 0x7FFFFFFF;
- if (const ConstantArrayType *CAT =
- SemaRef->Context.getAsConstantArrayType(DeclType)) {
- maxElements = static_cast<int>(CAT->getSize().getZExtValue());
- }
- return maxElements;
-}
-
-int InitListChecker::numStructUnionElements(QualType DeclType) {
- RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
- int InitializableMembers = 0;
- for (int i = 0; i < structDecl->getNumMembers(); i++)
- if (structDecl->getMember(i)->getIdentifier())
- ++InitializableMembers;
- if (structDecl->isUnion())
- return std::min(InitializableMembers, 1);
- return InitializableMembers - structDecl->hasFlexibleArrayMember();
-}
-
-void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
- QualType T, unsigned &Index) {
- llvm::SmallVector<Expr*, 4> InitExprs;
- int maxElements = 0;
-
- if (T->isArrayType())
- maxElements = numArrayElements(T);
- else if (T->isStructureType() || T->isUnionType())
- maxElements = numStructUnionElements(T);
- else if (T->isVectorType())
- maxElements = T->getAsVectorType()->getNumElements();
- else
- assert(0 && "CheckImplicitInitList(): Illegal type");
-
- if (maxElements == 0) {
- SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
- diag::err_implicit_empty_initializer);
- hadError = true;
- return;
- }
-
- // Check the element types *before* we create the implicit init list;
- // otherwise, we might end up taking the wrong number of elements
- unsigned NewIndex = Index;
- CheckListElementTypes(ParentIList, T, NewIndex);
-
- for (int i = 0; i < maxElements; ++i) {
- // Don't attempt to go past the end of the init list
- if (Index >= ParentIList->getNumInits())
- break;
- Expr* expr = ParentIList->getInit(Index);
-
- // Add the expr to the new implicit init list and remove if from the old.
- InitExprs.push_back(expr);
- ParentIList->removeInit(Index);
- }
- // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
- InitListExpr *ILE = new InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- ILE->setType(T);
-
- // Modify the parent InitListExpr to point to the implicit InitListExpr.
- ParentIList->addInit(Index, ILE);
-}
-
-void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
- unsigned &Index) {
- assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
-
- CheckListElementTypes(IList, T, Index);
- IList->setType(T);
- if (hadError)
- return;
-
- if (Index < IList->getNumInits()) {
- // We have leftover initializers
- if (IList->getNumInits() > 0 &&
- SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
- // Special-case
- SemaRef->Diag(IList->getInit(Index)->getLocStart(),
- diag::err_excess_initializers_in_char_array_initializer,
- IList->getInit(Index)->getSourceRange());
- hadError = true;
- } else if (!T->isIncompleteType()) {
- // Don't warn for incomplete types, since we'll get an error elsewhere
- SemaRef->Diag(IList->getInit(Index)->getLocStart(),
- diag::warn_excess_initializers,
- IList->getInit(Index)->getSourceRange());
- }
- }
-
- if (T->isScalarType())
- SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
- IList->getSourceRange());
-}
-
-void InitListChecker::CheckListElementTypes(InitListExpr *IList,
- QualType &DeclType,
- unsigned &Index) {
- if (DeclType->isScalarType()) {
- CheckScalarType(IList, DeclType, Index);
- } else if (DeclType->isVectorType()) {
- CheckVectorType(IList, DeclType, Index);
- } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
- if (DeclType->isStructureType() || DeclType->isUnionType())
- CheckStructUnionTypes(IList, DeclType, Index);
- else if (DeclType->isArrayType())
- CheckArrayType(IList, DeclType, Index);
- else
- assert(0 && "Aggregate that isn't a function or array?!");
- } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
- // This type is invalid, issue a diagnostic.
- Index++;
- SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type,
- DeclType.getAsString());
- hadError = true;
- } else {
- // In C, all types are either scalars or aggregates, but
- // additional handling is needed here for C++ (and possibly others?).
- assert(0 && "Unsupported initializer type");
- }
-}
-
-void InitListChecker::CheckSubElementType(InitListExpr *IList,
- QualType ElemType,
- unsigned &Index) {
- Expr* expr = IList->getInit(Index);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- CheckExplicitInitList(SubInitList, ElemType, newIndex);
- Index++;
- } else if (StringLiteral *lit =
- SemaRef->IsStringLiteralInit(expr, ElemType)) {
- SemaRef->CheckStringLiteralInit(lit, ElemType);
- Index++;
- } else if (ElemType->isScalarType()) {
- CheckScalarType(IList, ElemType, Index);
- } else if (expr->getType()->getAsRecordType() &&
- SemaRef->Context.typesAreCompatible(
- expr->getType().getUnqualifiedType(),
- ElemType.getUnqualifiedType())) {
- Index++;
- // FIXME: Add checking
- } else {
- CheckImplicitInitList(IList, ElemType, Index);
- Index++;
- }
-}
-
-void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
- unsigned &Index) {
- if (Index < IList->getNumInits()) {
- Expr* expr = IList->getInit(Index);
- if (isa<InitListExpr>(expr)) {
- SemaRef->Diag(IList->getLocStart(),
- diag::err_many_braces_around_scalar_init,
- IList->getSourceRange());
- hadError = true;
- ++Index;
- return;
- }
- Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
- if (SemaRef->CheckSingleInitializer(expr, DeclType))
- hadError = true; // types weren't compatible.
- else if (savExpr != expr)
- // The type was promoted, update initializer list.
- IList->setInit(Index, expr);
- ++Index;
- } else {
- SemaRef->Diag(IList->getLocStart(),
- diag::err_empty_scalar_initializer,
- IList->getSourceRange());
- hadError = true;
- return;
- }
-}
-
-void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
- unsigned &Index) {
- if (Index < IList->getNumInits()) {
- const VectorType *VT = DeclType->getAsVectorType();
- int maxElements = VT->getNumElements();
- QualType elementType = VT->getElementType();
-
- for (int i = 0; i < maxElements; ++i) {
- // Don't attempt to go past the end of the init list
- if (Index >= IList->getNumInits())
- break;
- CheckSubElementType(IList, elementType, Index);
- }
- }
-}
-
-void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
- unsigned &Index) {
- // Check for the special-case of initializing an array with a string.
- if (Index < IList->getNumInits()) {
- if (StringLiteral *lit =
- SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
- SemaRef->CheckStringLiteralInit(lit, DeclType);
- ++Index;
- return;
- }
- }
- if (const VariableArrayType *VAT =
- SemaRef->Context.getAsVariableArrayType(DeclType)) {
- // Check for VLAs; in standard C it would be possible to check this
- // earlier, but I don't know where clang accepts VLAs (gcc accepts
- // them in all sorts of strange places).
- SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
- diag::err_variable_object_no_init,
- VAT->getSizeExpr()->getSourceRange());
- hadError = true;
- return;
- }
-
- int maxElements = numArrayElements(DeclType);
- QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
- ->getElementType();
- int numElements = 0;
- for (int i = 0; i < maxElements; ++i, ++numElements) {
- // Don't attempt to go past the end of the init list
- if (Index >= IList->getNumInits())
- break;
- CheckSubElementType(IList, elementType, Index);
- }
- if (DeclType->isIncompleteArrayType()) {
- // If this is an incomplete array type, the actual type needs to
- // be calculated here.
- if (numElements == 0) {
- // Sizing an array implicitly to zero is not allowed by ISO C,
- // but is supported by GNU.
- SemaRef->Diag(IList->getLocStart(),
- diag::ext_typecheck_zero_array_size);
- }
-
- llvm::APSInt ConstVal(32);
- ConstVal = numElements;
- DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
- ArrayType::Normal, 0);
- }
-}
-
-void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
- QualType DeclType,
- unsigned &Index) {
- RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
-
- // If the record is invalid, some of it's members are invalid. To avoid
- // confusion, we forgo checking the intializer for the entire record.
- if (structDecl->isInvalidDecl()) {
- hadError = true;
- return;
- }
- // If structDecl is a forward declaration, this loop won't do anything;
- // That's okay, because an error should get printed out elsewhere. It
- // might be worthwhile to skip over the rest of the initializer, though.
- int numMembers = DeclType->getAsRecordType()->getDecl()->getNumMembers() -
- structDecl->hasFlexibleArrayMember();
- for (int i = 0; i < numMembers; i++) {
- // Don't attempt to go past the end of the init list
- if (Index >= IList->getNumInits())
- break;
- FieldDecl * curField = structDecl->getMember(i);
- if (!curField->getIdentifier()) {
- // Don't initialize unnamed fields, e.g. "int : 20;"
- continue;
- }
- CheckSubElementType(IList, curField->getType(), Index);
- if (DeclType->isUnionType())
- break;
- }
- // FIXME: Implement flexible array initialization GCC extension (it's a
- // really messy extension to implement, unfortunately...the necessary
- // information isn't actually even here!)
-}
-} // end namespace clang
-
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
deleted file mode 100644
index 68b36ba81848..000000000000
--- a/clang/lib/Sema/SemaStmt.cpp
+++ /dev/null
@@ -1,917 +0,0 @@
-//===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements semantic analysis for statements.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Diagnostic.h"
-using namespace clang;
-
-Sema::StmtResult Sema::ActOnExprStmt(ExprTy *expr) {
- Expr *E = static_cast<Expr*>(expr);
- assert(E && "ActOnExprStmt(): missing expression");
-
- // C99 6.8.3p2: The expression in an expression statement is evaluated as a
- // void expression for its side effects. Conversion to void allows any
- // operand, even incomplete types.
-
- // Same thing in for stmt first clause (when expr) and third clause.
- return E;
-}
-
-
-Sema::StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
- return new NullStmt(SemiLoc);
-}
-
-Sema::StmtResult Sema::ActOnDeclStmt(DeclTy *decl, SourceLocation StartLoc,
- SourceLocation EndLoc) {
- if (decl == 0)
- return true;
-
- ScopedDecl *SD = cast<ScopedDecl>(static_cast<Decl *>(decl));
- return new DeclStmt(SD, StartLoc, EndLoc);
-}
-
-Action::StmtResult
-Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
- StmtTy **elts, unsigned NumElts, bool isStmtExpr) {
- Stmt **Elts = reinterpret_cast<Stmt**>(elts);
- // If we're in C89 mode, check that we don't have any decls after stmts. If
- // so, emit an extension diagnostic.
- if (!getLangOptions().C99 && !getLangOptions().CPlusPlus) {
- // Note that __extension__ can be around a decl.
- unsigned i = 0;
- // Skip over all declarations.
- for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
- /*empty*/;
-
- // We found the end of the list or a statement. Scan for another declstmt.
- for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
- /*empty*/;
-
- if (i != NumElts) {
- ScopedDecl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
- Diag(D->getLocation(), diag::ext_mixed_decls_code);
- }
- }
- // Warn about unused expressions in statements.
- for (unsigned i = 0; i != NumElts; ++i) {
- Expr *E = dyn_cast<Expr>(Elts[i]);
- if (!E) continue;
-
- // Warn about expressions with unused results.
- if (E->hasLocalSideEffect() || E->getType()->isVoidType())
- continue;
-
- // The last expr in a stmt expr really is used.
- if (isStmtExpr && i == NumElts-1)
- continue;
-
- /// DiagnoseDeadExpr - This expression is side-effect free and evaluated in
- /// a context where the result is unused. Emit a diagnostic to warn about
- /// this.
- if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E))
- Diag(BO->getOperatorLoc(), diag::warn_unused_expr,
- BO->getLHS()->getSourceRange(), BO->getRHS()->getSourceRange());
- else if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
- Diag(UO->getOperatorLoc(), diag::warn_unused_expr,
- UO->getSubExpr()->getSourceRange());
- else
- Diag(E->getExprLoc(), diag::warn_unused_expr, E->getSourceRange());
- }
-
- return new CompoundStmt(Elts, NumElts, L, R);
-}
-
-Action::StmtResult
-Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
- SourceLocation DotDotDotLoc, ExprTy *rhsval,
- SourceLocation ColonLoc, StmtTy *subStmt) {
- Stmt *SubStmt = static_cast<Stmt*>(subStmt);
- Expr *LHSVal = ((Expr *)lhsval), *RHSVal = ((Expr *)rhsval);
- assert((LHSVal != 0) && "missing expression in case statement");
-
- SourceLocation ExpLoc;
- // C99 6.8.4.2p3: The expression shall be an integer constant.
- if (!LHSVal->isIntegerConstantExpr(Context, &ExpLoc)) {
- Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
- LHSVal->getSourceRange());
- return SubStmt;
- }
-
- // GCC extension: The expression shall be an integer constant.
- if (RHSVal && !RHSVal->isIntegerConstantExpr(Context, &ExpLoc)) {
- Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
- RHSVal->getSourceRange());
- RHSVal = 0; // Recover by just forgetting about it.
- }
-
- if (SwitchStack.empty()) {
- Diag(CaseLoc, diag::err_case_not_in_switch);
- return SubStmt;
- }
-
- CaseStmt *CS = new CaseStmt(LHSVal, RHSVal, SubStmt, CaseLoc);
- SwitchStack.back()->addSwitchCase(CS);
- return CS;
-}
-
-Action::StmtResult
-Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
- StmtTy *subStmt, Scope *CurScope) {
- Stmt *SubStmt = static_cast<Stmt*>(subStmt);
-
- if (SwitchStack.empty()) {
- Diag(DefaultLoc, diag::err_default_not_in_switch);
- return SubStmt;
- }
-
- DefaultStmt *DS = new DefaultStmt(DefaultLoc, SubStmt);
- SwitchStack.back()->addSwitchCase(DS);
-
- return DS;
-}
-
-Action::StmtResult
-Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, StmtTy *subStmt) {
- Stmt *SubStmt = static_cast<Stmt*>(subStmt);
- // Look up the record for this label identifier.
- LabelStmt *&LabelDecl = LabelMap[II];
-
- // If not forward referenced or defined already, just create a new LabelStmt.
- if (LabelDecl == 0)
- return LabelDecl = new LabelStmt(IdentLoc, II, SubStmt);
-
- assert(LabelDecl->getID() == II && "Label mismatch!");
-
- // Otherwise, this label was either forward reference or multiply defined. If
- // multiply defined, reject it now.
- if (LabelDecl->getSubStmt()) {
- Diag(IdentLoc, diag::err_redefinition_of_label, LabelDecl->getName());
- Diag(LabelDecl->getIdentLoc(), diag::err_previous_definition);
- return SubStmt;
- }
-
- // Otherwise, this label was forward declared, and we just found its real
- // definition. Fill in the forward definition and return it.
- LabelDecl->setIdentLoc(IdentLoc);
- LabelDecl->setSubStmt(SubStmt);
- return LabelDecl;
-}
-
-Action::StmtResult
-Sema::ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
- StmtTy *ThenVal, SourceLocation ElseLoc,
- StmtTy *ElseVal) {
- Expr *condExpr = (Expr *)CondVal;
- Stmt *thenStmt = (Stmt *)ThenVal;
-
- assert(condExpr && "ActOnIfStmt(): missing expression");
-
- DefaultFunctionArrayConversion(condExpr);
- QualType condType = condExpr->getType();
-
- if (getLangOptions().CPlusPlus) {
- if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4
- return true;
- } else if (!condType->isScalarType()) // C99 6.8.4.1p1
- return Diag(IfLoc, diag::err_typecheck_statement_requires_scalar,
- condType.getAsString(), condExpr->getSourceRange());
-
- // Warn if the if block has a null body without an else value.
- // this helps prevent bugs due to typos, such as
- // if (condition);
- // do_stuff();
- if (!ElseVal) {
- if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
- Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
- }
-
- return new IfStmt(IfLoc, condExpr, thenStmt, (Stmt*)ElseVal);
-}
-
-Action::StmtResult
-Sema::ActOnStartOfSwitchStmt(ExprTy *cond) {
- Expr *Cond = static_cast<Expr*>(cond);
-
- if (getLangOptions().CPlusPlus) {
- // C++ 6.4.2.p2:
- // The condition shall be of integral type, enumeration type, or of a class
- // type for which a single conversion function to integral or enumeration
- // type exists (12.3). If the condition is of class type, the condition is
- // converted by calling that conversion function, and the result of the
- // conversion is used in place of the original condition for the remainder
- // of this section. Integral promotions are performed.
-
- QualType Ty = Cond->getType();
-
- // FIXME: Handle class types.
-
- // If the type is wrong a diagnostic will be emitted later at
- // ActOnFinishSwitchStmt.
- if (Ty->isIntegralType() || Ty->isEnumeralType()) {
- // Integral promotions are performed.
- // FIXME: Integral promotions for C++ are not complete.
- UsualUnaryConversions(Cond);
- }
- } else {
- // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
- UsualUnaryConversions(Cond);
- }
-
- SwitchStmt *SS = new SwitchStmt(Cond);
- SwitchStack.push_back(SS);
- return SS;
-}
-
-/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
-/// the specified width and sign. If an overflow occurs, detect it and emit
-/// the specified diagnostic.
-void Sema::ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &Val,
- unsigned NewWidth, bool NewSign,
- SourceLocation Loc,
- unsigned DiagID) {
- // Perform a conversion to the promoted condition type if needed.
- if (NewWidth > Val.getBitWidth()) {
- // If this is an extension, just do it.
- llvm::APSInt OldVal(Val);
- Val.extend(NewWidth);
-
- // If the input was signed and negative and the output is unsigned,
- // warn.
- if (!NewSign && OldVal.isSigned() && OldVal.isNegative())
- Diag(Loc, DiagID, OldVal.toString(10), Val.toString(10));
-
- Val.setIsSigned(NewSign);
- } else if (NewWidth < Val.getBitWidth()) {
- // If this is a truncation, check for overflow.
- llvm::APSInt ConvVal(Val);
- ConvVal.trunc(NewWidth);
- ConvVal.setIsSigned(NewSign);
- ConvVal.extend(Val.getBitWidth());
- ConvVal.setIsSigned(Val.isSigned());
- if (ConvVal != Val)
- Diag(Loc, DiagID, Val.toString(10), ConvVal.toString(10));
-
- // Regardless of whether a diagnostic was emitted, really do the
- // truncation.
- Val.trunc(NewWidth);
- Val.setIsSigned(NewSign);
- } else if (NewSign != Val.isSigned()) {
- // Convert the sign to match the sign of the condition. This can cause
- // overflow as well: unsigned(INTMIN)
- llvm::APSInt OldVal(Val);
- Val.setIsSigned(NewSign);
-
- if (Val.isNegative()) // Sign bit changes meaning.
- Diag(Loc, DiagID, OldVal.toString(10), Val.toString(10));
- }
-}
-
-namespace {
- struct CaseCompareFunctor {
- bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
- const llvm::APSInt &RHS) {
- return LHS.first < RHS;
- }
- bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
- const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
- return LHS.first < RHS.first;
- }
- bool operator()(const llvm::APSInt &LHS,
- const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
- return LHS < RHS.first;
- }
- };
-}
-
-/// CmpCaseVals - Comparison predicate for sorting case values.
-///
-static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
- const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
- if (lhs.first < rhs.first)
- return true;
-
- if (lhs.first == rhs.first &&
- lhs.second->getCaseLoc().getRawEncoding()
- < rhs.second->getCaseLoc().getRawEncoding())
- return true;
- return false;
-}
-
-Action::StmtResult
-Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch,
- ExprTy *Body) {
- Stmt *BodyStmt = (Stmt*)Body;
-
- SwitchStmt *SS = SwitchStack.back();
- assert(SS == (SwitchStmt*)Switch && "switch stack missing push/pop!");
-
- SS->setBody(BodyStmt, SwitchLoc);
- SwitchStack.pop_back();
-
- Expr *CondExpr = SS->getCond();
- QualType CondType = CondExpr->getType();
-
- if (!CondType->isIntegerType()) { // C99 6.8.4.2p1
- Diag(SwitchLoc, diag::err_typecheck_statement_requires_integer,
- CondType.getAsString(), CondExpr->getSourceRange());
- return true;
- }
-
- // Get the bitwidth of the switched-on value before promotions. We must
- // convert the integer case values to this width before comparison.
- unsigned CondWidth = static_cast<unsigned>(Context.getTypeSize(CondType));
- bool CondIsSigned = CondType->isSignedIntegerType();
-
- // Accumulate all of the case values in a vector so that we can sort them
- // and detect duplicates. This vector contains the APInt for the case after
- // it has been converted to the condition type.
- typedef llvm::SmallVector<std::pair<llvm::APSInt, CaseStmt*>, 64> CaseValsTy;
- CaseValsTy CaseVals;
-
- // Keep track of any GNU case ranges we see. The APSInt is the low value.
- std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRanges;
-
- DefaultStmt *TheDefaultStmt = 0;
-
- bool CaseListIsErroneous = false;
-
- for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
- SC = SC->getNextSwitchCase()) {
-
- if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
- if (TheDefaultStmt) {
- Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
- Diag(TheDefaultStmt->getDefaultLoc(), diag::err_first_label);
-
- // FIXME: Remove the default statement from the switch block so that
- // we'll return a valid AST. This requires recursing down the
- // AST and finding it, not something we are set up to do right now. For
- // now, just lop the entire switch stmt out of the AST.
- CaseListIsErroneous = true;
- }
- TheDefaultStmt = DS;
-
- } else {
- CaseStmt *CS = cast<CaseStmt>(SC);
-
- // We already verified that the expression has a i-c-e value (C99
- // 6.8.4.2p3) - get that value now.
- Expr *Lo = CS->getLHS();
- llvm::APSInt LoVal = Lo->getIntegerConstantExprValue(Context);
-
- // Convert the value to the same width/sign as the condition.
- ConvertIntegerToTypeWarnOnOverflow(LoVal, CondWidth, CondIsSigned,
- CS->getLHS()->getLocStart(),
- diag::warn_case_value_overflow);
-
- // If the LHS is not the same type as the condition, insert an implicit
- // cast.
- ImpCastExprToType(Lo, CondType);
- CS->setLHS(Lo);
-
- // If this is a case range, remember it in CaseRanges, otherwise CaseVals.
- if (CS->getRHS())
- CaseRanges.push_back(std::make_pair(LoVal, CS));
- else
- CaseVals.push_back(std::make_pair(LoVal, CS));
- }
- }
-
- // Sort all the scalar case values so we can easily detect duplicates.
- std::stable_sort(CaseVals.begin(), CaseVals.end(), CmpCaseVals);
-
- if (!CaseVals.empty()) {
- for (unsigned i = 0, e = CaseVals.size()-1; i != e; ++i) {
- if (CaseVals[i].first == CaseVals[i+1].first) {
- // If we have a duplicate, report it.
- Diag(CaseVals[i+1].second->getLHS()->getLocStart(),
- diag::err_duplicate_case, CaseVals[i].first.toString(10));
- Diag(CaseVals[i].second->getLHS()->getLocStart(),
- diag::err_duplicate_case_prev);
- // FIXME: We really want to remove the bogus case stmt from the substmt,
- // but we have no way to do this right now.
- CaseListIsErroneous = true;
- }
- }
- }
-
- // Detect duplicate case ranges, which usually don't exist at all in the first
- // place.
- if (!CaseRanges.empty()) {
- // Sort all the case ranges by their low value so we can easily detect
- // overlaps between ranges.
- std::stable_sort(CaseRanges.begin(), CaseRanges.end());
-
- // Scan the ranges, computing the high values and removing empty ranges.
- std::vector<llvm::APSInt> HiVals;
- for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
- CaseStmt *CR = CaseRanges[i].second;
- Expr *Hi = CR->getRHS();
- llvm::APSInt HiVal = Hi->getIntegerConstantExprValue(Context);
-
- // Convert the value to the same width/sign as the condition.
- ConvertIntegerToTypeWarnOnOverflow(HiVal, CondWidth, CondIsSigned,
- CR->getRHS()->getLocStart(),
- diag::warn_case_value_overflow);
-
- // If the LHS is not the same type as the condition, insert an implicit
- // cast.
- ImpCastExprToType(Hi, CondType);
- CR->setRHS(Hi);
-
- // If the low value is bigger than the high value, the case is empty.
- if (CaseRanges[i].first > HiVal) {
- Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range,
- SourceRange(CR->getLHS()->getLocStart(),
- CR->getRHS()->getLocEnd()));
- CaseRanges.erase(CaseRanges.begin()+i);
- --i, --e;
- continue;
- }
- HiVals.push_back(HiVal);
- }
-
- // Rescan the ranges, looking for overlap with singleton values and other
- // ranges. Since the range list is sorted, we only need to compare case
- // ranges with their neighbors.
- for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
- llvm::APSInt &CRLo = CaseRanges[i].first;
- llvm::APSInt &CRHi = HiVals[i];
- CaseStmt *CR = CaseRanges[i].second;
-
- // Check to see whether the case range overlaps with any singleton cases.
- CaseStmt *OverlapStmt = 0;
- llvm::APSInt OverlapVal(32);
-
- // Find the smallest value >= the lower bound. If I is in the case range,
- // then we have overlap.
- CaseValsTy::iterator I = std::lower_bound(CaseVals.begin(),
- CaseVals.end(), CRLo,
- CaseCompareFunctor());
- if (I != CaseVals.end() && I->first < CRHi) {
- OverlapVal = I->first; // Found overlap with scalar.
- OverlapStmt = I->second;
- }
-
- // Find the smallest value bigger than the upper bound.
- I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
- if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
- OverlapVal = (I-1)->first; // Found overlap with scalar.
- OverlapStmt = (I-1)->second;
- }
-
- // Check to see if this case stmt overlaps with the subsequent case range.
- if (i && CRLo <= HiVals[i-1]) {
- OverlapVal = HiVals[i-1]; // Found overlap with range.
- OverlapStmt = CaseRanges[i-1].second;
- }
-
- if (OverlapStmt) {
- // If we have a duplicate, report it.
- Diag(CR->getLHS()->getLocStart(),
- diag::err_duplicate_case, OverlapVal.toString(10));
- Diag(OverlapStmt->getLHS()->getLocStart(),
- diag::err_duplicate_case_prev);
- // FIXME: We really want to remove the bogus case stmt from the substmt,
- // but we have no way to do this right now.
- CaseListIsErroneous = true;
- }
- }
- }
-
- // FIXME: If the case list was broken is some way, we don't have a good system
- // to patch it up. Instead, just return the whole substmt as broken.
- if (CaseListIsErroneous)
- return true;
-
- return SS;
-}
-
-Action::StmtResult
-Sema::ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, StmtTy *Body) {
- Expr *condExpr = (Expr *)Cond;
- assert(condExpr && "ActOnWhileStmt(): missing expression");
-
- DefaultFunctionArrayConversion(condExpr);
- QualType condType = condExpr->getType();
-
- if (getLangOptions().CPlusPlus) {
- if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4
- return true;
- } else if (!condType->isScalarType()) // C99 6.8.5p2
- return Diag(WhileLoc, diag::err_typecheck_statement_requires_scalar,
- condType.getAsString(), condExpr->getSourceRange());
-
- return new WhileStmt(condExpr, (Stmt*)Body, WhileLoc);
-}
-
-Action::StmtResult
-Sema::ActOnDoStmt(SourceLocation DoLoc, StmtTy *Body,
- SourceLocation WhileLoc, ExprTy *Cond) {
- Expr *condExpr = (Expr *)Cond;
- assert(condExpr && "ActOnDoStmt(): missing expression");
-
- DefaultFunctionArrayConversion(condExpr);
- QualType condType = condExpr->getType();
-
- if (getLangOptions().CPlusPlus) {
- if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4
- return true;
- } else if (!condType->isScalarType()) // C99 6.8.5p2
- return Diag(DoLoc, diag::err_typecheck_statement_requires_scalar,
- condType.getAsString(), condExpr->getSourceRange());
-
- return new DoStmt((Stmt*)Body, condExpr, DoLoc);
-}
-
-Action::StmtResult
-Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
- StmtTy *first, ExprTy *second, ExprTy *third,
- SourceLocation RParenLoc, StmtTy *body) {
- Stmt *First = static_cast<Stmt*>(first);
- Expr *Second = static_cast<Expr*>(second);
- Expr *Third = static_cast<Expr*>(third);
- Stmt *Body = static_cast<Stmt*>(body);
-
- if (!getLangOptions().CPlusPlus) {
- if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
- // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
- // identifiers for objects having storage class 'auto' or 'register'.
- for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
- DI!=DE; ++DI) {
- VarDecl *VD = dyn_cast<VarDecl>(*DI);
- if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage())
- VD = 0;
- if (VD == 0)
- Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for);
- // FIXME: mark decl erroneous!
- }
- }
- }
- if (Second) {
- DefaultFunctionArrayConversion(Second);
- QualType SecondType = Second->getType();
-
- if (getLangOptions().CPlusPlus) {
- if (CheckCXXBooleanCondition(Second)) // C++ 6.4p4
- return true;
- } else if (!SecondType->isScalarType()) // C99 6.8.5p2
- return Diag(ForLoc, diag::err_typecheck_statement_requires_scalar,
- SecondType.getAsString(), Second->getSourceRange());
- }
- return new ForStmt(First, Second, Third, Body, ForLoc);
-}
-
-Action::StmtResult
-Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- StmtTy *first, ExprTy *second,
- SourceLocation RParenLoc, StmtTy *body) {
- Stmt *First = static_cast<Stmt*>(first);
- Expr *Second = static_cast<Expr*>(second);
- Stmt *Body = static_cast<Stmt*>(body);
- if (First) {
- QualType FirstType;
- if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
- if (!DS->hasSolitaryDecl())
- return Diag((*DS->decl_begin())->getLocation(),
- diag::err_toomany_element_decls);
-
- ScopedDecl *D = DS->getSolitaryDecl();
- FirstType = cast<ValueDecl>(D)->getType();
- // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
- // identifiers for objects having storage class 'auto' or 'register'.
- VarDecl *VD = cast<VarDecl>(D);
- if (VD->isBlockVarDecl() && !VD->hasLocalStorage())
- return Diag(VD->getLocation(), diag::err_non_variable_decl_in_for);
- } else {
- Expr::isLvalueResult lval = cast<Expr>(First)->isLvalue(Context);
-
- if (lval != Expr::LV_Valid)
- return Diag(First->getLocStart(), diag::err_selector_element_not_lvalue,
- First->getSourceRange());
-
- FirstType = static_cast<Expr*>(first)->getType();
- }
- if (!Context.isObjCObjectPointerType(FirstType))
- Diag(ForLoc, diag::err_selector_element_type,
- FirstType.getAsString(), First->getSourceRange());
- }
- if (Second) {
- DefaultFunctionArrayConversion(Second);
- QualType SecondType = Second->getType();
- if (!Context.isObjCObjectPointerType(SecondType))
- Diag(ForLoc, diag::err_collection_expr_type,
- SecondType.getAsString(), Second->getSourceRange());
- }
- return new ObjCForCollectionStmt(First, Second, Body, ForLoc, RParenLoc);
-}
-
-Action::StmtResult
-Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
- IdentifierInfo *LabelII) {
- // If we are in a block, reject all gotos for now.
- if (CurBlock)
- return Diag(GotoLoc, diag::err_goto_in_block);
-
- // Look up the record for this label identifier.
- LabelStmt *&LabelDecl = LabelMap[LabelII];
-
- // If we haven't seen this label yet, create a forward reference.
- if (LabelDecl == 0)
- LabelDecl = new LabelStmt(LabelLoc, LabelII, 0);
-
- return new GotoStmt(LabelDecl, GotoLoc, LabelLoc);
-}
-
-Action::StmtResult
-Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc,
- ExprTy *DestExp) {
- // FIXME: Verify that the operand is convertible to void*.
-
- return new IndirectGotoStmt((Expr*)DestExp);
-}
-
-Action::StmtResult
-Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
- Scope *S = CurScope->getContinueParent();
- if (!S) {
- // C99 6.8.6.2p1: A break shall appear only in or as a loop body.
- Diag(ContinueLoc, diag::err_continue_not_in_loop);
- return true;
- }
-
- return new ContinueStmt(ContinueLoc);
-}
-
-Action::StmtResult
-Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
- Scope *S = CurScope->getBreakParent();
- if (!S) {
- // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
- Diag(BreakLoc, diag::err_break_not_in_loop_or_switch);
- return true;
- }
-
- return new BreakStmt(BreakLoc);
-}
-
-/// ActOnBlockReturnStmt - Utilty routine to figure out block's return type.
-///
-Action::StmtResult
-Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
-
- // If this is the first return we've seen in the block, infer the type of
- // the block from it.
- if (CurBlock->ReturnType == 0) {
- if (RetValExp) {
- // Don't call UsualUnaryConversions(), since we don't want to do
- // integer promotions here.
- DefaultFunctionArrayConversion(RetValExp);
- CurBlock->ReturnType = RetValExp->getType().getTypePtr();
- } else
- CurBlock->ReturnType = Context.VoidTy.getTypePtr();
- return new ReturnStmt(ReturnLoc, RetValExp);
- }
-
- // Otherwise, verify that this result type matches the previous one. We are
- // pickier with blocks than for normal functions because we don't have GCC
- // compatibility to worry about here.
- if (CurBlock->ReturnType->isVoidType()) {
- if (RetValExp) {
- Diag(ReturnLoc, diag::err_return_block_has_expr);
- delete RetValExp;
- RetValExp = 0;
- }
- return new ReturnStmt(ReturnLoc, RetValExp);
- }
-
- if (!RetValExp) {
- Diag(ReturnLoc, diag::err_block_return_missing_expr);
- return true;
- }
-
- // we have a non-void block with an expression, continue checking
- QualType RetValType = RetValExp->getType();
-
- // For now, restrict multiple return statements in a block to have
- // strict compatible types only.
- QualType BlockQT = QualType(CurBlock->ReturnType, 0);
- if (Context.getCanonicalType(BlockQT).getTypePtr()
- != Context.getCanonicalType(RetValType).getTypePtr()) {
- DiagnoseAssignmentResult(Incompatible, ReturnLoc, BlockQT,
- RetValType, RetValExp, "returning");
- return true;
- }
-
- if (RetValExp) CheckReturnStackAddr(RetValExp, BlockQT, ReturnLoc);
-
- return new ReturnStmt(ReturnLoc, (Expr*)RetValExp);
-}
-
-Action::StmtResult
-Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
- Expr *RetValExp = static_cast<Expr *>(rex);
- if (CurBlock)
- return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
- QualType FnRetType =
- getCurFunctionDecl() ? getCurFunctionDecl()->getResultType() :
- getCurMethodDecl()->getResultType();
-
- if (FnRetType->isVoidType()) {
- if (RetValExp) // C99 6.8.6.4p1 (ext_ since GCC warns)
- Diag(ReturnLoc, diag::ext_return_has_expr,
- ( getCurFunctionDecl() ?
- getCurFunctionDecl()->getIdentifier()->getName() :
- getCurMethodDecl()->getSelector().getName() ),
- RetValExp->getSourceRange());
- return new ReturnStmt(ReturnLoc, RetValExp);
- } else {
- if (!RetValExp) {
- const char *funcName =
- getCurFunctionDecl() ?
- getCurFunctionDecl()->getIdentifier()->getName() :
- getCurMethodDecl()->getSelector().getName().c_str();
- if (getLangOptions().C99) // C99 6.8.6.4p1 (ext_ since GCC warns)
- Diag(ReturnLoc, diag::ext_return_missing_expr, funcName);
- else // C90 6.6.6.4p4
- Diag(ReturnLoc, diag::warn_return_missing_expr, funcName);
- return new ReturnStmt(ReturnLoc, (Expr*)0);
- }
- }
- // we have a non-void function with an expression, continue checking
- QualType RetValType = RetValExp->getType();
-
- // C99 6.8.6.4p3(136): The return statement is not an assignment. The
- // overlap restriction of subclause 6.5.16.1 does not apply to the case of
- // function return.
- AssignConvertType ConvTy = CheckSingleAssignmentConstraints(FnRetType,
- RetValExp);
- if (DiagnoseAssignmentResult(ConvTy, ReturnLoc, FnRetType,
- RetValType, RetValExp, "returning"))
- return true;
-
- if (RetValExp) CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
-
- return new ReturnStmt(ReturnLoc, (Expr*)RetValExp);
-}
-
-Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
- bool IsSimple,
- bool IsVolatile,
- unsigned NumOutputs,
- unsigned NumInputs,
- std::string *Names,
- ExprTy **constraints,
- ExprTy **exprs,
- ExprTy *asmString,
- unsigned NumClobbers,
- ExprTy **clobbers,
- SourceLocation RParenLoc) {
- StringLiteral **Constraints = reinterpret_cast<StringLiteral**>(constraints);
- Expr **Exprs = reinterpret_cast<Expr **>(exprs);
- StringLiteral *AsmString = cast<StringLiteral>((Expr *)asmString);
- StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers);
-
- // The parser verifies that there is a string literal here.
- if (AsmString->isWide())
- // FIXME: We currently leak memory here.
- return Diag(AsmString->getLocStart(), diag::err_asm_wide_character,
- AsmString->getSourceRange());
-
-
- for (unsigned i = 0; i != NumOutputs; i++) {
- StringLiteral *Literal = Constraints[i];
- if (Literal->isWide())
- // FIXME: We currently leak memory here.
- return Diag(Literal->getLocStart(), diag::err_asm_wide_character,
- Literal->getSourceRange());
-
- std::string OutputConstraint(Literal->getStrData(),
- Literal->getByteLength());
-
- TargetInfo::ConstraintInfo info;
- if (!Context.Target.validateOutputConstraint(OutputConstraint.c_str(),info))
- // FIXME: We currently leak memory here.
- return Diag(Literal->getLocStart(),
- diag::err_asm_invalid_output_constraint, OutputConstraint);
-
- // Check that the output exprs are valid lvalues.
- ParenExpr *OutputExpr = cast<ParenExpr>(Exprs[i]);
- Expr::isLvalueResult Result = OutputExpr->isLvalue(Context);
- if (Result != Expr::LV_Valid) {
- // FIXME: We currently leak memory here.
- return Diag(OutputExpr->getSubExpr()->getLocStart(),
- diag::err_asm_invalid_lvalue_in_output,
- OutputExpr->getSubExpr()->getSourceRange());
- }
- }
-
- for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
- StringLiteral *Literal = Constraints[i];
- if (Literal->isWide())
- // FIXME: We currently leak memory here.
- return Diag(Literal->getLocStart(), diag::err_asm_wide_character,
- Literal->getSourceRange());
-
- std::string InputConstraint(Literal->getStrData(),
- Literal->getByteLength());
-
- TargetInfo::ConstraintInfo info;
- if (!Context.Target.validateInputConstraint(InputConstraint.c_str(),
- NumOutputs, info)) {
- // FIXME: We currently leak memory here.
- return Diag(Literal->getLocStart(),
- diag::err_asm_invalid_input_constraint, InputConstraint);
- }
-
- // Check that the input exprs aren't of type void.
- ParenExpr *InputExpr = cast<ParenExpr>(Exprs[i]);
- if (InputExpr->getType()->isVoidType()) {
-
- // FIXME: We currently leak memory here.
- return Diag(InputExpr->getSubExpr()->getLocStart(),
- diag::err_asm_invalid_type_in_input,
- InputExpr->getType().getAsString(), InputConstraint,
- InputExpr->getSubExpr()->getSourceRange());
- }
- }
-
- // Check that the clobbers are valid.
- for (unsigned i = 0; i != NumClobbers; i++) {
- StringLiteral *Literal = Clobbers[i];
- if (Literal->isWide())
- // FIXME: We currently leak memory here.
- return Diag(Literal->getLocStart(), diag::err_asm_wide_character,
- Literal->getSourceRange());
-
- llvm::SmallString<16> Clobber(Literal->getStrData(),
- Literal->getStrData() +
- Literal->getByteLength());
-
- if (!Context.Target.isValidGCCRegisterName(Clobber.c_str()))
- // FIXME: We currently leak memory here.
- return Diag(Literal->getLocStart(),
- diag::err_asm_unknown_register_name, Clobber.c_str());
- }
-
- return new AsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs,
- Names, Constraints, Exprs, AsmString, NumClobbers,
- Clobbers, RParenLoc);
-}
-
-Action::StmtResult
-Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
- SourceLocation RParen, StmtTy *Parm,
- StmtTy *Body, StmtTy *CatchList) {
- ObjCAtCatchStmt *CS = new ObjCAtCatchStmt(AtLoc, RParen,
- static_cast<Stmt*>(Parm), static_cast<Stmt*>(Body),
- static_cast<Stmt*>(CatchList));
- return CatchList ? CatchList : CS;
-}
-
-Action::StmtResult
-Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtTy *Body) {
- ObjCAtFinallyStmt *FS = new ObjCAtFinallyStmt(AtLoc,
- static_cast<Stmt*>(Body));
- return FS;
-}
-
-Action::StmtResult
-Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtTy *Try, StmtTy *Catch, StmtTy *Finally) {
- ObjCAtTryStmt *TS = new ObjCAtTryStmt(AtLoc, static_cast<Stmt*>(Try),
- static_cast<Stmt*>(Catch),
- static_cast<Stmt*>(Finally));
- return TS;
-}
-
-Action::StmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, StmtTy *Throw) {
- ObjCAtThrowStmt *TS = new ObjCAtThrowStmt(AtLoc, static_cast<Stmt*>(Throw));
- return TS;
-}
-
-Action::StmtResult
-Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprTy *SynchExpr,
- StmtTy *SynchBody) {
- ObjCAtSynchronizedStmt *SS = new ObjCAtSynchronizedStmt(AtLoc,
- static_cast<Stmt*>(SynchExpr), static_cast<Stmt*>(SynchBody));
- return SS;
-}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
deleted file mode 100644
index 209a00398801..000000000000
--- a/clang/lib/Sema/SemaType.cpp
+++ /dev/null
@@ -1,605 +0,0 @@
-//===--- SemaType.cpp - Semantic Analysis for Types -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements type-related semantic analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/DeclSpec.h"
-using namespace clang;
-
-/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate
-/// type object. This returns null on error.
-QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
- // FIXME: Should move the logic from DeclSpec::Finish to here for validity
- // checking.
- QualType Result;
-
- switch (DS.getTypeSpecType()) {
- default: assert(0 && "Unknown TypeSpecType!");
- case DeclSpec::TST_void:
- Result = Context.VoidTy;
- break;
- case DeclSpec::TST_char:
- if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
- Result = Context.CharTy;
- else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed)
- Result = Context.SignedCharTy;
- else {
- assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
- "Unknown TSS value");
- Result = Context.UnsignedCharTy;
- }
- break;
- case DeclSpec::TST_wchar:
- if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
- Result = Context.WCharTy;
- else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed) {
- Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec,
- DS.getSpecifierName(DS.getTypeSpecType()));
- Result = Context.getSignedWCharType();
- } else {
- assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
- "Unknown TSS value");
- Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec,
- DS.getSpecifierName(DS.getTypeSpecType()));
- Result = Context.getUnsignedWCharType();
- }
- break;
- case DeclSpec::TST_unspecified:
- // "<proto1,proto2>" is an objc qualified ID with a missing id.
- if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
- Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
- DS.getNumProtocolQualifiers());
- break;
- }
-
- // Unspecified typespec defaults to int in C90. However, the C90 grammar
- // [C90 6.5] only allows a decl-spec if there was *some* type-specifier,
- // type-qualifier, or storage-class-specifier. If not, emit an extwarn.
- // Note that the one exception to this is function definitions, which are
- // allowed to be completely missing a declspec. This is handled in the
- // parser already though by it pretending to have seen an 'int' in this
- // case.
- if (getLangOptions().ImplicitInt) {
- if ((DS.getParsedSpecifiers() & (DeclSpec::PQ_StorageClassSpecifier |
- DeclSpec::PQ_TypeSpecifier |
- DeclSpec::PQ_TypeQualifier)) == 0)
- Diag(DS.getSourceRange().getBegin(), diag::ext_missing_declspec);
- } else {
- // C99 and C++ require a type specifier. For example, C99 6.7.2p2 says:
- // "At least one type specifier shall be given in the declaration
- // specifiers in each declaration, and in the specifier-qualifier list in
- // each struct declaration and type name."
- if (!DS.hasTypeSpecifier())
- Diag(DS.getSourceRange().getBegin(), diag::ext_missing_type_specifier);
- }
-
- // FALL THROUGH.
- case DeclSpec::TST_int: {
- if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
- switch (DS.getTypeSpecWidth()) {
- case DeclSpec::TSW_unspecified: Result = Context.IntTy; break;
- case DeclSpec::TSW_short: Result = Context.ShortTy; break;
- case DeclSpec::TSW_long: Result = Context.LongTy; break;
- case DeclSpec::TSW_longlong: Result = Context.LongLongTy; break;
- }
- } else {
- switch (DS.getTypeSpecWidth()) {
- case DeclSpec::TSW_unspecified: Result = Context.UnsignedIntTy; break;
- case DeclSpec::TSW_short: Result = Context.UnsignedShortTy; break;
- case DeclSpec::TSW_long: Result = Context.UnsignedLongTy; break;
- case DeclSpec::TSW_longlong: Result =Context.UnsignedLongLongTy; break;
- }
- }
- break;
- }
- case DeclSpec::TST_float: Result = Context.FloatTy; break;
- case DeclSpec::TST_double:
- if (DS.getTypeSpecWidth() == DeclSpec::TSW_long)
- Result = Context.LongDoubleTy;
- else
- Result = Context.DoubleTy;
- break;
- case DeclSpec::TST_bool: Result = Context.BoolTy; break; // _Bool or bool
- case DeclSpec::TST_decimal32: // _Decimal32
- case DeclSpec::TST_decimal64: // _Decimal64
- case DeclSpec::TST_decimal128: // _Decimal128
- assert(0 && "FIXME: GNU decimal extensions not supported yet!");
- case DeclSpec::TST_class:
- case DeclSpec::TST_enum:
- case DeclSpec::TST_union:
- case DeclSpec::TST_struct: {
- Decl *D = static_cast<Decl *>(DS.getTypeRep());
- assert(D && "Didn't get a decl for a class/enum/union/struct?");
- assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
- DS.getTypeSpecSign() == 0 &&
- "Can't handle qualifiers on typedef names yet!");
- // TypeQuals handled by caller.
- Result = Context.getTypeDeclType(cast<TypeDecl>(D));
- break;
- }
- case DeclSpec::TST_typedef: {
- Decl *D = static_cast<Decl *>(DS.getTypeRep());
- assert(D && "Didn't get a decl for a typedef?");
- assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
- DS.getTypeSpecSign() == 0 &&
- "Can't handle qualifiers on typedef names yet!");
- DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers();
-
- // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
- // we have this "hack" for now...
- if (ObjCInterfaceDecl *ObjCIntDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
- if (PQ == 0) {
- Result = Context.getObjCInterfaceType(ObjCIntDecl);
- break;
- }
-
- Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl,
- (ObjCProtocolDecl**)PQ,
- DS.getNumProtocolQualifiers());
- break;
- } else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
- if (Context.getObjCIdType() == Context.getTypedefType(typeDecl) && PQ) {
- // id<protocol-list>
- Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
- DS.getNumProtocolQualifiers());
- break;
- }
- }
- // TypeQuals handled by caller.
- Result = Context.getTypeDeclType(dyn_cast<TypeDecl>(D));
- break;
- }
- case DeclSpec::TST_typeofType:
- Result = QualType::getFromOpaquePtr(DS.getTypeRep());
- assert(!Result.isNull() && "Didn't get a type for typeof?");
- // TypeQuals handled by caller.
- Result = Context.getTypeOfType(Result);
- break;
- case DeclSpec::TST_typeofExpr: {
- Expr *E = static_cast<Expr *>(DS.getTypeRep());
- assert(E && "Didn't get an expression for typeof?");
- // TypeQuals handled by caller.
- Result = Context.getTypeOfExpr(E);
- break;
- }
- }
-
- // Handle complex types.
- if (DS.getTypeSpecComplex() == DeclSpec::TSC_complex)
- Result = Context.getComplexType(Result);
-
- assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary &&
- "FIXME: imaginary types not supported yet!");
-
- // See if there are any attributes on the declspec that apply to the type (as
- // opposed to the decl).
- if (const AttributeList *AL = DS.getAttributes())
- ProcessTypeAttributeList(Result, AL);
-
- // Apply const/volatile/restrict qualifiers to T.
- if (unsigned TypeQuals = DS.getTypeQualifiers()) {
-
- // Enforce C99 6.7.3p2: "Types other than pointer types derived from object
- // or incomplete types shall not be restrict-qualified." C++ also allows
- // restrict-qualified references.
- if (TypeQuals & QualType::Restrict) {
- if (const PointerLikeType *PT = Result->getAsPointerLikeType()) {
- QualType EltTy = PT->getPointeeType();
-
- // If we have a pointer or reference, the pointee must have an object or
- // incomplete type.
- if (!EltTy->isIncompleteOrObjectType()) {
- Diag(DS.getRestrictSpecLoc(),
- diag::err_typecheck_invalid_restrict_invalid_pointee,
- EltTy.getAsString(), DS.getSourceRange());
- TypeQuals &= ~QualType::Restrict; // Remove the restrict qualifier.
- }
- } else {
- Diag(DS.getRestrictSpecLoc(),
- diag::err_typecheck_invalid_restrict_not_pointer,
- Result.getAsString(), DS.getSourceRange());
- TypeQuals &= ~QualType::Restrict; // Remove the restrict qualifier.
- }
- }
-
- // Warn about CV qualifiers on functions: C99 6.7.3p8: "If the specification
- // of a function type includes any type qualifiers, the behavior is
- // undefined."
- if (Result->isFunctionType() && TypeQuals) {
- // Get some location to point at, either the C or V location.
- SourceLocation Loc;
- if (TypeQuals & QualType::Const)
- Loc = DS.getConstSpecLoc();
- else {
- assert((TypeQuals & QualType::Volatile) &&
- "Has CV quals but not C or V?");
- Loc = DS.getVolatileSpecLoc();
- }
- Diag(Loc, diag::warn_typecheck_function_qualifiers,
- Result.getAsString(), DS.getSourceRange());
- }
-
- Result = Result.getQualifiedType(TypeQuals);
- }
- return Result;
-}
-
-/// GetTypeForDeclarator - Convert the type for the specified declarator to Type
-/// instances.
-QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
- // long long is a C99 feature.
- if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
- D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong)
- Diag(D.getDeclSpec().getTypeSpecWidthLoc(), diag::ext_longlong);
-
- QualType T = ConvertDeclSpecToType(D.getDeclSpec());
-
- // Walk the DeclTypeInfo, building the recursive type as we go. DeclTypeInfos
- // are ordered from the identifier out, which is opposite of what we want :).
- for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
- DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
- switch (DeclType.Kind) {
- default: assert(0 && "Unknown decltype!");
- case DeclaratorChunk::BlockPointer:
- if (DeclType.Cls.TypeQuals)
- Diag(D.getIdentifierLoc(), diag::err_qualified_block_pointer_type);
- if (!T.getTypePtr()->isFunctionType())
- Diag(D.getIdentifierLoc(), diag::err_nonfunction_block_type);
- else
- T = Context.getBlockPointerType(T);
- break;
- case DeclaratorChunk::Pointer:
- if (T->isReferenceType()) {
- // C++ 8.3.2p4: There shall be no ... pointers to references ...
- Diag(DeclType.Loc, diag::err_illegal_decl_pointer_to_reference,
- D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
- D.setInvalidType(true);
- T = Context.IntTy;
- }
-
- // Enforce C99 6.7.3p2: "Types other than pointer types derived from
- // object or incomplete types shall not be restrict-qualified."
- if ((DeclType.Ptr.TypeQuals & QualType::Restrict) &&
- !T->isIncompleteOrObjectType()) {
- Diag(DeclType.Loc,
- diag::err_typecheck_invalid_restrict_invalid_pointee,
- T.getAsString());
- DeclType.Ptr.TypeQuals &= QualType::Restrict;
- }
-
- // Apply the pointer typequals to the pointer object.
- T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals);
- break;
- case DeclaratorChunk::Reference:
- if (const ReferenceType *RT = T->getAsReferenceType()) {
- // C++ 8.3.2p4: There shall be no references to references.
- Diag(DeclType.Loc, diag::err_illegal_decl_reference_to_reference,
- D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
- D.setInvalidType(true);
- T = RT->getPointeeType();
- }
-
- // Enforce C99 6.7.3p2: "Types other than pointer types derived from
- // object or incomplete types shall not be restrict-qualified."
- if (DeclType.Ref.HasRestrict &&
- !T->isIncompleteOrObjectType()) {
- Diag(DeclType.Loc,
- diag::err_typecheck_invalid_restrict_invalid_pointee,
- T.getAsString());
- DeclType.Ref.HasRestrict = false;
- }
-
- T = Context.getReferenceType(T);
-
- // Handle restrict on references.
- if (DeclType.Ref.HasRestrict)
- T.addRestrict();
- break;
- case DeclaratorChunk::Array: {
- DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
- Expr *ArraySize = static_cast<Expr*>(ATI.NumElts);
- ArrayType::ArraySizeModifier ASM;
- if (ATI.isStar)
- ASM = ArrayType::Star;
- else if (ATI.hasStatic)
- ASM = ArrayType::Static;
- else
- ASM = ArrayType::Normal;
-
- // C99 6.7.5.2p1: If the element type is an incomplete or function type,
- // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
- if (T->isIncompleteType()) {
- Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_incomplete_type,
- T.getAsString());
- T = Context.IntTy;
- D.setInvalidType(true);
- } else if (T->isFunctionType()) {
- Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_functions,
- D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
- T = Context.getPointerType(T);
- D.setInvalidType(true);
- } else if (const ReferenceType *RT = T->getAsReferenceType()) {
- // C++ 8.3.2p4: There shall be no ... arrays of references ...
- Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references,
- D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
- T = RT->getPointeeType();
- D.setInvalidType(true);
- } else if (const RecordType *EltTy = T->getAsRecordType()) {
- // If the element type is a struct or union that contains a variadic
- // array, reject it: C99 6.7.2.1p2.
- if (EltTy->getDecl()->hasFlexibleArrayMember()) {
- Diag(DeclType.Loc, diag::err_flexible_array_in_array,
- T.getAsString());
- T = Context.IntTy;
- D.setInvalidType(true);
- }
- } else if (T->isObjCInterfaceType()) {
- Diag(DeclType.Loc, diag::warn_objc_array_of_interfaces,
- T.getAsString());
- }
-
- // C99 6.7.5.2p1: The size expression shall have integer type.
- if (ArraySize && !ArraySize->getType()->isIntegerType()) {
- Diag(ArraySize->getLocStart(), diag::err_array_size_non_int,
- ArraySize->getType().getAsString(), ArraySize->getSourceRange());
- D.setInvalidType(true);
- delete ArraySize;
- ATI.NumElts = ArraySize = 0;
- }
- llvm::APSInt ConstVal(32);
- if (!ArraySize) {
- T = Context.getIncompleteArrayType(T, ASM, ATI.TypeQuals);
- } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) ||
- !T->isConstantSizeType()) {
- // Per C99, a variable array is an array with either a non-constant
- // size or an element type that has a non-constant-size
- T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
- } else {
- // C99 6.7.5.2p1: If the expression is a constant expression, it shall
- // have a value greater than zero.
- if (ConstVal.isSigned()) {
- if (ConstVal.isNegative()) {
- Diag(ArraySize->getLocStart(),
- diag::err_typecheck_negative_array_size,
- ArraySize->getSourceRange());
- D.setInvalidType(true);
- } else if (ConstVal == 0) {
- // GCC accepts zero sized static arrays.
- Diag(ArraySize->getLocStart(), diag::ext_typecheck_zero_array_size,
- ArraySize->getSourceRange());
- }
- }
- T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals);
- }
- // If this is not C99, extwarn about VLA's and C99 array size modifiers.
- if (!getLangOptions().C99 &&
- (ASM != ArrayType::Normal ||
- (ArraySize && !ArraySize->isIntegerConstantExpr(Context))))
- Diag(D.getIdentifierLoc(), diag::ext_vla);
- break;
- }
- case DeclaratorChunk::Function:
- // If the function declarator has a prototype (i.e. it is not () and
- // does not have a K&R-style identifier list), then the arguments are part
- // of the type, otherwise the argument list is ().
- const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
-
- // C99 6.7.5.3p1: The return type may not be a function or array type.
- if (T->isArrayType() || T->isFunctionType()) {
- Diag(DeclType.Loc, diag::err_func_returning_array_function,
- T.getAsString());
- T = Context.IntTy;
- D.setInvalidType(true);
- }
-
- if (FTI.NumArgs == 0) {
- // Simple void foo(), where the incoming T is the result type.
- T = Context.getFunctionTypeNoProto(T);
- } else if (FTI.ArgInfo[0].Param == 0) {
- // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
- Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
- } else {
- // Otherwise, we have a function with an argument list that is
- // potentially variadic.
- llvm::SmallVector<QualType, 16> ArgTys;
-
- for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- ParmVarDecl *Param = (ParmVarDecl *)FTI.ArgInfo[i].Param;
- QualType ArgTy = Param->getType();
- assert(!ArgTy.isNull() && "Couldn't parse type?");
- //
- // Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
- // This matches the conversion that is done in
- // Sema::ActOnParamDeclarator(). Without this conversion, the
- // argument type in the function prototype *will not* match the
- // type in ParmVarDecl (which makes the code generator unhappy).
- //
- // FIXME: We still apparently need the conversion in
- // Sema::ActOnParamDeclarator(). This doesn't make any sense, since
- // it should be driving off the type being created here.
- //
- // FIXME: If a source translation tool needs to see the original type,
- // then we need to consider storing both types somewhere...
- //
- if (ArgTy->isArrayType()) {
- ArgTy = Context.getArrayDecayedType(ArgTy);
- } else if (ArgTy->isFunctionType())
- ArgTy = Context.getPointerType(ArgTy);
-
- // Look for 'void'. void is allowed only as a single argument to a
- // function with no other parameters (C99 6.7.5.3p10). We record
- // int(void) as a FunctionTypeProto with an empty argument list.
- else if (ArgTy->isVoidType()) {
- // If this is something like 'float(int, void)', reject it. 'void'
- // is an incomplete type (C99 6.2.5p19) and function decls cannot
- // have arguments of incomplete type.
- if (FTI.NumArgs != 1 || FTI.isVariadic) {
- Diag(DeclType.Loc, diag::err_void_only_param);
- ArgTy = Context.IntTy;
- Param->setType(ArgTy);
- } else if (FTI.ArgInfo[i].Ident) {
- // Reject, but continue to parse 'int(void abc)'.
- Diag(FTI.ArgInfo[i].IdentLoc,
- diag::err_param_with_void_type);
- ArgTy = Context.IntTy;
- Param->setType(ArgTy);
- } else {
- // Reject, but continue to parse 'float(const void)'.
- if (ArgTy.getCVRQualifiers())
- Diag(DeclType.Loc, diag::err_void_param_qualified);
-
- // Do not add 'void' to the ArgTys list.
- break;
- }
- } else if (!FTI.hasPrototype) {
- if (ArgTy->isPromotableIntegerType()) {
- ArgTy = Context.IntTy;
- } else if (const BuiltinType* BTy = ArgTy->getAsBuiltinType()) {
- if (BTy->getKind() == BuiltinType::Float)
- ArgTy = Context.DoubleTy;
- }
- }
-
- ArgTys.push_back(ArgTy);
- }
- T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
- FTI.isVariadic);
- }
- break;
- }
-
- // See if there are any attributes on this declarator chunk.
- if (const AttributeList *AL = DeclType.getAttrs())
- ProcessTypeAttributeList(T, AL);
- }
-
- // If there were any type attributes applied to the decl itself (not the
- // type, apply the type attribute to the type!)
- if (const AttributeList *Attrs = D.getAttributes())
- ProcessTypeAttributeList(T, Attrs);
-
- return T;
-}
-
-/// ObjCGetTypeForMethodDefinition - Builds the type for a method definition
-/// declarator
-QualType Sema::ObjCGetTypeForMethodDefinition(DeclTy *D) {
- ObjCMethodDecl *MDecl = dyn_cast<ObjCMethodDecl>(static_cast<Decl *>(D));
- QualType T = MDecl->getResultType();
- llvm::SmallVector<QualType, 16> ArgTys;
-
- // Add the first two invisible argument types for self and _cmd.
- if (MDecl->isInstance()) {
- QualType selfTy = Context.getObjCInterfaceType(MDecl->getClassInterface());
- selfTy = Context.getPointerType(selfTy);
- ArgTys.push_back(selfTy);
- }
- else
- ArgTys.push_back(Context.getObjCIdType());
- ArgTys.push_back(Context.getObjCSelType());
-
- for (int i = 0, e = MDecl->getNumParams(); i != e; ++i) {
- ParmVarDecl *PDecl = MDecl->getParamDecl(i);
- QualType ArgTy = PDecl->getType();
- assert(!ArgTy.isNull() && "Couldn't parse type?");
- // Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
- // This matches the conversion that is done in
- // Sema::ActOnParamDeclarator().
- if (ArgTy->isArrayType())
- ArgTy = Context.getArrayDecayedType(ArgTy);
- else if (ArgTy->isFunctionType())
- ArgTy = Context.getPointerType(ArgTy);
- ArgTys.push_back(ArgTy);
- }
- T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
- MDecl->isVariadic());
- return T;
-}
-
-Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
- // C99 6.7.6: Type names have no identifier. This is already validated by
- // the parser.
- assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
-
- QualType T = GetTypeForDeclarator(D, S);
-
- assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
-
- // Check that there are no default arguments (C++ only).
- if (getLangOptions().CPlusPlus)
- CheckExtraCXXDefaultArguments(D);
-
- // In this context, we *do not* check D.getInvalidType(). If the declarator
- // type was invalid, GetTypeForDeclarator() still returns a "valid" type,
- // though it will not reflect the user specified type.
- return T.getAsOpaquePtr();
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// Type Attribute Processing
-//===----------------------------------------------------------------------===//
-
-/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
-/// specified type. The attribute contains 1 argument, the id of the address
-/// space for the type.
-static void HandleAddressSpaceTypeAttribute(QualType &Type,
- const AttributeList &Attr, Sema &S){
- // If this type is already address space qualified, reject it.
- // Clause 6.7.3 - Type qualifiers: "No type shall be qualified by qualifiers
- // for two or more different address spaces."
- if (Type.getAddressSpace()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
- return;
- }
-
- // Check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- Expr *ASArgExpr = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt addrSpace(32);
- if (!ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_address_space_not_int,
- ASArgExpr->getSourceRange());
- return;
- }
-
- unsigned ASIdx = static_cast<unsigned>(addrSpace.getZExtValue());
- Type = S.Context.getASQualType(Type, ASIdx);
-}
-
-void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
- // Scan through and apply attributes to this type where it makes sense. Some
- // attributes (such as __address_space__, __vector_size__, etc) apply to the
- // type, but others can be present in the type specifiers even though they
- // apply to the decl. Here we apply type attributes and ignore the rest.
- for (; AL; AL = AL->getNext()) {
- // If this is an attribute we can handle, do so now, otherwise, add it to
- // the LeftOverAttrs list for rechaining.
- switch (AL->getKind()) {
- default: break;
- case AttributeList::AT_address_space:
- HandleAddressSpaceTypeAttribute(Result, *AL, *this);
- break;
- }
- }
-}
-
-
diff --git a/clang/lib/Sema/SemaUtil.h b/clang/lib/Sema/SemaUtil.h
deleted file mode 100644
index 35452b18e6f1..000000000000
--- a/clang/lib/Sema/SemaUtil.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===--- SemaUtil.h - Utility functions for semantic analysis -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a few static inline functions that are useful for
-// performing semantic analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_UTIL_H
-#define LLVM_CLANG_SEMA_UTIL_H
-
-#include "clang/AST/Expr.h"
-
-namespace clang {
-
-/// Utility method to determine if a CallExpr is a call to a builtin.
-static inline bool isCallBuiltin(CallExpr* cexp) {
- Expr* sub = cexp->getCallee()->IgnoreParenCasts();
-
- if (DeclRefExpr* E = dyn_cast<DeclRefExpr>(sub))
- if (E->getDecl()->getIdentifier()->getBuiltinID() > 0)
- return true;
-
- return false;
-}
-
-} // end namespace clang
-
-#endif
diff --git a/clang/test/Analysis/CFDate.m b/clang/test/Analysis/CFDate.m
deleted file mode 100644
index ed076c680b27..000000000000
--- a/clang/test/Analysis/CFDate.m
+++ /dev/null
@@ -1,143 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// Foundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not including Foundation.h directly makes this test case both svelte and
-// portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef const struct __CFAllocator * CFAllocatorRef;
-typedef double CFTimeInterval;
-typedef CFTimeInterval CFAbsoluteTime;
-typedef const struct __CFDate * CFDateRef;
-extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
-typedef struct objc_object {} *id;
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; - (id)retain; - (oneway void)release; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-typedef double NSTimeInterval;
-@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
-@class NSString, NSArray, NSTimeZone;
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-CFAbsoluteTime f1() {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(0, t);
- CFRetain(date);
- CFRelease(date);
- CFDateGetAbsoluteTime(date); // no-warning
- CFRelease(date);
- t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
- return t;
-}
-
-CFAbsoluteTime f2() {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(0, t);
- [((NSDate*) date) retain];
- CFRelease(date);
- CFDateGetAbsoluteTime(date); // no-warning
- [((NSDate*) date) release];
- t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
- return t;
-}
-
-
-NSDate* global_x;
-
- // Test to see if we supresss an error when we store the pointer
- // to a global.
-
-CFAbsoluteTime f3() {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(0, t);
- [((NSDate*) date) retain];
- CFRelease(date);
- CFDateGetAbsoluteTime(date); // no-warning
- global_x = (NSDate*) date;
- [((NSDate*) date) release];
- t = CFDateGetAbsoluteTime(date); // no-warning
- return t;
-}
-
-// Test to see if we supresss an error when we store the pointer
-// to a struct.
-
-struct foo {
- NSDate* f;
-};
-
-CFAbsoluteTime f4() {
- struct foo x;
-
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(0, t);
- [((NSDate*) date) retain];
- CFRelease(date);
- CFDateGetAbsoluteTime(date); // no-warning
- x.f = (NSDate*) date;
- [((NSDate*) date) release];
- t = CFDateGetAbsoluteTime(date); // no-warning
- return t;
-}
-
-// Test a leak.
-
-CFAbsoluteTime f5(int x) {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(0, t);
-
- if (x)
- CFRelease(date);
-
- return t; // expected-warning{{leak}}
-}
-
-// Test a leak involving the return.
-
-CFDateRef f6(int x) {
- CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
- CFRetain(date);
- return date; // expected-warning{{leak}}
-}
-
-// Test a leak involving an overwrite.
-
-CFDateRef f7() {
- CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
- CFRetain(date); //expected-warning{{leak}}
- date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
- return date;
-}
-
-// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and
-// has the word create.
-
-CFDateRef MyDateCreate();
-
-CFDateRef f8() {
- CFDateRef date = MyDateCreate();
- CFRetain(date);
- return date; // expected-warning{{leak}}
-}
-
-CFDateRef f9() {
- CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
- int *p = 0;
- // test that the checker assumes that CFDateCreate returns a non-null
- // pointer
- if (!date) *p = 1; // no-warning
- return date;
-}
diff --git a/clang/test/Analysis/CFDateGC.m b/clang/test/Analysis/CFDateGC.m
deleted file mode 100644
index 0f693ba7a05a..000000000000
--- a/clang/test/Analysis/CFDateGC.m
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: clang -checker-cfref -verify -fobjc-gc %s
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// Foundation.h and CoreFoundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not directly including [Core]Foundation.h directly makes this test case
-// both svelte and portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef const void * CFTypeRef;
-typedef const struct __CFAllocator * CFAllocatorRef;
-typedef double CFTimeInterval;
-typedef CFTimeInterval CFAbsoluteTime;
-typedef const struct __CFDate * CFDateRef;
-extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) {}
-@protocol NSObject - (BOOL)isEqual:(id)object; - (oneway void)release; @end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-CFAbsoluteTime f1() {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(0, t);
- CFRetain(date);
- [NSMakeCollectable(date) release];
- CFDateGetAbsoluteTime(date); // no-warning
- CFRelease(date);
- t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
- return t;
-}
-
diff --git a/clang/test/Analysis/CFNumber.c b/clang/test/Analysis/CFNumber.c
deleted file mode 100644
index c82e0a683e59..000000000000
--- a/clang/test/Analysis/CFNumber.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang -checker-cfref -verify -triple x86_64-apple-darwin9 %s
-
-typedef signed long CFIndex;
-typedef const struct __CFAllocator * CFAllocatorRef;
-enum { kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2,
- kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4,
- kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6,
- kCFNumberCharType = 7, kCFNumberShortType = 8,
- kCFNumberIntType = 9, kCFNumberLongType = 10,
- kCFNumberLongLongType = 11, kCFNumberFloatType = 12,
- kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14,
- kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16,
- kCFNumberMaxType = 16 };
-typedef CFIndex CFNumberType;
-typedef const struct __CFNumber * CFNumberRef;
-extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
-
-#include <stdint.h>
-
-CFNumberRef f1() {
- uint8_t x = 1;
- return CFNumberCreate(0, kCFNumberSInt16Type, &x); // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage.}}
-}
-
-CFNumberRef f2() {
- uint16_t x = 1;
- return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost.}}
-}
-
-CFNumberRef f3(unsigned i) {
- return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer.}}
-} \ No newline at end of file
diff --git a/clang/test/Analysis/CFRetainRelease_NSAssertionHandler.m b/clang/test/Analysis/CFRetainRelease_NSAssertionHandler.m
deleted file mode 100644
index b17a51a673cb..000000000000
--- a/clang/test/Analysis/CFRetainRelease_NSAssertionHandler.m
+++ /dev/null
@@ -1,64 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-typedef struct objc_selector *SEL;
-typedef signed char BOOL;
-typedef int NSInteger;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} - (id)init; @end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
-- (NSUInteger)length;
-+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
-@end extern NSString * const NSBundleDidLoadNotification;
-@interface NSAssertionHandler : NSObject {}
-+ (NSAssertionHandler *)currentHandler;
-- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
-@end
-extern NSString * const NSConnectionReplyMode;
-
-//----------------------------------------------------------------------------//
-// The following test case was filed in PR 2593:
-// http://llvm.org/bugs/show_bug.cgi?id=2593
-//
-// There should be no null dereference flagged by the checker because of
-// NSParameterAssert and NSAssert.
-
-
-@interface TestAssert : NSObject {}
-@end
-
-@implementation TestAssert
-
-- (id)initWithPointer: (int*)x
-{
- // Expansion of: NSParameterAssert( x != 0 );
- do { if (!((x != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"CFRetainRelease_NSAssertionHandler.m"] lineNumber:21 description:(@"Invalid parameter not satisfying: %s"), ("x != 0"), (0), (0), (0), (0)]; } } while(0);
-
- if( (self = [super init]) != 0 )
- {
- *x = 1; // no-warning
- }
-
- return self;
-}
-
-- (id)initWithPointer2: (int*)x
-{
- // Expansion of: NSAssert( x != 0, @"" );
- do { if (!((x != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"CFRetainRelease_NSAssertionHandler.m"] lineNumber:33 description:((@"")), (0), (0), (0), (0), (0)]; } } while(0);
-
- if( (self = [super init]) != 0 )
- {
- *x = 1; // no-warning
- }
-
- return self;
-}
-
-@end
diff --git a/clang/test/Analysis/CFString.c b/clang/test/Analysis/CFString.c
deleted file mode 100644
index cb53bb1c66b6..000000000000
--- a/clang/test/Analysis/CFString.c
+++ /dev/null
@@ -1,60 +0,0 @@
-// RUN: clang -checker-cfref -pedantic -verify %s
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// CoreFoundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not directly including CoreFoundation.h directly makes this test case
-// both svelte and portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef unsigned long UInt32;
-typedef unsigned char Boolean;
-typedef signed long CFIndex;
-typedef const void * CFTypeRef;
-typedef const struct __CFString * CFStringRef;
-typedef struct { CFIndex location; } CFRange;
-typedef const struct __CFAllocator * CFAllocatorRef;
-extern void CFRelease(CFTypeRef cf);
-typedef Boolean (*CFArrayEqualCallBack)(const void *value1, const void *value2);
-typedef struct { CFArrayEqualCallBack equal; } CFArrayCallBacks;
-extern const CFArrayCallBacks kCFTypeArrayCallBacks;
-typedef const struct __CFArray * CFArrayRef;
-typedef struct __CFArray * CFMutableArrayRef;
-extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
-extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
-extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
-typedef UInt32 CFStringEncoding;
-enum { kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 };
-extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-void f1() {
-
- // Create the array.
- CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
-
- // Create a string.
- CFStringRef s1 = CFStringCreateWithCString(0, "hello world",
- kCFStringEncodingUTF8);
-
- // Add the string to the array.
- CFArrayAppendValue(A, s1);
-
- // Decrement the reference count.
- CFRelease(s1); // no-warning
-
- // Get the string. We don't own it.
- s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
-
- // Release the array.
- CFRelease(A); // no-warning
-
- // Release the string. This is a bug.
- CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
-}
-
diff --git a/clang/test/Analysis/CheckNSError.m b/clang/test/Analysis/CheckNSError.m
deleted file mode 100644
index c6d846ef440f..000000000000
--- a/clang/test/Analysis/CheckNSError.m
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-typedef signed char BOOL;
-typedef int NSInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-@class NSDictionary;
-@interface NSError : NSObject <NSCopying, NSCoding> {}
-+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict;
-@end
-extern NSString * const NSXMLParserErrorDomain ;
-
-@interface A
-- (void)myMethodWhichMayFail:(NSError **)error;
-- (BOOL)myMethodWhichMayFail2:(NSError **)error;
-@end
-
-@implementation A
-- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning: {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occured.}}
- *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning: {{Potential null dereference.}}
-}
-
-- (BOOL)myMethodWhichMayFail2:(NSError **)error { // no-warning
- if (error) *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // no-warning
- return 0;
-}
-@end
-
-struct __CFError {};
-typedef struct __CFError* CFErrorRef;
-
-void foo(CFErrorRef* error) { // expected-warning{{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occured.}}
- *error = 0; // expected-warning{{Potential null dereference.}}
-}
-
-int bar(CFErrorRef* error) {
- if (error) *error = 0;
- return 0;
-}
diff --git a/clang/test/Analysis/MissingDealloc_IBOutlet.m b/clang/test/Analysis/MissingDealloc_IBOutlet.m
deleted file mode 100644
index 4049e795547e..000000000000
--- a/clang/test/Analysis/MissingDealloc_IBOutlet.m
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -warn-objc-missing-dealloc '-DIBOutlet=__attribute__((iboutlet))' %s --verify
-
-#ifndef IBOutlet
-#define IBOutlet
-#endif
-
-@class NSWindow;
-
-@interface NSObject {}
-- (void)dealloc;
-@end
-
-@interface A : NSObject {
-IBOutlet NSWindow *window;
-}
-@end
-
-@implementation A // no-warning
-@end
-
diff --git a/clang/test/Analysis/MissingDealloc_SEL.m b/clang/test/Analysis/MissingDealloc_SEL.m
deleted file mode 100644
index be3e0b7af815..000000000000
--- a/clang/test/Analysis/MissingDealloc_SEL.m
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: clang -warn-objc-missing-dealloc -verify %s
-
-typedef struct objc_selector *SEL;
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-@end
-@interface NSObject <NSObject> {}
-- (id)init;
-@end
-
-@interface TestSELs : NSObject {
- SEL a;
- SEL b;
-}
-
-@end
-
-@implementation TestSELs // no-warning
-- (id)init {
- if( (self = [super init]) ) {
- a = @selector(a);
- b = @selector(b);
- }
-
- return self;
-}
-@end
diff --git a/clang/test/Analysis/NSPanel.m b/clang/test/Analysis/NSPanel.m
deleted file mode 100644
index a24818e19ed8..000000000000
--- a/clang/test/Analysis/NSPanel.m
+++ /dev/null
@@ -1,87 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-// BEGIN delta-debugging reduced header stuff
-
-typedef struct objc_selector *SEL;
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-- (oneway void)release;
-@end
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-@protocol NSMutableCopying
-- (id)mutableCopyWithZone:(NSZone *)zone;
-@end
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-@interface NSObject <NSObject> {}
-+ (id)alloc;
-@end
-typedef float CGFloat;
-typedef struct _NSPoint {} NSRect;
-static __inline__ __attribute__((always_inline)) NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) {}
-typedef struct {} NSFastEnumerationState;
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-@class NSString;
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-@end
-@interface NSMutableArray : NSArray
-- (void)addObject:(id)anObject;
-@end @class NSAppleEventDescriptor;
-enum { NSBackingStoreRetained = 0, NSBackingStoreNonretained = 1, NSBackingStoreBuffered = 2 };
-typedef NSUInteger NSBackingStoreType;
-@interface NSResponder : NSObject <NSCoding> {} @end
-@protocol NSAnimatablePropertyContainer
-- (id)animator;
-@end
-@protocol NSValidatedUserInterfaceItem
-- (SEL)action;
-@end
-@protocol NSUserInterfaceValidations
-- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
-@end @class NSDate, NSDictionary, NSError, NSException, NSNotification;
-enum { NSBorderlessWindowMask = 0, NSTitledWindowMask = 1 << 0, NSClosableWindowMask = 1 << 1, NSMiniaturizableWindowMask = 1 << 2, NSResizableWindowMask = 1 << 3 };
-@interface NSWindow : NSResponder <NSAnimatablePropertyContainer, NSUserInterfaceValidations> {}
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
-@end
-extern NSString *NSWindowDidBecomeKeyNotification;
-@interface NSPanel : NSWindow {}
-@end
-@class NSTableHeaderView;
-
-// END delta-debugging reduced header stuff
-
-@interface MyClass
-{
- NSMutableArray *panels;
-}
-- (void)myMethod;
-- (void)myMethod2;
-@end
-
-@implementation MyClass // no-warning
-- (void)myMethod
-{
- NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:(BOOL)1];
-
- [panels addObject:panel];
-
- [panel release]; // no-warning
-}
-- (void)myMethod2
-{
- NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:(BOOL)1];
-
- [panels addObject:panel]; // expected-warning{{leak}}
-}
-@end
-
diff --git a/clang/test/Analysis/NSString.m b/clang/test/Analysis/NSString.m
deleted file mode 100644
index a56c5b858521..000000000000
--- a/clang/test/Analysis/NSString.m
+++ /dev/null
@@ -1,181 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// Foundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not directly including Foundation.h directly makes this test case
-// both svelte and portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef const void * CFTypeRef;
-typedef const struct __CFString * CFStringRef;
-typedef const struct __CFAllocator * CFAllocatorRef;
-extern const CFAllocatorRef kCFAllocatorDefault;
-extern CFTypeRef CFRetain(CFTypeRef cf);
-typedef const struct __CFDictionary * CFDictionaryRef;
-extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
-typedef signed char BOOL;
-typedef int NSInteger;
-typedef unsigned int NSUInteger;
-@class NSString, Protocol;
-extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
-typedef NSInteger NSComparisonResult;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-- (oneway void)release;
-@end
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-@protocol NSMutableCopying
-- (id)mutableCopyWithZone:(NSZone *)zone;
-@end
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-@interface NSObject <NSObject> {}
-- (id)init;
-+ (id)alloc;
-@end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-typedef struct {} NSFastEnumerationState;
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-@class NSString;
-typedef struct _NSRange {} NSRange;
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-@end
-@interface NSMutableArray : NSArray
-- (void)addObject:(id)anObject;
-- (id)initWithCapacity:(NSUInteger)numItems;
-@end
-typedef unsigned short unichar;
-@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
-typedef NSUInteger NSStringCompareOptions;
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
-- (NSComparisonResult)compare:(NSString *)string;
-- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
-- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
-- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;
-- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
-- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator;
-@end
-@interface NSSimpleCString : NSString {} @end
-@interface NSConstantString : NSSimpleCString @end
-extern void *_NSConstantStringClassReference;
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-NSComparisonResult f1(NSString* s) {
- NSString *aString = 0;
- return [s compare:aString]; // expected-warning {{Argument to 'NSString' method 'compare:' cannot be nil.}}
-}
-
-NSComparisonResult f2(NSString* s) {
- NSString *aString = 0;
- return [s caseInsensitiveCompare:aString]; // expected-warning {{Argument to 'NSString' method 'caseInsensitiveCompare:' cannot be nil.}}
-}
-
-NSComparisonResult f3(NSString* s, NSStringCompareOptions op) {
- NSString *aString = 0;
- return [s compare:aString options:op]; // expected-warning {{Argument to 'NSString' method 'compare:options:' cannot be nil.}}
-}
-
-NSComparisonResult f4(NSString* s, NSStringCompareOptions op, NSRange R) {
- NSString *aString = 0;
- return [s compare:aString options:op range:R]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:' cannot be nil.}}
-}
-
-NSComparisonResult f5(NSString* s, NSStringCompareOptions op, NSRange R) {
- NSString *aString = 0;
- return [s compare:aString options:op range:R locale:0]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:locale:' cannot be nil.}}
-}
-
-NSArray *f6(NSString* s) {
- return [s componentsSeparatedByCharactersInSet:0]; // expected-warning {{Argument to 'NSString' method 'componentsSeparatedByCharactersInSet:' cannot be nil.}}
-}
-
-NSString* f7(NSString* s1, NSString* s2, NSString* s3) {
-
- NSString* s4 = (NSString*)
- CFStringCreateWithFormat(kCFAllocatorDefault, 0,
- (CFStringRef) __builtin___CFStringMakeConstantString("%@ %@ (%@)"),
- s1, s2, s3);
-
- CFRetain(s4);
- return s4; // expected-warning{{leak}}
-}
-
-NSMutableArray* f8() {
-
- NSString* s = [[NSString alloc] init];
- NSMutableArray* a = [[NSMutableArray alloc] initWithCapacity:2];
- [a addObject:s];
- [s release]; // no-warning
- return a;
-}
-
-void f9() {
-
- NSString* s = [[NSString alloc] init];
- NSString* q = s;
- [s release];
- [q release]; // expected-warning {{used after it is released}}
-}
-
-NSString* f10() {
-
- static NSString* s = 0;
-
- if (!s) s = [[NSString alloc] init];
-
- return s; // no-warning
-}
-
-@interface C1 : NSObject {}
-- (NSString*) getShared;
-+ (C1*) sharedInstance;
-@end
-@implementation C1 : NSObject {}
-- (NSString*) getShared {
- static NSString* s = 0;
- if (!s) s = [[NSString alloc] init];
- return s; // no-warning
-}
-+ (C1 *)sharedInstance {
- static C1 *sharedInstance = 0;
- if (!sharedInstance) {
- sharedInstance = [[C1 alloc] init];
- }
- return sharedInstance; // no-warning
-}
-@end
-
-@interface SharedClass : NSObject
-+ (id)sharedInstance;
-@end
-@implementation SharedClass
-
-- (id)_init {
- if ((self = [super init])) {
- NSLog(@"Bar");
- }
- return self;
-}
-
-+ (id)sharedInstance {
- static SharedClass *_sharedInstance = 0;
- if (!_sharedInstance) {
- _sharedInstance = [[SharedClass alloc] _init];
- }
- return _sharedInstance; // no-warning
-}
-@end
diff --git a/clang/test/Analysis/NSWindow.m b/clang/test/Analysis/NSWindow.m
deleted file mode 100644
index 012b2ded2291..000000000000
--- a/clang/test/Analysis/NSWindow.m
+++ /dev/null
@@ -1,84 +0,0 @@
-// RUN: clang -checker-cfref -warn-dead-stores -verify %s
-
-// These declarations were reduced using Delta-Debugging from Foundation.h
-// on Mac OS X. The test cases are below.
-
-typedef struct objc_selector *SEL;
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-- (id)retain;
-@end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-@interface NSObject <NSObject> {}
- + (id)alloc;
-@end
-typedef float CGFloat;
-typedef struct _NSPoint {} NSRect;
-NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h);
-enum { NSBackingStoreRetained = 0, NSBackingStoreNonretained = 1, NSBackingStoreBuffered = 2 };
-typedef NSUInteger NSBackingStoreType;
-@interface NSResponder : NSObject <NSCoding> {}
-@end
-@protocol NSAnimatablePropertyContainer
-- (id)animator;
-@end
-extern NSString *NSAnimationTriggerOrderIn ;
-@class CIFilter, CALayer, NSDictionary, NSScreen, NSShadow, NSTrackingArea;
-@interface NSView : NSResponder <NSAnimatablePropertyContainer> {} @end
-@protocol NSValidatedUserInterfaceItem - (SEL)action; @end
-@protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; @end @class NSNotification, NSText, NSView, NSMutableSet, NSSet, NSDate;
-enum { NSBorderlessWindowMask = 0, NSTitledWindowMask = 1 << 0, NSClosableWindowMask = 1 << 1, NSMiniaturizableWindowMask = 1 << 2, NSResizableWindowMask = 1 << 3 };
-@interface NSWindow : NSResponder <NSAnimatablePropertyContainer, NSUserInterfaceValidations> {
- struct __wFlags {} _wFlags;
-}
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen;
-- (void)orderFrontRegardless;
-@end
-
-extern NSString *NSWindowDidBecomeKeyNotification;
-
-// Test cases.
-
-void f1() {
- NSWindow *window = [[NSWindow alloc]
- initWithContentRect:NSMakeRect(0,0,100,100)
- styleMask:NSTitledWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered
- defer:0];
-
- [window orderFrontRegardless]; // no-warning
-}
-
-void f2() {
- NSWindow *window = [[NSWindow alloc]
- initWithContentRect:NSMakeRect(0,0,100,100)
- styleMask:NSTitledWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered
- defer:0
- screen:0];
-
- [window orderFrontRegardless]; // no-warning
-}
-
-void f2b() {
- NSWindow *window = [[NSWindow alloc]
- initWithContentRect:NSMakeRect(0,0,100,100)
- styleMask:NSTitledWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered
- defer:0
- screen:0];
-
- [window orderFrontRegardless];
-
- [window retain]; // expected-warning{{leak}}
-}
-
-
-void f3() {
- NSWindow *window = [NSWindow alloc]; // expected-warning{{never read}} expected-warning{{leak}}
-}
diff --git a/clang/test/Analysis/NoReturn.m b/clang/test/Analysis/NoReturn.m
deleted file mode 100644
index f67a673adb6e..000000000000
--- a/clang/test/Analysis/NoReturn.m
+++ /dev/null
@@ -1,78 +0,0 @@
-// RUN: clang -checker-simple -verify %s &&
-// RUN: clang -checker-cfref -verify %s
-
-#include <stdarg.h>
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// Foundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not directly including Foundation.h directly makes this test case
-// both svelte and portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object;
-@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
-@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
-- (NSUInteger)length;
-+ (id)stringWithFormat:(NSString *)format, ...;
-@end
-@interface NSSimpleCString : NSString {} @end
-@interface NSConstantString : NSSimpleCString @end
-extern void *_NSConstantStringClassReference;
-typedef double NSTimeInterval;
-@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
-@class NSString, NSDictionary, NSArray;
-@interface NSException : NSObject <NSCopying, NSCoding> {}
-+ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
-- (void)raise;
-@end
-@interface NSException (NSExceptionRaisingConveniences)
-+ (void)raise:(NSString *)name format:(NSString *)format, ...;
-+ (void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
-@end
-
-enum {NSPointerFunctionsStrongMemory = (0 << 0), NSPointerFunctionsZeroingWeakMemory = (1 << 0), NSPointerFunctionsOpaqueMemory = (2 << 0), NSPointerFunctionsMallocMemory = (3 << 0), NSPointerFunctionsMachVirtualMemory = (4 << 0), NSPointerFunctionsObjectPersonality = (0 << 8), NSPointerFunctionsOpaquePersonality = (1 << 8), NSPointerFunctionsObjectPointerPersonality = (2 << 8), NSPointerFunctionsCStringPersonality = (3 << 8), NSPointerFunctionsStructPersonality = (4 << 8), NSPointerFunctionsIntegerPersonality = (5 << 8), NSPointerFunctionsCopyIn = (1 << 16), };
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-int f1(int *x, NSString* s) {
-
- if (x) ++x;
-
- [NSException raise:@"Blah" format:[NSString stringWithFormat:@"Blah %@", s]];
-
- return *x; // no-warning
-}
-
-int f2(int *x, ...) {
-
- if (x) ++x;
- va_list alist;
- va_start(alist, x);
-
- [NSException raise:@"Blah" format:@"Blah %@" arguments:alist];
-
- return *x; // no-warning
-}
-
-int f3(int* x) {
-
- if (x) ++x;
-
- [[NSException exceptionWithName:@"My Exception" reason:@"Want to test exceptions." userInfo:0] raise];
-
- return *x; // no-warning
-}
-
diff --git a/clang/test/Analysis/ObjCRetSigs.m b/clang/test/Analysis/ObjCRetSigs.m
deleted file mode 100644
index 009f6c380805..000000000000
--- a/clang/test/Analysis/ObjCRetSigs.m
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -warn-objc-methodsigs -verify %s
-
-#include <stdio.h>
-
-@interface MyBase
--(long long)length;
-@end
-
-@interface MySub : MyBase{}
--(double)length;
-@end
-
-@implementation MyBase
--(long long)length{
- printf("Called MyBase -length;\n");
- return 3;
-}
-@end
-
-@implementation MySub
--(double)length{ // expected-warning{{types are incompatible}}
- printf("Called MySub -length;\n");
- return 3.3;
-}
-@end
diff --git a/clang/test/Analysis/cfref_PR2519.c b/clang/test/Analysis/cfref_PR2519.c
deleted file mode 100644
index aa429a6f7eb5..000000000000
--- a/clang/test/Analysis/cfref_PR2519.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-typedef unsigned char Boolean;
-typedef signed long CFIndex;
-typedef const void * CFTypeRef;
-typedef const struct __CFString * CFStringRef;
-typedef const struct __CFAllocator * CFAllocatorRef;
-extern const CFAllocatorRef kCFAllocatorDefault;
-typedef struct {} CFAllocatorContext;
-extern void CFRelease(CFTypeRef cf);
-typedef struct {}
-CFDictionaryKeyCallBacks;
-extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
-typedef struct {}
-CFDictionaryValueCallBacks;
-extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
-typedef const struct __CFDictionary * CFDictionaryRef;
-extern CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
-enum { kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 };
-typedef CFIndex CFNumberType;
-typedef const struct __CFNumber * CFNumberRef;
-extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
-typedef struct __CFNotificationCenter * CFNotificationCenterRef;
-extern CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
-extern void CFNotificationCenterPostNotification(CFNotificationCenterRef center, CFStringRef name, const void *object, CFDictionaryRef userInfo, Boolean deliverImmediately);
-
-// This test case was reported in PR2519 as a false positive (_value was
-// reported as being leaked).
-
-int main(int argc, char **argv) {
- CFStringRef _key = ((CFStringRef) __builtin___CFStringMakeConstantString ("" "Process identifier" ""));
- int pid = 42;
-
- CFNumberRef _value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
- CFDictionaryRef userInfo = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&_key, (const void **)&_value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFRelease(_value); // no-warning
- CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
- ((CFStringRef) __builtin___CFStringMakeConstantString ("" "GrowlPreferencesChanged" "")),
- ((CFStringRef) __builtin___CFStringMakeConstantString ("" "GrowlUserDefaults" "")),
- userInfo, 0);
- CFRelease(userInfo); // no-warning
-
- return 0;
-}
-
diff --git a/clang/test/Analysis/cfref_rdar6080742.c b/clang/test/Analysis/cfref_rdar6080742.c
deleted file mode 100644
index 28d7d15c666b..000000000000
--- a/clang/test/Analysis/cfref_rdar6080742.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-// This test case was reported in <rdar:problem/6080742>.
-// It tests path-sensitivity with respect to '!(cfstring != 0)' (negation of inequality).
-
-int printf(const char *restrict,...);
-typedef unsigned long UInt32;
-typedef signed long SInt32;
-typedef SInt32 OSStatus;
-typedef unsigned char Boolean;
-enum { noErr = 0};
-typedef const void *CFTypeRef;
-typedef const struct __CFString *CFStringRef;
-typedef const struct __CFAllocator *CFAllocatorRef;
-extern void CFRelease(CFTypeRef cf);
-typedef UInt32 CFStringEncoding;
-enum { kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500,
- kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01,
- kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100,
- kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF,
- kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100,
- kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100,
- kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100};
-extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
-
-enum { memROZWarn = -99, memROZError = -99, memROZErr = -99, memFullErr = -108,
- nilHandleErr = -109, memWZErr = -111, memPurErr = -112, memAdrErr = -110,
- memAZErr = -113, memPCErr = -114, memBCErr = -115, memSCErr = -116, memLockedErr = -117};
-
-#define DEBUG1
-
-void DebugStop(const char *format,...);
-void DebugTraceIf(unsigned int condition, const char *format,...);
-Boolean DebugDisplayOSStatusMsg(OSStatus status, const char *statusStr, const char *fileName, unsigned long lineNumber);
-
-#define Assert(condition)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); }
-#define AssertMsg(condition, message)if (!(condition)) { DebugStop("Assertion failure: %s (%s) [File: %s, Line: %lu]", #condition, message, __FILE__, __LINE__); }
-#define Require(condition)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); }
-#define RequireAction(condition, action)if (!(condition)) { DebugStop("Assertion failure: %s [File: %s, Line: %lu]", #condition, __FILE__, __LINE__); action }
-#define RequireActionSilent(condition, action)if (!(condition)) { action }
-#define AssertNoErr(err){ DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__); }
-#define RequireNoErr(err, action){ if( DebugDisplayOSStatusMsg((err), #err, __FILE__, __LINE__) ) { action }}
-
-void DebugStop(const char *format,...); /* Not an abort function. */
-
-int main(int argc, char *argv[]) {
- CFStringRef cfString;
- OSStatus status = noErr;
- cfString = CFStringCreateWithCString(0, "hello", kCFStringEncodingUTF8);
- RequireAction(cfString != 0, return memFullErr;) //no - warning
- printf("cfstring %p\n", cfString);
-Exit:
- CFRelease(cfString);
- return 0;
-}
diff --git a/clang/test/Analysis/complex.c b/clang/test/Analysis/complex.c
deleted file mode 100644
index 0698d9cd8b69..000000000000
--- a/clang/test/Analysis/complex.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-
-#include <stdint.h>
-
-int f1(int * p) {
-
- // This branch should be infeasible
- // because __imag__ p is 0.
- if (!p && __imag__ (intptr_t) p)
- *p = 1; // no-warning
-
- // If p != 0 then this branch is feasible; otherwise it is not.
- if (__real__ (intptr_t) p)
- *p = 1; // no-warning
-
- *p = 2; // expected-warning{{Dereference of null pointer}}
-}
diff --git a/clang/test/Analysis/conditional-op-missing-lhs.c b/clang/test/Analysis/conditional-op-missing-lhs.c
deleted file mode 100644
index 9fbb9f198755..000000000000
--- a/clang/test/Analysis/conditional-op-missing-lhs.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -warn-dead-stores -warn-uninit-values -verify %s
-
-void f1()
-{
- int i;
-
- int j = i ? : 1; // expected-warning{{use of uninitialized variable}} //expected-warning{{Value stored to 'j' during its initialization is never read}}
-}
-
-void *f2(int *i)
-{
- return i ? : 0;
-}
-
-void *f3(int *i)
-{
- int a;
-
- return &a ? : i;
-}
-
-void f4()
-{
- char c[1 ? : 2];
-}
-
diff --git a/clang/test/Analysis/dead-stores.c b/clang/test/Analysis/dead-stores.c
deleted file mode 100644
index 2a67afd0b0f5..000000000000
--- a/clang/test/Analysis/dead-stores.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// RUN: clang -warn-dead-stores -verify %s &&
-// RUN: clang -checker-simple -warn-dead-stores -verify %s &&
-// RUN: clang -warn-dead-stores -checker-simple -verify %s
-
-
-void f1() {
- int k, y;
- int abc=1;
- long idx=abc+3*5; // expected-warning {{never read}}
-}
-
-void f2(void *b) {
- char *c = (char*)b; // no-warning
- char *d = b+1; // expected-warning {{never read}}
- printf("%s", c);
-}
-
-void f3() {
- int r;
- if ((r = f()) != 0) { // no-warning
- int y = r; // no-warning
- printf("the error is: %d\n", y);
- }
-}
-
-void f4(int k) {
-
- k = 1;
-
- if (k)
- f1();
-
- k = 2; // expected-warning {{never read}}
-}
-
-void f5() {
-
- int x = 4; // no-warning
- int *p = &x; // expected-warning{{never read}}
-
-}
-
-int f6() {
-
- int x = 4;
- ++x; // expected-warning{{never read}}
- return 1;
-}
-
-int f7(int *p) {
- // This is allowed for defensive programming.
- p = 0; // no-warning
- return 1;
-}
-
-int f8(int *p) {
- extern int *baz();
- if (p = baz()) // expected-warning{{Although the value}}
- return 1;
- return 0;
-}
-
-int f9() {
- int x = 4;
- x = x + 10; // expected-warning{{never read}}
- return 1;
-}
-
-int f10() {
- int x = 4;
- x = 10 + x; // expected-warning{{never read}}
- return 1;
-}
-
-int f11() {
- int x = 4;
- return ++x; // expected-warning{{never read}}
-}
-
-int f12a(int y) {
- int x = y; // expected-warning{{never read}}
- return 1;
-}
-int f12b(int y) {
- int x __attribute__((unused)) = y; // no-warning
- return 1;
-}
-
-// Filed with PR 2630. This code should produce no warnings.
-int f13(void)
-{
- int a = 1;
- int b, c = b = a + a;
-
- if (b > 0)
- return (0);
-
- return (a + b + c);
-}
-
-// Filed with PR 2763.
-int f14(int count) {
- int index, nextLineIndex;
- for (index = 0; index < count; index = nextLineIndex+1) {
- nextLineIndex = index+1; // no-warning
- continue;
- }
- return index;
-}
-
-// Test case for <rdar://problem/6248086>
-void f15(unsigned x, unsigned y) {
- int count = x * y; // no-warning
- int z[count];
-}
-
-int f16(int x) {
- x = x * 2;
- x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}}
- ? 5 : 8;
- return x;
-}
-
diff --git a/clang/test/Analysis/dead-stores.m b/clang/test/Analysis/dead-stores.m
deleted file mode 100644
index f58c2c135f6c..000000000000
--- a/clang/test/Analysis/dead-stores.m
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -warn-dead-stores -verify %s
-
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; @end
-typedef float CGFloat;
-typedef struct _NSPoint {} NSRange;
-@interface NSValue (NSValueRangeExtensions) + (NSValue *)valueWithRange:(NSRange)range;
-- (BOOL)containsObject:(id)anObject;
-@end
-@class NSURLAuthenticationChallenge;
-@interface NSResponder : NSObject <NSCoding> {} @end
-@class NSArray, NSDictionary, NSString;
-@interface NSObject (NSKeyValueBindingCreation)
-+ (void)exposeBinding:(NSString *)binding;
-- (NSArray *)exposedBindings;
-@end
-extern NSString *NSAlignmentBinding;
-
-// This test case was reported as a false positive due to a bug in the
-// LiveVariables <-> DeadStores interplay. We should not flag a warning
-// here. The test case was reported in:
-// http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-July/002157.html
-void DeadStoreTest(NSObject *anObject) {
- NSArray *keys;
- if ((keys = [anObject exposedBindings]) && // no-warning
- ([keys containsObject:@"name"] && [keys containsObject:@"icon"])) {}
-}
-
diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c
deleted file mode 100644
index 0d5af4bcde2d..000000000000
--- a/clang/test/Analysis/exercise-ps.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-//
-// Just exercise the analyzer (no assertions).
-
-
-static const char * f1(const char *x, char *y) {
- while (*x != 0) {
- *y++ = *x++;
- }
-}
diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m
deleted file mode 100644
index f96b1a22c7df..000000000000
--- a/clang/test/Analysis/misc-ps.m
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -checker-cfref --verify %s
-
-// Reduced test case from crash in <rdar://problem/6253157>
-@class NSObject;
-@interface A @end
-@implementation A
-- (void)foo:(void (^)(NSObject *x))block {
- if (!((block != ((void *)0)))) {}
-}
-@end
-
diff --git a/clang/test/Analysis/no-exit-cfg.c b/clang/test/Analysis/no-exit-cfg.c
deleted file mode 100644
index b61abf548f0d..000000000000
--- a/clang/test/Analysis/no-exit-cfg.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-// This is a test case for the issue reported in PR 2819:
-// http://llvm.org/bugs/show_bug.cgi?id=2819
-// The flow-sensitive dataflow solver should work even when no block in
-// the CFG reaches the exit block.
-
-int g(int x);
-void h(int x);
-
-int f(int x)
-{
-out_err:
- if (g(x)) {
- h(x);
- }
- goto out_err;
-}
diff --git a/clang/test/Analysis/null-deref-ps.c b/clang/test/Analysis/null-deref-ps.c
deleted file mode 100644
index a085d5a963ed..000000000000
--- a/clang/test/Analysis/null-deref-ps.c
+++ /dev/null
@@ -1,115 +0,0 @@
-// RUN: clang -std=gnu99 -checker-simple -verify %s
-
-#include<stdint.h>
-#include <assert.h>
-
-void f1(int *p) {
- if (p) *p = 1;
- else *p = 0; // expected-warning{{ereference}}
-}
-
-struct foo_struct {
- int x;
-};
-
-int f2(struct foo_struct* p) {
-
- if (p)
- p->x = 1;
-
- return p->x++; // expected-warning{{Dereference of null pointer.}}
-}
-
-int f3(char* x) {
-
- int i = 2;
-
- if (x)
- return x[i - 1];
-
- return x[i+1]; // expected-warning{{Dereference of null pointer.}}
-}
-
-int f3_b(char* x) {
-
- int i = 2;
-
- if (x)
- return x[i - 1];
-
- return x[i+1]++; // expected-warning{{Dereference of null pointer.}}
-}
-
-int f4(int *p) {
-
- uintptr_t x = (uintptr_t) p;
-
- if (x)
- return 1;
-
- int *q = (int*) x;
- return *q; // expected-warning{{Dereference of null pointer.}}
-}
-
-int f5() {
-
- char *s = "hello world";
- return s[0]; // no-warning
-}
-
-int bar(int* p, int q) __attribute__((nonnull));
-
-int f6(int *p) {
- return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
- : bar(p, 0); // no-warning
-}
-
-int* qux();
-
-int f7(int x) {
-
- int* p = 0;
-
- if (0 == x)
- p = qux();
-
- if (0 == x)
- *p = 1; // no-warning
-
- return x;
-}
-
-int f8(int *p, int *q) {
- if (!p)
- if (p)
- *p = 1; // no-warning
-
- if (q)
- if (!q)
- *q = 1; // no-warning
-}
-
-int* qux();
-
-int f9(unsigned len) {
- assert (len != 0);
- int *p = 0;
- unsigned i;
-
- for (i = 0; i < len; ++i)
- p = qux(i);
-
- return *p++; // no-warning
-}
-
-int f9b(unsigned len) {
- assert (len > 0); // note use of '>'
- int *p = 0;
- unsigned i;
-
- for (i = 0; i < len; ++i)
- p = qux(i);
-
- return *p++; // no-warning
-}
-
diff --git a/clang/test/Analysis/stack-addr-ps.c b/clang/test/Analysis/stack-addr-ps.c
deleted file mode 100644
index 8e2a0c06af47..000000000000
--- a/clang/test/Analysis/stack-addr-ps.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-
-int* f1() {
- int x = 0;
- return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned.}} expected-warning{{address of stack memory associated with local variable 'x' returned}}
-}
-
-int* f2(int y) {
- return &y; // expected-warning{{Address of stack memory associated with local variable 'y' returned.}} expected-warning{{address of stack memory associated with local variable 'y' returned}}
-}
-
-int* f3(int x, int *y) {
- int w = 0;
-
- if (x)
- y = &w;
-
- return y; // expected-warning{{Address of stack memory associated with local variable 'w' returned.}}
-}
-
-
diff --git a/clang/test/Analysis/uninit-msg-expr.m b/clang/test/Analysis/uninit-msg-expr.m
deleted file mode 100644
index 10b983731424..000000000000
--- a/clang/test/Analysis/uninit-msg-expr.m
+++ /dev/null
@@ -1,56 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// Foundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not directly including Foundation.h directly makes this test case
-// both svelte and portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-@class NSString, NSData;
-@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
-typedef struct {} NSFastEnumerationState;
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-@class NSData, NSIndexSet, NSString, NSURL;
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-@end
-@interface NSArray (NSArrayCreation)
-+ (id)array;
-- (NSUInteger)length;
-- (void)addObject:(id)object;
-@end
-extern NSString * const NSUndoManagerCheckpointNotification;
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-unsigned f1() {
- NSString *aString;
- return [aString length]; // expected-warning {{Receiver in message expression is an uninitialized value}}
-}
-
-unsigned f2() {
- NSString *aString = 0;
- return [aString length]; // no-warning
-}
-
-void f3() {
- NSMutableArray *aArray = [NSArray array];
- NSString *aString;
- [aArray addObject:aString]; // expected-warning {{Pass-by-value argument in message expression is undefined.}}
-}
diff --git a/clang/test/Analysis/uninit-ps-rdar6145427.m b/clang/test/Analysis/uninit-ps-rdar6145427.m
deleted file mode 100644
index b24cbaf65706..000000000000
--- a/clang/test/Analysis/uninit-ps-rdar6145427.m
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -verify -checker-cfref %s
-
-// Delta-Debugging reduced preamble.
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-@class NSString, Protocol;
-extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} + (id)alloc; @end
-extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; @end
-@class NSString, NSData;
-typedef struct _NSPoint {} NSRange;
-@interface NSValue (NSValueRangeExtensions)
-+ (NSValue *)valueWithRange:(NSRange)range;
-- (id)objectAtIndex:(NSUInteger)index;
-@end
-@interface NSAutoreleasePool : NSObject {} - (void)drain; @end
-extern NSString * const NSBundleDidLoadNotification;
-typedef struct {} NSDecimal;
-@interface NSNetService : NSObject {} - (id)init; @end
-extern NSString * const NSUndoManagerCheckpointNotification;
-
-// Test case: <rdar://problem/6145427>
-
-int main (int argc, const char * argv[]) {
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- id someUnintializedPointer = [someUnintializedPointer objectAtIndex:0]; // expected-warning{{Receiver in message expression is an uninitialized value.}}
- NSLog(@"%@", someUnintializedPointer);
- [pool drain];
- return 0;
-}
diff --git a/clang/test/Analysis/uninit-vals-ps.c b/clang/test/Analysis/uninit-vals-ps.c
deleted file mode 100644
index 707f78a96bd4..000000000000
--- a/clang/test/Analysis/uninit-vals-ps.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-
-struct FPRec {
- void (*my_func)(int * x);
-};
-
-int bar(int x);
-
-int f1_a(struct FPRec* foo) {
- int x;
- (*foo->my_func)(&x);
- return bar(x)+1; // no-warning
-}
-
-int f1_b() {
- int x;
- return bar(x)+1; // expected-warning{{Pass-by-value argument in function is undefined.}}
-}
-
-int f2() {
-
- int x;
-
- if (x+1) // expected-warning{{Branch}}
- return 1;
-
- return 2;
-}
-
-int f2_b() {
- int x;
-
- return ((x+1)+2+((x))) + 1 ? 1 : 2; // expected-warning{{Branch}}
-}
-
-int f3(void) {
- int i;
- int *p = &i;
- if (*p > 0) // expected-warning{{Branch condition evaluates to an uninitialized value}}
- return 0;
- else
- return 1;
-}
diff --git a/clang/test/Analysis/uninit-vals.c b/clang/test/Analysis/uninit-vals.c
deleted file mode 100644
index fa6d0fc481b4..000000000000
--- a/clang/test/Analysis/uninit-vals.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: clang -warn-uninit-values -verify %s
-
-int f1() {
- int x;
- return x; // expected-warning {{use of uninitialized variable}}
-}
-
-int f2(int x) {
- int y;
- int z = x + y; // expected-warning {{use of uninitialized variable}}
- return z;
-}
-
-
-int f3(int x) {
- int y;
- return x ? 1 : y; // expected-warning {{use of uninitialized variable}}
-}
-
-int f4(int x) {
- int y;
- if (x) y = 1;
- return y; // expected-warning {{use of uninitialized variable}}
-}
-
-int f5() {
- int a;
- a = 30; // no-warning
-}
-
-void f6(int i) {
- int x;
- for (i = 0 ; i < 10; i++)
- printf("%d",x++); // expected-warning {{use of uninitialized variable}}
-}
-
-void f7(int i) {
- int x = i;
- int y;
- for (i = 0; i < 10; i++ ) {
- printf("%d",x++); // no-warning
- x += y; // expected-warning {{use of uninitialized variable}}
- }
-}
diff --git a/clang/test/Analysis/uninit-vals.m b/clang/test/Analysis/uninit-vals.m
deleted file mode 100644
index 74aa66720270..000000000000
--- a/clang/test/Analysis/uninit-vals.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-typedef unsigned int NSUInteger;
-
-@interface A
-- (NSUInteger)foo;
-@end
-
-NSUInteger f8(A* x){
- const NSUInteger n = [x foo];
- int* bogus;
-
- if (n > 0) { // tests const cast transfer function logic
- NSUInteger i;
-
- for (i = 0; i < n; ++i)
- bogus = 0;
-
- if (bogus) // no-warning
- return n+1;
- }
-
- return n;
-}
diff --git a/clang/test/Analysis/unused-ivars.m b/clang/test/Analysis/unused-ivars.m
deleted file mode 100644
index dd6d69e597cd..000000000000
--- a/clang/test/Analysis/unused-ivars.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -warn-objc-unused-ivars %s -verify
-
-@interface A
-{
- @private int x; // expected-warning {{Instance variable 'x' in class 'A' is never used}}
-}
-@end
-
-@implementation A @end
-
diff --git a/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c b/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c
deleted file mode 100644
index 74203c5b1e78..000000000000
--- a/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-int array[] = {1, 2, 3, 4, 5};
-
diff --git a/clang/test/CodeGen/2008-02-07-bitfield-bug.c b/clang/test/CodeGen/2008-02-07-bitfield-bug.c
deleted file mode 100644
index 65f54115425c..000000000000
--- a/clang/test/CodeGen/2008-02-07-bitfield-bug.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-// PR1990
-
-struct test {
- char a[3];
- unsigned char b:1;
-};
-
-void f(struct test *t) {
- t->b = 1;
-}
diff --git a/clang/test/CodeGen/2008-02-08-bitfield-bug.c b/clang/test/CodeGen/2008-02-08-bitfield-bug.c
deleted file mode 100644
index 3818e961c73d..000000000000
--- a/clang/test/CodeGen/2008-02-08-bitfield-bug.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-struct test {
- unsigned a:1;
- unsigned b:1;
-};
-
-struct test *t;
-
diff --git a/clang/test/CodeGen/2008-02-26-inline-asm-bug.c b/clang/test/CodeGen/2008-02-26-inline-asm-bug.c
deleted file mode 100644
index 668b06c0d18b..000000000000
--- a/clang/test/CodeGen/2008-02-26-inline-asm-bug.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep "\$0,\$1"
-
-void f() {
- int d1, d2;
- asm("%0,%1": "=r" (d1) : "r" (d2));
-}
diff --git a/clang/test/CodeGen/2008-07-17-no-emit-on-error.c b/clang/test/CodeGen/2008-07-17-no-emit-on-error.c
deleted file mode 100644
index 5339695887e3..000000000000
--- a/clang/test/CodeGen/2008-07-17-no-emit-on-error.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: rm -f %t1.bc
-// RUN: ! clang %s -emit-llvm-bc -o %t1.bc
-// RUN: ! test -f %t1.bc
-
-void f() {
-}
-
-void g() {
- *10;
-}
diff --git a/clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c b/clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c
deleted file mode 100644
index a7d09765134f..000000000000
--- a/clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -emit-llvm -o - %s | grep -e "@g[0-9] " | count 2
-
-int g0, f0();
-int f1(), g1;
-
diff --git a/clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c b/clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c
deleted file mode 100644
index d8b7adcacf70..000000000000
--- a/clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang --emit-llvm -o %t %s &&
-// RUN: grep "i8 52" %s | count 1
-
-struct et7 {
- float lv7[0];
- char mv7:6;
-} yv7 = {
- {},
- 52,
-};
-
diff --git a/clang/test/CodeGen/2008-07-22-packed-bitfield-access.c b/clang/test/CodeGen/2008-07-22-packed-bitfield-access.c
deleted file mode 100644
index b41b5e0e40d1..000000000000
--- a/clang/test/CodeGen/2008-07-22-packed-bitfield-access.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang %s -emit-llvm -o -
-
-int main () {
- struct foo {
- unsigned a:16;
- unsigned b:32 __attribute__ ((packed));
- } x;
- x.b = 0x56789abcL;
- return 0;
-}
diff --git a/clang/test/CodeGen/2008-07-29-override-alias-decl.c b/clang/test/CodeGen/2008-07-29-override-alias-decl.c
deleted file mode 100644
index 115cc33b04e1..000000000000
--- a/clang/test/CodeGen/2008-07-29-override-alias-decl.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -emit-llvm -o - %s | grep -e "^@f" | count 1
-
-int x() {}
-
-int f() __attribute__((weak, alias("x")));
-
-/* Test that we link to the alias correctly instead of making a new
- forward definition. */
-int f();
-int h() {
- return f();
-}
diff --git a/clang/test/CodeGen/2008-07-30-implicit-initialization.c b/clang/test/CodeGen/2008-07-30-implicit-initialization.c
deleted file mode 100644
index ee33b6d70cbe..000000000000
--- a/clang/test/CodeGen/2008-07-30-implicit-initialization.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt --std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 2 &&
-// RUN: grep "ret i32 0" %t | count 2
-// <rdar://problem/6113085>
-
-struct s0 {
- int x, y;
-};
-
-int f0() {
- struct s0 x = {0};
- return x.y;
-}
-
-#if 0
-/* Optimizer isn't smart enough to reduce this since we use
- memset. Hrm. */
-int f1() {
- struct s0 x[2] = { {0} };
- return x[1].x;
-}
-#endif
-
-int f2() {
- int x[2] = { 0 };
- return x[1];
-}
-
diff --git a/clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c b/clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c
deleted file mode 100644
index f7c2908d98ff..000000000000
--- a/clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang --emit-llvm -o - %s
-// <rdar://problem/6108358>
-
-/* For posterity, the issue here begins initial "char []" decl for
- * s. This is a tentative definition and so a global was being
- * emitted, however the mapping in GlobalDeclMap referred to a bitcast
- * of this global.
- *
- * The problem was that later when the correct definition for s is
- * emitted we were doing a RAUW on the old global which was destroying
- * the bitcast in the GlobalDeclMap (since it cannot be replaced
- * properly), leaving a dangling pointer.
- *
- * The purpose of bar is just to trigger a use of the old decl
- * sometime after the dangling pointer has been introduced.
- */
-
-char s[];
-
-static void bar(void *db) {
- eek(s);
-}
-
-char s[5] = "hi";
-
-int foo() {
- bar(0);
-}
diff --git a/clang/test/CodeGen/2008-07-31-asm-labels.c b/clang/test/CodeGen/2008-07-31-asm-labels.c
deleted file mode 100644
index 1b5e0ca91da1..000000000000
--- a/clang/test/CodeGen/2008-07-31-asm-labels.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: grep "@pipe()" %t | count 0 &&
-// RUN: grep '_thisIsNotAPipe' %t | count 3 &&
-// RUN: clang -DUSE_DEF -emit-llvm -o %t %s &&
-// RUN: grep "@pipe()" %t | count 0 &&
-// RUN: grep '_thisIsNotAPipe' %t | count 3
-// <rdr://6116729>
-
-void pipe() asm("_thisIsNotAPipe");
-
-void f0() {
- pipe();
-}
-
-void pipe(int);
-
-void f1() {
- pipe(1);
-}
-
-#ifdef USE_DEF
-void pipe(int arg) {
- int x = 10;
-}
-#endif
diff --git a/clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c b/clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
deleted file mode 100644
index e0364d1fda51..000000000000
--- a/clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis | grep "ret i32 1" | count 3
-// <rdr://6115726>
-
-int f0() {
- int x;
- unsigned short n = 1;
- int *a = &x;
- int *b = &x;
- a = a - n;
- b -= n;
- return a == b;
-}
-
-int f1(int *a) {
- int b = a - (int*) 1;
- a -= (int*) 1;
- return b == (int) a;
-}
-
-int f2(int n) {
- int *b = n + (int*) 1;
- n += (int*) 1;
- return b == (int*) n;
-}
-
diff --git a/clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c b/clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c
deleted file mode 100644
index fc54dcac5e7b..000000000000
--- a/clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang --emit-llvm -o - %s
-// <rdar://problem/6122967>
-
-int f0(void *a, void *b) {
- return a - b;
-}
diff --git a/clang/test/CodeGen/2008-08-19-cast-of-typedef.c b/clang/test/CodeGen/2008-08-19-cast-of-typedef.c
deleted file mode 100644
index 581c79356b66..000000000000
--- a/clang/test/CodeGen/2008-08-19-cast-of-typedef.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang --emit-llvm -o %t %s
-
-typedef short T[4];
-struct s {
- T f0;
-};
-
-void foo(struct s *x) {
- bar((long) x->f0);
-}
diff --git a/clang/test/CodeGen/2008-08-25-incompatible-cond-expr.m b/clang/test/CodeGen/2008-08-25-incompatible-cond-expr.m
deleted file mode 100644
index c58935590b87..000000000000
--- a/clang/test/CodeGen/2008-08-25-incompatible-cond-expr.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s
-
-@protocol P0
-@end
-@interface A <P0>
-@end
-
-id f0(int a, id<P0> x, A* p) {
- return a ? x : p;
-}
diff --git a/clang/test/CodeGen/2008-09-22-bad-switch-type.c b/clang/test/CodeGen/2008-09-22-bad-switch-type.c
deleted file mode 100644
index 62a420eed3d4..000000000000
--- a/clang/test/CodeGen/2008-09-22-bad-switch-type.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s
-// PR2817
-
-void f0(void) {
- switch (0) {
- case (unsigned long long) 0 < 0:
- break;
- }
-
- switch (0) {
- case (unsigned long long) 0 > 0:
- break;
- }
-
- switch (0) {
- case (unsigned long long) 0 <= 0:
- break;
- }
-
- switch (0) {
- case (unsigned long long) 0 >= 0:
- break;
- }
-
- switch (0) {
- case (unsigned long long) 0 == 0:
- break;
- }
-
- switch (0) {
- case (unsigned long long) 0 != 0:
- break;
- }
-}
diff --git a/clang/test/CodeGen/OpaqueStruct.c b/clang/test/CodeGen/OpaqueStruct.c
deleted file mode 100644
index f005f2a0e5f8..000000000000
--- a/clang/test/CodeGen/OpaqueStruct.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-typedef struct a b;
-
-b* x;
-
-struct a {
- b* p;
-};
-
-void f() {
- b* z = x->p;
-}
diff --git a/clang/test/CodeGen/PR2001-bitfield-reload.c b/clang/test/CodeGen/PR2001-bitfield-reload.c
deleted file mode 100644
index caafced93565..000000000000
--- a/clang/test/CodeGen/PR2001-bitfield-reload.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt --std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 1 &&
-// RUN: grep "ret i32 1" %t | count 1
-// PR2001
-
-/* Test that the result of the assignment properly uses the value *in
- the bitfield* as opposed to the RHS. */
-static int foo(int i) {
- struct {
- int f0 : 2;
- } x;
- return (x.f0 = i);
-}
-
-int bar() {
- return foo(-5) == -1;
-}
diff --git a/clang/test/CodeGen/PR2643-null-store-to-bitfield.c b/clang/test/CodeGen/PR2643-null-store-to-bitfield.c
deleted file mode 100644
index 4fef84255a56..000000000000
--- a/clang/test/CodeGen/PR2643-null-store-to-bitfield.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -emit-llvm -o - %s
-// PR2643
-
-void foo() {
- struct {
- int a : 1;
- int b : 1;
- } entry = {0};
-}
-
diff --git a/clang/test/CodeGen/PR2743-reference-missing-static.c b/clang/test/CodeGen/PR2743-reference-missing-static.c
deleted file mode 100644
index 007a22f6ee88..000000000000
--- a/clang/test/CodeGen/PR2743-reference-missing-static.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s
-// PR2743
-// <rdr://6094512>
-
-/* CodeGen should handle this even if it makes it past
- sema. Unfortunately this test will become useless once sema starts
- rejecting this. */
-
-static void e0();
-void f0() { e0(); }
-
-inline void e1();
-void f1() { e1(); }
-
-void e2() __attribute__((weak));
-void f2() { e2(); }
diff --git a/clang/test/CodeGen/address-space-cast.c b/clang/test/CodeGen/address-space-cast.c
deleted file mode 100644
index 473c8e0e81c9..000000000000
--- a/clang/test/CodeGen/address-space-cast.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm < %s
-
-volatile unsigned char* const __attribute__((address_space(1))) serial_ctrl = 0x02;
-
diff --git a/clang/test/CodeGen/address-space.c b/clang/test/CodeGen/address-space.c
deleted file mode 100644
index 0edad303ed98..000000000000
--- a/clang/test/CodeGen/address-space.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -emit-llvm < %s 2>&1 | grep '@foo.*global.*addrspace(1)' &&
-// RUN: clang -emit-llvm < %s 2>&1 | grep '@ban.*global.*addrspace(1)' &&
-// RUN: clang -emit-llvm < %s 2>&1 | grep 'load.*addrspace(1)' | count 2 &&
-// RUN: clang -emit-llvm < %s 2>&1 | grep 'load.*addrspace(2).. @A' &&
-// RUN: clang -emit-llvm < %s 2>&1 | grep 'load.*addrspace(2).. @B'
-
-int foo __attribute__((address_space(1)));
-int ban[10] __attribute__((address_space(1)));
-
-int bar() { return foo; }
-
-int baz(int i) { return ban[i]; }
-
-// Both A and B point into addrspace(2).
-__attribute__((address_space(2))) int *A, *B;
-
-void test3() {
- *A = *B;
-}
-
diff --git a/clang/test/CodeGen/align-local.c b/clang/test/CodeGen/align-local.c
deleted file mode 100644
index 46f83fab8db7..000000000000
--- a/clang/test/CodeGen/align-local.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep "align 16" | count 2
-
-typedef struct __attribute((aligned(16))) {int x[4];} ff;
-
-int a() {
- ff a;
- struct {int x[4];} b __attribute((aligned(16)));
-}
diff --git a/clang/test/CodeGen/array.c b/clang/test/CodeGen/array.c
deleted file mode 100644
index ed56b5be63d4..000000000000
--- a/clang/test/CodeGen/array.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-int f() {
- int a[2];
- a[0] = 0;
-}
-
-int f2() {
- int x = 0;
- int y = 1;
- int a[10] = { y, x, 2, 3};
- int b[10] = { 2,4,x,6,y,8};
- int c[5] = { 0,1,2,3};
-}
diff --git a/clang/test/CodeGen/atomic.c b/clang/test/CodeGen/atomic.c
deleted file mode 100644
index bfebd345829c..000000000000
--- a/clang/test/CodeGen/atomic.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: clang %s -emit-llvm -o - > %t1 &&
-// RUN: grep @llvm.atomic.load.add.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.sub.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.min.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.max.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.umin.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.umax.i32 %t1 &&
-// RUN: grep @llvm.atomic.swap.i32 %t1 &&
-// RUN: grep @llvm.atomic.cmp.swap.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.and.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.or.i32 %t1 &&
-// RUN: grep @llvm.atomic.load.xor.i32 %t1
-
-
-int atomic(void)
-{
- // nonsenical test for sync functions
- int old;
- int val = 1;
- unsigned int uval = 1;
- int cmp = 0;
-
- old = __sync_fetch_and_add(&val, 1);
- old = __sync_fetch_and_sub(&val, 2);
- old = __sync_fetch_and_min(&val, 3);
- old = __sync_fetch_and_max(&val, 4);
- old = __sync_fetch_and_umin(&uval, 5u);
- old = __sync_fetch_and_umax(&uval, 6u);
- old = __sync_lock_test_and_set(&val, 7);
- old = __sync_val_compare_and_swap(&val, 4, 1976);
- old = __sync_fetch_and_and(&val, 0x9);
- old = __sync_fetch_and_or(&val, 0xa);
- old = __sync_fetch_and_xor(&val, 0xb);
- return old;
-}
diff --git a/clang/test/CodeGen/attributes.c b/clang/test/CodeGen/attributes.c
deleted file mode 100644
index 45b0cebf792b..000000000000
--- a/clang/test/CodeGen/attributes.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: grep 't1.*noreturn' %t &&
-// RUN: grep 't2.*nounwind' %t &&
-// RUN: grep 'weak.*t3' %t &&
-// RUN: grep 'hidden.*t4' %t &&
-// RUN: grep 't5.*weak' %t &&
-// RUN: grep 't6.*protected' %t &&
-// RUN: grep 't7.*noreturn' %t &&
-// RUN: grep 't7.*nounwind' %t &&
-// RUN: grep 't9.*alias.*weak.*t8' %t
-
-void t1() __attribute__((noreturn));
-void t1() {}
-
-void t2() __attribute__((nothrow));
-void t2() {}
-
-void t3() __attribute__((weak));
-void t3() {}
-
-void t4() __attribute__((visibility("hidden")));
-void t4() {}
-
-int t5 __attribute__((weak)) = 2;
-
-int t6 __attribute__((visibility("protected")));
-
-void t7() __attribute__((noreturn, nothrow));
-void t7() {}
-
-void __t8() {}
-void t9() __attribute__((weak, alias("__t8")));
diff --git a/clang/test/CodeGen/bitfield-init.c b/clang/test/CodeGen/bitfield-init.c
deleted file mode 100644
index 1749bd3ff4d2..000000000000
--- a/clang/test/CodeGen/bitfield-init.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-typedef struct { unsigned int i: 1; } c;
-const c d = { 1 };
-
-// PR2310
-struct Token {
- unsigned n : 31;
-};
-void sqlite3CodeSubselect(){
- struct Token one = { 1 };
-}
-
diff --git a/clang/test/CodeGen/bitfield.c b/clang/test/CodeGen/bitfield.c
deleted file mode 100644
index 5d522682ef77..000000000000
--- a/clang/test/CodeGen/bitfield.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// RUN: clang %s -emit-llvm-bc -o - | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 4 &&
-// RUN: grep "ret i32 1" %t | count 4
-
-static int f0(int n) {
- struct s0 {
- int a : 30;
- int b : 2;
- long long c : 31;
- } x = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
-
- x.a += n;
- x.b += n;
- x.c += n;
-
- return x.a + x.b + x.c;
-}
-
-int g0(void) {
- return f0(-1) + 44335655;
-}
-
-static int f1(void) {
- struct s1 {
- int a:13;
- char b;
- unsigned short c:7;
- } x;
-
- x.a = -40;
- x.b = 10;
- x.c = 15;
-
- return x.a + x.b + x.c;
-}
-
-int g1(void) {
- return f1() + 16;
-}
-
-static int f2(void) {
- struct s2 {
- short a[3];
- int b : 15;
- } x;
-
- x.a[0] = x.a[1] = x.a[2] = -40;
- x.b = 10;
-
- return x.b;
-}
-
-int g2(void) {
- return f2() - 9;
-}
-
-static int f3(int n) {
- struct s3 {
- unsigned a:16;
- unsigned b:28 __attribute__ ((packed));
- } x = { 0xdeadbeef, 0xdeadbeef };
- struct s4 {
- signed a:16;
- signed b:28 __attribute__ ((packed));
- } y;
- y.a = -0x56789abcL;
- y.b = -0x56789abcL;
- return ((y.a += x.a += n) +
- (y.b += x.b += n));
-}
-
-int g3(void) {
- return f3(20) + 130725747;
-}
diff --git a/clang/test/CodeGen/bool-bitfield.c b/clang/test/CodeGen/bool-bitfield.c
deleted file mode 100644
index d50927f9f33d..000000000000
--- a/clang/test/CodeGen/bool-bitfield.c
+++ /dev/null
@@ -1,54 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-// From GCC PR19331
-struct SysParams
-{
- unsigned short tag;
- unsigned short version;
- unsigned int seqnum;
- int contrast;
- int igain_1, igain_2;
- int oattn_1, oattn_2;
- int max_out_vltg_1, max_out_vltg_2;
- int max_mains_current;
- int meters_mode;
- int input_select;
- _Bool input_parallelch2:1;
- _Bool cliplmt_ch1:1;
- _Bool cliplmt_ch2:1;
- _Bool gate_ch1:1;
- _Bool gate_ch2:1;
- _Bool mute_ch1:1;
- _Bool mute_ch2:1;
- _Bool brownout:1;
- _Bool power_on:1;
- _Bool pwrup_mute:1;
- _Bool keylock:1;
- _Bool dsp_ch1:1;
- _Bool dsp_ch2:1;
- int dsp_preset;
- long unlock_code;
-};
-extern struct SysParams params;
-
-void foo(void *);
-void kcmd_setParams(void)
-{
- struct {
- unsigned char igain_1;
- unsigned char igain_2;
- unsigned char max_out_vltg_1;
- unsigned char max_out_vltg_2;
- unsigned char max_imains;
- unsigned char cliplmt_ch1:1;
- unsigned char cliplmt_ch2:1;
- unsigned char gate_ch1:1;
- unsigned char gate_ch2:1;
- } msg;
- foo(&msg);
- params.cliplmt_ch1 = msg.cliplmt_ch1;
- params.cliplmt_ch2 = msg.cliplmt_ch2;
- params.gate_ch1 = msg.gate_ch1;
- params.gate_ch2 = msg.gate_ch2;
-}
-
diff --git a/clang/test/CodeGen/bool-init.c b/clang/test/CodeGen/bool-init.c
deleted file mode 100644
index 2e5d56a0a1cd..000000000000
--- a/clang/test/CodeGen/bool-init.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep i1 | count 1
-
-// Check that the type of this global isn't i1
-_Bool test = &test;
diff --git a/clang/test/CodeGen/boolassign.c b/clang/test/CodeGen/boolassign.c
deleted file mode 100644
index 0d4bf490ed6e..000000000000
--- a/clang/test/CodeGen/boolassign.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-int testBoolAssign(void) {
-int ss;
-if ((ss = ss && ss)) {}
-}
diff --git a/clang/test/CodeGen/builtin-count-zeros.c b/clang/test/CodeGen/builtin-count-zeros.c
deleted file mode 100644
index 5453cb1d8905..000000000000
--- a/clang/test/CodeGen/builtin-count-zeros.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm %s -o - | grep 'cttz' | count 2 &&
-// RUN: clang -emit-llvm %s -o - | grep 'ctlz' | count 2
-
-int a(int a) {return __builtin_ctz(a) + __builtin_clz(a);}
diff --git a/clang/test/CodeGen/builtin-memfns.c b/clang/test/CodeGen/builtin-memfns.c
deleted file mode 100644
index d28a48c53740..000000000000
--- a/clang/test/CodeGen/builtin-memfns.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -emit-llvm -o - %s | not grep __builtin
-
-int main(int argc, char **argv) {
- unsigned char a = 0x11223344;
- unsigned char b = 0x11223344;
- __builtin_bzero(&a, sizeof(a));
- __builtin_memset(&a, 0, sizeof(a));
- __builtin_memcpy(&a, &b, sizeof(a));
- __builtin_memmove(&a, &b, sizeof(a));
- return 0;
-}
diff --git a/clang/test/CodeGen/builtin-stackaddress.c b/clang/test/CodeGen/builtin-stackaddress.c
deleted file mode 100644
index ddfb9dc790aa..000000000000
--- a/clang/test/CodeGen/builtin-stackaddress.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep "llvm.returnaddress" &&
-// RUN: clang -emit-llvm < %s | grep "llvm.frameaddress"
-void* a(unsigned x) {
-return __builtin_return_address(0);
-}
-
-void* c(unsigned x) {
-return __builtin_frame_address(0);
-}
diff --git a/clang/test/CodeGen/builtinmemcpy.c b/clang/test/CodeGen/builtinmemcpy.c
deleted file mode 100644
index 8600d986965b..000000000000
--- a/clang/test/CodeGen/builtinmemcpy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-llvm < %s -o - | grep "llvm.memcpy"
-
-char* x(char* a, char* b) {return __builtin_memcpy(a, b, 4);}
diff --git a/clang/test/CodeGen/builtins-ffs_parity_popcount.c b/clang/test/CodeGen/builtins-ffs_parity_popcount.c
deleted file mode 100644
index 19a5cf9a679b..000000000000
--- a/clang/test/CodeGen/builtins-ffs_parity_popcount.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -emit-llvm -o - %s > %t
-// RUN: ! grep "__builtin" %t
-
-#include <stdio.h>
-
-void test(int M, long long N) {
- printf("%d %lld: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
- M, N,
- __builtin_ffs(M), __builtin_ffsl(M), __builtin_ffsll(M),
- __builtin_parity(M), __builtin_parityl(M), __builtin_parityll(M),
- __builtin_popcount(M), __builtin_popcountl(M), __builtin_popcountll(M),
- __builtin_ffs(N), __builtin_ffsl(N), __builtin_ffsll(N),
- __builtin_parity(N), __builtin_parityl(N), __builtin_parityll(N),
- __builtin_popcount(N), __builtin_popcountl(N), __builtin_popcountll(N));
-}
diff --git a/clang/test/CodeGen/builtins-powi.c b/clang/test/CodeGen/builtins-powi.c
deleted file mode 100644
index 6d82f8af51ff..000000000000
--- a/clang/test/CodeGen/builtins-powi.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: clang -emit-llvm -o - %s > %t
-// RUN: ! grep "__builtin" %t
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-void test(long double a, int b) {
- printf("%Lf**%d: %08x %08x %016Lx\n",
- a, b,
- __builtin_powi(a, b),
- __builtin_powif(a, b),
- __builtin_powil(a, b)
- );
-}
-
-int main() {
- int i;
-
- test(-1,-1LL);
- test(0,0);
- test(1,1);
-
- for (i=0; i<3; i++) {
- test(random(), i);
- }
-
- return 0;
-}
diff --git a/clang/test/CodeGen/builtins-x86.c b/clang/test/CodeGen/builtins-x86.c
deleted file mode 100644
index 01ab93db67d9..000000000000
--- a/clang/test/CodeGen/builtins-x86.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// RUN: clang -DUSE_64 -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -DUSE_ALL -triple x86_64-unknown-unknown -emit-llvm -o %t %s
-// XFAIL
-
-#ifdef USE_ALL
-#define USE_3DNOW
-#define USE_64
-#define USE_SSE4
-#endif
-
-// 64-bit
-typedef char V8c __attribute__((vector_size(8 * sizeof(char))));
-typedef signed short V4s __attribute__((vector_size(8)));
-typedef signed int V2i __attribute__((vector_size(8)));
-typedef signed long long V1LLi __attribute__((vector_size(8)));
-
-typedef float V2f __attribute__((vector_size(8)));
-
-// 128-bit
-typedef char V16c __attribute__((vector_size(16)));
-typedef signed short V8s __attribute__((vector_size(16)));
-typedef signed int V4i __attribute__((vector_size(16)));
-typedef signed long long V2LLi __attribute__((vector_size(16)));
-
-typedef float V4f __attribute__((vector_size(16)));
-typedef double V2d __attribute__((vector_size(16)));
-
-void f0() {
- signed char tmp_c;
-// unsigned char tmp_Uc;
- signed short tmp_s;
-#ifdef USE_ALL
- unsigned short tmp_Us;
-#endif
- signed int tmp_i;
- unsigned int tmp_Ui;
- signed long long tmp_LLi;
-// unsigned long long tmp_ULLi;
- float tmp_f;
- double tmp_d;
-
- void* tmp_vp;
- const void* tmp_vCp;
- char* tmp_cp;
- const char* tmp_cCp;
- int* tmp_ip;
- float* tmp_fp;
- const float* tmp_fCp;
- double* tmp_dp;
- const double* tmp_dCp;
-
-#define imm_i 32
-#define imm_i_0_2 0
-#define imm_i_0_4 3
-#define imm_i_0_8 7
-#define imm_i_0_16 15
- // Check this.
-#define imm_i_0_256 0
-
- V2i* tmp_V2ip;
- V1LLi* tmp_V1LLip;
- V2LLi* tmp_V2LLip;
-
- // 64-bit
- V8c tmp_V8c;
- V4s tmp_V4s;
- V2i tmp_V2i;
- V1LLi tmp_V1LLi;
-#ifdef USE_3DNOW
- V2f tmp_V2f;
-#endif
-
- // 128-bit
- V16c tmp_V16c;
- V8s tmp_V8s;
- V4i tmp_V4i;
- V2LLi tmp_V2LLi;
- V4f tmp_V4f;
- V2d tmp_V2d;
-
- tmp_i = __builtin_ia32_comieq(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_comilt(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_comile(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_comigt(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_comige(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_comineq(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_ucomieq(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_ucomilt(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_ucomile(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_ucomigt(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_ucomige(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_ucomineq(tmp_V4f, tmp_V4f);
- tmp_i = __builtin_ia32_comisdeq(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_comisdlt(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_comisdle(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_comisdgt(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_comisdge(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_comisdneq(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_ucomisdeq(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_ucomisdlt(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_ucomisdle(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_ucomisdgt(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_ucomisdge(tmp_V2d, tmp_V2d);
- tmp_i = __builtin_ia32_ucomisdneq(tmp_V2d, tmp_V2d);
- tmp_V4f = __builtin_ia32_addps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_subps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_mulps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_divps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_addss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_subss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_mulss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_divss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpeqps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpltps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpleps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpgtps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpgeps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpunordps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpneqps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpnltps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpnleps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpngtps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpngeps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpordps(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpeqss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpltss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpless(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpunordss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpneqss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpnltss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpnless(tmp_V4f, tmp_V4f);
-#ifdef USE_ALL
- tmp_V4i = __builtin_ia32_cmpngtss(tmp_V4f, tmp_V4f);
- tmp_V4i = __builtin_ia32_cmpngess(tmp_V4f, tmp_V4f);
-#endif
- tmp_V4i = __builtin_ia32_cmpordss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_minps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_maxps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_minss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_maxss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_andps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_andnps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_orps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_xorps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_movss(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_movhlps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_movlhps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_unpckhps(tmp_V4f, tmp_V4f);
- tmp_V4f = __builtin_ia32_unpcklps(tmp_V4f, tmp_V4f);
- tmp_V8c = __builtin_ia32_paddb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_paddw(tmp_V4s, tmp_V4s);
- tmp_V2i = __builtin_ia32_paddd(tmp_V2i, tmp_V2i);
-
- tmp_V1LLi = __builtin_ia32_paddq(tmp_V1LLi, tmp_V1LLi);
- tmp_V8c = __builtin_ia32_psubb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_psubw(tmp_V4s, tmp_V4s);
- tmp_V2i = __builtin_ia32_psubd(tmp_V2i, tmp_V2i);
- tmp_V1LLi = __builtin_ia32_psubq(tmp_V1LLi, tmp_V1LLi);
- tmp_V8c = __builtin_ia32_paddsb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_paddsw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_psubsb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_psubsw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_paddusb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_paddusw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_psubusb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_psubusw(tmp_V4s, tmp_V4s);
- tmp_V4s = __builtin_ia32_pmullw(tmp_V4s, tmp_V4s);
- tmp_V4s = __builtin_ia32_pmulhw(tmp_V4s, tmp_V4s);
- tmp_V4s = __builtin_ia32_pmulhuw(tmp_V4s, tmp_V4s);
- tmp_V1LLi = __builtin_ia32_pand(tmp_V1LLi, tmp_V1LLi);
- tmp_V1LLi = __builtin_ia32_pandn(tmp_V1LLi, tmp_V1LLi);
- tmp_V1LLi = __builtin_ia32_por(tmp_V1LLi, tmp_V1LLi);
- tmp_V1LLi = __builtin_ia32_pxor(tmp_V1LLi, tmp_V1LLi);
- tmp_V8c = __builtin_ia32_pavgb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_pavgw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_pcmpeqb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_pcmpeqw(tmp_V4s, tmp_V4s);
- tmp_V2i = __builtin_ia32_pcmpeqd(tmp_V2i, tmp_V2i);
- tmp_V8c = __builtin_ia32_pcmpgtb(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_pcmpgtw(tmp_V4s, tmp_V4s);
- tmp_V2i = __builtin_ia32_pcmpgtd(tmp_V2i, tmp_V2i);
- tmp_V8c = __builtin_ia32_pmaxub(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_pmaxsw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_pminub(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_pminsw(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_punpckhbw(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_punpckhwd(tmp_V4s, tmp_V4s);
- tmp_V2i = __builtin_ia32_punpckhdq(tmp_V2i, tmp_V2i);
- tmp_V8c = __builtin_ia32_punpcklbw(tmp_V8c, tmp_V8c);
- tmp_V4s = __builtin_ia32_punpcklwd(tmp_V4s, tmp_V4s);
- tmp_V2i = __builtin_ia32_punpckldq(tmp_V2i, tmp_V2i);
- tmp_V2d = __builtin_ia32_addpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_subpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_mulpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_divpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_addsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_subsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_mulsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_divsd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpeqpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpltpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmplepd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpgtpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpgepd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpunordpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpneqpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpnltpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpnlepd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpngtpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpngepd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpordpd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpeqsd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpltsd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmplesd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpunordsd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpneqsd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpnltsd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpnlesd(tmp_V2d, tmp_V2d);
- tmp_V4i = __builtin_ia32_cmpordsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_minpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_maxpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_minsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_maxsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_andpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_andnpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_orpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_xorpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_movsd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_unpckhpd(tmp_V2d, tmp_V2d);
- tmp_V2d = __builtin_ia32_unpcklpd(tmp_V2d, tmp_V2d);
- tmp_V16c = __builtin_ia32_paddb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_paddw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_paddd128(tmp_V4i, tmp_V4i);
- tmp_V2LLi = __builtin_ia32_paddq128(tmp_V2LLi, tmp_V2LLi);
- tmp_V16c = __builtin_ia32_psubb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_psubw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_psubd128(tmp_V4i, tmp_V4i);
- tmp_V2LLi = __builtin_ia32_psubq128(tmp_V2LLi, tmp_V2LLi);
- tmp_V16c = __builtin_ia32_paddsb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_paddsw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_psubsb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_psubsw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_paddusb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_paddusw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_psubusb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_psubusw128(tmp_V8s, tmp_V8s);
- tmp_V8s = __builtin_ia32_pmullw128(tmp_V8s, tmp_V8s);
- tmp_V8s = __builtin_ia32_pmulhw128(tmp_V8s, tmp_V8s);
- tmp_V2LLi = __builtin_ia32_pand128(tmp_V2LLi, tmp_V2LLi);
- tmp_V2LLi = __builtin_ia32_pandn128(tmp_V2LLi, tmp_V2LLi);
- tmp_V2LLi = __builtin_ia32_por128(tmp_V2LLi, tmp_V2LLi);
- tmp_V2LLi = __builtin_ia32_pxor128(tmp_V2LLi, tmp_V2LLi);
- tmp_V16c = __builtin_ia32_pavgb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pavgw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_pcmpeqb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pcmpeqw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_pcmpeqd128(tmp_V4i, tmp_V4i);
- tmp_V16c = __builtin_ia32_pcmpgtb128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pcmpgtw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_pcmpgtd128(tmp_V4i, tmp_V4i);
- tmp_V16c = __builtin_ia32_pmaxub128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pmaxsw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_pminub128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pminsw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_punpckhbw128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_punpckhwd128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_punpckhdq128(tmp_V4i, tmp_V4i);
- tmp_V2LLi = __builtin_ia32_punpckhqdq128(tmp_V2LLi, tmp_V2LLi);
- tmp_V16c = __builtin_ia32_punpcklbw128(tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_punpcklwd128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_punpckldq128(tmp_V4i, tmp_V4i);
- tmp_V2LLi = __builtin_ia32_punpcklqdq128(tmp_V2LLi, tmp_V2LLi);
- tmp_V8s = __builtin_ia32_packsswb128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_packssdw128(tmp_V4i, tmp_V4i);
- tmp_V8s = __builtin_ia32_packuswb128(tmp_V8s, tmp_V8s);
- tmp_V8s = __builtin_ia32_pmulhuw128(tmp_V8s, tmp_V8s);
- tmp_V4f = __builtin_ia32_addsubps(tmp_V4f, tmp_V4f);
- tmp_V2d = __builtin_ia32_addsubpd(tmp_V2d, tmp_V2d);
- tmp_V4f = __builtin_ia32_haddps(tmp_V4f, tmp_V4f);
- tmp_V2d = __builtin_ia32_haddpd(tmp_V2d, tmp_V2d);
- tmp_V4f = __builtin_ia32_hsubps(tmp_V4f, tmp_V4f);
- tmp_V2d = __builtin_ia32_hsubpd(tmp_V2d, tmp_V2d);
- tmp_V8s = __builtin_ia32_phaddw128(tmp_V8s, tmp_V8s);
- tmp_V4s = __builtin_ia32_phaddw(tmp_V4s, tmp_V4s);
- tmp_V4i = __builtin_ia32_phaddd128(tmp_V4i, tmp_V4i);
- tmp_V2i = __builtin_ia32_phaddd(tmp_V2i, tmp_V2i);
- tmp_V8s = __builtin_ia32_phaddsw128(tmp_V8s, tmp_V8s);
- tmp_V4s = __builtin_ia32_phaddsw(tmp_V4s, tmp_V4s);
- tmp_V8s = __builtin_ia32_phsubw128(tmp_V8s, tmp_V8s);
- tmp_V4s = __builtin_ia32_phsubw(tmp_V4s, tmp_V4s);
- tmp_V4i = __builtin_ia32_phsubd128(tmp_V4i, tmp_V4i);
- tmp_V2i = __builtin_ia32_phsubd(tmp_V2i, tmp_V2i);
- tmp_V8s = __builtin_ia32_phsubsw128(tmp_V8s, tmp_V8s);
- tmp_V4s = __builtin_ia32_phsubsw(tmp_V4s, tmp_V4s);
- tmp_V16c = __builtin_ia32_pmaddubsw128(tmp_V16c, tmp_V16c);
- tmp_V8c = __builtin_ia32_pmaddubsw(tmp_V8c, tmp_V8c);
- tmp_V8s = __builtin_ia32_pmulhrsw128(tmp_V8s, tmp_V8s);
- tmp_V4s = __builtin_ia32_pmulhrsw(tmp_V4s, tmp_V4s);
- tmp_V16c = __builtin_ia32_pshufb128(tmp_V16c, tmp_V16c);
- tmp_V8c = __builtin_ia32_pshufb(tmp_V8c, tmp_V8c);
- tmp_V16c = __builtin_ia32_psignb128(tmp_V16c, tmp_V16c);
- tmp_V8c = __builtin_ia32_psignb(tmp_V8c, tmp_V8c);
- tmp_V8s = __builtin_ia32_psignw128(tmp_V8s, tmp_V8s);
- tmp_V4s = __builtin_ia32_psignw(tmp_V4s, tmp_V4s);
- tmp_V4i = __builtin_ia32_psignd128(tmp_V4i, tmp_V4i);
- tmp_V2i = __builtin_ia32_psignd(tmp_V2i, tmp_V2i);
- tmp_V16c = __builtin_ia32_pabsb128(tmp_V16c);
- tmp_V8c = __builtin_ia32_pabsb(tmp_V8c);
- tmp_V8s = __builtin_ia32_pabsw128(tmp_V8s);
- tmp_V4s = __builtin_ia32_pabsw(tmp_V4s);
- tmp_V4i = __builtin_ia32_pabsd128(tmp_V4i);
- tmp_V2i = __builtin_ia32_pabsd(tmp_V2i);
- tmp_V4s = __builtin_ia32_psllw(tmp_V4s, tmp_V1LLi);
- tmp_V2i = __builtin_ia32_pslld(tmp_V2i, tmp_V1LLi);
- tmp_V1LLi = __builtin_ia32_psllq(tmp_V1LLi, tmp_V1LLi);
- tmp_V4s = __builtin_ia32_psrlw(tmp_V4s, tmp_V1LLi);
- tmp_V2i = __builtin_ia32_psrld(tmp_V2i, tmp_V1LLi);
- tmp_V1LLi = __builtin_ia32_psrlq(tmp_V1LLi, tmp_V1LLi);
- tmp_V4s = __builtin_ia32_psraw(tmp_V4s, tmp_V1LLi);
- tmp_V2i = __builtin_ia32_psrad(tmp_V2i, tmp_V1LLi);
-#ifdef USE_ALL
- tmp_V4s = __builtin_ia32_pshufw(tmp_V4s, imm_i);
-#endif
- tmp_V2i = __builtin_ia32_pmaddwd(tmp_V4s, tmp_V4s);
- tmp_V8c = __builtin_ia32_packsswb(tmp_V4s, tmp_V4s);
- tmp_V4s = __builtin_ia32_packssdw(tmp_V2i, tmp_V2i);
- tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s);
-
- (void) __builtin_ia32_ldmxcsr(tmp_Ui);
- tmp_Ui = __builtin_ia32_stmxcsr();
- tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i);
- tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f);
- tmp_V4f = __builtin_ia32_cvtsi2ss(tmp_V4f, tmp_i);
-#ifdef USE_64
- tmp_V4f = __builtin_ia32_cvtsi642ss(tmp_V4f, tmp_LLi);
-#endif
- tmp_i = __builtin_ia32_cvtss2si(tmp_V4f);
-#ifdef USE_64
- tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f);
-#endif
- tmp_V2i = __builtin_ia32_cvttps2pi(tmp_V4f);
- tmp_i = __builtin_ia32_cvttss2si(tmp_V4f);
-#ifdef USE_64
- tmp_LLi = __builtin_ia32_cvttss2si64(tmp_V4f);
-#endif
- (void) __builtin_ia32_maskmovq(tmp_V8c, tmp_V8c, tmp_cp);
- tmp_V4f = __builtin_ia32_loadups(tmp_fCp);
- (void) __builtin_ia32_storeups(tmp_fp, tmp_V4f);
- tmp_V4f = __builtin_ia32_loadhps(tmp_V4f, tmp_V2ip);
- tmp_V4f = __builtin_ia32_loadlps(tmp_V4f, tmp_V2ip);
- (void) __builtin_ia32_storehps(tmp_V2ip, tmp_V4f);
- (void) __builtin_ia32_storelps(tmp_V2ip, tmp_V4f);
- tmp_i = __builtin_ia32_movmskps(tmp_V4f);
- tmp_i = __builtin_ia32_pmovmskb(tmp_V8c);
- (void) __builtin_ia32_movntps(tmp_fp, tmp_V4f);
- (void) __builtin_ia32_movntq(tmp_V1LLip, tmp_V1LLi);
- (void) __builtin_ia32_sfence();
-
- tmp_V4s = __builtin_ia32_psadbw(tmp_V8c, tmp_V8c);
- tmp_V4f = __builtin_ia32_rcpps(tmp_V4f);
- tmp_V4f = __builtin_ia32_rcpss(tmp_V4f);
- tmp_V4f = __builtin_ia32_rsqrtps(tmp_V4f);
- tmp_V4f = __builtin_ia32_rsqrtss(tmp_V4f);
- tmp_V4f = __builtin_ia32_sqrtps(tmp_V4f);
- tmp_V4f = __builtin_ia32_sqrtss(tmp_V4f);
- tmp_V4f = __builtin_ia32_shufps(tmp_V4f, tmp_V4f, imm_i);
-#ifdef USE_3DNOW
- (void) __builtin_ia32_femms();
- tmp_V8c = __builtin_ia32_pavgusb(tmp_V8c, tmp_V8c);
- tmp_V2i = __builtin_ia32_pf2id(tmp_V2f);
- tmp_V2f = __builtin_ia32_pfacc(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfadd(tmp_V2f, tmp_V2f);
- tmp_V2i = __builtin_ia32_pfcmpeq(tmp_V2f, tmp_V2f);
- tmp_V2i = __builtin_ia32_pfcmpge(tmp_V2f, tmp_V2f);
- tmp_V2i = __builtin_ia32_pfcmpgt(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfmax(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfmin(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfmul(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfrcp(tmp_V2f);
- tmp_V2f = __builtin_ia32_pfrcpit1(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfrcpit2(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfrsqrt(tmp_V2f);
- tmp_V2f = __builtin_ia32_pfrsqit1(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfsub(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfsubr(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pi2fd(tmp_V2i);
- tmp_V4s = __builtin_ia32_pmulhrw(tmp_V4s, tmp_V4s);
-#endif
-#ifdef USE_3DNOWA
- tmp_V2i = __builtin_ia32_pf2iw(tmp_V2f);
- tmp_V2f = __builtin_ia32_pfnacc(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pfpnacc(tmp_V2f, tmp_V2f);
- tmp_V2f = __builtin_ia32_pi2fw(tmp_V2i);
- tmp_V2f = __builtin_ia32_pswapdsf(tmp_V2f);
- tmp_V2i = __builtin_ia32_pswapdsi(tmp_V2i);
-#endif
- (void) __builtin_ia32_maskmovdqu(tmp_V16c, tmp_V16c, tmp_cp);
- tmp_V2d = __builtin_ia32_loadupd(tmp_dCp);
- (void) __builtin_ia32_storeupd(tmp_dp, tmp_V2d);
- tmp_V2d = __builtin_ia32_loadhpd(tmp_V2d, tmp_dCp);
- tmp_V2d = __builtin_ia32_loadlpd(tmp_V2d, tmp_dCp);
- tmp_i = __builtin_ia32_movmskpd(tmp_V2d);
- tmp_i = __builtin_ia32_pmovmskb128(tmp_V16c);
- (void) __builtin_ia32_movnti(tmp_ip, tmp_i);
- (void) __builtin_ia32_movntpd(tmp_dp, tmp_V2d);
- (void) __builtin_ia32_movntdq(tmp_V2LLip, tmp_V2LLi);
- tmp_V4i = __builtin_ia32_pshufd(tmp_V4i, imm_i);
- tmp_V8s = __builtin_ia32_pshuflw(tmp_V8s, imm_i);
- tmp_V8s = __builtin_ia32_pshufhw(tmp_V8s, imm_i);
- tmp_V2LLi = __builtin_ia32_psadbw128(tmp_V16c, tmp_V16c);
- tmp_V2d = __builtin_ia32_sqrtpd(tmp_V2d);
- tmp_V2d = __builtin_ia32_sqrtsd(tmp_V2d);
- tmp_V2d = __builtin_ia32_shufpd(tmp_V2d, tmp_V2d, imm_i);
- tmp_V2d = __builtin_ia32_cvtdq2pd(tmp_V4i);
- tmp_V4f = __builtin_ia32_cvtdq2ps(tmp_V4i);
- tmp_V2LLi = __builtin_ia32_cvtpd2dq(tmp_V2d);
- tmp_V2i = __builtin_ia32_cvtpd2pi(tmp_V2d);
- tmp_V4f = __builtin_ia32_cvtpd2ps(tmp_V2d);
- tmp_V4i = __builtin_ia32_cvttpd2dq(tmp_V2d);
- tmp_V2i = __builtin_ia32_cvttpd2pi(tmp_V2d);
- tmp_V2d = __builtin_ia32_cvtpi2pd(tmp_V2i);
- tmp_i = __builtin_ia32_cvtsd2si(tmp_V2d);
- tmp_i = __builtin_ia32_cvttsd2si(tmp_V2d);
-#ifdef USE_64
- tmp_LLi = __builtin_ia32_cvtsd2si64(tmp_V2d);
- tmp_LLi = __builtin_ia32_cvttsd2si64(tmp_V2d);
-#endif
- tmp_V4i = __builtin_ia32_cvtps2dq(tmp_V4f);
- tmp_V2d = __builtin_ia32_cvtps2pd(tmp_V4f);
- tmp_V4i = __builtin_ia32_cvttps2dq(tmp_V4f);
- tmp_V2d = __builtin_ia32_cvtsi2sd(tmp_V2d, tmp_i);
-#ifdef USE_64
- tmp_V2d = __builtin_ia32_cvtsi642sd(tmp_V2d, tmp_LLi);
-#endif
- tmp_V4f = __builtin_ia32_cvtsd2ss(tmp_V4f, tmp_V2d);
- tmp_V2d = __builtin_ia32_cvtss2sd(tmp_V2d, tmp_V4f);
- (void) __builtin_ia32_clflush(tmp_vCp);
- (void) __builtin_ia32_lfence();
- (void) __builtin_ia32_mfence();
- tmp_V16c = __builtin_ia32_loaddqu(tmp_cCp);
- (void) __builtin_ia32_storedqu(tmp_cp, tmp_V16c);
- tmp_V4s = __builtin_ia32_psllwi(tmp_V4s, tmp_i);
- tmp_V2i = __builtin_ia32_pslldi(tmp_V2i, tmp_i);
- tmp_V1LLi = __builtin_ia32_psllqi(tmp_V1LLi, tmp_i);
- tmp_V4s = __builtin_ia32_psrawi(tmp_V4s, tmp_i);
- tmp_V2i = __builtin_ia32_psradi(tmp_V2i, tmp_i);
- tmp_V4s = __builtin_ia32_psrlwi(tmp_V4s, tmp_i);
- tmp_V2i = __builtin_ia32_psrldi(tmp_V2i, tmp_i);
- tmp_V1LLi = __builtin_ia32_psrlqi(tmp_V1LLi, tmp_i);
- tmp_V1LLi = __builtin_ia32_pmuludq(tmp_V2i, tmp_V2i);
- tmp_V2LLi = __builtin_ia32_pmuludq128(tmp_V4i, tmp_V4i);
- tmp_V8s = __builtin_ia32_psraw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_psrad128(tmp_V4i, tmp_V4i);
- tmp_V8s = __builtin_ia32_psrlw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_psrld128(tmp_V4i, tmp_V4i);
- tmp_V2LLi = __builtin_ia32_psrlq128(tmp_V2LLi, tmp_V2LLi);
- tmp_V8s = __builtin_ia32_psllw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_pslld128(tmp_V4i, tmp_V4i);
- tmp_V2LLi = __builtin_ia32_psllq128(tmp_V2LLi, tmp_V2LLi);
- tmp_V8s = __builtin_ia32_psllwi128(tmp_V8s, tmp_i);
- tmp_V4i = __builtin_ia32_pslldi128(tmp_V4i, tmp_i);
- tmp_V2LLi = __builtin_ia32_psllqi128(tmp_V2LLi, tmp_i);
- tmp_V8s = __builtin_ia32_psrlwi128(tmp_V8s, tmp_i);
- tmp_V4i = __builtin_ia32_psrldi128(tmp_V4i, tmp_i);
- tmp_V2LLi = __builtin_ia32_psrlqi128(tmp_V2LLi, tmp_i);
- tmp_V8s = __builtin_ia32_psrawi128(tmp_V8s, tmp_i);
- tmp_V4i = __builtin_ia32_psradi128(tmp_V4i, tmp_i);
- tmp_V8s = __builtin_ia32_pmaddwd128(tmp_V8s, tmp_V8s);
- (void) __builtin_ia32_monitor(tmp_vp, tmp_Ui, tmp_Ui);
- (void) __builtin_ia32_mwait(tmp_Ui, tmp_Ui);
-#ifdef USE_ALL
- tmp_V4f = __builtin_ia32_movshdup(tmp_V4f);
- tmp_V4f = __builtin_ia32_movsldup(tmp_V4f);
-#endif
- tmp_V16c = __builtin_ia32_lddqu(tmp_cCp);
- tmp_V2LLi = __builtin_ia32_palignr128(tmp_V2LLi, tmp_V2LLi, imm_i);
- tmp_V1LLi = __builtin_ia32_palignr(tmp_V1LLi, tmp_V1LLi, imm_i);
- tmp_V2i = __builtin_ia32_vec_init_v2si(tmp_i, tmp_i);
- tmp_V4s = __builtin_ia32_vec_init_v4hi(tmp_s, tmp_s, tmp_s, tmp_s);
- tmp_V8c = __builtin_ia32_vec_init_v8qi(tmp_c, tmp_c, tmp_c, tmp_c, tmp_c, tmp_c, tmp_c, tmp_c);
- tmp_d = __builtin_ia32_vec_ext_v2df(tmp_V2d, imm_i_0_2);
- tmp_LLi = __builtin_ia32_vec_ext_v2di(tmp_V2LLi, imm_i_0_2);
- tmp_f = __builtin_ia32_vec_ext_v4sf(tmp_V4f, imm_i_0_4);
- tmp_i = __builtin_ia32_vec_ext_v4si(tmp_V4i, imm_i_0_4);
-#ifdef USE_ALL
- tmp_Us = __builtin_ia32_vec_ext_v8hi(tmp_V8s, imm_i_0_8);
- tmp_s = __builtin_ia32_vec_ext_v4hi(tmp_V4s, imm_i_0_4);
-#endif
- tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, imm_i_0_2);
- tmp_V8s = __builtin_ia32_vec_set_v8hi(tmp_V8s, tmp_s, imm_i_0_8);
- tmp_V4s = __builtin_ia32_vec_set_v4hi(tmp_V4s, tmp_s, imm_i_0_4);
- tmp_V4i = __builtin_ia32_movqv4si(tmp_V4i);
- tmp_V4i = __builtin_ia32_loadlv4si(tmp_V2ip);
- (void) __builtin_ia32_storelv4si(tmp_V2ip, tmp_V2LLi);
-#ifdef USE_SSE4
- tmp_V16c = __builtin_ia32_pblendvb128(tmp_V16c, tmp_V16c, tmp_V16c);
- tmp_V8s = __builtin_ia32_pblendw128(tmp_V8s, tmp_V8s, imm_i_0_256);
- tmp_V2d = __builtin_ia32_blendpd(tmp_V2d, tmp_V2d, imm_i_0_256);
- tmp_V4f = __builtin_ia32_blendps(tmp_V4f, tmp_V4f, imm_i_0_256);
- tmp_V2d = __builtin_ia32_blendvpd(tmp_V2d, tmp_V2d, tmp_V2d);
- tmp_V4f = __builtin_ia32_blendvps(tmp_V4f, tmp_V4f, tmp_V4f);
- tmp_V8s = __builtin_ia32_packusdw128(tmp_V4i, tmp_V4i);
- tmp_V16c = __builtin_ia32_pmaxsb128(tmp_V16c, tmp_V16c);
- tmp_V4i = __builtin_ia32_pmaxsd128(tmp_V4i, tmp_V4i);
- tmp_V4i = __builtin_ia32_pmaxud128(tmp_V4i, tmp_V4i);
- tmp_V8s = __builtin_ia32_pmaxuw128(tmp_V8s, tmp_V8s);
- tmp_V16c = __builtin_ia32_pminsb128(tmp_V16c, tmp_V16c);
- tmp_V4i = __builtin_ia32_pminsd128(tmp_V4i, tmp_V4i);
- tmp_V4i = __builtin_ia32_pminud128(tmp_V4i, tmp_V4i);
- tmp_V8s = __builtin_ia32_pminuw128(tmp_V8s, tmp_V8s);
- tmp_V4i = __builtin_ia32_pmovsxbd128(tmp_V16c);
- tmp_V2LLi = __builtin_ia32_pmovsxbq128(tmp_V16c);
- tmp_V8s = __builtin_ia32_pmovsxbw128(tmp_V16c);
- tmp_V2LLi = __builtin_ia32_pmovsxdq128(tmp_V4i);
- tmp_V4i = __builtin_ia32_pmovsxwd128(tmp_V8s);
- tmp_V2LLi = __builtin_ia32_pmovsxwq128(tmp_V8s);
- tmp_V4i = __builtin_ia32_pmovzxbd128(tmp_V16c);
- tmp_V2LLi = __builtin_ia32_pmovzxbq128(tmp_V16c);
- tmp_V8s = __builtin_ia32_pmovzxbw128(tmp_V16c);
- tmp_V2LLi = __builtin_ia32_pmovzxdq128(tmp_V4i);
- tmp_V4i = __builtin_ia32_pmovzxwd128(tmp_V8s);
- tmp_V2LLi = __builtin_ia32_pmovzxwq128(tmp_V8s);
- tmp_V2LLi = __builtin_ia32_pmuldq128(tmp_V4i, tmp_V4i);
- tmp_V4i = __builtin_ia32_pmulld128(tmp_V4i, tmp_V4i);
- tmp_V4f = __builtin_ia32_roundps(tmp_V4f, imm_i_0_16);
- tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16);
- tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16);
- tmp_V2d = __builtin_ia32_roundpd(tmp_V2d, imm_i_0_16);
-#endif
-}
-
-
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
deleted file mode 100644
index e7055d9ad8a4..000000000000
--- a/clang/test/CodeGen/builtins.c
+++ /dev/null
@@ -1,106 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: not grep __builtin %t
-
-#include <stdio.h>
-#include <math.h>
-
-void p(char *str, int x) {
- printf("%s: %d\n", str, x);
-}
-void q(char *str, double x) {
- printf("%s: %f\n", str, x);
-}
-
-int main() {
- int N = random();
-#define P(n,args) p(#n #args, __builtin_##n args)
-#define Q(n,args) q(#n #args, __builtin_##n args)
-#define V(n,args) p(#n #args, (__builtin_##n args, 0))
- P(types_compatible_p, (int, float));
- P(choose_expr, (0, 10, 20));
- P(constant_p, (sizeof(10)));
- P(expect, (N == 12, 0));
- V(prefetch, (&N));
- V(prefetch, (&N, 1));
- V(prefetch, (&N, 1, 0));
-
- // Numeric Constants
-
- Q(huge_val, ());
- Q(huge_valf, ());
- Q(huge_vall, ());
- Q(inf, ());
- Q(inff, ());
- Q(infl, ());
-
- // FIXME:
- // XXX note funny semantics for the (last) argument
- // P(fpclassify, (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, 1.0));
- // P(isinf_sign, (1.0));
-
- Q(nan, (""));
- Q(nanf, (""));
- Q(nanl, (""));
- Q(nans, (""));
- Q(nan, ("10"));
- Q(nanf, ("10"));
- Q(nanl, ("10"));
- Q(nans, ("10"));
-
- P(isgreater, (1., 2.));
- P(isgreaterequal, (1., 2.));
- P(isless, (1., 2.));
- P(islessequal, (1., 2.));
- P(islessgreater, (1., 2.));
- P(isunordered, (1., 2.));
-
- // Bitwise & Numeric Functions
-
- P(abs, (N));
-
- P(clz, (N));
- P(clzl, (N));
- P(clzll, (N));
- P(ctz, (N));
- P(ctzl, (N));
- P(ctzll, (N));
- P(ffs, (N));
- P(ffsl, (N));
- P(ffsll, (N));
- P(parity, (N));
- P(parityl, (N));
- P(parityll, (N));
- P(popcount, (N));
- P(popcountl, (N));
- P(popcountll, (N));
- Q(powi, (1.2f, N));
- Q(powif, (1.2f, N));
- Q(powil, (1.2f, N));
-
- // Object size checking
- int a, b, n = random(); // Avoid optimizing out.
- char s0[10], s1[] = "Hello";
- V(__memset_chk, (s0, 0, sizeof s0, n));
- V(__memcpy_chk, (s0, s1, sizeof s0, n));
- V(__memmove_chk, (s0, s1, sizeof s0, n));
- V(__mempcpy_chk, (s0, s1, sizeof s0, n));
- V(__strncpy_chk, (s0, s1, sizeof s0, n));
- V(__strcpy_chk, (s0, s1, n));
- s0[0] = 0;
- V(__strcat_chk, (s0, s1, n));
- P(object_size, (s0, 0));
- P(object_size, (s0, 1));
- P(object_size, (s0, 2));
- P(object_size, (s0, 3));
-
- // Whatever
-
- P(bswap32, (N));
- P(bswap64, (N));
- // FIXME
- // V(clear_cache, (&N, &N+1));
- V(trap, ());
-
- return 0;
-}
-
diff --git a/clang/test/CodeGen/builtinshufflevector.c b/clang/test/CodeGen/builtinshufflevector.c
deleted file mode 100644
index 46741d345666..000000000000
--- a/clang/test/CodeGen/builtinshufflevector.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -emit-llvm < %s 2>&1 | grep 'shufflevector' | count 1
-typedef int v4si __attribute__ ((vector_size (16)));
-
-v4si a(v4si x, v4si y) {return __builtin_shufflevector(x, y, 3, 2, 5, 7);}
-
diff --git a/clang/test/CodeGen/c-strings.c b/clang/test/CodeGen/c-strings.c
deleted file mode 100644
index a5a7ccd3b9c1..000000000000
--- a/clang/test/CodeGen/c-strings.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: grep "hello" %t | count 3 &&
-// RUN: grep 'c"hello\\00"' %t | count 2 &&
-// RUN: grep 'c"hello\\00\\00\\00"' %t | count 1 &&
-// RUN: grep 'c"ola"' %t | count 1
-
-/* Should be 3 hello string, two global (of different sizes), the rest
- are shared. */
-
-void f0() {
- bar("hello");
-}
-
-void f1() {
- static char *x = "hello";
- bar(x);
-}
-
-void f2() {
- static char x[] = "hello";
- bar(x);
-}
-
-void f3() {
- static char x[8] = "hello";
- bar(x);
-}
-
-void f4() {
- static struct s {
- char *name;
- } x = { "hello" };
- gaz(&x);
-}
-
-char x[3] = "ola";
diff --git a/clang/test/CodeGen/cast.c b/clang/test/CodeGen/cast.c
deleted file mode 100644
index 00dd4c880d1b..000000000000
--- a/clang/test/CodeGen/cast.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-extern void go(const void *p);
-float v[2] = { 0.0, 1.0 };
-void foo(void) { go(v); }
-
diff --git a/clang/test/CodeGen/cfstring.c b/clang/test/CodeGen/cfstring.c
deleted file mode 100644
index 7d7edeca3cb3..000000000000
--- a/clang/test/CodeGen/cfstring.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-#define CFSTR __builtin___CFStringMakeConstantString
-
-void f() {
- CFSTR("Hello, World!");
-}
-
-// rdar://6248329
-void *G = CFSTR("yo joe");
-
-
diff --git a/clang/test/CodeGen/cfstring2.c b/clang/test/CodeGen/cfstring2.c
deleted file mode 100644
index f92dc8c17711..000000000000
--- a/clang/test/CodeGen/cfstring2.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-#ifdef __APPLE__
-#include <Carbon/Carbon.h>
-
-void f() {
- CFSTR("Hello, World!");
-}
-
-// rdar://6151192
-void *G = CFSTR("yo joe");
-
-#endif
diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
deleted file mode 100644
index 93e25cf459c1..000000000000
--- a/clang/test/CodeGen/complex.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// RUN: clang -emit-llvm < %s
-
-int main(void)
-{
- double _Complex a = 5;
- double _Complex b = 42;
-
- return a * b != b * a;
-}
-
-_Complex double bar(int);
-void test(_Complex double*);
-void takecomplex(_Complex double);
-
-void test2(int c) {
- _Complex double X;
- X = bar(1);
- test(&X);
- takecomplex(X);
-}
-
-_Complex double g1, g2;
-_Complex float cf;
-double D;
-
-void test3() {
- g1 = g1 + g2;
- g1 = g1 - g2;
- g1 = g1 * g2;
- g1 = +-~g1;
-
- double Gr = __real g1;
-
- cf += D;
- D += cf;
- cf /= g1;
- g1 = g1 + D;
- g1 = D + g1;
-}
-
-void t1() {
- (__real__ cf) = 4.0;
-}
-
-void t2() {
- (__imag__ cf) = 4.0;
-}
-
-// PR1960
-void t3() {
- __complex__ long long v = 2;
-}
-
diff --git a/clang/test/CodeGen/compound-literal.c b/clang/test/CodeGen/compound-literal.c
deleted file mode 100644
index a99ffe81704d..000000000000
--- a/clang/test/CodeGen/compound-literal.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang < %s -emit-llvm
-
-int* a = &(int){1};
-struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
-// Not working; complex constants are broken
-// _Complex double * x = &(_Complex double){1.0f};
-
-int xxx() {
-int* a = &(int){1};
-struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
-_Complex double * x = &(_Complex double){1.0f};
-}
diff --git a/clang/test/CodeGen/compound.c b/clang/test/CodeGen/compound.c
deleted file mode 100644
index c8afceef7600..000000000000
--- a/clang/test/CodeGen/compound.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang < %s -emit-llvm
-int A;
-long long B;
-int C;
-int *P;
-void test1() {
- C = (A /= B);
-
- P -= 4;
-
- C = P - (P+10);
-}
-
-short x;
-void test2(char c) { x += c; }
-
-void foo(char *strbuf) {
- int stufflen = 4;
- strbuf += stufflen;
-}
-
-
-// Aggregate cast to void
-union uu { int a;}; void f(union uu p) { (void) p;}
-
diff --git a/clang/test/CodeGen/conditional-gnu-ext.c b/clang/test/CodeGen/conditional-gnu-ext.c
deleted file mode 100644
index d4ae330949ff..000000000000
--- a/clang/test/CodeGen/conditional-gnu-ext.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-// PR1824
-
-int foo(int x, short y) {
- return x ?: y;
-}
diff --git a/clang/test/CodeGen/conditional.c b/clang/test/CodeGen/conditional.c
deleted file mode 100644
index 81e5ff525c90..000000000000
--- a/clang/test/CodeGen/conditional.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-float test1(int cond, float a, float b)
-{
- return cond ? a : b;
-}
-double test2(int cond, float a, double b)
-{
- return cond ? a : b;
-}
-
-void f();
-
-void test3(){
- 1 ? f() : (void)0;
-}
-
-void test4() {
-int i; short j;
-float* k = 1 ? &i : &j;
-}
-
-void test5() {
- const int* cip;
- void* vp;
- cip = 0 ? vp : cip;
-}
-
-void test6();
-void test7(int);
-void* test8() {return 1 ? test6 : test7;}
-
-
-void _efree(void *ptr);
-
-void _php_stream_free3()
-{
- (1 ? free(0) : _efree(0));
-}
-
-void _php_stream_free4()
-{
- 1 ? _efree(0) : free(0);
-}
diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c
deleted file mode 100644
index 0efab6f90367..000000000000
--- a/clang/test/CodeGen/const-init.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -verify -emit-llvm -o %t %s
-
-#include <stdint.h>
-
-// Brace-enclosed string array initializers
-char a[] = { "asdf" };
-
-// Double-implicit-conversions of array/functions (not legal C, but
-// clang accepts it for gcc compat).
-intptr_t b = a; // expected-warning {{incompatible pointer to integer conversion}}
-int c();
-void *d = c;
-intptr_t e = c; // expected-warning {{incompatible pointer to integer conversion}}
-
-int f, *g = __extension__ &f, *h = (1 != 1) ? &f : &f;
diff --git a/clang/test/CodeGen/constant-comparison.c b/clang/test/CodeGen/constant-comparison.c
deleted file mode 100644
index b7b2a0ed5abb..000000000000
--- a/clang/test/CodeGen/constant-comparison.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -emit-llvm %s -o - 2>&1 | not grep warning &&
-// RUN: clang -emit-llvm %s -o - | grep @b | count 1
-
-int a, b;
-int *c1 = 1 < 2 ? &a : &b;
-int *c2 = 3 != 3LL ? &b : &a;
-int *c3 = !(3 <= 4.0) ? &b : &a;
-int *c4 = &a - (6 * 5 > 30);
-int *c5 = &a + (6 * 5 >= 30);
-int c6 = 44 < 33;
-
-
diff --git a/clang/test/CodeGen/constructor-attribute.c b/clang/test/CodeGen/constructor-attribute.c
deleted file mode 100644
index 0ecc47babfe6..000000000000
--- a/clang/test/CodeGen/constructor-attribute.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: grep -e "global_ctors.*@A" %t &&
-// RUN: grep -e "global_dtors.*@B" %t
-
-#include <stdio.h>
-
-void A() __attribute__((constructor));
-void B() __attribute__((destructor));
-
-void A() {
- printf("A\n");
-}
-
-void B() {
- printf("B\n");
-}
-
-int main() {
- return 0;
-}
diff --git a/clang/test/CodeGen/cxx-condition.cpp b/clang/test/CodeGen/cxx-condition.cpp
deleted file mode 100644
index 746aadda5521..000000000000
--- a/clang/test/CodeGen/cxx-condition.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-void f() {
- int a;
- if (int x=a) ++a; else a=x;
- while (int x=a) ++a;
- for (; int x=a; --a) ;
- switch (int x=0) { }
-}
diff --git a/clang/test/CodeGen/cxx-default-arg.cpp b/clang/test/CodeGen/cxx-default-arg.cpp
deleted file mode 100644
index 017b17d2c996..000000000000
--- a/clang/test/CodeGen/cxx-default-arg.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-// Note: define CLANG_GENERATE_KNOWN_GOOD and compile to generate code
-// that makes all of the defaulted arguments explicit. The resulting
-// byte code should be identical to the compilation without
-// CLANG_GENERATE_KNOWN_GOOD.
-#ifdef CLANG_GENERATE_KNOWN_GOOD
-# define DEFARG(...) __VA_ARGS__
-#else
-# define DEFARG(...)
-#endif
-
-extern int x;
-struct S { float x; float y; } s;
-double _Complex c;
-
-void f(int i = 0, int j = 1, int k = x, struct S t = s, double _Complex d = c);
-
-void g() {
- f(0, 1, x, s DEFARG(, c));
- f(0, 1, x DEFARG(, s, c));
- f(0, 1 DEFARG(, x, s, c));
- f(0 DEFARG(, 1, x, s, c));
- f(DEFARG(0, 1, x, s, c));
-}
diff --git a/clang/test/CodeGen/cxx-value-init.cpp b/clang/test/CodeGen/cxx-value-init.cpp
deleted file mode 100644
index 50e08dba02db..000000000000
--- a/clang/test/CodeGen/cxx-value-init.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-enum E {};
-int v1 = E();
-float v2 = float();
-
-void f() {
- int v3 = int();
- _Complex int v4 = typeof(_Complex int)();
- _Complex float v5 = typeof(_Complex float)();
-}
diff --git a/clang/test/CodeGen/dostmt.c b/clang/test/CodeGen/dostmt.c
deleted file mode 100644
index 63547da328c4..000000000000
--- a/clang/test/CodeGen/dostmt.c
+++ /dev/null
@@ -1,70 +0,0 @@
-// RUN: clang %s -emit-llvm -o -
-
-int bar();
-int test0() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- i = bar();
- } while(0);
- return i;
-}
-
-
-int test1() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- break;
- i = bar();
- } while(1);
- return i;
-}
-
-
-int test2() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- continue;
- i = bar();
- } while(1);
- return i;
-}
-
-
-int test3() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- break;
- } while(0);
- return i;
-}
-
-
-int test4() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- continue;
- } while(0);
- return i;
-}
-
-// rdar://6103124
-void test5() {
- do { break; } while(0);
-}
-
-
-
diff --git a/clang/test/CodeGen/empty-union-init.c b/clang/test/CodeGen/empty-union-init.c
deleted file mode 100644
index 82ff84d0deb2..000000000000
--- a/clang/test/CodeGen/empty-union-init.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -emit-llvm < %s -o -
-// PR2419
-
-struct Mem {
- union {
- } u;
-};
-
-struct Mem *columnMem(){
- static const struct Mem nullMem = { {} };
-}
-
-
diff --git a/clang/test/CodeGen/enum.c b/clang/test/CodeGen/enum.c
deleted file mode 100644
index c8641926ee27..000000000000
--- a/clang/test/CodeGen/enum.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -emit-llvm-bc -o - | opt -std-compile-opts | llvm-dis | grep 'ret i32 6'
-
-static enum { foo, bar = 1U } z;
-
-int main (void)
-{
- int r = 0;
-
- if (bar - 2 < 0)
- r += 4;
- if (foo - 1 < 0)
- r += 2;
- if (z - 1 < 0)
- r++;
-
- return r;
-}
-
diff --git a/clang/test/CodeGen/exprs.c b/clang/test/CodeGen/exprs.c
deleted file mode 100644
index f1c9a5d73fa6..000000000000
--- a/clang/test/CodeGen/exprs.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// RUN: clang %s -emit-llvm -o -
-
-// PR1895
-// sizeof function
-int zxcv(void);
-int x=sizeof(zxcv);
-int y=__alignof__(zxcv);
-
-
-void *test(int *i) {
- short a = 1;
- i += a;
- i + a;
- a + i;
-}
-
-_Bool test2b;
-int test2() {if (test2b);}
-
-// PR1921
-int test3() {
- const unsigned char *bp;
- bp -= (short)1;
-}
-
-// PR2080 - sizeof void
-int t1 = sizeof(void);
-int t2 = __alignof__(void);
-void test4() {
- t1 = sizeof(void);
- t2 = __alignof__(void);
-
- t1 = sizeof(test4());
- t2 = __alignof__(test4());
-}
-
-// 'const float' promotes to double in varargs.
-int test5(const float x, float float_number) {
- return __builtin_isless(x, float_number);
-}
-
diff --git a/clang/test/CodeGen/extern-block-var.c b/clang/test/CodeGen/extern-block-var.c
deleted file mode 100644
index 35136384913f..000000000000
--- a/clang/test/CodeGen/extern-block-var.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-int f() {
- extern int a;
- return a;
-}
diff --git a/clang/test/CodeGen/func-decl-cleanup.c b/clang/test/CodeGen/func-decl-cleanup.c
deleted file mode 100644
index fa1e3d69b163..000000000000
--- a/clang/test/CodeGen/func-decl-cleanup.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -emit-llvm -o -
-
-
-// PR2360
-typedef void fn_t();
-
-fn_t a,b;
-
-void b()
-{
-}
-
diff --git a/clang/test/CodeGen/func-return-member.c b/clang/test/CodeGen/func-return-member.c
deleted file mode 100644
index f31a53afceeb..000000000000
--- a/clang/test/CodeGen/func-return-member.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang -emit-llvm < %s 2>&1 | not grep 'cannot codegen this l-value expression yet'
-
-struct frk { float _Complex c; int x; };
-struct faz { struct frk f; };
-struct fuz { struct faz f; };
-
-extern struct fuz foo(void);
-
-int X;
-struct frk F;
-float _Complex C;
-
-void bar(void) {
- X = foo().f.f.x;
-}
-
-void bun(void) {
- F = foo().f.f;
-}
-
-void ban(void) {
- C = foo().f.f.c;
-}
diff --git a/clang/test/CodeGen/function-attributes.c b/clang/test/CodeGen/function-attributes.c
deleted file mode 100644
index 1ee855dbc1be..000000000000
--- a/clang/test/CodeGen/function-attributes.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: grep 'define signext i8 @f0(i32 %x) nounwind' %t &&
-// RUN: grep 'define zeroext i8 @f1(i32 %x) nounwind' %t &&
-// RUN: grep 'define void @f2(i8 signext %x) nounwind' %t &&
-// RUN: grep 'define void @f3(i8 zeroext %x) nounwind' %t &&
-// RUN: grep 'define signext i16 @f4(i32 %x) nounwind' %t &&
-// RUN: grep 'define zeroext i16 @f5(i32 %x) nounwind' %t &&
-// RUN: grep 'define void @f6(i16 signext %x) nounwind' %t &&
-// RUN: grep 'define void @f7(i16 zeroext %x) nounwind' %t
-
-signed char f0(int x) { return x; }
-
-unsigned char f1(int x) { return x; }
-
-void f2(signed char x) { }
-
-void f3(unsigned char x) { }
-
-signed short f4(int x) { return x; }
-
-unsigned short f5(int x) { return x; }
-
-void f6(signed short x) { }
-
-void f7(unsigned short x) { }
-
diff --git a/clang/test/CodeGen/functions.c b/clang/test/CodeGen/functions.c
deleted file mode 100644
index 60e2b6c80cff..000000000000
--- a/clang/test/CodeGen/functions.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang %s -emit-llvm -o -
-int g();
-
-int foo(int i) {
- return g(i);
-}
-
-int g(int i) {
- return g(i);
-}
-
-// rdar://6110827
-typedef void T(void);
-void test3(T f) {
- f();
-}
-
diff --git a/clang/test/CodeGen/global-with-initialiser.c b/clang/test/CodeGen/global-with-initialiser.c
deleted file mode 100644
index be12c24f81df..000000000000
--- a/clang/test/CodeGen/global-with-initialiser.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-const int globalInt = 1;
-int globalIntWithFloat = 1.5f;
-int globalIntArray[5] = { 1, 2 };
-int globalIntFromSizeOf = sizeof(globalIntArray);
-char globalChar = 'a';
-char globalCharArray[5] = { 'a', 'b' };
-float globalFloat = 1.0f;
-float globalFloatWithInt = 1;
-float globalFloatArray[5] = { 1.0f, 2.0f };
-double globalDouble = 1.0;
-double globalDoubleArray[5] = { 1.0, 2.0 };
-char *globalString = "abc";
-char *globalStringArray[5] = { "123", "abc" };
-long double globalLongDouble = 1;
-long double globalLongDoubleArray[5] = { 1.0, 2.0 };
-
-struct Struct {
- int member1;
- float member2;
- char *member3;
-};
-
-struct Struct globalStruct = { 1, 2.0f, "foobar"};
diff --git a/clang/test/CodeGen/globalinit.c b/clang/test/CodeGen/globalinit.c
deleted file mode 100644
index 0f3e21a6cafd..000000000000
--- a/clang/test/CodeGen/globalinit.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-int A[10] = { 1,2,3,4,5 };
-
-
-extern int x[];
-void foo() { x[0] = 1; }
-int x[10];
-void bar() { x[0] = 1; }
-
-
-extern int y[];
-void *g = y;
-
-int latin_ptr2len (char *p);
-int (*mb_ptr2len) (char *p) = latin_ptr2len;
-
-
-char string[8] = "string"; // extend init
-char string2[4] = "string"; // truncate init
-
-char *test(int c) {
- static char buf[10];
- static char *bufptr = buf;
-
- return c ? buf : bufptr;
-}
-
-
-_Bool booltest = 0;
-void booltest2() {
- static _Bool booltest3 = 4;
-}
-
-// Scalars in braces.
-static int a = { 1 };
-static int b = { 1, 2 };
-
-// References to enums.
-enum {
- EnumA, EnumB
-};
-
-int c[] = { EnumA, EnumB };
-
-// Binary operators
-int d[] = { EnumA | EnumB };
-
-// PR1968
-static int array[];
-static int array[4];
-
diff --git a/clang/test/CodeGen/indirect-goto.c b/clang/test/CodeGen/indirect-goto.c
deleted file mode 100644
index c0dc8a8298d2..000000000000
--- a/clang/test/CodeGen/indirect-goto.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 1 &&
-// RUN: grep "ret i32 210" %t | count 1
-
-static int foo(unsigned i) {
- const void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 };
- int res = 1;
-
- goto *addrs[i];
- L5: res *= 11;
- L4: res *= 7;
- L3: res *= 5;
- L2: res *= 3;
- L1: res *= 2;
- return res;
-}
-
-int bar() {
- return foo(3);
-}
diff --git a/clang/test/CodeGen/init-with-member-expr.c b/clang/test/CodeGen/init-with-member-expr.c
deleted file mode 100644
index 606f9dc8d005..000000000000
--- a/clang/test/CodeGen/init-with-member-expr.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang < %s -emit-llvm
-struct test {
- int a;
-};
-
-extern struct test t;
-
-int *b=&t.a;
-
-
-// PR2049
-typedef struct mark_header_tag {
- unsigned char mark[7];
-} mark_header_t;
-int is_rar_archive(int fd) {
- const mark_header_t rar_hdr[2] = {{0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, {'U', 'n', 'i', 'q', 'u', 'E', '!'}};
- foo(rar_hdr);
-
- return 0;
-}
-
diff --git a/clang/test/CodeGen/init.c b/clang/test/CodeGen/init.c
deleted file mode 100644
index 9d18f0a767d5..000000000000
--- a/clang/test/CodeGen/init.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang -emit-llvm %s -o -
-void f1() {
- // Scalars in braces.
- int a = { 1 };
- int b = { 1, 2 };
-}
-
-void f2() {
- int a[2][2] = { { 1, 2 }, { 3, 4 } };
- int b[3][3] = { { 1, 2 }, { 3, 4 } };
- int *c[2] = { &a[1][1], &b[2][2] };
- int *d[2][2] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
- int *e[3][3] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
- char ext[3][3] = {".Y",".U",".V"};
-}
-
-typedef void (* F)(void);
-extern void foo(void);
-struct S { F f; };
-void f3() {
- struct S a[1] = { { foo } };
-}
-
diff --git a/clang/test/CodeGen/int-to-pointer.c b/clang/test/CodeGen/int-to-pointer.c
deleted file mode 100644
index e427e73f6d55..000000000000
--- a/clang/test/CodeGen/int-to-pointer.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-void *test(int i)
-{
- return (void *)i;
-}
diff --git a/clang/test/CodeGen/kr-func-promote.c b/clang/test/CodeGen/kr-func-promote.c
deleted file mode 100644
index a20532a97680..000000000000
--- a/clang/test/CodeGen/kr-func-promote.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -emit-llvm -o - | grep "i32 @a(i32)"
-
-int a();
-int a(x) short x; {return x;}
-
diff --git a/clang/test/CodeGen/long-double-x86.c b/clang/test/CodeGen/long-double-x86.c
deleted file mode 100644
index 8954042afd9a..000000000000
--- a/clang/test/CodeGen/long-double-x86.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -emit-llvm -o - -triple=i686-apple-darwin9 | grep x86_fp80
-
-long double x = 0;
-int checksize[sizeof(x) == 16 ? 1 : -1];
diff --git a/clang/test/CodeGen/mandel.c b/clang/test/CodeGen/mandel.c
deleted file mode 100644
index 388e922e0102..000000000000
--- a/clang/test/CodeGen/mandel.c
+++ /dev/null
@@ -1,67 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-/* Sparc is not C99-compliant */
-#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
-
-int main() { return 0; }
-
-#else /* sparc */
-
-#define ESCAPE 2
-#define IMAGE_WIDTH 150
-#define IMAGE_HEIGHT 50
-#if 1
-#define IMAGE_SIZE 60
-#else
-#define IMAGE_SIZE 5000
-#endif
-#define START_X -2.1
-#define END_X 1.0
-#define START_Y -1.25
-#define MAX_ITER 100
-
-#define step_X ((END_X - START_X)/IMAGE_WIDTH)
-#define step_Y ((-START_Y - START_Y)/IMAGE_HEIGHT)
-
-#define I 1.0iF
-
-#include <math.h>
-
-#include <stdio.h>
-
-volatile double __complex__ accum;
-
-void mandel() {
- int x, y, n;
- for (y = 0; y < IMAGE_HEIGHT; ++y) {
- for (x = 0; x < IMAGE_WIDTH; ++x) {
- double __complex__ c = (START_X+x*step_X) + (START_Y+y*step_Y) * I;
- double __complex__ z = 0.0;
-
- for (n = 0; n < MAX_ITER; ++n) {
- z = z * z + c;
- if (hypot(__real__ z, __imag__ z) >= ESCAPE)
- break;
- }
-
- if (n == MAX_ITER)
- putchar(' ');
- else if (n > 6)
- putchar('.');
- else if (n > 3)
- putchar('+');
- else if (n > 2)
- putchar('x');
- else
- putchar('*');
- }
- putchar('\n');
- }
-}
-
-int main() {
- mandel();
- return 0;
-}
-
-#endif /* sparc */
diff --git a/clang/test/CodeGen/merge-attrs.c b/clang/test/CodeGen/merge-attrs.c
deleted file mode 100644
index c3349d8e97b7..000000000000
--- a/clang/test/CodeGen/merge-attrs.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-void *malloc(int size) __attribute__ ((__nothrow__));
-
-inline static void __zend_malloc() {
- malloc(1);
-}
-
-void *malloc(int size) __attribute__ ((__nothrow__));
-
-void fontFetch() {
- __zend_malloc(1);
-}
diff --git a/clang/test/CodeGen/merge-statics.c b/clang/test/CodeGen/merge-statics.c
deleted file mode 100644
index 1e0d68912212..000000000000
--- a/clang/test/CodeGen/merge-statics.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang < %s -emit-llvm | grep internal | count 1
-
-// The two decls for 'a' should merge into one llvm GlobalVariable.
-
-struct s { int x; };
-static struct s a;
-
-struct s *ap1 = &a;
-
-static struct s a = {
- 10
-};
-
diff --git a/clang/test/CodeGen/ocu-vector.c b/clang/test/CodeGen/ocu-vector.c
deleted file mode 100644
index 24ea17d527aa..000000000000
--- a/clang/test/CodeGen/ocu-vector.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-typedef __attribute__(( ext_vector_type(4) )) float float4;
-typedef __attribute__(( ext_vector_type(2) )) float float2;
-
-float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
-
-float4 test1(float4 V) {
- return V.wzyx+V;
-}
-
-float2 vec2, vec2_2;
-float4 vec4, vec4_2;
-float f;
-
-static void test2() {
- vec2 = vec4.rg; // shorten
- f = vec2.x; // extract elt
- vec4 = vec4.yyyy; // splat
-
- vec2.x = f; // insert one.
- vec2.yx = vec2; // reverse
-}
-
-static void test3(float4 *out) {
- *out = ((float4) {1.0f, 2.0f, 3.0f, 4.0f });
-}
-
-static void test4(float4 *out) {
- float a = 1.0f;
- float b = 2.0f;
- float c = 3.0f;
- float d = 4.0f;
- *out = ((float4) {a,b,c,d});
-}
-
-static void test5(float4 *out) {
- float a;
- float4 b;
-
- a = 1.0f;
- b = a;
- b = b * 5.0f;
- b = 5.0f * b;
- b *= a;
-
- *out = b;
-}
diff --git a/clang/test/CodeGen/opaque-pointer.c b/clang/test/CodeGen/opaque-pointer.c
deleted file mode 100644
index 31c27f49144f..000000000000
--- a/clang/test/CodeGen/opaque-pointer.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-struct test;
-
-typedef void (*my_func) (struct test *);
-my_func handler;
-
-struct test {
- char a;
-};
-
-char f(struct test *t) {
- return t->a;
-}
diff --git a/clang/test/CodeGen/pointer-arithmetic.c b/clang/test/CodeGen/pointer-arithmetic.c
deleted file mode 100644
index 3133c9effe4e..000000000000
--- a/clang/test/CodeGen/pointer-arithmetic.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-typedef int Int;
-
-int test1(int *a, Int *b) { return a - b; }
-
-int test2(const char *a, char *b) { return b - a; }
diff --git a/clang/test/CodeGen/pointer-cmp-type.c b/clang/test/CodeGen/pointer-cmp-type.c
deleted file mode 100644
index 02fc4c767596..000000000000
--- a/clang/test/CodeGen/pointer-cmp-type.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-llvm %s -o - | grep "icmp ult"
-
-int a(char* a, char* b) {return a<b;}
diff --git a/clang/test/CodeGen/pointer-to-int.c b/clang/test/CodeGen/pointer-to-int.c
deleted file mode 100644
index a3eaf91bc161..000000000000
--- a/clang/test/CodeGen/pointer-to-int.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -emit-llvm %s -o -
-
-int test(void* i)
-{
- return (int)i;
-}
-
-// rdar://6093986
-int test2(void) {
- float x[2];
- return x;
-}
-
diff --git a/clang/test/CodeGen/rdr-6095112-alias-references-inline.c b/clang/test/CodeGen/rdr-6095112-alias-references-inline.c
deleted file mode 100644
index 4805d47c1601..000000000000
--- a/clang/test/CodeGen/rdr-6095112-alias-references-inline.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang --emit-llvm -o %t %s &&
-// RUN: grep -e "alias" %t
-// XFAIL
-
-static inline int foo () { return 0; }
-int bar () __attribute__ ((alias ("foo")));
diff --git a/clang/test/CodeGen/rdr-6098585-default-after-caserange.c b/clang/test/CodeGen/rdr-6098585-default-after-caserange.c
deleted file mode 100644
index 1a7a53fc7fca..000000000000
--- a/clang/test/CodeGen/rdr-6098585-default-after-caserange.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 1 &&
-// RUN: grep "ret i32 10" %t | count 1
-
-// Ensure that default after a case range is not ignored.
-
-static int f1(unsigned x) {
- switch(x) {
- case 10 ... 0xFFFFFFFF:
- return 0;
- default:
- return 10;
- }
-}
-
-int g() {
- return f1(2);
-}
diff --git a/clang/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c b/clang/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c
deleted file mode 100644
index 7cb9384cdeaf..000000000000
--- a/clang/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32 10" %t
-
-// Ensure that this doesn't compile to infinite loop in g() due to
-// miscompilation of fallthrough from default to a (tested) case
-// range.
-
-static int f0(unsigned x) {
- switch(x) {
- default:
- x += 1;
- case 10 ... 0xFFFFFFFF:
- return 0;
- }
-}
-
-int g() {
- f0(1);
- return 10;
-}
diff --git a/clang/test/CodeGen/rdr-6098585-empty-case-range.c b/clang/test/CodeGen/rdr-6098585-empty-case-range.c
deleted file mode 100644
index 2dc3cf3da855..000000000000
--- a/clang/test/CodeGen/rdr-6098585-empty-case-range.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 2 &&
-// RUN: grep "ret i32 3" %t | count 2
-
-// This generated incorrect code because of poor switch chaining.
-int f1(int x) {
- switch(x) {
- default:
- return 3;
- case 10 ... 0xFFFFFFFF:
- return 0;
- }
-}
-
-// This just asserted because of the way case ranges were calculated.
-int f2(int x) {
- switch (x) {
- default:
- return 3;
- case 10 ... -1:
- return 0;
- }
-}
diff --git a/clang/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c b/clang/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c
deleted file mode 100644
index 007a0c7587f0..000000000000
--- a/clang/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32 %" %t
-
-// Make sure return is not constant (if empty range is skipped or miscompiled)
-
-int f0(unsigned x) {
- switch(x) {
- case 2:
- // fallthrough empty range
- case 10 ... 9:
- return 10;
- default:
- return 0;
- }
-}
diff --git a/clang/test/CodeGen/rdr-6098585-unsigned-caserange.c b/clang/test/CodeGen/rdr-6098585-unsigned-caserange.c
deleted file mode 100644
index adf825c81355..000000000000
--- a/clang/test/CodeGen/rdr-6098585-unsigned-caserange.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t &&
-// RUN: grep "ret i32" %t | count 1 &&
-// RUN: grep "ret i32 3" %t | count 1
-
-int f2(unsigned x) {
- switch(x) {
- default:
- return 3;
- case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
- return 0;
- }
-}
diff --git a/clang/test/CodeGen/rdr-6140807-alias-references-forward.c b/clang/test/CodeGen/rdr-6140807-alias-references-forward.c
deleted file mode 100644
index eff69aca2d2f..000000000000
--- a/clang/test/CodeGen/rdr-6140807-alias-references-forward.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: grep -e "@f = alias" %t | count 1 &&
-// RUN: grep -e "bitcast (i32 (i32)\\* @f to i32 (float)\\*)" %t | count 1
-// <rdar://problem/6140807>
-
-int f(float) __attribute__((weak, alias("x")));
-
-// Make sure we replace uses properly...
-int y() {
- return f(1.);
-}
-
-int x(int) {
-}
diff --git a/clang/test/CodeGen/shared-string-literals.c b/clang/test/CodeGen/shared-string-literals.c
deleted file mode 100644
index 2e8269b2a38e..000000000000
--- a/clang/test/CodeGen/shared-string-literals.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-char *globalString = "abc";
-char *globalStringArray[5] = { "123", "abc" };
-char *anotherGlobalString = "123";
-
-int main() {
- printf("123");
-}
diff --git a/clang/test/CodeGen/statements.c b/clang/test/CodeGen/statements.c
deleted file mode 100644
index 409212139350..000000000000
--- a/clang/test/CodeGen/statements.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang < %s -emit-llvm
-
-void test1(int x) {
-switch (x) {
-case 111111111111111111111111111111111111111:
-bar();
-}
-}
-
-// Mismatched type between return and function result.
-int test2() { return; }
-void test3() { return 4; }
-
diff --git a/clang/test/CodeGen/static-forward-decl-fun.c b/clang/test/CodeGen/static-forward-decl-fun.c
deleted file mode 100644
index 69080e3a0389..000000000000
--- a/clang/test/CodeGen/static-forward-decl-fun.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-static int staticfun(void);
-int (*staticuse1)(void) = staticfun;
-static int staticfun() {return 1;}
-int (*staticuse2)(void) = staticfun;
diff --git a/clang/test/CodeGen/static-forward-decl.c b/clang/test/CodeGen/static-forward-decl.c
deleted file mode 100644
index 8e0825cb6c82..000000000000
--- a/clang/test/CodeGen/static-forward-decl.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -emit-llvm -o - -triple=i686-apple-darwin9 | grep "global i32 10"
-
-static int i;
-int*j=&i;
-static int i = 10;
diff --git a/clang/test/CodeGen/static-local-union.c b/clang/test/CodeGen/static-local-union.c
deleted file mode 100644
index 9515a316d62d..000000000000
--- a/clang/test/CodeGen/static-local-union.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm < %s
-
-int a() {static union{int a;} r[2] = {1,2};return r[1].a;}
-
diff --git a/clang/test/CodeGen/staticinit.c b/clang/test/CodeGen/staticinit.c
deleted file mode 100644
index 50c837a1c2f1..000000000000
--- a/clang/test/CodeGen/staticinit.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep "g.b = internal global i8. getelementptr"
-
-struct AStruct {
- int i;
- char *s;
- double d;
-};
-
-void f() {
- static int i = 42;
- static int is[] = { 1, 2, 3, 4 };
- static char* str = "forty-two";
- static char* strs[] = { "one", "two", "three", "four" };
- static struct AStruct myStruct = { 1, "two", 3.0 };
-}
-
-void g() {
- static char a[10];
- static char *b = a;
-}
diff --git a/clang/test/CodeGen/string-init.c b/clang/test/CodeGen/string-init.c
deleted file mode 100644
index f3ad4c51ee87..000000000000
--- a/clang/test/CodeGen/string-init.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -emit-llvm %s -o - | not grep -F "[5 x i8]" &&
-// RUN: clang -emit-llvm %s -o - | not grep "store"
-
-void test(void) {
- char a[10] = "asdf";
- char b[10] = { "asdf" };
-}
-
diff --git a/clang/test/CodeGen/string-literal.c b/clang/test/CodeGen/string-literal.c
deleted file mode 100644
index e19168e4104c..000000000000
--- a/clang/test/CodeGen/string-literal.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-int main() {
- char a[10] = "abc";
-}
diff --git a/clang/test/CodeGen/struct-comma.c b/clang/test/CodeGen/struct-comma.c
deleted file mode 100644
index b53013f7aab7..000000000000
--- a/clang/test/CodeGen/struct-comma.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-struct S {int a, b;} x;
-void a(struct S* b) {*b = (r(), x);}
diff --git a/clang/test/CodeGen/struct-init.c b/clang/test/CodeGen/struct-init.c
deleted file mode 100644
index ab14a1dc1d47..000000000000
--- a/clang/test/CodeGen/struct-init.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-typedef struct _zend_ini_entry zend_ini_entry;
-struct _zend_ini_entry {
- void *mh_arg1;
-};
-
-char a;
-
-const zend_ini_entry ini_entries[] = {
- { ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)},
-};
diff --git a/clang/test/CodeGen/struct-x86-darwin.c b/clang/test/CodeGen/struct-x86-darwin.c
deleted file mode 100644
index 7a2e7de36b14..000000000000
--- a/clang/test/CodeGen/struct-x86-darwin.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang < %s -emit-llvm > %t1 -triple=i686-apple-darwin9
-// Run grep "STest1 = type <{ i32, \[4 x i16\], double }>" %t1 &&
-// RUN: grep "STest2 = type <{ i16, i16, i32, i32 }>" %t1 &&
-// RUN: grep "STest3 = type <{ i8, i8, i16, i32 }>" %t1 &&
-// RUN: grep "STestB1 = type <{ i8, i8 }>" %t1 &&
-// RUN: grep "STestB2 = type <{ i8, i8, i8 }>" %t1 &&
-// RUN: grep "STestB3 = type <{ i8, i8 }>" %t1 &&
-// RUN: grep "STestB4 = type <{ i8, i8, i8, i8 }>" %t1 &&
-// RUN: grep "STestB5 = type <{ i8, i8, i8, i8, i8, i8 }>" %t1 &&
-// RUN: grep "STestB6 = type <{ i8, i8, i8, i8 }>" %t1
-// Test struct layout for x86-darwin target
-
-struct STest1 {int x; short y[4]; double z; } st1;
-struct STest2 {short a,b; int c,d; } st2;
-struct STest3 {char a; short b; int c; } st3;
-
-// Bitfields
-struct STestB1 {char a; char b:2; } stb1;
-struct STestB2 {char a; char b:5; char c:4; } stb2;
-struct STestB3 {char a; char b:2; } stb3;
-struct STestB4 {char a; short b:2; char c; } stb4;
-struct STestB5 {char a; short b:10; char c; } stb5;
-struct STestB6 {int a:1; char b; int c:13 } stb6;
-
-// Packed struct STestP1 {char a; short b; int c; } __attribute__((__packed__)) stp1;
diff --git a/clang/test/CodeGen/struct.c b/clang/test/CodeGen/struct.c
deleted file mode 100644
index 76d9b772742e..000000000000
--- a/clang/test/CodeGen/struct.c
+++ /dev/null
@@ -1,191 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-struct {
- int x;
- int y;
-} point;
-
-void fn1() {
- point.x = 42;
-}
-
-/* Nested member */
-struct {
- struct {
- int a;
- int b;
- } p1;
-} point2;
-
-void fn2() {
- point2.p1.a = 42;
-}
-
-/* Indirect reference */
-typedef struct __sf {
- unsigned char *c;
- short flags;
-} F;
-
-typedef struct __sf2 {
- F *ff;
-} F2;
-
-int fn3(F2 *c) {
- if (c->ff->c >= 0)
- return 1;
- else
- return 0;
-}
-
-/* Nested structs */
-typedef struct NA {
- int data;
- struct NA *next;
-} NA;
-void f1() { NA a; }
-
-typedef struct NB {
- int d1;
- struct _B2 {
- int d2;
- struct NB *n2;
- } B2;
-} NB;
-
-void f2() { NB b; }
-
-extern NB *f3();
-void f4() {
- f3()->d1 = 42;
-}
-
-void f5() {
- (f3())->d1 = 42;
-}
-
-/* Function calls */
-typedef struct {
- int location;
- int length;
-} range;
-extern range f6();
-void f7()
-{
- range r = f6();
-}
-
-/* Member expressions */
-typedef struct {
- range range1;
- range range2;
-} rangepair;
-
-void f8()
-{
- rangepair p;
-
- range r = p.range1;
-}
-
-void f9(range *p)
-{
- range r = *p;
-}
-
-void f10(range *p)
-{
- range r = p[0];
-}
-
-/* _Bool types */
-
-struct _w
-{
- short a,b;
- short c,d;
- short e,f;
- short g;
-
- unsigned int h,i;
-
- _Bool j,k;
-} ws;
-
-/* Implicit casts (due to typedefs) */
-typedef struct _a
-{
- int a;
-} a;
-
-void f11()
-{
- struct _a a1;
- a a2;
-
- a1 = a2;
- a2 = a1;
-}
-
-/* Implicit casts (due to const) */
-void f12()
-{
- struct _a a1;
- const struct _a a2;
-
- a1 = a2;
-}
-
-/* struct initialization */
-struct a13 {int b; int c;};
-struct a13 c13 = {5};
-typedef struct a13 a13;
-struct a14 { short a; int b; } x = {1, 1};
-
-/* flexible array members */
-struct a15 {char a; int b[];} c15;
-int a16(void) {c15.a = 1;}
-
-/* compound literals */
-void f13()
-{
- a13 x; x = (a13){1,2};
-}
-
-/* va_arg */
-int f14(int i, ...) {
- __builtin_va_list l;
- __builtin_va_start(l,i);
- a13 b = __builtin_va_arg(l, a13);
- return b.b;
-}
-
-/* Attribute packed */
-struct __attribute__((packed)) S2839 { double a[19]; signed char b; } s2839[5];
-
-struct __attribute__((packed)) SS { long double a; char b; } SS;
-
-
-/* As lvalue */
-
-int f15() {
- extern range f15_ext();
- return f15_ext().location;
-}
-
-range f16() {
- extern rangepair f16_ext();
- return f16_ext().range1;
-}
-
-int f17() {
- extern range f17_ext();
- range r;
- return (r = f17_ext()).location;
-}
-
-range f18() {
- extern rangepair f18_ext();
- rangepair rp;
- return (rp = f18_ext()).range1;
-}
diff --git a/clang/test/CodeGen/switch.c b/clang/test/CodeGen/switch.c
deleted file mode 100644
index 056337465bc3..000000000000
--- a/clang/test/CodeGen/switch.c
+++ /dev/null
@@ -1,87 +0,0 @@
-// RUN: clang %s -emit-llvm-bc -o - | opt -std-compile-opts -disable-output
-
-int foo(int i) {
- int j = 0;
- switch (i) {
- case -1:
- j = 1; break;
- case 1 :
- j = 2; break;
- case 2:
- j = 3; break;
- default:
- j = 42; break;
- }
- j = j + 1;
- return j;
-}
-
-
-int foo2(int i) {
- int j = 0;
- switch (i) {
- case 1 :
- j = 2; break;
- case 2 ... 10:
- j = 3; break;
- default:
- j = 42; break;
- }
- j = j + 1;
- return j;
-}
-
-
-int foo3(int i) {
- int j = 0;
- switch (i) {
- default:
- j = 42; break;
- case 111:
- j = 111; break;
- case 0 ... 100:
- j = 1; break;
- case 222:
- j = 222; break;
- }
- return j;
-}
-
-
-int foo4(int i) {
- int j = 0;
- switch (i) {
- case 111:
- j = 111; break;
- case 0 ... 100:
- j = 1; break;
- case 222:
- j = 222; break;
- default:
- j = 42; break;
- case 501 ... 600:
- j = 5; break;
- }
- return j;
-}
-
-void foo5(){
- switch(0){
- default:
- if (0) {
-
- }
- }
-}
-
-void foo6(){
- switch(0){
- }
-}
-
-void foo7(){
- switch(0){
- foo7();
- }
-}
-
diff --git a/clang/test/CodeGen/tentative-array.c b/clang/test/CodeGen/tentative-array.c
deleted file mode 100644
index 71231237fafe..000000000000
--- a/clang/test/CodeGen/tentative-array.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm < %s -triple=i686-apple-darwin9 | grep "global \[1 x i32\]"
-
-int r[];
-int (*a)[] = &r;
diff --git a/clang/test/CodeGen/trunc-array-initializer.c b/clang/test/CodeGen/trunc-array-initializer.c
deleted file mode 100644
index f397657f8f9f..000000000000
--- a/clang/test/CodeGen/trunc-array-initializer.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-int ary[2] = { 1, 2, 3 };
diff --git a/clang/test/CodeGen/typedef-func.c b/clang/test/CodeGen/typedef-func.c
deleted file mode 100644
index c14a42c1e8ad..000000000000
--- a/clang/test/CodeGen/typedef-func.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -emit-llvm < %s
-
-// PR2414
-struct mad_frame{};
-enum mad_flow {};
-
-typedef enum mad_flow filter_func_t(void *, struct mad_frame *);
-
-filter_func_t mono_filter;
-
-void addfilter2(filter_func_t *func){}
-
-void setup_filters()
-{
- addfilter2( mono_filter);
-}
diff --git a/clang/test/CodeGen/typedef.c b/clang/test/CodeGen/typedef.c
deleted file mode 100644
index 75f6933c40d0..000000000000
--- a/clang/test/CodeGen/typedef.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-
-typedef struct { int i; } Value;
-typedef Value *PValue;
-
-int get_value(PValue v) {
- return v->i;
-}
diff --git a/clang/test/CodeGen/types.c b/clang/test/CodeGen/types.c
deleted file mode 100644
index c542a758b8d7..000000000000
--- a/clang/test/CodeGen/types.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang -emit-llvm <%s
-
-struct FileName {
- struct FileName *next;
-} *fnhead;
-
-
-struct ieeeExternal {
- struct ieeeExternal *next;
-} *exthead;
-
-
-void test1()
-{
- struct ieeeExternal *exttmp = exthead;
-}
-
-struct MpegEncContext;
-typedef struct MpegEncContext {int pb;} MpegEncContext;
-static void test2(void) {MpegEncContext s; s.pb;}
-
-
-struct Village;
-
-struct List {
- struct Village *v;
-};
-
-struct Village {
- struct List returned;
-};
-
-void test3(struct List a) {
-}
diff --git a/clang/test/CodeGen/union-init.c b/clang/test/CodeGen/union-init.c
deleted file mode 100644
index 9a515a72d92b..000000000000
--- a/clang/test/CodeGen/union-init.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: clang -emit-llvm < %s -o -
-
-// A nice and complicated initialization example with unions from Python
-typedef int Py_ssize_t;
-
-typedef union _gc_head {
- struct {
- union _gc_head *gc_next;
- union _gc_head *gc_prev;
- Py_ssize_t gc_refs;
- } gc;
- long double dummy; /* force worst-case alignment */
-} PyGC_Head;
-
-struct gc_generation {
- PyGC_Head head;
- int threshold; /* collection threshold */
- int count; /* count of allocations or collections of younger
- generations */
-};
-
-#define NUM_GENERATIONS 3
-#define GEN_HEAD(n) (&generations[n].head)
-
-/* linked lists of container objects */
-struct gc_generation generations[NUM_GENERATIONS] = {
- /* PyGC_Head, threshold, count */
- {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700, 0},
- {{{GEN_HEAD(1), GEN_HEAD(1), 0}}, 10, 0},
- {{{GEN_HEAD(2), GEN_HEAD(2), 0}}, 10, 0},
-};
diff --git a/clang/test/CodeGen/union.c b/clang/test/CodeGen/union.c
deleted file mode 100644
index 96287ea0a6d0..000000000000
--- a/clang/test/CodeGen/union.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-union u_tag {
- int a;
- float b;
-} u;
-
-void f() {
- u.b = 11;
-}
-
-float get_b(union u_tag *my_u) {
- return my_u->b;
-}
-
-int f2( float __x ) {
- union{
- float __f;
- unsigned int __u;
- }__u;
- return (int)(__u.__u >> 31);
-}
-
-typedef union { int i; int *j; } value;
-
-int f3(value v) {
- return *v.j;
-}
-
-enum E9 { one, two };
-union S65 { enum E9 a:62; } ; union S65 s65;
-void fS65() { enum E9 e = s65.a; }
-
-typedef union{
- unsigned char x[65536];
-} q;
-int qfunc() {q buf; unsigned char* x = buf.x;}
-
-union RR {_Bool a : 1;} RRU;
-int RRF(void) {return RRU.a;}
-
diff --git a/clang/test/CodeGen/unwind-attr.c b/clang/test/CodeGen/unwind-attr.c
deleted file mode 100644
index 92f43ecc9ae8..000000000000
--- a/clang/test/CodeGen/unwind-attr.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fexceptions -emit-llvm -o - %s | grep "@foo() {" | count 1 &&
-// RUN: clang -emit-llvm -o - %s | grep "@foo() nounwind {" | count 1
-
-int foo(void) {
-}
diff --git a/clang/test/CodeGen/var-align.c b/clang/test/CodeGen/var-align.c
deleted file mode 100644
index be585c052e8a..000000000000
--- a/clang/test/CodeGen/var-align.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm %s -o - | grep "align 16" | count 2
-
-__attribute((aligned(16))) float a[128];
-union {int a[4]; __attribute((aligned(16))) float b[4];} u;
diff --git a/clang/test/CodeGen/vector.c b/clang/test/CodeGen/vector.c
deleted file mode 100644
index 86956e05f58f..000000000000
--- a/clang/test/CodeGen/vector.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -emit-llvm %s -o %t
-typedef short __v4hi __attribute__ ((__vector_size__ (8)));
-
-void f()
-{
- __v4hi A = (__v4hi)0LL;
-}
-
-__v4hi x = {1,2,3};
-__v4hi y = {1,2,3,4};
-__v4hi z = {1,2,3,4,5};
diff --git a/clang/test/CodeGen/volatile.c b/clang/test/CodeGen/volatile.c
deleted file mode 100644
index 4db4a5d84318..000000000000
--- a/clang/test/CodeGen/volatile.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep volatile | count 26
-
-// The number 26 comes from the current codegen for volatile loads;
-// if this number changes, it's not necessarily something wrong, but
-// something has changed to affect volatile load/store codegen
-
-int S;
-volatile int vS;
-
-int* pS;
-volatile int* pvS;
-
-int A[10];
-volatile int vA[10];
-
-struct { int x; } F;
-struct { volatile int x; } vF;
-
-struct { int x; } F2;
-volatile struct { int x; } vF2;
-volatile struct { int x; } *vpF2;
-
-struct { struct { int y; } x; } F3;
-volatile struct { struct { int y; } x; } vF3;
-
-struct { int x:3; } BF;
-struct { volatile int x:3; } vBF;
-
-typedef int v4si __attribute__ ((vector_size (16)));
-v4si V;
-volatile v4si vV;
-
-typedef __attribute__(( ext_vector_type(4) )) int extv4;
-extv4 VE;
-volatile extv4 vVE;
-
-volatile struct {int x;} aggFct(void);
-
-void main() {
- int i;
-
- // load
- i=S;
- i=vS;
- i=*pS;
- i=*pvS;
- i=A[2];
- i=vA[2];
- i=F.x;
- i=vF.x;
- i=F2.x;
- i=vF2.x;
- i=vpF2->x;
- i=F3.x.y;
- i=vF3.x.y;
- i=BF.x;
- i=vBF.x;
- i=V[3];
- i=vV[3];
- i=VE.yx[1];
- i=vVE.zy[1];
- i = aggFct().x;
-
-
- // store
- S=i;
- vS=i;
- *pS=i;
- *pvS=i;
- A[2]=i;
- vA[2]=i;
- F.x=i;
- vF.x=i;
- F2.x=i;
- vF2.x=i;
- vpF2->x=i;
- vF3.x.y=i;
- BF.x=i;
- vBF.x=i; // FIXME: This generates an extra volatile load
- V[3]=i;
- vV[3]=i;
-
- // other ops:
- ++S;
- ++vS;
- i+=S;
- i+=vS;
-}
diff --git a/clang/test/CodeGen/weak-global.c b/clang/test/CodeGen/weak-global.c
deleted file mode 100644
index d19dd6129179..000000000000
--- a/clang/test/CodeGen/weak-global.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep common
-
-int i;
diff --git a/clang/test/CodeGen/whilestmt.c b/clang/test/CodeGen/whilestmt.c
deleted file mode 100644
index c7f8de8a5291..000000000000
--- a/clang/test/CodeGen/whilestmt.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// RUN: clang %s -emit-llvm -o %t
-
-int bar();
-int foo() {
- int i;
- i = 1 + 2;
- while(1) {
- i = bar();
- i = bar();
- };
- return i;
-}
-
-
-int foo1() {
- int i;
- i = 1 + 2;
- while(1) {
- i = bar();
- if (i == 42)
- break;
- i = bar();
- };
- return i;
-}
-
-
-int foo2() {
- int i;
- i = 1 + 2;
- while(1) {
- i = bar();
- if (i == 42)
- continue;
- i = bar();
- };
- return i;
-}
-
-
-int foo3() {
- int i;
- i = 1 + 2;
- while(1) {
- i = bar();
- if (i == 42)
- break;
- };
- return i;
-}
-
-
-int foo4() {
- int i;
- i = 1 + 2;
- while(1) {
- i = bar();
- if (i == 42)
- continue;
- };
- return i;
-}
diff --git a/clang/test/CodeGen/writable-strings.c b/clang/test/CodeGen/writable-strings.c
deleted file mode 100644
index cde64aa5e6d3..000000000000
--- a/clang/test/CodeGen/writable-strings.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -emit-llvm -o %t -fwritable-strings %s
-
-int main() {
- char *str = "abc";
- str[0] = '1';
- printf("%s", str);
-}
-
diff --git a/clang/test/CodeGen/x86-inline-asm.c b/clang/test/CodeGen/x86-inline-asm.c
deleted file mode 100644
index 7bdea9733823..000000000000
--- a/clang/test/CodeGen/x86-inline-asm.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang %s -triple=i686-pc-linux-gnu -emit-llvm -o - > %t1
-// RUN: grep "ax" %t1 &&
-// RUN: grep "bx" %t1 &&
-// RUN: grep "cx" %t1 &&
-// RUN: grep "dx" %t1 &&
-// RUN: grep "di" %t1 &&
-// RUN: grep "si" %t1 &&
-// RUN: grep "st" %t1 &&
-// RUN: grep "st(1)" %t1
-
-void f() {
- int d1, d2;
- asm ("" : "=a" (d1), "=b" (d2) :
- "c" (0), "d" (0), "S" (0), "D" (0), "t" (0), "u" (0));
-}
diff --git a/clang/test/CodeGenObjC/constant-strings.m b/clang/test/CodeGenObjC/constant-strings.m
deleted file mode 100644
index 879f91a43248..000000000000
--- a/clang/test/CodeGenObjC/constant-strings.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fnext-runtime -emit-llvm -o %t %s
-
-id a = @"Hello World!";
-
diff --git a/clang/test/CodeGenObjC/dot-syntax-1.m b/clang/test/CodeGenObjC/dot-syntax-1.m
deleted file mode 100644
index cd12d85c0ecc..000000000000
--- a/clang/test/CodeGenObjC/dot-syntax-1.m
+++ /dev/null
@@ -1,264 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-#include <stdio.h>
-
-@interface Root
--(id) alloc;
--(id) init;
-@end
-
-// Property above methods...
-
-@interface Top0 : Root
-@property(getter=_getX,setter=_setX:) int x;
-@end
-
-@interface Bot0 : Top0
--(int) x;
--(void) setX: (int) arg;
-@end
-
-@implementation Top0
--(int) _getX {
- printf("-[ Top0 _getX ]\n");
- return 0;
-}
--(void) _setX: (int) arg {
- printf("-[ Top0 _setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot0
--(int) x {
- printf("-[ Bot0 _getX ]\n");
- return 0;
-}
--(void) setX: (int) arg {
- printf("-[ Bot0 _setX: %d ]\n", arg);
-}
-@end
-
-// Methods above property...
-
-@interface Top1 : Root
--(int) x;
--(void) setX: (int) arg;
-@end
-
-@interface Bot1 : Top1
-@property(getter=_getX,setter=_setX:) int x;
-@end
-
-@implementation Top1
--(int) x {
- printf("-[ Top1 x ]\n");
- return 0;
-}
--(void) setX: (int) arg {
- printf("-[ Top1 setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot1
--(int) _getX {
- printf("-[ Bot1 _getX ]\n");
- return 0;
-}
--(void) _setX: (int) arg {
- printf("-[ Bot1 _setX: %d ]\n", arg);
-}
-@end
-
-// Mixed setter & getter (variant 1)
-
-@interface Top2 : Root
--(int) x;
--(void) _setX: (int) arg;
-@end
-
-@interface Bot2 : Top2
-@property(getter=_getX,setter=_setX:) int x;
-@end
-
-@implementation Top2
--(int) x {
- printf("-[ Top2 x ]\n");
- return 0;
-}
--(void) _setX: (int) arg {
- printf("-[ Top2 _setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot2
--(int) _getX {
- printf("-[ Bot2 _getX ]\n");
- return 0;
-}
--(void) setX: (int) arg {
- printf("-[ Bot2 setX: %d ]\n", arg);
-}
-@end
-
-// Mixed setter & getter (variant 2)
-
-@interface Top3 : Root
--(int) _getX;
--(void) setX: (int) arg;
-@end
-
-@interface Bot3 : Top3
-@property(getter=_getX,setter=_setX:) int x;
-@end
-
-@implementation Top3
--(int) _getX {
- printf("-[ Top3 _getX ]\n");
- return 0;
-}
--(void) setX: (int) arg {
- printf("-[ Top3 setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot3
--(int) x {
- printf("-[ Bot3 x ]\n");
- return 0;
-}
--(void) _setX: (int) arg {
- printf("-[ Bot3 _setX: %d ]\n", arg);
-}
-@end
-
-// Mixed setter & getter (variant 3)
-
-@interface Top4 : Root
-@property(getter=_getX,setter=_setX:) int x;
-@end
-
-@interface Bot4 : Top4
--(int) _getX;
--(void) setX: (int) arg;
-@end
-
-@implementation Top4
--(int) x {
- printf("-[ Top4 x ]\n");
- return 0;
-}
--(void) _setX: (int) arg {
- printf("-[ Top4 _setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot4
--(int) _getX {
- printf("-[ Bot4 _getX ]\n");
- return 0;
-}
--(void) setX: (int) arg {
- printf("-[ Bot4 setX: %d ]\n", arg);
-}
-@end
-
-// Mixed setter & getter (variant 4)
-
-@interface Top5 : Root
-@property(getter=_getX,setter=_setX:) int x;
-@end
-
-@interface Bot5 : Top5
--(int) x;
--(void) _setX: (int) arg;
-@end
-
-@implementation Top5
--(int) _getX {
- printf("-[ Top5 _getX ]\n");
- return 0;
-}
--(void) setX: (int) arg {
- printf("-[ Top5 setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot5
--(int) x {
- printf("-[ Bot5 x ]\n");
- return 0;
-}
--(void) _setX: (int) arg {
- printf("-[ Bot5 _setX: %d ]\n", arg);
-}
-@end
-
-// Mixed level calls (variant 1)
-
-@interface Top6 : Root
--(int) x;
-@end
-
-@interface Bot6 : Top6
--(void) setX: (int) arg;
-@end
-
-@implementation Top6
--(int) x {
- printf("-[ Top6 x ]\n");
- return 0;
-}
-@end
-
-@implementation Bot6
--(void) setX: (int) arg {
- printf("-[ Bot5 setX: %d ]\n", arg);
-}
-@end
-
-// Mixed level calls (variant 1)
-
-@interface Top7 : Root
--(void) setX: (int) arg;
-@end
-
-@interface Bot7 : Top7
--(int) x;
-@end
-
-@implementation Top7
--(void) setX: (int) arg {
- printf("-[ Top7 setX: %d ]\n", arg);
-}
-@end
-
-@implementation Bot7
--(int) x {
- printf("-[ Bot7 x ]\n");
- return 0;
-}
-@end
-
-//
-
-// FIXME: Two more (thats it?) interesting cases. Method access on
-// getter w/o setter and method access on setter w/o getter.
-
-int main() {
-#define test(N) { \
- Bot##N *ob = [[Bot##N alloc] init]; \
- int x = ob.x; \
- ob.x = 10; }
-
- test(0);
- test(1);
- test(2);
- test(3);
- test(4);
- test(5);
- // test(6);
- // test(7);
-
- return 0;
-}
-
diff --git a/clang/test/CodeGenObjC/dot-syntax.m b/clang/test/CodeGenObjC/dot-syntax.m
deleted file mode 100644
index 39e9c49309c0..000000000000
--- a/clang/test/CodeGenObjC/dot-syntax.m
+++ /dev/null
@@ -1,98 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-#include <stdio.h>
-
-@interface Root
--(id) alloc;
--(id) init;
-@end
-
-typedef struct {
- float x, y, z[2];
-} S;
-
-@interface A : Root {
- int myX;
- // __complex myY;
- S myZ;
-}
-
-@property int x;
-//@property __complex int y;
-@property S z;
-@end
-
-@implementation A
--(int) x {
- printf("-[A x] = %d\n", myX);
- return myX;
-}
--(void) setX: (int) arg {
- myX = arg;
- printf("-[A setX: %d]\n", myX);
-}
-
-// FIXME: Add back
-#if 0
--(__complex int) y {
- printf("-[A y] = (%d, %d)\n", __real myY, __imag myY);
- return myY;
-}
--(void) setY: (__complex int) arg {
- myY = arg;
- printf("-[A setY: (%d, %d)]\n", __real myY, __imag myY);
-}
-#endif
-
--(S) z {
- printf("-[A z] = { %f, %f, { %f, %f } }\n",
- myZ.x, myZ.y, myZ.z[0], myZ.z[1]);
- return myZ;
-}
--(void) setZ: (S) arg {
- myZ = arg;
- printf("-[A setZ: { %f, %f, { %f, %f } } ]\n",
- myZ.x, myZ.y, myZ.z[0], myZ.z[1]);
-}
-
-@end
-
-int main() {
-#define SWAP(T,a,b) { T a_tmp = a; a = b; b = a_tmp; }
- A *a = [[A alloc] init];
- A *b = [[A alloc] init];
- int a0 = 23;
- // __complex a1 = 25 + 10i;
- S a2 = { 246, 458, {275, 12} };
- int b0 = 42673;
- // __complex b1 = 15 + 13i;
- S b2 = { 26, 2, {367, 13} };
-
- a.x = a0;
- // a.y = a1;
- a.z = a2;
-
- a.x += a0;
- // a.y += a1;
- // Yay, no compound assign of structures. A GCC extension in the
- // works, perhaps?
-
- b.x = b0;
- // b.y = b1;
- b.z = b2;
-
- int x0 = (b.x = b0);
- printf("(b.x = b0): %d\n", x0);
-
- // int x1 = __real (b.y = b1);
- // printf("__real (b.y = b1) = %d\n", x1);
-
- float x2 = (b.z = b2).x;
- printf("(b.z = b2).x: %f\n", x2);
-
- SWAP(int, a.x, b.x);
- // SWAP(__complex int, a.y, b.y);
- SWAP(S, a.z, b.z);
-
- return 0;
-}
diff --git a/clang/test/CodeGenObjC/hidden.m b/clang/test/CodeGenObjC/hidden.m
deleted file mode 100644
index 2cc3aefde49c..000000000000
--- a/clang/test/CodeGenObjC/hidden.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-__attribute__((visibility("hidden")))
-@interface Hidden
-+(void) bar;
-@end
-
-@implementation Hidden
-+(void) bar {}
-@end
-
-__attribute__((visibility("default")))
-@interface Default
-+(void) bar;
-@end
-
-@implementation Default
-+(void) bar {}
-@end
diff --git a/clang/test/CodeGenObjC/link-errors.m b/clang/test/CodeGenObjC/link-errors.m
deleted file mode 100644
index 8e0a0ecde945..000000000000
--- a/clang/test/CodeGenObjC/link-errors.m
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: clang -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: grep '.lazy_reference .objc_class_name_A' %t | count 1 &&
-// RUN: grep '.lazy_reference .objc_class_name_Unknown' %t | count 1 &&
-// RUN: grep '.lazy_reference .objc_class_name_Protocol' %t | count 1 &&
-// RUN: clang -DWITH_IMPL -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: grep '.lazy_reference .objc_class_name_Root' %t | count 1
-
-@interface Root
--(id) alloc;
--(id) init;
-@end
-
-@protocol P;
-
-@interface A : Root
-@end
-
-@interface A (Category)
-+(void) foo;
-@end
-
-#ifdef WITH_IMPL
-@implementation A
-@end
-#endif
-
-@interface Unknown
-+test;
-@end
-
-
-int main() {
- id x = @protocol(P);
- [ A alloc ];
- [ A foo ];
- [ Unknown test ];
- return 0;
-}
-
diff --git a/clang/test/CodeGenObjC/message-arrays.m b/clang/test/CodeGenObjC/message-arrays.m
deleted file mode 100644
index 55b5d9b84ef0..000000000000
--- a/clang/test/CodeGenObjC/message-arrays.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s
-
-void f0(id a) {
- // This should have an implicit cast
- [ a print: "hello" ];
-}
-
-@interface A
--(void) m: (int) arg0, ...;
-@end
-
-int f1(A *a) {
- // This should also get an implicit cast (for the vararg)
- [a m: 1, "test"];
-}
diff --git a/clang/test/CodeGenObjC/messages-2.m b/clang/test/CodeGenObjC/messages-2.m
deleted file mode 100644
index dcea93b8616d..000000000000
--- a/clang/test/CodeGenObjC/messages-2.m
+++ /dev/null
@@ -1,139 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-#include <stdio.h>
-
-@interface Root
-@end
-
-typedef struct {
- int x, y, z[10];
-} MyPoint;
-typedef struct {
- float width, height;
-} MySize;
-
-@interface A : Root
-+(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3;
-+(float) returnAFloat;
-+(double) returnADouble;
-+(MyPoint) returnAPoint;
-+(void) printThisSize: (MySize) arg0;
-+(MySize) returnASize;
-
--(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3;
--(float) returnAFloat;
--(double) returnADouble;
--(MyPoint) returnAPoint;
--(void) printThisSize: (MySize) arg0;
--(MySize) returnASize;
-@end
-@interface B : A
-@end
-
-@implementation A
-+(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
- printf("(CLASS) theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n",
- arg0, arg1, arg2, arg3.x, arg3.y);
-}
-+(float) returnAFloat {
- return 15.;
-}
-+(double) returnADouble {
- return 25.;
-}
-+(MyPoint) returnAPoint {
- MyPoint x = { 35, 45 };
- return x;
-}
-+(void) printThisSize: (MySize) arg0 {
- printf("(CLASS) theSize: { %f, %f }\n",
- arg0.width, arg0.height);
-}
-+(MySize) returnASize {
- MySize x = { 32, 44 };
- return x;
-}
-
--(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
- printf("theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n",
- arg0, arg1, arg2, arg3.x, arg3.y);
-}
--(float) returnAFloat {
- return 10.;
-}
--(double) returnADouble {
- return 20.;
-}
--(MyPoint) returnAPoint {
- MyPoint x = { 30, 40 };
- return x;
-}
--(void) printThisSize: (MySize) arg0 {
- printf("theSize: { %f, %f }\n",
- arg0.width, arg0.height);
-}
--(MySize) returnASize {
- MySize x = { 22, 34 };
- return x;
-}
-@end
-
-@implementation B
-+(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
- arg3.x *= 2;
- arg3.y *= 2;
- [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ];
-}
-+(void) printThisSize: (MySize) arg0 {
- arg0.width *= 2;
- arg0.height *= 2;
- [ super printThisSize: arg0 ];
-}
-+(float) returnAFloat {
- return [ super returnAFloat ]*2;
-}
-+(double) returnADouble {
- return [ super returnADouble ]*2;
-}
-+(MyPoint) returnAPoint {
- MyPoint x = [ super returnAPoint ];
- x.x *= 2;
- x.y *= 2;
- return x;
-}
-+(MySize) returnASize {
- MySize x = [ super returnASize ];
- x.width *= 2;
- x.height *= 2;
- return x;
-}
-
--(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 {
- arg3.x *= 2;
- arg3.y *= 2;
- [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ];
-}
--(void) printThisSize: (MySize) arg0 {
- arg0.width *= 2;
- arg0.height *= 2;
- [ super printThisSize: arg0 ];
-}
--(float) returnAFloat {
- return [ super returnAFloat ]*2;
-}
--(double) returnADouble {
- return [ super returnADouble ]*2;
-}
--(MyPoint) returnAPoint {
- MyPoint x = [ super returnAPoint ];
- x.x *= 2;
- x.y *= 2;
- return x;
-}
--(MySize) returnASize {
- MySize x = [ super returnASize ];
- x.width *= 2;
- x.height *= 2;
- return x;
-}
-@end
diff --git a/clang/test/CodeGenObjC/messages.m b/clang/test/CodeGenObjC/messages.m
deleted file mode 100644
index fab3c5d85808..000000000000
--- a/clang/test/CodeGenObjC/messages.m
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-typedef struct {
- int x;
- int y;
- int z[10];
-} MyPoint;
-
-void f0(id a) {
- int i;
- MyPoint pt = { 1, 2};
-
- [a print0];
- [a print1: 10];
- [a print2: 10 and: "hello" and: 2.2];
- [a takeStruct: pt ];
-
- void *s = @selector(print0);
- for (i=0; i<2; ++i)
- [a performSelector:s];
-}
diff --git a/clang/test/CodeGenObjC/predefined-expr-in-method.m b/clang/test/CodeGenObjC/predefined-expr-in-method.m
deleted file mode 100644
index d835ed827b33..000000000000
--- a/clang/test/CodeGenObjC/predefined-expr-in-method.m
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-@interface A
-@end
-@implementation A
-+(void) foo {
- printf("__func__: %s\n", __func__);
- printf("__FUNCTION__: %s\n", __FUNCTION__);
- printf("__PRETTY_FUNCTION__: %s\n", __PRETTY_FUNCTION__);
- return 0;
-}
-@end
-
-int main() {
- [A foo];
- return 0;
-}
diff --git a/clang/test/CodeGenObjC/property.m b/clang/test/CodeGenObjC/property.m
deleted file mode 100644
index 4598aaa79aad..000000000000
--- a/clang/test/CodeGenObjC/property.m
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang -fnext-runtime --emit-llvm -o %t %s
-
-#include <stdio.h>
-
-@interface Root
--(id) alloc;
--(id) init;
-@end
-
-@interface A : Root {
- int x;
- id ob0, ob1, ob2, ob3, ob4;
-}
-@property int x;
-@property int y;
-@property int z;
-@property(readonly) int ro;
-@property(assign) id ob0;
-@property(retain) id ob1;
-@property(copy) id ob2;
-@property(retain, nonatomic) id ob3;
-@property(copy, nonatomic) id ob4;
-@end
-
-@implementation A
-@dynamic x;
-@synthesize x;
-@synthesize y = x;
-@synthesize z = x;
-@synthesize ro = x;
-@synthesize ob0;
-@synthesize ob1;
-@synthesize ob2;
-@synthesize ob3;
-@synthesize ob4;
--(int) y {
- return x + 1;
-}
--(void) setZ: (int) arg {
- x = arg - 1;
-}
-@end
-
-@interface A (Cat)
-@property int dyn;
-@end
-
-@implementation A (Cat)
--(int) dyn {
- return 10;
-}
-@end
diff --git a/clang/test/CodeGenObjC/runtime-fns.m b/clang/test/CodeGenObjC/runtime-fns.m
deleted file mode 100644
index f132b5420f5e..000000000000
--- a/clang/test/CodeGenObjC/runtime-fns.m
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: grep -e "^de.*objc_msgSend[0-9]*(" %t | count 1 &&
-// RUN: clang -DWITHDEF -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: grep -e "^de.*objc_msgSend[0-9]*(" %t | count 1
-
-id objc_msgSend(int x);
-
-@interface A @end
-
-@implementation A
--(void) f0 {
- objc_msgSend(12);
-}
-
--(void) hello {
-}
-@end
-
-void f0(id x) {
- [x hello];
-}
-
-#ifdef WITHDEF
-// This isn't a very good send function.
-id objc_msgSend(int x) {
- return 0;
-}
-#endif
diff --git a/clang/test/Coverage/ast-printing.c b/clang/test/Coverage/ast-printing.c
deleted file mode 100644
index 0fc8b9f83381..000000000000
--- a/clang/test/Coverage/ast-printing.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang --fsyntax-only %s &&
-// RUN: clang --ast-print %s &&
-// RUN: clang --ast-dump %s
-
-#include "c-language-features.inc"
diff --git a/clang/test/Coverage/ast-printing.m b/clang/test/Coverage/ast-printing.m
deleted file mode 100644
index c53efac0d718..000000000000
--- a/clang/test/Coverage/ast-printing.m
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang --fsyntax-only %s &&
-// RUN: clang --ast-print %s &&
-// RUN: clang --ast-dump %s
-
-#include "objc-language-features.inc"
diff --git a/clang/test/Coverage/c-language-features.inc b/clang/test/Coverage/c-language-features.inc
deleted file mode 100644
index 624f89a355d6..000000000000
--- a/clang/test/Coverage/c-language-features.inc
+++ /dev/null
@@ -1,139 +0,0 @@
-//-*- C -*-
-
-/* This is a
- multiline comment */
-
-// Intended to exercise all syntactic parts of the C language.
-
-int g0;
-int g1, g2;
-
-struct s0;
-
-struct s0 {
- int x;
-};
-
-int g3 = 10;
-
-__asm("");
-
-typedef int td0;
-
-td0 g4;
-
-enum e0 {
- ec0
-};
-
-static void f0(int x) {
-}
-
-inline void f0_0(int x) {
- ;
-}
-
-extern void f0_1(int x) {
-}
-
-void f1(int, ...);
-
-// Statements.
-void f2() {
- for (;;) {
- break;
- continue;
- }
-
- while (0) {
- }
-
- do {
- } while (0);
-
- void *label = &&theif;
- goto *label;
-
- goto theif;
-theif:
- if (0) {
- ;
- } else if (0) {
- } else {
- }
-
- switch(0) {
- case 0:
- case 1 ... 2:
- break;
- default:
- break;
- }
-
- asm ("nop");
-
- return;
-}
-
-// Expressions.
-
-#include <stdarg.h>
-
-typedef struct ipair {
- int first, second;
-} ipair;
-
-void f4(int a0, int a1, int a2, va_list ap) {
- int t0 = a0 ? a1 : a2;
- float t1 = (float) a0;
- ipair t2 = {1, 2};
- int t3 = sizeof(ipair);
- ipair t4;
- t4 = (ipair) {1, 2};
- extern int g(int);
- int t5 = g(a0);
- int t6 = t4.first;
- int t7[10];
- int t8 = t7[a0];
- t8++;
- const char *t9 = __FUNCTION__;
- char t10 = 'x';
- int t11 = __builtin_offsetof(ipair, first);
- int t12 = __builtin_types_compatible_p(ipair, int);
- int t12_0 = __builtin_classify_type(t0);
- int t12_1 = __builtin_classify_type(t1);
- int t12_2 = __builtin_classify_type(t2);
- int t13 = va_arg(ap, int);
- va_list t13_0;
- va_copy(t13_0, ap);
- int t14 = __extension__(t13);
- int t15 = +t13;
- unsigned t16 = t14 ^ t15;
- int t17 = t14 % t15;
- int t17_0 = t16 % t16;
- float t18;
- int t19 = t18 ? 0 : 1;
- char *t20; ++t20; --t20;
- float t21; ++t21; --t21;
- double t22; ++t22; --t22;
- long double t23; ++t23; --t23;
- int t24 = !t19;
- int t25 = __real t24;
- int t26 = __imag t24;
- const char *t27 = t9;
- t27 += (unsigned char) 0xFF;
- t27 += (signed char) 0xFF;
-
- struct { char f0[10]; } *t28;
- int t29 = t28 - t28;
-}
-
-// Extended vectors
-
-typedef __attribute__((ext_vector_type(4))) float float4;
-
-void f5() {
- float4 t0 = (float4) { 0, 1, 2, 3 };
- float4 t1 = t0;
- t0.lo.e = t1.hi.x;
-}
diff --git a/clang/test/Coverage/codegen-gnu.m b/clang/test/Coverage/codegen-gnu.m
deleted file mode 100644
index 63cd46850524..000000000000
--- a/clang/test/Coverage/codegen-gnu.m
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fgnu-runtime -emit-llvm -o %t %s &&
-// RUN: clang -g -fgnu-runtime -emit-llvm -o %t %s
-// XFAIL
-
-#include "objc-language-features.inc"
diff --git a/clang/test/Coverage/codegen-next.m b/clang/test/Coverage/codegen-next.m
deleted file mode 100644
index 74df555d1084..000000000000
--- a/clang/test/Coverage/codegen-next.m
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: clang -g -fnext-runtime -emit-llvm -o %t %s
-// XFAIL
-
-#include "objc-language-features.inc"
diff --git a/clang/test/Coverage/codegen.c b/clang/test/Coverage/codegen.c
deleted file mode 100644
index 8c9ce02d7cf4..000000000000
--- a/clang/test/Coverage/codegen.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -emit-llvm -o %t %s &&
-// RUN: clang -emit-llvm-bc -o %t %s &&
-// RUN: clang -g -emit-llvm-bc -o %t %s
-
-#include "c-language-features.inc"
diff --git a/clang/test/Coverage/html-diagnostics.c b/clang/test/Coverage/html-diagnostics.c
deleted file mode 100644
index 75d4e067fc6d..000000000000
--- a/clang/test/Coverage/html-diagnostics.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: rm -rf %t &&
-// RUN: clang --html-diags=%t -checker-simple %s
-
-void f0(int x) {
- int *p = &x;
-
- if (x > 10) {
- if (x == 22)
- p = 0;
- }
-
- *p = 10;
-}
-
-
diff --git a/clang/test/Coverage/html-print.c b/clang/test/Coverage/html-print.c
deleted file mode 100644
index 7ade9c6237bb..000000000000
--- a/clang/test/Coverage/html-print.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-html -o %t %s
-
-#include "c-language-features.inc"
diff --git a/clang/test/Coverage/objc-language-features.inc b/clang/test/Coverage/objc-language-features.inc
deleted file mode 100644
index 87177cf243cd..000000000000
--- a/clang/test/Coverage/objc-language-features.inc
+++ /dev/null
@@ -1,67 +0,0 @@
-//-*- ObjC -*-
-
-@protocol P0;
-
-@protocol P1
--(void) fm0;
-@end
-
-@class B;
-
-@interface Root
-@end
-
-@interface A : Root <P1> {
- int iv0;
- B *iv1;
-}
-
-@property(assign,readonly) int p0;
-@property(assign,nonatomic,readwrite) int p1;
-@property(copy) id p2;
-@property(retain) id p3;
-@property(assign, getter=getme, setter=setme:) id p4;
-@end
-
-@implementation A
-@dynamic p0;
-@synthesize p1 = iv0;
-+(void) fm0 {
- [super fm0];
-}
--(void) im0 {
- [super im0];
-}
--(void) im1: (int) x, ... {
-}
-@end
-
-@implementation C : A
-@end
-
-@interface A (Cat)
-@end
-
-@implementation A (Cat)
-@end
-
-int f0(id x) {
- @synchronized(x) {
- }
-
- @try {
- @throw x;
- } @catch(A *e) {
- @throw;
- } @finally {
- ;
- }
-
- for (id y in x) {
- break;
- }
-}
-
-struct s0 {
- @defs(A);
-};
diff --git a/clang/test/Coverage/parse-callbacks.c b/clang/test/Coverage/parse-callbacks.c
deleted file mode 100644
index f65d9513d4bb..000000000000
--- a/clang/test/Coverage/parse-callbacks.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang --parse-noop %s &&
-// RUN: clang --parse-print-callbacks %s
-
-#include "c-language-features.inc"
diff --git a/clang/test/Coverage/parse-callbacks.m b/clang/test/Coverage/parse-callbacks.m
deleted file mode 100644
index efce13e95861..000000000000
--- a/clang/test/Coverage/parse-callbacks.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang --parse-noop %s &&
-// RUN: clang --parse-print-callbacks %s
-
-#include "objc-language-features.inc"
diff --git a/clang/test/Coverage/serialize.c b/clang/test/Coverage/serialize.c
deleted file mode 100644
index 5c81f31f5d99..000000000000
--- a/clang/test/Coverage/serialize.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only --serialize %s
-// XFAIL
-
-#include "c-language-features.inc"
diff --git a/clang/test/Coverage/serialize.m b/clang/test/Coverage/serialize.m
deleted file mode 100644
index 8ad330a71d6a..000000000000
--- a/clang/test/Coverage/serialize.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only --serialize %s
-// XFAIL
-
-#include "objc-language-features.inc"
diff --git a/clang/test/Coverage/targets.c b/clang/test/Coverage/targets.c
deleted file mode 100644
index 669fe841fe3a..000000000000
--- a/clang/test/Coverage/targets.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -g -triple i686-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -g -triple i686-pc-linux-gnu -emit-llvm -o %t %s &&
-// RUN: clang -g -triple i686-unknown-dragonfly -emit-llvm -o %t %s &&
-// RUN: clang -g -triple i686-unknown-win32 -emit-llvm -o %t %s &&
-// RUN: clang -g -triple i686-apple-darwin9 -emit-llvm -o %t %s &&
-// RUN: clang -g -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -g -triple x86_64-pc-linux-gnu -emit-llvm -o %t %s &&
-// RUN: clang -g -triple x86_64-apple-darwin9 -emit-llvm -o %t %s &&
-// RUN: clang -g -triple ppc-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -g -triple ppc-apple-darwin9 -emit-llvm -o %t %s &&
-// RUN: clang -g -triple ppc64-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -g -triple ppc64-apple-darwin9 -emit-llvm -o %t %s &&
-// RUN: clang -g -triple armv6-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -g -triple armv6-apple-darwin9 -emit-llvm -o %t %s &&
-// RUN: clang -g -triple sparc-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: clang -g -triple sparc-unknown-solaris -emit-llvm -o %t %s &&
-// RUN: clang -g -triple pic16-unknown-unknown -emit-llvm -o %t %s &&
-// RUN: true
diff --git a/clang/test/Coverage/verbose.c b/clang/test/Coverage/verbose.c
deleted file mode 100644
index 6157bad395fe..000000000000
--- a/clang/test/Coverage/verbose.c
+++ /dev/null
@@ -1 +0,0 @@
-// RUN: clang -fsyntax-only -v %s
diff --git a/clang/test/Driver/env-include-paths.c b/clang/test/Driver/env-include-paths.c
deleted file mode 100644
index ced24311c009..000000000000
--- a/clang/test/Driver/env-include-paths.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -fsyntax-only -verify -DAS_SOURCE %s &&
-// RUN: env CPATH="" clang -fsyntax-only -verify -DAS_SOURCE %s &&
-// RUN: env CPATH="xyz:xyz" clang -fsyntax-only -verify -DAS_SOURCE %s &&
-// RUN: cd $(dirname %s) &&
-// RUN: env CPATH="xyz::xyz" clang -fsyntax-only -verify -DSHOULD_FIND -DAS_SOURCE %s &&
-// RUN: env CPATH="../Driver" clang -fsyntax-only -verify -DSHOULD_FIND -DAS_SOURCE %s
-
-#ifdef AS_SOURCE
-#undef AS_SOURCE
-
-#define AS_INCLUDE
-
-#ifdef SHOULD_FIND
-#include <env-include-paths.c>
-#else
-/* expected-error {{file not found}} */ #include <env-include-paths.c>
-#endif
-
-#undef AS_INCLUDE
-
-#endif
-
-#ifdef AS_INCLUDE
-
-/* expected-warning {{Hello}} */ #warning "Hello"
-
-#endif
diff --git a/clang/test/Driver/rewrite-macros.c b/clang/test/Driver/rewrite-macros.c
deleted file mode 100644
index deb54f4297f5..000000000000
--- a/clang/test/Driver/rewrite-macros.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -verify --rewrite-macros -o %t %s &&
-
-#define A(a,b) a ## b
-
-// RUN: grep '12 */\*A\*/ /\*(1,2)\*/' %t &&
-A(1,2)
-
-// RUN: grep '/\*_Pragma("mark")\*/' %t &&
-_Pragma("mark")
-
-// RUN: grep "//#warning eek" %t &&
-/* expected-warning {{#warning eek}} */ #warning eek
-
-// RUN: grep "//#pragma mark mark" %t &&
-#pragma mark mark
-
-// RUN: true
-
diff --git a/clang/test/Lexer/11-27-2007-FloatLiterals.c b/clang/test/Lexer/11-27-2007-FloatLiterals.c
deleted file mode 100644
index c0e21546a851..000000000000
--- a/clang/test/Lexer/11-27-2007-FloatLiterals.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -emit-llvm -o - | grep 0x3BFD83C940000000 | count 2 &&
-// RUN: clang %s -emit-llvm -o - | grep 2.000000e+32 | count 2
-
-float F = 1e-19f;
-double D = 2e32;
-float F2 = 01e-19f;
-double D2 = 02e32;
diff --git a/clang/test/Lexer/badstring_in_if0.c b/clang/test/Lexer/badstring_in_if0.c
deleted file mode 100644
index 714f89b38698..000000000000
--- a/clang/test/Lexer/badstring_in_if0.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -E %s 2>&1 | not grep error
-#if 0
-
- "
-
- '
-
-#endif
diff --git a/clang/test/Lexer/block_cmt_end.c b/clang/test/Lexer/block_cmt_end.c
deleted file mode 100644
index 347f78f5e8d6..000000000000
--- a/clang/test/Lexer/block_cmt_end.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- RUN: clang -E -trigraphs %s | grep bar &&
- RUN: clang -E -trigraphs %s | grep foo &&
- RUN: clang -E -trigraphs %s | not grep abc &&
- RUN: clang -E -trigraphs %s | not grep xyz &&
- RUN: clang -fsyntax-only -trigraphs -verify %s
-*/
-
-// This is a simple comment, /*/ does not end a comment, the trailing */ does.
-int i = /*/ */ 1;
-
-/* abc
-
-next comment ends with normal escaped newline:
-*/
-
-/* expected-warning {{escaped newline}} expected-warning {{backslash and newline}} *\
-/
-
-bar
-
-/* xyz
-
-next comment ends with a trigraph escaped newline: */
-
-/* expected-warning {{escaped newline between}} expected-warning {{backslash and newline separated by space}} expected-warning {{trigraph ends block comment}} *??/
-/
-
-foo /* expected-error {{expected '=', ',', ';', 'asm', or '__attribute__' after declarator}} */
-
diff --git a/clang/test/Lexer/c90.c b/clang/test/Lexer/c90.c
deleted file mode 100644
index 4bbddaf38b4d..000000000000
--- a/clang/test/Lexer/c90.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* RUN: clang -std=c90 -fsyntax-only %s -verify -pedantic-errors
- */
-
-enum { cast_hex = (long) (
- 0x0p-1 /* expected-error {{hexadecimal floating constants are a C99 feature}} */
- ) };
diff --git a/clang/test/Lexer/constants.c b/clang/test/Lexer/constants.c
deleted file mode 100644
index 6d7ca19cdb92..000000000000
--- a/clang/test/Lexer/constants.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* RUN: clang -fsyntax-only -verify %s
- */
-
-int x = 000000080; /* expected-error {{invalid digit}} */
-
-int y = 0000\
-00080; /* expected-error {{invalid digit}} */
-
diff --git a/clang/test/Lexer/cxx0x_keyword.cpp b/clang/test/Lexer/cxx0x_keyword.cpp
deleted file mode 100644
index d55649cecc7d..000000000000
--- a/clang/test/Lexer/cxx0x_keyword.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang -fsyntax-only -verify -std=c++0x %s 2>&1
-int static_assert; /* expected-error {{expected identifier or '('}} */
diff --git a/clang/test/Lexer/cxx0x_keyword_as_cxx98.cpp b/clang/test/Lexer/cxx0x_keyword_as_cxx98.cpp
deleted file mode 100644
index 6700dcb1827e..000000000000
--- a/clang/test/Lexer/cxx0x_keyword_as_cxx98.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang %s -fsyntax-only
-int static_assert;
diff --git a/clang/test/Lexer/digraph.c b/clang/test/Lexer/digraph.c
deleted file mode 100644
index 9683ee4f9981..000000000000
--- a/clang/test/Lexer/digraph.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -fsyntax-only -verify < %s
-
-%:include <stdio.h>
-
- %:ifndef BUFSIZE
- %:define BUFSIZE 512
- %:endif
-
- void copy(char d<::>, const char s<::>, int len)
- <%
- while (len-- >= 0)
- <%
- d<:len:> = s<:len:>;
- %>
- %>
diff --git a/clang/test/Lexer/escape_newline.c b/clang/test/Lexer/escape_newline.c
deleted file mode 100644
index 2e4b7cd7cd89..000000000000
--- a/clang/test/Lexer/escape_newline.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E -trigraphs %s | grep -- ' ->' &&
-// RUN: clang -E -trigraphs %s 2>&1 | grep 'backslash and newline separated by space' &&
-// RUN: clang -E -trigraphs %s 2>&1 | grep 'trigraph converted'
-
-// This is an ugly way to spell a -> token.
- -??/
->
diff --git a/clang/test/Lexer/multiple-include.c b/clang/test/Lexer/multiple-include.c
deleted file mode 100644
index ccea3ff7745a..000000000000
--- a/clang/test/Lexer/multiple-include.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-#ifndef XVID_AUTO_INCLUDE
-
-#define XVID_AUTO_INCLUDE
-#define FUNC_H H_Pass_16_C
-#include "multiple-include.c"
-
-#define FUNC_H H_Pass_8_C
-
-#include "multiple-include.c"
-#undef XVID_AUTO_INCLUDE
-
-typedef void ff();
-typedef struct { ff *a;} S;
-
-S s = { H_Pass_8_C };
-
-#endif
-
-#if defined(XVID_AUTO_INCLUDE) && defined(REFERENCE_CODE)
-#elif defined(XVID_AUTO_INCLUDE) && !defined(REFERENCE_CODE)
-
-static void FUNC_H(){};
-#undef FUNC_H
-
-#endif
diff --git a/clang/test/Lexer/number.c b/clang/test/Lexer/number.c
deleted file mode 100644
index bafbc022d5e8..000000000000
--- a/clang/test/Lexer/number.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-float X = 1.17549435e-38F;
-float Y = 08.123456;
-
-// PR2252
-#if -0x8000000000000000 // should not warn.
-#endif
-
diff --git a/clang/test/Lexer/numeric-literal-trash.c b/clang/test/Lexer/numeric-literal-trash.c
deleted file mode 100644
index 243825a53638..000000000000
--- a/clang/test/Lexer/numeric-literal-trash.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* RUN: clang -fsyntax-only -verify %s
- */
-# define XRECORD(x, c_name) e##c (x, __LINE__)
-
-
-
-
-
-
- void x() {
-
-XRECORD (XRECORD (1, 1), 1);
- }
diff --git a/clang/test/Lexer/pragma-mark.c b/clang/test/Lexer/pragma-mark.c
deleted file mode 100644
index 388fef55755d..000000000000
--- a/clang/test/Lexer/pragma-mark.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-// Lexer diagnostics shouldn't be included in #pragma mark.
-#pragma mark Mike's world
-_Pragma("mark foo ' bar")
-
-#define X(S) _Pragma(S)
-X("mark foo ' bar")
-
-int i;
-
diff --git a/clang/test/Lexer/preprocess-compat.c b/clang/test/Lexer/preprocess-compat.c
deleted file mode 100644
index e895975477f7..000000000000
--- a/clang/test/Lexer/preprocess-compat.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -E -x c -o %t.i %s
-// RUN: gcc -fsyntax-only %t.i
-
diff --git a/clang/test/Lexer/rdr-6096838.c b/clang/test/Lexer/rdr-6096838.c
deleted file mode 100644
index 1b56a910db71..000000000000
--- a/clang/test/Lexer/rdr-6096838.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* RUN: clang -fsyntax-only -verify %s &&
- * RUN: clang -std=gnu89 -fsyntax-only -verify %s &&
- * RUN: clang -DPEDANTIC -pedantic -std=gnu89 -fsyntax-only -verify %s
- */
-
-#ifdef PEDANTIC
-
-long double d = 0x0.0000003ffffffff00000p-16357L; /* expected-warning {{ hexadecimal floating constants are a C99 feature }} */
-
-#else
-
-long double d = 0x0.0000003ffffffff00000p-16357L;
-
-#endif
diff --git a/clang/test/Lexer/unknown-char.c b/clang/test/Lexer/unknown-char.c
deleted file mode 100644
index 8bdfe60553de..000000000000
--- a/clang/test/Lexer/unknown-char.c
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang -E %s 2>&1 | not grep error
- ` ` ` `
diff --git a/clang/test/Makefile b/clang/test/Makefile
deleted file mode 100644
index 0963fee542ca..000000000000
--- a/clang/test/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-LEVEL = ../../..
-include $(LEVEL)/Makefile.common
-
-# Test in all immediate subdirectories if unset.
-TESTDIRS ?= $(shell echo $(PROJ_SRC_DIR)/*/)
-
-# Only run rewriter tests on darwin.
-ifeq ($(OS),Darwin)
-TESTDIRS +=
-endif
-
-ifdef VERBOSE
-PROGRESS = echo $<
-REPORTFAIL = cat $@
-DONE = true
-else
-PROGRESS = printf '.'
-REPORTFAIL = (echo; echo '----' $< 'failed ----')
-DONE = echo
-endif
-
-TESTS := $(addprefix Output/, $(addsuffix .testresults, $(shell find $(TESTDIRS) \( -name '*.c' -or -name '*.cpp' -or -name '*.m' -or -name '*.mm' \))))
-Output/%.testresults: %
- @ $(PROGRESS)
- @ PATH=$(ToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$$PATH VG=$(VG) $(PROJ_SRC_DIR)/TestRunner.sh $< > $@ || $(REPORTFAIL)
-
-all::
- @ mkdir -p $(addprefix Output/, $(TESTDIRS))
- @ rm -f $(TESTS)
- @ echo '--- Running clang tests ---'
- @ $(MAKE) $(TESTS)
- @ $(DONE)
- @ !(cat $(TESTS) | grep -q " FAILED! ")
-
-report: $(TESTS)
- @ cat $^
-
-clean::
- @ rm -rf Output/
-
-.PHONY: all report clean
diff --git a/clang/test/Misc/diag-checker.c b/clang/test/Misc/diag-checker.c
deleted file mode 100644
index e5864461a67d..000000000000
--- a/clang/test/Misc/diag-checker.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#include <stdio.h>
-
-void foo(FILE *FP) {}
diff --git a/clang/test/Parser/CompoundStmtScope.c b/clang/test/Parser/CompoundStmtScope.c
deleted file mode 100644
index 9aadbceac139..000000000000
--- a/clang/test/Parser/CompoundStmtScope.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int foo() {
- {
- typedef float X;
- }
- X Y; // expected-error {{use of undeclared identifier}}
-}
diff --git a/clang/test/Parser/argument_qualified.c b/clang/test/Parser/argument_qualified.c
deleted file mode 100644
index cd92c3258c6a..000000000000
--- a/clang/test/Parser/argument_qualified.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s
-int abc (const float x) {
- return 1;
-}
-
diff --git a/clang/test/Parser/argument_redef.c b/clang/test/Parser/argument_redef.c
deleted file mode 100644
index d831d48b5a15..000000000000
--- a/clang/test/Parser/argument_redef.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* RUN: clang -fsyntax-only -verify %s
-*/
-
-int foo(int A) { /* expected-error {{previous definition is here}} */
- int A; /* expected-error {{redefinition of 'A'}} */
-}
diff --git a/clang/test/Parser/argument_scope.c b/clang/test/Parser/argument_scope.c
deleted file mode 100644
index 8b9f065c822a..000000000000
--- a/clang/test/Parser/argument_scope.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -fsyntax-only %s
-typedef struct foo foo;
-
-void blah(int foo) {
- foo = 1;
-}
diff --git a/clang/test/Parser/asm.c b/clang/test/Parser/asm.c
deleted file mode 100644
index c23d31a7247b..000000000000
--- a/clang/test/Parser/asm.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f1() {
- asm ("ret" : : :); // expected-error {{expected string literal}}
-}
-
-void f2() {
- asm("foo" : "=r" (a)); // expected-error {{use of undeclared identifier 'a'}}
- asm("foo" : : "r" (b)); // expected-error {{use of undeclared identifier 'b'}}
-}
-
-
-// rdar://5952468
-__asm ; // expected-error {{expected '(' after 'asm'}}
-
diff --git a/clang/test/Parser/attributes.c b/clang/test/Parser/attributes.c
deleted file mode 100644
index 7161d6c22b11..000000000000
--- a/clang/test/Parser/attributes.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s -pedantic
-
-static __inline void __attribute__((__always_inline__, __nodebug__)) // expected-warning {{extension used}}
-foo (void)
-{
-}
diff --git a/clang/test/Parser/bad-control.c b/clang/test/Parser/bad-control.c
deleted file mode 100644
index fab9fa303945..000000000000
--- a/clang/test/Parser/bad-control.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* RUN: clang -fsyntax-only -verify %s
-*/
-int foo() {
- break; /* expected-error {{'break' statement not in loop or switch statement}} */
-}
-
-int foo2() {
- continue; /* expected-error {{'continue' statement not in loop statement}} */
-}
diff --git a/clang/test/Parser/block-block-storageclass.c b/clang/test/Parser/block-block-storageclass.c
deleted file mode 100644
index c9be12f1f077..000000000000
--- a/clang/test/Parser/block-block-storageclass.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -fsyntax-only -verify -parse-noop %s
-#if 0
-#include <stdio.h>
-void _Block_byref_release(void*src){}
-
-int main() {
- __block int X = 1234;
- __block const char * message = "HELLO";
-
- X = X - 1234;
-
- X += 1;
-
- printf ("%s(%d)\n", message, X);
- X -= 1;
-
- return X;
-}
-#endif
diff --git a/clang/test/Parser/block-pointer-decl.c b/clang/test/Parser/block-pointer-decl.c
deleted file mode 100644
index a9da3256a94f..000000000000
--- a/clang/test/Parser/block-pointer-decl.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -fsyntax-only -verify -parse-noop %s
-
-struct blockStruct {
- int (^a)(float, int);
- int b;
-};
-
-int blockTaker (int (^myBlock)(int), int other_input)
-{
- return 5 * myBlock (other_input);
-}
-
-int main (int argc, char **argv)
-{
- int (^blockptr) (int) = ^(int inval) {
- printf ("Inputs: %d, %d.\n", argc, inval);
- return argc * inval;
- };
-
-
- argc = 10;
- printf ("I got: %d.\n",
- blockTaker (blockptr, 6));
- return 0;
-}
-
diff --git a/clang/test/Parser/builtin_classify_type.c b/clang/test/Parser/builtin_classify_type.c
deleted file mode 100644
index 7cf3d5cd922d..000000000000
--- a/clang/test/Parser/builtin_classify_type.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-struct foo { int a; };
-
-int main() {
- int a;
- float b;
- double d;
- struct foo s;
-
- static int ary[__builtin_classify_type(a)];
- static int ary2[(__builtin_classify_type)(a)]; // expected-error{{arrays with static storage duration must have constant integer length}}
- static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{arrays with static storage duration must have constant integer length}}
-
- int result;
-
- result = __builtin_classify_type(a);
- result = __builtin_classify_type(b);
- result = __builtin_classify_type(d);
- result = __builtin_classify_type(s);
-}
diff --git a/clang/test/Parser/builtin_types_compatible.c b/clang/test/Parser/builtin_types_compatible.c
deleted file mode 100644
index 925c7ea50a16..000000000000
--- a/clang/test/Parser/builtin_types_compatible.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-extern int funcInt(int);
-extern float funcFloat(float);
-extern double funcDouble(double);
-// figure out why "char *" doesn't work (with gcc, nothing to do with clang)
-//extern void funcCharPtr(char *);
-
-#define func(expr) \
- do { \
- typeof(expr) tmp; \
- if (__builtin_types_compatible_p(typeof(expr), int)) funcInt(tmp); \
- else if (__builtin_types_compatible_p(typeof(expr), float)) funcFloat(tmp); \
- else if (__builtin_types_compatible_p(typeof(expr), double)) funcDouble(tmp); \
- } while (0)
-#define func_choose(expr) \
- __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), int), funcInt(expr), \
- __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), float), funcFloat(expr), \
- __builtin_choose_expr(__builtin_types_compatible_p(typeof(expr), double), funcDouble(expr), (void)0)))
-
-static void test()
-{
- int a;
- float b;
- double d;
-
- func(a);
- func(b);
- func(d);
- a = func_choose(a);
- b = func_choose(b);
- d = func_choose(d);
-
- int c;
- struct xx { int a; } x, y;
-
- c = __builtin_choose_expr(a+3-7, b, x); // expected-error{{'__builtin_choose_expr' requires a constant expression}}
- c = __builtin_choose_expr(0, b, x); // expected-error{{incompatible type assigning 'struct xx', expected 'int'}}
- c = __builtin_choose_expr(5+3-7, b, x);
- y = __builtin_choose_expr(4+3-7, b, x);
-
-}
-
diff --git a/clang/test/Parser/c-namespace.c b/clang/test/Parser/c-namespace.c
deleted file mode 100644
index 2b380503ace6..000000000000
--- a/clang/test/Parser/c-namespace.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -fsyntax-only %s
-void bla1() {
- struct XXX;
- int XXX;
-}
-
diff --git a/clang/test/Parser/char-literal-printing.c b/clang/test/Parser/char-literal-printing.c
deleted file mode 100644
index 990b8f76e1a5..000000000000
--- a/clang/test/Parser/char-literal-printing.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: clang -ast-print %s
-
-#include <stddef.h>
-
-char test1(void) { return '\\'; }
-wchar_t test2(void) { return L'\\'; }
-char test3(void) { return '\''; }
-wchar_t test4(void) { return L'\''; }
-char test5(void) { return '\a'; }
-wchar_t test6(void) { return L'\a'; }
-char test7(void) { return '\b'; }
-wchar_t test8(void) { return L'\b'; }
-char test9(void) { return '\e'; }
-wchar_t test10(void) { return L'\e'; }
-char test11(void) { return '\f'; }
-wchar_t test12(void) { return L'\f'; }
-char test13(void) { return '\n'; }
-wchar_t test14(void) { return L'\n'; }
-char test15(void) { return '\r'; }
-wchar_t test16(void) { return L'\r'; }
-char test17(void) { return '\t'; }
-wchar_t test18(void) { return L'\t'; }
-char test19(void) { return '\v'; }
-wchar_t test20(void) { return L'\v'; }
-
-char test21(void) { return 'c'; }
-wchar_t test22(void) { return L'c'; }
-char test23(void) { return '\x3'; }
-wchar_t test24(void) { return L'\x3'; }
-
-wchar_t test25(void) { return L'\x333'; }
diff --git a/clang/test/Parser/check-objc2-syntax-1.m b/clang/test/Parser/check-objc2-syntax-1.m
deleted file mode 100644
index b0b0e8a35e36..000000000000
--- a/clang/test/Parser/check-objc2-syntax-1.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Subclass
-+ (int)magicNumber;
-@end
-
-int main (void) {
- return Subclass.magicNumber; // expected-error {{unexpected interface name 'Subclass': expected expression}}
-}
-
diff --git a/clang/test/Parser/check-syntax-1.m b/clang/test/Parser/check-syntax-1.m
deleted file mode 100644
index 9036c65dce55..000000000000
--- a/clang/test/Parser/check-syntax-1.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int @interface bla ; // expected-error {{cannot combine with previous 'int' declaration specifier}}
-@end
diff --git a/clang/test/Parser/check_cast.c b/clang/test/Parser/check_cast.c
deleted file mode 100644
index c69f0f0d0353..000000000000
--- a/clang/test/Parser/check_cast.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-struct foo {
- int a;
-};
-
-int main() {
- struct foo xxx;
- int i;
-
- xxx = (struct foo)1; // expected-error {{used type 'struct foo' where arithmetic or pointer type is required}}
- i = (int)xxx; // expected-error {{operand of type 'struct foo' where arithmetic or pointer type is required}}
-}
diff --git a/clang/test/Parser/compound_literal.c b/clang/test/Parser/compound_literal.c
deleted file mode 100644
index c6d665ca43be..000000000000
--- a/clang/test/Parser/compound_literal.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-int main() {
- char *s;
- s = (char []){"whatever"};
-}
diff --git a/clang/test/Parser/control-scope.c b/clang/test/Parser/control-scope.c
deleted file mode 100644
index 3d588d63b4cc..000000000000
--- a/clang/test/Parser/control-scope.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: not clang %s -std=c90 &&
-// RUN: clang %s -std=c99
-
-int f (int z) {
- if (z + sizeof (enum {a}))
- return 1 + sizeof (enum {a});
- return 0;
-}
diff --git a/clang/test/Parser/cxx-bool.cpp b/clang/test/Parser/cxx-bool.cpp
deleted file mode 100644
index 623dcb2887e8..000000000000
--- a/clang/test/Parser/cxx-bool.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-bool a = true;
-bool b = false;
diff --git a/clang/test/Parser/cxx-casting.cpp b/clang/test/Parser/cxx-casting.cpp
deleted file mode 100644
index 4b11dc8a2bce..000000000000
--- a/clang/test/Parser/cxx-casting.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-char *const_cast_test(const char *var)
-{
- return const_cast<char*>(var);
-}
-
-#if 0
-// FIXME: Uncomment when C++ is supported more.
-struct A {
- virtual ~A() {}
-};
-
-struct B : public A {
-};
-
-struct B *dynamic_cast_test(struct A *a)
-{
- return dynamic_cast<struct B*>(a);
-}
-#endif
-
-char *reinterpret_cast_test()
-{
- return reinterpret_cast<char*>(0xdeadbeef);
-}
-
-double static_cast_test(int i)
-{
- return static_cast<double>(i);
-}
-
-char postfix_expr_test()
-{
- return reinterpret_cast<char*>(0xdeadbeef)[0];
-} \ No newline at end of file
diff --git a/clang/test/Parser/cxx-class.cpp b/clang/test/Parser/cxx-class.cpp
deleted file mode 100644
index 6d030bdc578a..000000000000
--- a/clang/test/Parser/cxx-class.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -parse-noop -verify %s
-class C {
-public:
-protected:
- typedef int A,B;
- static int sf(), u;
-
- struct S {};
- enum {};
- int; // expected-error {{error: declaration does not declare anything}}
- int : 1, : 2;
-
-public:
- void m() {
- int l = 2;
- }
-
-private:
- int x,f(),y,g();
-};
diff --git a/clang/test/Parser/cxx-condition.cpp b/clang/test/Parser/cxx-condition.cpp
deleted file mode 100644
index 9ffdf79ba013..000000000000
--- a/clang/test/Parser/cxx-condition.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -parse-noop -verify %s
-
-void f() {
- int a;
- while (a) ;
- while (int x) ; // expected-error {{expected '=' after declarator}}
- while (float x = 0) ;
- if (const int x = a) ;
- switch (int x = a+10) {}
- for (; int x = ++a; ) ;
-}
diff --git a/clang/test/Parser/cxx-reference.cpp b/clang/test/Parser/cxx-reference.cpp
deleted file mode 100644
index 4f3b58c5d53e..000000000000
--- a/clang/test/Parser/cxx-reference.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-extern char *bork;
-char *& bar = bork;
-
-void foo(int &a) {
-}
-
-typedef int & A;
-
-void g(const A aref) {
-}
-
-int & const X; // expected-error {{'const' qualifier may not be applied to a reference}}
-int & volatile Y; // expected-error {{'volatile' qualifier may not be applied to a reference}}
-int & const volatile Z; /* expected-error {{'const' qualifier may not be applied}} \
- expected-error {{'volatile' qualifier may not be applied}} */
diff --git a/clang/test/Parser/cxx-typeof.cpp b/clang/test/Parser/cxx-typeof.cpp
deleted file mode 100644
index 7e09905d8f4c..000000000000
--- a/clang/test/Parser/cxx-typeof.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-static void test() {
- int *pi;
- int x;
- typeof pi[x] y;
-}
diff --git a/clang/test/Parser/cxx-variadic-func.cpp b/clang/test/Parser/cxx-variadic-func.cpp
deleted file mode 100644
index 0ef8684c1afa..000000000000
--- a/clang/test/Parser/cxx-variadic-func.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-void f(...) {
- int g(int(...));
-}
diff --git a/clang/test/Parser/declarators.c b/clang/test/Parser/declarators.c
deleted file mode 100644
index 3e0380ea8786..000000000000
--- a/clang/test/Parser/declarators.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic
-
-extern int a1[];
-
-void f0();
-void f1(int [*]);
-void f2(int [const *]);
-void f3(int [volatile const*]);
-int f4(*XX)(void); /* expected-error {{cannot return}} expected-warning {{type specifier missing, defaults to 'int'}} */
-
-char ((((*X))));
-
-void (*signal(int, void (*)(int)))(int);
-
-int a, ***C, * const D, b(int);
-
-int *A;
-
-struct str;
-
-int test2(int *P, int A) {
- struct str;
-
- // Hard case for array decl, not Array[*].
- int Array[*(int*)P+A];
-}
-
-typedef int atype;
-int test3(x,
- atype /* expected-error {{unexpected type name 'atype': expected identifier}} */
- ) int x, atype; {}
-
-int test4(x, x) int x; {} /* expected-error {{redefinition of parameter 'x'}} */
-
diff --git a/clang/test/Parser/encode.m b/clang/test/Parser/encode.m
deleted file mode 100644
index ce12882ecf02..000000000000
--- a/clang/test/Parser/encode.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int main(void) {
- const char ch = @encode(char *)[2];
- char c = @encode(char *)[2] + 4;
- return c;
-}
-
diff --git a/clang/test/Parser/enhanced-proto-1.m b/clang/test/Parser/enhanced-proto-1.m
deleted file mode 100644
index 354502e7913e..000000000000
--- a/clang/test/Parser/enhanced-proto-1.m
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol MyProto1
-@optional
-- (void) FOO;
-@optional
-- (void) FOO;
-@required
-- (void) REQ;
-@optional
-@end
-
-@protocol MyProto2 <MyProto1>
-- (void) FOO2;
-@optional
-- (void) FOO3;
-@end
diff --git a/clang/test/Parser/expressions.c b/clang/test/Parser/expressions.c
deleted file mode 100644
index 3b47260c32f2..000000000000
--- a/clang/test/Parser/expressions.c
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: clang -parse-noop %s
-
-void test1() {
- if (sizeof (int){ 1}); // sizeof compound literal
- if (sizeof (int)); // sizeof type
-
- (int)4; // cast.
- (int){4}; // compound literal.
-
- // FIXME: change this to the struct version when we can.
- //int A = (struct{ int a;}){ 1}.a;
- int A = (int){ 1}.a;
-}
-
-int test2(int a, int b) {
- return a ? a,b : a;
-}
-
-int test3(int a, int b, int c) {
- return a = b = c;
-}
-
-int test4() {
- test4();
-}
-
-int test_offsetof() {
- // FIXME: change into something that is semantically correct.
- __builtin_offsetof(int, a.b.c[4][5]);
-}
-
-void test_sizeof(){
- int arr[10];
- sizeof arr[0];
- sizeof(arr[0]);
- sizeof(arr)[0];
-}
-
-
diff --git a/clang/test/Parser/expressions.m b/clang/test/Parser/expressions.m
deleted file mode 100644
index 8e314aca6f7e..000000000000
--- a/clang/test/Parser/expressions.m
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -parse-noop %s
-
-void test1() {
- @"s"; // expected-warning {{expression result unused}}
-}
-
diff --git a/clang/test/Parser/extension.c b/clang/test/Parser/extension.c
deleted file mode 100644
index 9bd18de63f7d..000000000000
--- a/clang/test/Parser/extension.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-// Top level extension marker.
-
-__extension__ typedef struct
-{
- long long int quot;
- long long int rem;
-}lldiv_t;
-
-
-// Compound expr __extension__ marker.
-void bar() {
- __extension__ int i;
- int j;
-}
-
diff --git a/clang/test/Parser/function-decls.c b/clang/test/Parser/function-decls.c
deleted file mode 100644
index 3493baa156d8..000000000000
--- a/clang/test/Parser/function-decls.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* RUN: clang %s -ast-print
- */
-
-void foo() {
- int X;
- X = sizeof(void (*(*)())());
- X = sizeof(int(*)(int, float, ...));
- X = sizeof(void (*(int arga, void (*argb)(double Y)))(void* Z));
-}
-
diff --git a/clang/test/Parser/goto-ident.c b/clang/test/Parser/goto-ident.c
deleted file mode 100644
index 87d6ea5513d0..000000000000
--- a/clang/test/Parser/goto-ident.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* RUN: clang -fsyntax-only -verify %s
-*/
-
-void foo() {
- goto ; /* expected-error {{expected identifier}} */
-}
diff --git a/clang/test/Parser/if-scope-c90.c b/clang/test/Parser/if-scope-c90.c
deleted file mode 100644
index 43a3676ca487..000000000000
--- a/clang/test/Parser/if-scope-c90.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify --std=c90 %s
-
-int f (int z)
-{
- if (z > sizeof (enum {a, b}))
- return a;
- return b;
-}
diff --git a/clang/test/Parser/if-scope-c99.c b/clang/test/Parser/if-scope-c99.c
deleted file mode 100644
index 41d7ae2e1815..000000000000
--- a/clang/test/Parser/if-scope-c99.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify --std=c99 %s
-
-int f (int z)
-{
- if (z > sizeof (enum {a, b}))
- return a;
- return b; // expected-error{{use of undeclared identifier}}
-}
diff --git a/clang/test/Parser/implicit-casts.c b/clang/test/Parser/implicit-casts.c
deleted file mode 100644
index 2e8e00018221..000000000000
--- a/clang/test/Parser/implicit-casts.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-_Complex double X;
-void test1(int c) {
- X = 5;
-}
-void test2() {
- int i;
- double d = i;
- double _Complex a = 5;
-
- test1(a);
- a = 5;
- d = i;
-}
-int test3() {
- int a[2];
- a[0] = test3; // expected-warning{{incompatible pointer to integer conversion assigning 'int ()', expected 'int'}}
-}
-short x; void test4(char c) { x += c; }
-int y; void test5(char c) { y += c; }
diff --git a/clang/test/Parser/method-prototype-1.m b/clang/test/Parser/method-prototype-1.m
deleted file mode 100644
index 6399f040a9cf..000000000000
--- a/clang/test/Parser/method-prototype-1.m
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang %s -parse-noop
-@interface MyObject
-- (void) bycopy : (int) woodo, ... ;
-- (void) break : (int) woodo, ... ;
-- (void) enum : (int) woodo, ... ;
-- (void) struct : (int) woodo, ... ;
-- (void) union : (int) woodo, ... ;
-- (void) if : (int) woodo, int i, char chh, ... ;
-- (void) else : (int) woodo, ... ;
-- (void) while : (int) woodo, ... ;
-- (void) do : (int) woodo, ... ;
-- (void) for : (int) woodo, ... ;
-- (void) switch : (int) woodo, ... ;
-- (void) case : (int) woodo, ... ;
-- (void) default : (int) woodo, ... ;
-- (void) break : (int) woodo, ... ;
-- (void) continue : (int) woodo, ... ;
-- (void) return : (int) woodo, ... ;
-- (void) goto : (int) woodo, ... ;
-- (void) sizeof : (int) woodo, ... ;
-- (void) typeof : (int) woodo, ... ;
-- (void) __alignof : (int) woodo, ... ;
-- (void) unsigned : (int) woodo, ... ;
-- (void) long : (int) woodo, ... ;
-- (void) const : (int) woodo, ... ;
-- (void) short : (int) woodo, ... ;
-- (void) volatile : (int) woodo, ... ;
-- (void) signed : (int) woodo, ... ;
-- (void) restrict : (int) woodo, ... ;
-- (void) _Complex : (int) woodo, ... ;
-- (void) in : (int) woodo, ... ;
-- (void) out : (int) woodo, ... ;
-- (void) inout : (int) woodo, ... ;
-- (void) bycopy : (int) woodo, ... ;
-- (void) byref : (int) woodo, ... ;
-- (void) oneway : (int) woodo, ... ;
-- (void) int : (int) woodo, ... ;
-- (void) char : (int) woodo, ... ;
-- (void) float : (int) woodo, ... ;
-- (void) double : (int) woodo, ... ;
-- (void) void : (int) woodo, ... ;
-- (void) _Bool : (int) woodo, ... ;
-@end
diff --git a/clang/test/Parser/namelookup-bug-1.c b/clang/test/Parser/namelookup-bug-1.c
deleted file mode 100644
index 298798c5fa18..000000000000
--- a/clang/test/Parser/namelookup-bug-1.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -verify %s
-
-typedef int Object;
-
-struct Object *pp;
-
-Object staticObject1;
diff --git a/clang/test/Parser/namelookup-bug-2.c b/clang/test/Parser/namelookup-bug-2.c
deleted file mode 100644
index 443b50ab02f4..000000000000
--- a/clang/test/Parser/namelookup-bug-2.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -verify %s
-
-typedef int Object;
-
-struct Object {int i1; } *P;
-
-void foo() {
- struct Object { int i2; } *X;
- Object:
- {
- Object a;
- }
-}
-
diff --git a/clang/test/Parser/objc-alias-printing.m b/clang/test/Parser/objc-alias-printing.m
deleted file mode 100644
index 67e013f1d3db..000000000000
--- a/clang/test/Parser/objc-alias-printing.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -ast-print %s
-
-@protocol P1 @end
-@protocol P2 @end
-
-@interface INTF @end
-
-@compatibility_alias alias INTF;
-
-
-int foo ()
-{
- INTF *pi;
- INTF<P2,P1> *pi2;
- alias *p;
- alias<P1,P2> *p2;
- return pi2 == p2;
-}
diff --git a/clang/test/Parser/objc-category-neg-1.m b/clang/test/Parser/objc-category-neg-1.m
deleted file mode 100644
index 3da911b6deca..000000000000
--- a/clang/test/Parser/objc-category-neg-1.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
-static __inline__ int __inline_isfinitef (float ) __attribute__ ((always_inline));
-
-@interface NSATSTypesetter (NSPantherCompatibility) // expected-error {{ "cannot find interface declaration for 'NSATSTypesetter'" }}
-- (id)lineFragmentRectForProposedRect:(id)proposedRect remainingRect:(id)remainingRect __attribute__((deprecated));
-@end
diff --git a/clang/test/Parser/objc-forcollection-1.m b/clang/test/Parser/objc-forcollection-1.m
deleted file mode 100644
index 6db74dc9527b..000000000000
--- a/clang/test/Parser/objc-forcollection-1.m
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-typedef struct objc_class *Class;
-typedef struct objc_object {
- Class isa;
-} *id;
-
-
-@protocol P @end
-
-@interface MyList
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- int i;
- for (id elem in self)
- ++i;
- for (MyList *elem in self)
- ++i;
- for (id<P> se in self)
- ++i;
-
- MyList<P> *p;
- for (p in self)
- ++i;
-
- for (p in p)
- ++i;
-}
-@end
-
diff --git a/clang/test/Parser/objc-forcollection-neg-2.m b/clang/test/Parser/objc-forcollection-neg-2.m
deleted file mode 100644
index bde7d223596e..000000000000
--- a/clang/test/Parser/objc-forcollection-neg-2.m
+++ /dev/null
@@ -1,38 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef struct objc_class *Class;
-typedef struct objc_object {
- Class isa;
-} *id;
-
-
-@protocol P @end
-
-@interface MyList
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- static i;
- for (id el, elem in self) // expected-error {{Only one element declaration is allowed}}
- ++i;
- for (id el in self)
- ++i;
- MyList<P> ***p;
- for (p in self) // expected-error {{selector element type ('MyList<P> ***') is not a valid object type}}
- ++i;
-
-}
-@end
-
diff --git a/clang/test/Parser/objc-forcollection-neg.m b/clang/test/Parser/objc-forcollection-neg.m
deleted file mode 100644
index 8e1c05a05904..000000000000
--- a/clang/test/Parser/objc-forcollection-neg.m
+++ /dev/null
@@ -1,37 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef struct objc_class *Class;
-typedef struct objc_object {
- Class isa;
-} *id;
-
-
-@interface MyList
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
-
- int i=0;
- for (int * elem in elem) // expected-error {{selector element type ('int *') is not a valid object}} \
- expected-error {{collection expression type ('int *') is not a valid object}}
- ++i;
- for (i in elem) // expected-error {{use of undeclared identifier 'elem'}} \
- expected-error {{selector element type ('int') is not a valid object}}
- ++i;
- for (id se in i) // expected-error {{collection expression type ('int') is not a valid object}}
- ++i;
-}
-@end
-
diff --git a/clang/test/Parser/objc-foreach-error-1.m b/clang/test/Parser/objc-foreach-error-1.m
deleted file mode 100644
index 76251abf33fc..000000000000
--- a/clang/test/Parser/objc-foreach-error-1.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-ce MyList // expected-error {{expected '=', ',', ';', 'asm', or '__attribute__' after declarator}}
-@end
-
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-
-int LOOP();
-
-@implementation MyList (BasicTest) // expected-error {{cannot find interface declaration for 'MyList'}}
-- (void)compilerTestAgainst {
-MyList * el; // expected-error {{use of undeclared identifier 'MyList'}}
- for (el in @"foo") // expected-error {{use of undeclared identifier 'el'}}
- { LOOP(); }
-}
-@end
-
diff --git a/clang/test/Parser/objc-init.m b/clang/test/Parser/objc-init.m
deleted file mode 100644
index 4478665f7acc..000000000000
--- a/clang/test/Parser/objc-init.m
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-// rdar://5707001
-
-@interface NSNumber;
-- () METH;
-- (unsigned) METH2;
-@end
-
-void test1() {
- id objects[] = {[NSNumber METH]};
-}
-
-void test2(NSNumber x) {
- id objects[] = {[x METH]}; // expected-error {{bad receiver type}}
-}
-
-void test3(NSNumber *x) {
- id objects[] = {[x METH]};
-}
-
-
-// rdar://5977581
-void test4() {
- unsigned x[] = {[NSNumber METH2]+2};
-}
-
diff --git a/clang/test/Parser/objc-messaging-1.m b/clang/test/Parser/objc-messaging-1.m
deleted file mode 100644
index 7340fac5f7cd..000000000000
--- a/clang/test/Parser/objc-messaging-1.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang %s -parse-noop
-int main ()
-{
- int i,j;
- struct S *p;
- id a, b, c;
- [p ii];
- [p if: 1 :2];
- [p inout: 1 :2 another:(2,3,4)];
- [p inout: 1 :2 another:(2,3,4), 6,6,8];
- [p inout: 1 :2 another:(2,3,4), (6,4,5),6,8];
- [p inout: 1 :2 another:(i+10), (i,j-1,5),6,8];
- [p long: 1 :2 another:(i+10), (i,j-1,5),6,8];
- [p : "Hello\n" :2 another:(i+10), (i,j-1,5),6,8];
-
- // Comma expression as receiver (rdar://6222856)
- [a, b, c foo];
-
-}
diff --git a/clang/test/Parser/objc-messaging-neg-1.m b/clang/test/Parser/objc-messaging-neg-1.m
deleted file mode 100644
index 23db7e28c44c..000000000000
--- a/clang/test/Parser/objc-messaging-neg-1.m
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int main()
- {
- id a;
- [a bla:0 6:7]; // expected-error {{expected ']'}}
- }
diff --git a/clang/test/Parser/objc-missing-impl.m b/clang/test/Parser/objc-missing-impl.m
deleted file mode 100644
index 7d38371190ca..000000000000
--- a/clang/test/Parser/objc-missing-impl.m
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-@end // expected-warning {{@end must appear in an @implementation context}}
diff --git a/clang/test/Parser/objc-quirks.m b/clang/test/Parser/objc-quirks.m
deleted file mode 100644
index b726d9a8274f..000000000000
--- a/clang/test/Parser/objc-quirks.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// FIXME: This is a horrible error message here. Fix.
-int @"s" = 5; // expected-error {{prefix attribute must be}}
diff --git a/clang/test/Parser/objc-try-catch-1.m b/clang/test/Parser/objc-try-catch-1.m
deleted file mode 100644
index 072c4609eb2a..000000000000
--- a/clang/test/Parser/objc-try-catch-1.m
+++ /dev/null
@@ -1,65 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void * proc();
-
-@interface NSConstantString
-@end
-
-@interface Frob
-@end
-
-@interface Frob1
-@end
-
-void * foo()
-{
- @try {
- return proc();
- }
- @catch (Frob* ex) {
- @throw;
- }
- @catch (Frob1* ex) {
- @throw proc();
- }
- @finally {
- @try {
- return proc();
- }
- @catch (Frob* ex) {
- @throw 1,2;
- }
- @catch(...) {
- @throw (4,3,proc());
- }
- }
-
- @try { // expected-error {{@try statement without a @catch and @finally clause}}
- return proc();
- }
-}
-
-
-void bar()
-{
- @try {}// expected-error {{@try statement without a @catch and @finally clause}}
- @"s"; // expected-warning {{result unused}}
-}
-
-void baz()
-{
- @try {}// expected-error {{@try statement without a @catch and @finally clause}}
- @try {}
- @finally {}
-}
-
-void noTwoTokenLookAheadRequiresABitOfFancyFootworkInTheParser() {
- @try {
- // Do something
- } @catch (...) {}
- @try {
- // Do something
- } @catch (...) {}
- return 0;
-}
-
diff --git a/clang/test/Parser/objc-type-printing.m b/clang/test/Parser/objc-type-printing.m
deleted file mode 100644
index 5d3cbd994f9d..000000000000
--- a/clang/test/Parser/objc-type-printing.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -ast-print %s
-
-@protocol P1 @end
-@protocol P2 @end
-@protocol P3 @end
-
-@interface INTF
-- (INTF<P1>*) METH;
-@end
-
-void foo()
-{
- INTF *pintf;
- INTF<P1>* p1;
- INTF<P1, P1>* p2;
- INTF<P1, P3>* p3;
- INTF<P1, P3, P2>* p4;
- INTF<P2,P2, P3, P1>* p5;
-}
diff --git a/clang/test/Parser/ocu_vector_components.c b/clang/test/Parser/ocu_vector_components.c
deleted file mode 100644
index ec54631e7bbf..000000000000
--- a/clang/test/Parser/ocu_vector_components.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef __attribute__(( ext_vector_type(2) )) float float2;
-typedef __attribute__(( ext_vector_type(3) )) float float3;
-typedef __attribute__(( ext_vector_type(4) )) float float4;
-
-static void test() {
- float2 vec2, vec2_2;
- float3 vec3;
- float4 vec4, vec4_2;
- float f;
-
- vec2.z; // expected-error {{vector component access exceeds type 'float2'}}
- vec2.rgba; // expected-error {{vector component access exceeds type 'float2'}}
- vec4.rgba; // expected-warning {{expression result unused}}
- vec4.rgbc; // expected-error {{illegal vector component name 'c'}}
- vec3 = vec4.rgb; // legal, shorten
- f = vec2.x; // legal, shorten
-
- vec4_2.rgbr = vec4.rgba; // expected-error {{vector is not assignable (contains duplicate components)}}
- vec4_2.rgbb = vec4.rgba; // expected-error {{vector is not assignable (contains duplicate components)}}
- vec4_2.rgga = vec4.rgba; // expected-error {{vector is not assignable (contains duplicate components)}}
- vec2.x = f;
- vec2.xx = vec2_2.xy; // expected-error {{vector is not assignable (contains duplicate components)}}
- vec2.yx = vec2_2.xy;
- vec4 = (float4){ 1,2,3,4 };
- vec4.rg.a; // expected-error {{vector component access exceeds type 'float2'}}
-}
diff --git a/clang/test/Parser/parmvardecl_conversion.c b/clang/test/Parser/parmvardecl_conversion.c
deleted file mode 100644
index 81acc07b61c8..000000000000
--- a/clang/test/Parser/parmvardecl_conversion.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f (int p[]) { p++; }
-
diff --git a/clang/test/Parser/pointer-arithmetic.c b/clang/test/Parser/pointer-arithmetic.c
deleted file mode 100644
index 3556c9aa4d40..000000000000
--- a/clang/test/Parser/pointer-arithmetic.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int *test1(int *a) { return a + 1; }
-int *test2(int *a) { return 1 + a; }
-int *test3(int *a) { return a - 1; }
-int test4(int *a, int *b) { return a - b; }
-
-int test5(int *a, int *b) { return a + b; } /* expected-error {{invalid operands}} */
-int *test6(int *a) { return 1 - a; } /* expected-error {{invalid operands}} */
diff --git a/clang/test/Parser/pointer_promotion.c b/clang/test/Parser/pointer_promotion.c
deleted file mode 100644
index c648209bcf8f..000000000000
--- a/clang/test/Parser/pointer_promotion.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int test() {
- void *vp;
- int *ip;
- char *cp;
- struct foo *fp;
- struct bar *bp;
- short sint = 7;
-
- if (ip < cp) {} // expected-warning {{comparison of distinct pointer types ('int *' and 'char *')}}
- if (cp < fp) {} // expected-warning {{comparison of distinct pointer types ('char *' and 'struct foo *')}}
- if (fp < bp) {} // expected-warning {{comparison of distinct pointer types ('struct foo *' and 'struct bar *')}}
- if (ip < 7) {} // expected-warning {{comparison between pointer and integer ('int *' and 'int')}}
- if (sint < ip) {} // expected-warning {{comparison between pointer and integer ('int' and 'int *')}}
- if (ip == cp) {} // expected-warning {{comparison of distinct pointer types ('int *' and 'char *')}}
-}
-
diff --git a/clang/test/Parser/pragma-pack.c b/clang/test/Parser/pragma-pack.c
deleted file mode 100644
index 3c2196b2b3bb..000000000000
--- a/clang/test/Parser/pragma-pack.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// Note that this puts the expected lines before the directives to work around
-// limitations in the -verify mode.
-
-/* expected-warning {{missing '(' after '#pragma pack'}}*/ #pragma pack 10
-#pragma pack()
-#pragma pack(8)
-
-/*expected-warning {{unknown action for '#pragma pack'}}*/ #pragma pack(hello)
-#pragma pack(push)
-#pragma pack(pop)
-
-/* expected-warning {{malformed '#pragma pack', expected '#pragma pack(push}}*/ #pragma pack(push,)
-/* expected-warning {{malformed '#pragma pack', expected '#pragma pack(push}}*/ #pragma pack(push,)
-/* expected-warning {{malformed '#pragma pack', expected '#pragma pack(pop}}*/ #pragma pack(pop,)
-
-#pragma pack(push,i)
-/* expected-warning {{malformed '#pragma pack', expected}}*/ #pragma pack(push,i,
-/* expected-warning {{malformed '#pragma pack', expected}}*/ #pragma pack(push,i,)
-/* expected-warning {{malformed '#pragma pack', expected}}*/ #pragma pack(push,i,help)
-
-#pragma pack(push,8)
-/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push,8,
-/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push,8,)
-/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push,i,8
-#pragma pack(push,i,8)
-
-/* expected-warning {{missing ')' after '#pragma pack'}}*/ #pragma pack(push
-
-_Pragma("pack(push)")
-/* expected-warning {{malformed '#pragma pack', expected '#pragma pack(push}}*/ _Pragma("pack(push,)")
diff --git a/clang/test/Parser/prefix-attributes.m b/clang/test/Parser/prefix-attributes.m
deleted file mode 100644
index 46eb90cd2b30..000000000000
--- a/clang/test/Parser/prefix-attributes.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -verify -fsyntax-only %s
-
-__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}}
-
-__attribute__((deprecated)) @interface A @end
-__attribute__((deprecated)) @protocol P0;
-__attribute__((deprecated)) @protocol P1
-@end
diff --git a/clang/test/Parser/promote_types_in_proto.c b/clang/test/Parser/promote_types_in_proto.c
deleted file mode 100644
index 40617a2a7df5..000000000000
--- a/clang/test/Parser/promote_types_in_proto.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s
-void functionPromotion(void f(char *const []));
-void arrayPromotion(char * const argv[]);
-
-int whatever(int argc, char *argv[])
-{
- arrayPromotion(argv);
- functionPromotion(arrayPromotion);
-}
diff --git a/clang/test/Parser/recovery-1.c b/clang/test/Parser/recovery-1.c
deleted file mode 100644
index d70cdab364a1..000000000000
--- a/clang/test/Parser/recovery-1.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -fno-caret-diagnostics -pedantic %s 2>&1 | grep warning | wc -l | grep 1 &&
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-char (((( /* expected-error {{to match this '('}} */
-*X x ] )))); /* expected-error {{expected ')'}} */
-
-; // expected-warning {{ISO C does not allow an extra ';' outside of a function}}
-
-
-
-
-struct S { void *X, *Y; };
-
-struct S A = {
- &BADIDENT, 0 /* expected-error {{use of undeclared identifier}} */
-};
diff --git a/clang/test/Parser/recovery-2.c b/clang/test/Parser/recovery-2.c
deleted file mode 100644
index 4451232dca81..000000000000
--- a/clang/test/Parser/recovery-2.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-
-// PR2241
-float f[] = {
- 1e, // expected-error {{exponent}}
- 1ee0 // expected-error {{exponent}}
-};
diff --git a/clang/test/Parser/recovery-3.c b/clang/test/Parser/recovery-3.c
deleted file mode 100644
index 40cf8cd709dd..000000000000
--- a/clang/test/Parser/recovery-3.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-// Testcase derived from PR2692
-static char *f (char * (*g) (char **, int), char **p, ...) {
- char *s;
- va_list v; // expected-error {{identifier}}
- s = g (p, __builtin_va_arg(v, int)); // expected-error {{identifier}} expected-warning {{extension}}
-}
-
diff --git a/clang/test/Parser/selector-1.m b/clang/test/Parser/selector-1.m
deleted file mode 100644
index abe94241aed0..000000000000
--- a/clang/test/Parser/selector-1.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -parse-noop %s
-
-int main() {
- SEL s = @selector(retain);
- SEL s1 = @selector(meth1:);
- SEL s2 = @selector(retainArgument::);
- SEL s3 = @selector(retainArgument:::::);
- SEL s4 = @selector(retainArgument:with:);
- SEL s5 = @selector(meth1:with:with:);
- SEL s6 = @selector(getEnum:enum:bool:);
- SEL s7 = @selector(char:float:double:unsigned:short:long:);
-
- SEL s9 = @selector(:enum:bool:);
-}
diff --git a/clang/test/Parser/statements.c b/clang/test/Parser/statements.c
deleted file mode 100644
index b3f043eaaaf7..000000000000
--- a/clang/test/Parser/statements.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-int test1() {
- { ; { ;;}} ;;
-}
-
-int test2() {
- if (0) { if (1) {} } else { }
-
- do { } while (0);
-
- while (0) while(0) do ; while(0);
-
- for (0;0;0)
- for (;;)
- for (9;0;2)
- ;
- for (int X = 0; 0; 0);
-}
-
-int test3() {
- switch (0) {
-
- case 4:
- if (0) {
- case 6: ;
- }
- default:
- ;
- }
-}
-
-int test4() {
- if (0);
-
- int X; // declaration in a block.
-
-foo: if (0);
-}
-
-typedef int t;
-void test5() {
- if (0);
-
- //t x = 0; // FIXME: Enable when handling of typedef names is impl.
-
- if (0);
-}
-
diff --git a/clang/test/Parser/struct-recursion.c b/clang/test/Parser/struct-recursion.c
deleted file mode 100644
index c16f9fc185dc..000000000000
--- a/clang/test/Parser/struct-recursion.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-// C99 6.7.2.3p11
-
-// mutually recursive structs
-struct s1 { struct s2 *A; };
-struct s2 { struct s1 *B; };
-
-// both types are complete now.
-struct s1 a;
-struct s2 b;
diff --git a/clang/test/Parser/traditional_arg_scope.c b/clang/test/Parser/traditional_arg_scope.c
deleted file mode 100644
index e1b02567eec2..000000000000
--- a/clang/test/Parser/traditional_arg_scope.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-
-x(a) int a; {return a;}
-y(b) int b; {return a;} // expected-error {{use of undeclared identifier}}
-
-// PR2332
-a(a)int a;{a=10;return a;}
diff --git a/clang/test/Parser/typeof.c b/clang/test/Parser/typeof.c
deleted file mode 100644
index 3ea277559e0a..000000000000
--- a/clang/test/Parser/typeof.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef int TInt;
-
-static void test() {
- int *pi;
-
- int typeof (int) aIntInt; // expected-error{{cannot combine with previous 'int' declaration specifier}}
- short typeof (int) aShortInt; // expected-error{{'short typeof' is invalid}}
- int int ttt; // expected-error{{cannot combine with previous 'int' declaration specifier}}
- typeof(TInt) anInt;
- short TInt eee; // expected-error{{parse error}}
- void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{parse error}}
- typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-error{{to match this '('}}
- typeof(const int) aci;
- const typeof (*pi) aConstInt;
- int xx;
- int *i;
-}
diff --git a/clang/test/Parser/types.c b/clang/test/Parser/types.c
deleted file mode 100644
index f1ffb94b98c6..000000000000
--- a/clang/test/Parser/types.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-// Test the X can be overloaded inside the struct.
-typedef int X;
-struct Y { short X; };
-
diff --git a/clang/test/Preprocessor/_Pragma-dependency.c b/clang/test/Preprocessor/_Pragma-dependency.c
deleted file mode 100644
index f7d7efe41b02..000000000000
--- a/clang/test/Preprocessor/_Pragma-dependency.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -E 2>&1 | grep 'DO_PRAGMA (STR' &&
-// RUN: clang %s -E 2>&1 | grep '7:12'
-
-#define DO_PRAGMA _Pragma
-#define STR "GCC dependency \"parse.y\"")
-// Test that this line is printed by caret diagnostics.
-DO_PRAGMA (STR
diff --git a/clang/test/Preprocessor/_Pragma-location.c b/clang/test/Preprocessor/_Pragma-location.c
deleted file mode 100644
index 152e71ac13bf..000000000000
--- a/clang/test/Preprocessor/_Pragma-location.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -E | not grep 'scratch space'
-
-#define push _Pragma ("pack(push)")
-push
diff --git a/clang/test/Preprocessor/_Pragma-physloc.c b/clang/test/Preprocessor/_Pragma-physloc.c
deleted file mode 100644
index b8f5499c7a15..000000000000
--- a/clang/test/Preprocessor/_Pragma-physloc.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -E | grep '#pragma x y z' &&
-// RUN: clang %s -E | grep '#pragma a b c'
-
-_Pragma("x y z")
-_Pragma("a b c")
-
diff --git a/clang/test/Preprocessor/_Pragma-poison.c b/clang/test/Preprocessor/_Pragma-poison.c
deleted file mode 100644
index 82a7fbecc2e8..000000000000
--- a/clang/test/Preprocessor/_Pragma-poison.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -Eonly %s 2>&1 | grep error | wc -l | grep 1 &&
-// RUN: clang -Eonly %s 2>&1 | grep 7:4 | wc -l | grep 1
-
-#define BAR _Pragma ("GCC poison XYZW") XYZW /*NO ERROR*/
-XYZW // NO ERROR
-BAR
- XYZW // ERROR
-
diff --git a/clang/test/Preprocessor/_Pragma-syshdr.c b/clang/test/Preprocessor/_Pragma-syshdr.c
deleted file mode 100644
index 4d2d29e023aa..000000000000
--- a/clang/test/Preprocessor/_Pragma-syshdr.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -E 2>&1 | grep 'system_header ignored in main file'
-
-_Pragma ("GCC system_header")
-
diff --git a/clang/test/Preprocessor/_Pragma-syshdr2.c b/clang/test/Preprocessor/_Pragma-syshdr2.c
deleted file mode 100644
index 190e5a7a3078..000000000000
--- a/clang/test/Preprocessor/_Pragma-syshdr2.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -E %s 2>&1 | grep 'file not found'
-
-#define DO_PRAGMA _Pragma
-DO_PRAGMA ("GCC dependency \"blahblabh\"")
-
diff --git a/clang/test/Preprocessor/builtin_line.c b/clang/test/Preprocessor/builtin_line.c
deleted file mode 100644
index c9ce558c1ab6..000000000000
--- a/clang/test/Preprocessor/builtin_line.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -E | grep "^ 4"
-#define FOO __LINE__
-
- FOO
diff --git a/clang/test/Preprocessor/c99-6_10_3_3_p4.c b/clang/test/Preprocessor/c99-6_10_3_3_p4.c
deleted file mode 100644
index 13d5661e3608..000000000000
--- a/clang/test/Preprocessor/c99-6_10_3_3_p4.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -E %s | grep -F 'char p[] = "x ## y";'
-#define hash_hash # ## #
-#define mkstr(a) # a
-#define in_between(a) mkstr(a)
-#define join(c, d) in_between(c hash_hash d)
-char p[] = join(x, y);
diff --git a/clang/test/Preprocessor/c99-6_10_3_4_p5.c b/clang/test/Preprocessor/c99-6_10_3_4_p5.c
deleted file mode 100644
index fa5f7358b9eb..000000000000
--- a/clang/test/Preprocessor/c99-6_10_3_4_p5.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// Example from C99 6.10.3.4p5
-
-// RUN: clang -E %s | grep -F 'f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);' &&
-// RUN: clang -E %s | grep -F 'f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);' &&
-// RUN: clang -E %s | grep -F 'int i[] = { 1, 23, 4, 5, };' &&
-// RUN: clang -E %s | grep -F 'char c[2][6] = { "hello", "" };'
-
-
-#define x 3
-#define f(a) f(x * (a))
-#undef x
-#define x 2
-#define g f
-#define z z[0]
-#define h g(~
-#define m(a) a(w)
-#define w 0,1
-#define t(a) a
-#define p() int
-#define q(x) x
-#define r(x,y) x ## y
-#define str(x) # x
- f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
- g(x+(3,4)-w) | h 5) & m
-(f)^m(m);
-p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
-char c[2][6] = { str(hello), str() };
-
-
diff --git a/clang/test/Preprocessor/c99-6_10_3_4_p6.c b/clang/test/Preprocessor/c99-6_10_3_4_p6.c
deleted file mode 100644
index ce7990a4cf3e..000000000000
--- a/clang/test/Preprocessor/c99-6_10_3_4_p6.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// Example from C99 6.10.3.4p6
-
-// RUN: clang -E %s | grep -F 'printf("x" "1" "= %d, x" "2" "= s" x1, x2);' &&
-// RUN: clang -E %s | grep 'fputs("strncmp(\\"abc\\\\0d\\" \\"abc\\", .\\\\4.) == 0" ": @\\n", s);' &&
-// RUN: clang -E %s | grep -F 'include "vers2.h"' &&
-// RUN: clang -E %s | grep -F '"hello";' &&
-// RUN: clang -E %s | grep -F '"hello" ", world"'
-
-#define str(s) # s
-#define xstr(s) str(s)
-#define debug(s, t) printf("x" # s "= %d, x" # t "= s" \
- x ## s, x ## t)
-#define INCFILE(n) vers ## n
-#define glue(a, b) a ## b
-#define xglue(a, b) glue(a, b)
-#define HIGHLOW "hello"
-#define LOW LOW ", world"
-debug(1, 2);
-fputs(str(strncmp("abc\0d" "abc", '\4') // this goes away
- == 0) str(: @\n), s);
-include xstr(INCFILE(2).h)
-glue(HIGH, LOW);
-xglue(HIGH, LOW)
-
diff --git a/clang/test/Preprocessor/c99-6_10_3_4_p7.c b/clang/test/Preprocessor/c99-6_10_3_4_p7.c
deleted file mode 100644
index 88957dfb6752..000000000000
--- a/clang/test/Preprocessor/c99-6_10_3_4_p7.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// Example from C99 6.10.3.4p7
-
-// RUN: clang -E %s | grep -F 'int j[] = { 123, 45, 67, 89,' &&
-// RUN: clang -E %s | grep -F '10, 11, 12, };'
-
-#define t(x,y,z) x ## y ## z
-int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
-t(10,,), t(,11,), t(,,12), t(,,) };
-
diff --git a/clang/test/Preprocessor/c99-6_10_3_4_p9.c b/clang/test/Preprocessor/c99-6_10_3_4_p9.c
deleted file mode 100644
index 08b4637e0e30..000000000000
--- a/clang/test/Preprocessor/c99-6_10_3_4_p9.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Example from C99 6.10.3.4p9
-
-// RUN: clang -E %s | grep -F 'fprintf(stderr, "Flag");' &&
-// RUN: clang -E %s | grep -F 'fprintf(stderr, "X = %d\n", x);' &&
-// RUN: clang -E %s | grep -F 'puts("The first, second, and third items.");' &&
-// RUN: clang -E %s | grep -F '((x>y)?puts("x>y"): printf("x is %d but y is %d", x, y));'
-
-#define debug(...) fprintf(stderr, __VA_ARGS__)
-#define showlist(...) puts(#__VA_ARGS__)
-#define report(test, ...) ((test)?puts(#test):\
- printf(__VA_ARGS__))
-debug("Flag");
-debug("X = %d\n", x);
-showlist(The first, second, and third items.);
-report(x>y, "x is %d but y is %d", x, y);
-
diff --git a/clang/test/Preprocessor/comment_save.c b/clang/test/Preprocessor/comment_save.c
deleted file mode 100644
index 1a3bd96efb5e..000000000000
--- a/clang/test/Preprocessor/comment_save.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E -C %s | grep '^// foo$' &&
-// RUN: clang -E -C %s | grep -F '^/* bar */$'
-
-// foo
-/* bar */
-
-
diff --git a/clang/test/Preprocessor/comment_save_if.c b/clang/test/Preprocessor/comment_save_if.c
deleted file mode 100644
index ce7b4c45b10e..000000000000
--- a/clang/test/Preprocessor/comment_save_if.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -E -CC -pedantic 2>&1 | grep -v '^/' | not grep warning
-
-#if 1 /*bar */
-
-#endif /*foo*/
-
diff --git a/clang/test/Preprocessor/comment_save_macro.c b/clang/test/Preprocessor/comment_save_macro.c
deleted file mode 100644
index 635a6fd4064e..000000000000
--- a/clang/test/Preprocessor/comment_save_macro.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -E -C %s | grep '^boo bork bar // zot$' &&
-// RUN: clang -E -CC %s | grep -F '^boo bork /* blah*/ bar // zot$' &&
-// RUN: clang -E %s | grep '^boo bork bar$'
-
-
-#define FOO bork // blah
-boo FOO bar // zot
-
diff --git a/clang/test/Preprocessor/cxx_and.cpp b/clang/test/Preprocessor/cxx_and.cpp
deleted file mode 100644
index b6bd00e5293d..000000000000
--- a/clang/test/Preprocessor/cxx_and.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -DA -DB -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -DB -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927'
-#if defined(A) and defined(B)
-#define X 37
-#else
-#define X 927
-#endif
-
-#if defined(A) && defined(B)
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_bitand.cpp b/clang/test/Preprocessor/cxx_bitand.cpp
deleted file mode 100644
index ecc52e89ab5a..000000000000
--- a/clang/test/Preprocessor/cxx_bitand.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -DA=1 -DB=2 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927'
-#if A bitand B
-#define X 37
-#else
-#define X 927
-#endif
-
-#if A & B
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_bitor.cpp b/clang/test/Preprocessor/cxx_bitor.cpp
deleted file mode 100644
index 36c44523df39..000000000000
--- a/clang/test/Preprocessor/cxx_bitor.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927'
-#if A bitor B
-#define X 37
-#else
-#define X 927
-#endif
-
-#if A | B
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_compl.cpp b/clang/test/Preprocessor/cxx_compl.cpp
deleted file mode 100644
index 12e589ffa1e2..000000000000
--- a/clang/test/Preprocessor/cxx_compl.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -DA=1 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA=0 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927'
-#if compl 0 bitand A
-#define X 37
-#else
-#define X 927
-#endif
-
-#if ~0 & A
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_not.cpp b/clang/test/Preprocessor/cxx_not.cpp
deleted file mode 100644
index 2587b0ab994c..000000000000
--- a/clang/test/Preprocessor/cxx_not.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -DA=1 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -E %s | grep 'int a = 37 == 37'
-#if not defined(A)
-#define X 37
-#else
-#define X 927
-#endif
-
-#if ! defined(A)
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_not_eq.cpp b/clang/test/Preprocessor/cxx_not_eq.cpp
deleted file mode 100644
index b0be7b391739..000000000000
--- a/clang/test/Preprocessor/cxx_not_eq.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -DA=1 -DB=2 -E %s | grep 'int a = 37 == 37'
-#if A not_eq B
-#define X 37
-#else
-#define X 927
-#endif
-
-#if A != B
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_oper_keyword.cpp b/clang/test/Preprocessor/cxx_oper_keyword.cpp
deleted file mode 100644
index 66586e7b36ce..000000000000
--- a/clang/test/Preprocessor/cxx_oper_keyword.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: not clang %s -E &&
-// RUN: clang %s -E -fno-operator-names
-
-// Not valid in C++ unless -fno-operator-names is passed.
-#define and foo
-
-
diff --git a/clang/test/Preprocessor/cxx_oper_spelling.cpp b/clang/test/Preprocessor/cxx_oper_spelling.cpp
deleted file mode 100644
index fc8bc70e5196..000000000000
--- a/clang/test/Preprocessor/cxx_oper_spelling.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -E %s | grep 'a: "and"'
-
-#define X(A) #A
-
-// C++'03 2.5p2: "In all respects of the language, each alternative
-// token behaves the same, respectively, as its primary token,
-// except for its spelling"
-//
-// This should be spelled as 'and', not '&&'
-a: X(and)
-
diff --git a/clang/test/Preprocessor/cxx_or.cpp b/clang/test/Preprocessor/cxx_or.cpp
deleted file mode 100644
index ce3fed1cd48f..000000000000
--- a/clang/test/Preprocessor/cxx_or.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -DA -DB -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DB -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927'
-#if defined(A) or defined(B)
-#define X 37
-#else
-#define X 927
-#endif
-
-#if defined(A) || defined(B)
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/cxx_true.cpp b/clang/test/Preprocessor/cxx_true.cpp
deleted file mode 100644
index 5ebdaf8d2fec..000000000000
--- a/clang/test/Preprocessor/cxx_true.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/* RUN: clang -E %s -x=c++ | grep block_1 &&
- RUN: clang -E %s -x=c++ | not grep block_2 &&
- RUN: clang -E %s -x=c | not grep block
-*/
-
-#if true
-block_1
-#endif
-
-#if false
-block_2
-#endif
-
diff --git a/clang/test/Preprocessor/cxx_xor.cpp b/clang/test/Preprocessor/cxx_xor.cpp
deleted file mode 100644
index 7a4c8822cda9..000000000000
--- a/clang/test/Preprocessor/cxx_xor.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37' &&
-// RUN: clang -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927' &&
-// RUN: clang -E %s | grep 'int a = 927 == 927'
-#if A xor B
-#define X 37
-#else
-#define X 927
-#endif
-
-#if A ^ B
-#define Y 37
-#else
-#define Y 927
-#endif
-
-int a = X == Y;
diff --git a/clang/test/Preprocessor/disabled-cond-diags.c b/clang/test/Preprocessor/disabled-cond-diags.c
deleted file mode 100644
index df9dc8919b1f..000000000000
--- a/clang/test/Preprocessor/disabled-cond-diags.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -E %s 2>&1 | not grep "warning\|error"
-
-#if 0
-
-// Shouldn't get warnings here.
-??( ??)
-
-// Should not get an error here.
-` ` ` `
-#endif
diff --git a/clang/test/Preprocessor/dumptokens_phyloc.c b/clang/test/Preprocessor/dumptokens_phyloc.c
deleted file mode 100644
index ea468728bb4f..000000000000
--- a/clang/test/Preprocessor/dumptokens_phyloc.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -dumptokens %s 2>&1 | grep "PhysLoc=[-_.a-zA-Z/\\]*:3:20"
-
-#define TESTPHYLOC 10
-
-TESTPHYLOC
diff --git a/clang/test/Preprocessor/expr_comma.c b/clang/test/Preprocessor/expr_comma.c
deleted file mode 100644
index e36f0407bf8d..000000000000
--- a/clang/test/Preprocessor/expr_comma.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Comma is not allowed in C89
-// RUN: not clang -E %s -std=c89 -pedantic-errors &&
-
-// Comma is allowed if unevaluated in C99
-// RUN: clang -E %s -std=c99 -pedantic-errors
-
-// PR2279
-
-#if 0? 1,2:3
-#endif
diff --git a/clang/test/Preprocessor/expr_invalid_tok.c b/clang/test/Preprocessor/expr_invalid_tok.c
deleted file mode 100644
index 877a845eff66..000000000000
--- a/clang/test/Preprocessor/expr_invalid_tok.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: not clang -E %s 2>&1 | grep 'invalid token at start of a preprocessor expression' &&
-// RUN: not clang -E %s 2>&1 | grep 'token is not a valid binary operator in a preprocessor subexpression' &&
-// RUN: not clang -E %s 2>&1 | grep ':14: error: expected end of line in preprocessor expression'
-// PR2220
-
-#if 1 * * 2
-#endif
-
-#if 4 [ 2
-#endif
-
-
-// PR2284 - The constant-expr production does not including comma.
-#if 1 ? 2 : 0, 1
-#endif
diff --git a/clang/test/Preprocessor/expr_liveness.c b/clang/test/Preprocessor/expr_liveness.c
deleted file mode 100644
index 3f4003ea3af1..000000000000
--- a/clang/test/Preprocessor/expr_liveness.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* RUN: clang -E %s -DNO_ERRORS &&
- RUN: not clang -E %s
- */
-
-#ifdef NO_ERRORS
-/* None of these divisions by zero are in live parts of the expression, do not
- emit any diagnostics. */
-
-#define MACRO_0 0
-#define MACRO_1 1
-
-#if MACRO_0 && 10 / MACRO_0
-foo
-#endif
-
-#if MACRO_1 || 10 / MACRO_0
-bar
-#endif
-
-#if 0 ? 124/0 : 42
-#endif
-
-// PR2279
-#if 0 ? 1/0: 2
-#else
-#error
-#endif
-
-// PR2279
-#if 1 ? 2 ? 3 : 4 : 5
-#endif
-
-// PR2284
-#if 1 ? 0: 1 ? 1/0: 1/0
-#endif
-
-#else
-
-
-/* The 1/0 is live, it should error out. */
-#if 0 && 1 ? 4 : 1 / 0
-baz
-#endif
-
-
-#endif
diff --git a/clang/test/Preprocessor/expr_usual_conversions.c b/clang/test/Preprocessor/expr_usual_conversions.c
deleted file mode 100644
index 90275c994444..000000000000
--- a/clang/test/Preprocessor/expr_usual_conversions.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang %s -E 2>&1 | grep warning | wc -l | grep 2
-
-#define INTMAX_MIN (-9223372036854775807LL -1)
-
-#if (-42 + 0U) / -2
-foo
-#endif
-
-// Shifts don't want the usual conversions: PR2279
-#if (2 << 1U) - 30 >= 0
-#error
-#endif
-
diff --git a/clang/test/Preprocessor/extension-warning.c b/clang/test/Preprocessor/extension-warning.c
deleted file mode 100644
index c325c2fcf232..000000000000
--- a/clang/test/Preprocessor/extension-warning.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-// The preprocessor shouldn't warn about extensions within macro bodies that
-// aren't expanded.
-#define __block __attribute__((__blocks__(byref)))
-
-// This warning is entirely valid.
-__block int x; // expected-warning{{extension used}}
-
-void whatever() {}
diff --git a/clang/test/Preprocessor/file_to_include.h b/clang/test/Preprocessor/file_to_include.h
deleted file mode 100644
index 97728ab0830b..000000000000
--- a/clang/test/Preprocessor/file_to_include.h
+++ /dev/null
@@ -1,3 +0,0 @@
-
-#warning file successfully included
-
diff --git a/clang/test/Preprocessor/function_macro_file.c b/clang/test/Preprocessor/function_macro_file.c
deleted file mode 100644
index eeb9256ec738..000000000000
--- a/clang/test/Preprocessor/function_macro_file.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* RUN: clang -E -P %s | grep f
- */
-
-#include "function_macro_file.h"
-()
diff --git a/clang/test/Preprocessor/function_macro_file.h b/clang/test/Preprocessor/function_macro_file.h
deleted file mode 100644
index 43d1199bfebb..000000000000
--- a/clang/test/Preprocessor/function_macro_file.h
+++ /dev/null
@@ -1,3 +0,0 @@
-
-#define f() x
-f
diff --git a/clang/test/Preprocessor/hash_line.c b/clang/test/Preprocessor/hash_line.c
deleted file mode 100644
index 788440ba82aa..000000000000
--- a/clang/test/Preprocessor/hash_line.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// The 1 and # should not go on the same line.
-// RUN: clang %s -E | not grep "1 #" &&
-// RUN: clang %s -E | grep '^1$' &&
-// RUN: clang %s -E | grep '^ #$'
-1
-#define EMPTY
-EMPTY #
-
diff --git a/clang/test/Preprocessor/hash_space.c b/clang/test/Preprocessor/hash_space.c
deleted file mode 100644
index 77f5cfc5306f..000000000000
--- a/clang/test/Preprocessor/hash_space.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -E | grep " #"
-
-// Should put a space before the # so that -fpreprocessed mode doesn't
-// macro expand this again.
-#define HASH #
-HASH define foo bar
diff --git a/clang/test/Preprocessor/header_lookup1.c b/clang/test/Preprocessor/header_lookup1.c
deleted file mode 100644
index 10049adcd374..000000000000
--- a/clang/test/Preprocessor/header_lookup1.c
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang -I /usr/include %s -E | grep 'stdio.h.*3.*4'
-#include <stdio.h>
diff --git a/clang/test/Preprocessor/if_warning.c b/clang/test/Preprocessor/if_warning.c
deleted file mode 100644
index bf30d303b66d..000000000000
--- a/clang/test/Preprocessor/if_warning.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -E -Wundef -Werror 2>&1 | grep error | count 1 &&
-// RUN: clang %s -E -Werror 2>&1 | not grep error
-
-#if foo // Should generate an warning
-#endif
-
-#ifdef foo
-#endif
-
-#if defined(foo)
-#endif
-
diff --git a/clang/test/Preprocessor/ifdef-recover.c b/clang/test/Preprocessor/ifdef-recover.c
deleted file mode 100644
index 7fad8c20bd4c..000000000000
--- a/clang/test/Preprocessor/ifdef-recover.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* RUN: clang -E %s 2>&1 >/dev/null | grep error: | count 3
- */
-
-#ifdef
-
-#endif
-
-/* End of function-like macro invocation in #ifdef */
-/* PR1936 */
-#define f(x) x
-#if f(2
-#endif
-
-int x;
-
diff --git a/clang/test/Preprocessor/import_self.c b/clang/test/Preprocessor/import_self.c
deleted file mode 100644
index e8f6fa793d1b..000000000000
--- a/clang/test/Preprocessor/import_self.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E -I. %s | grep BODY_OF_FILE | wc -l | grep 1
-
-// This #import should have no effect, as we're importing the current file.
-#import <import_self.c>
-
-BODY_OF_FILE
-
diff --git a/clang/test/Preprocessor/includeexpand.c b/clang/test/Preprocessor/includeexpand.c
deleted file mode 100644
index 89696c470cc4..000000000000
--- a/clang/test/Preprocessor/includeexpand.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -E %s -fno-caret-diagnostics 2>&1 >/dev/null | grep 'file successfully included' | count 3
-
-// XX expands to nothing.
-#define XX
-
-#define FILE "file_to_include.h"
-#include XX FILE
-
-#include FILE
-
-
-#include "file_to_include.h"
diff --git a/clang/test/Preprocessor/includeexpand2.c b/clang/test/Preprocessor/includeexpand2.c
deleted file mode 100644
index 970c9abe40f9..000000000000
--- a/clang/test/Preprocessor/includeexpand2.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -Eonly %s -I.
-# define HEADER <stdio.h>
-
-# include HEADER
diff --git a/clang/test/Preprocessor/indent_macro.c b/clang/test/Preprocessor/indent_macro.c
deleted file mode 100644
index 0dcaa7b4b9af..000000000000
--- a/clang/test/Preprocessor/indent_macro.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -E %s | grep '^ zzap$'
-
-// zzap is on a new line, should be indented.
-#define BLAH zzap
- BLAH
-
diff --git a/clang/test/Preprocessor/macro_arg_keyword.c b/clang/test/Preprocessor/macro_arg_keyword.c
deleted file mode 100644
index 1f9d7e790f4f..000000000000
--- a/clang/test/Preprocessor/macro_arg_keyword.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -E %s | grep xxx-xxx
-
-#define foo(return) return-return
-
-foo(xxx)
-
diff --git a/clang/test/Preprocessor/macro_defined.c b/clang/test/Preprocessor/macro_defined.c
deleted file mode 100644
index f1201977161d..000000000000
--- a/clang/test/Preprocessor/macro_defined.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -E 2>&1 | not grep error
-
-// This should not be rejected.
-#ifdef defined
-#endif
-
diff --git a/clang/test/Preprocessor/macro_disable.c b/clang/test/Preprocessor/macro_disable.c
deleted file mode 100644
index 33b856d8f645..000000000000
--- a/clang/test/Preprocessor/macro_disable.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -E %s | grep 'a: 2 + M_0(3)(4)(5);' &&
-// RUN: clang -E %s | grep 'b: 4 + 4 + 3 + 2 + 1 + M_0(3)(2)(1);'
-
-#define M_0(x) M_ ## x
-#define M_1(x) x + M_0(0)
-#define M_2(x) x + M_1(1)
-#define M_3(x) x + M_2(2)
-#define M_4(x) x + M_3(3)
-#define M_5(x) x + M_4(4)
-
-a: M_0(1)(2)(3)(4)(5);
-b: M_0(5)(4)(3)(2)(1);
-
diff --git a/clang/test/Preprocessor/macro_disable2.c b/clang/test/Preprocessor/macro_disable2.c
deleted file mode 100644
index 6e1f80469c34..000000000000
--- a/clang/test/Preprocessor/macro_disable2.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -E %s | grep 'A B C A B A C A B C A'
-
-#define A A B C
-#define B B C A
-#define C C A B
-
-A
-
diff --git a/clang/test/Preprocessor/macro_disable3.c b/clang/test/Preprocessor/macro_disable3.c
deleted file mode 100644
index b358a556775e..000000000000
--- a/clang/test/Preprocessor/macro_disable3.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang %s -E | grep -F 'f(2 * (f(2 * (z[0]))));'
-// Check for C99 6.10.3.4p2.
-
-#define f(a) f(x * (a))
-#define x 2
-#define z z[0]
-f(f(z));
-
diff --git a/clang/test/Preprocessor/macro_disable4.c b/clang/test/Preprocessor/macro_disable4.c
deleted file mode 100644
index 4858813a0ec0..000000000000
--- a/clang/test/Preprocessor/macro_disable4.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -P -E %s | grep 'int f(void)'
-// PR1820
-
-#define f(x) h(x
-#define h(x) x(void)
-extern int f(f));
diff --git a/clang/test/Preprocessor/macro_expand.c b/clang/test/Preprocessor/macro_expand.c
deleted file mode 100644
index 69a4835c5a6b..000000000000
--- a/clang/test/Preprocessor/macro_expand.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E %s | grep '^Y$'
-
-#define X() Y
-#define Y() X
-
-X()()()
-
diff --git a/clang/test/Preprocessor/macro_expandloc.c b/clang/test/Preprocessor/macro_expandloc.c
deleted file mode 100644
index 00bba6f60d7b..000000000000
--- a/clang/test/Preprocessor/macro_expandloc.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -E 2>&1 | grep '#include'
-#define FOO 1
-
-// The error message should be on the #include line, not the 1.
-#include FOO
-
diff --git a/clang/test/Preprocessor/macro_expandloc2.c b/clang/test/Preprocessor/macro_expandloc2.c
deleted file mode 100644
index 3a833299fdf9..000000000000
--- a/clang/test/Preprocessor/macro_expandloc2.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -E 2>&1 | grep '#include'
-#define FOO BAR
-
-// The error message should be on the #include line, not the 1.
-#include FOO
-
diff --git a/clang/test/Preprocessor/macro_fn_comma_swallow.c b/clang/test/Preprocessor/macro_fn_comma_swallow.c
deleted file mode 100644
index d4f3bb9940dd..000000000000
--- a/clang/test/Preprocessor/macro_fn_comma_swallow.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Test the GNU comma swallowing extension.
-// RUN: clang %s -E | grep 'foo{A, }' &&
-// RUN: clang %s -E | grep 'fo2{A,}' &&
-// RUN: clang %s -E | grep '{foo}'
-
-#define X(Y) foo{A, Y}
-X()
-
-#define X2(Y) fo2{A,##Y}
-X2()
-
-// should eat the comma.
-#define X3(b, ...) {b, ## __VA_ARGS__}
-X3(foo)
-
-
diff --git a/clang/test/Preprocessor/macro_fn_disable_expand.c b/clang/test/Preprocessor/macro_fn_disable_expand.c
deleted file mode 100644
index a9e1d46f06a2..000000000000
--- a/clang/test/Preprocessor/macro_fn_disable_expand.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -E | grep 'bar foo (2)' &&
-// RUN: clang %s -E | grep 'm(ABCD)'
-
-#define foo(x) bar x
-foo(foo) (2)
-
-
-#define m(a) a(w)
-#define w ABCD
-m(m) // m(ABCD)
-
diff --git a/clang/test/Preprocessor/macro_fn_lparen_scan.c b/clang/test/Preprocessor/macro_fn_lparen_scan.c
deleted file mode 100644
index 497ef230d26a..000000000000
--- a/clang/test/Preprocessor/macro_fn_lparen_scan.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -E %s | grep 'noexp: foo y' &&
-// RUN: clang -E %s | grep 'expand: abc' &&
-// RUN: clang -E %s | grep 'noexp2: foo nonexp' &&
-// RUN: clang -E %s | grep 'expand2: abc'
-
-#define A foo
-#define foo() abc
-#define X A y
-
-// This should not expand to abc, because the foo macro isn't followed by (.
-noexp: X
-
-
-// This should expand to abc.
-#undef X
-#define X A ()
-expand: X
-
-
-// This should be 'foo nonexp'
-noexp2: A nonexp
-
-// This should expand
-expand2: A (
-)
-
-
diff --git a/clang/test/Preprocessor/macro_fn_lparen_scan2.c b/clang/test/Preprocessor/macro_fn_lparen_scan2.c
deleted file mode 100644
index fa4d5047fb08..000000000000
--- a/clang/test/Preprocessor/macro_fn_lparen_scan2.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E %s | grep 'FUNC (3 +1);'
-
-#define F(a) a
-#define FUNC(a) (a+1)
-
-F(FUNC) FUNC (3); /* final token sequence is FUNC(3+1) */
-
diff --git a/clang/test/Preprocessor/macro_fn_placemarker.c b/clang/test/Preprocessor/macro_fn_placemarker.c
deleted file mode 100644
index 30c0bcf47fad..000000000000
--- a/clang/test/Preprocessor/macro_fn_placemarker.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -E | grep 'foo(A, )'
-
-#define X(Y) foo(A, Y)
-X()
-
diff --git a/clang/test/Preprocessor/macro_fn_preexpand.c b/clang/test/Preprocessor/macro_fn_preexpand.c
deleted file mode 100644
index 81a7c4172684..000000000000
--- a/clang/test/Preprocessor/macro_fn_preexpand.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -E | grep 'pre: 1 1 X' &&
-// RUN: clang %s -E | grep 'nopre: 1A(X)'
-
-/* Preexpansion of argument. */
-#define A(X) 1 X
-pre: A(A(X))
-
-/* The ## operator disables preexpansion. */
-#undef A
-#define A(X) 1 ## X
-nopre: A(A(X))
-
diff --git a/clang/test/Preprocessor/macro_fn_varargs_iso.c b/clang/test/Preprocessor/macro_fn_varargs_iso.c
deleted file mode 100644
index 716e920336e5..000000000000
--- a/clang/test/Preprocessor/macro_fn_varargs_iso.c
+++ /dev/null
@@ -1,11 +0,0 @@
-
-// RUN: clang -E %s | grep 'foo{a, b, c, d, e}' &&
-// RUN: clang -E %s | grep 'foo2{d, C, B}' &&
-// RUN: clang -E %s | grep 'foo2{d,e, C, B}'
-
-#define va1(...) foo{a, __VA_ARGS__, e}
-va1(b, c, d)
-#define va2(a, b, ...) foo2{__VA_ARGS__, b, a}
-va2(B, C, d)
-va2(B, C, d,e)
-
diff --git a/clang/test/Preprocessor/macro_fn_varargs_named.c b/clang/test/Preprocessor/macro_fn_varargs_named.c
deleted file mode 100644
index b3bb72c64310..000000000000
--- a/clang/test/Preprocessor/macro_fn_varargs_named.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -E %s | grep '^a: x$' &&
-// RUN: clang -E %s | grep '^b: x y, z,h$' &&
-// RUN: clang -E %s | grep '^c: foo(x)$'
-
-#define A(b, c...) b c
-a: A(x)
-b: A(x, y, z,h)
-
-#define B(b, c...) foo(b, ## c)
-c: B(x)
diff --git a/clang/test/Preprocessor/macro_not_define.c b/clang/test/Preprocessor/macro_not_define.c
deleted file mode 100644
index 388481a90e87..000000000000
--- a/clang/test/Preprocessor/macro_not_define.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -E %s | grep '^ # define X 3$'
-
-#define H #
- #define D define
-
- #define DEFINE(a, b) H D a b
-
- DEFINE(X, 3)
-
diff --git a/clang/test/Preprocessor/macro_paste_bad.c b/clang/test/Preprocessor/macro_paste_bad.c
deleted file mode 100644
index 60caa4274389..000000000000
--- a/clang/test/Preprocessor/macro_paste_bad.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -Eonly %s 2>&1 | grep error
-// pasting ""x"" and ""+"" does not give a valid preprocessing token
-#define XYZ x ## +
-XYZ
-
diff --git a/clang/test/Preprocessor/macro_paste_bcpl_comment.c b/clang/test/Preprocessor/macro_paste_bcpl_comment.c
deleted file mode 100644
index 9a864d520cc5..000000000000
--- a/clang/test/Preprocessor/macro_paste_bcpl_comment.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -Eonly 2>&1 | grep error
-
-#define COMM1 / ## /
-COMM1
-
diff --git a/clang/test/Preprocessor/macro_paste_c_block_comment.c b/clang/test/Preprocessor/macro_paste_c_block_comment.c
deleted file mode 100644
index 9299514c51e2..000000000000
--- a/clang/test/Preprocessor/macro_paste_c_block_comment.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -Eonly 2>&1 | grep error &&
-// RUN: clang %s -Eonly 2>&1 | not grep unterminated &&
-// RUN: clang %s -Eonly 2>&1 | not grep scratch
-
-#define COMM / ## *
-COMM
-
diff --git a/clang/test/Preprocessor/macro_paste_commaext.c b/clang/test/Preprocessor/macro_paste_commaext.c
deleted file mode 100644
index e75ac1f5740a..000000000000
--- a/clang/test/Preprocessor/macro_paste_commaext.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang %s -E | grep 'V);' &&
-// RUN: clang %s -E | grep 'W, 1, 2);' &&
-// RUN: clang %s -E | grep 'X, 1, 2);' &&
-// RUN: clang %s -E | grep 'Y, );' &&
-// RUN: clang %s -E | grep 'Z, );'
-
-#define debug(format, ...) format, ## __VA_ARGS__)
-debug(V);
-debug(W, 1, 2);
-debug(X, 1, 2 );
-debug(Y, );
-debug(Z,);
-
diff --git a/clang/test/Preprocessor/macro_paste_empty.c b/clang/test/Preprocessor/macro_paste_empty.c
deleted file mode 100644
index 8b78ecddd68d..000000000000
--- a/clang/test/Preprocessor/macro_paste_empty.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -E %s | grep 'a:Y' &&
-// RUN: clang -E %s | grep 'b:Y' &&
-// RUN: clang -E %s | grep 'c:YY'
-
-#define FOO(X) X ## Y
-a:FOO()
-
-#define FOO2(X) Y ## X
-b:FOO2()
-
-#define FOO3(X) X ## Y ## X ## Y ## X ## X
-c:FOO3()
-
diff --git a/clang/test/Preprocessor/macro_paste_hard.c b/clang/test/Preprocessor/macro_paste_hard.c
deleted file mode 100644
index be467456bf7f..000000000000
--- a/clang/test/Preprocessor/macro_paste_hard.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -E %s | grep '1: aaab 2' &&
-// RUN: clang -E %s | grep '2: 2 baaa' &&
-// RUN: clang -E %s | grep '3: 2 xx'
-
-#define a(n) aaa ## n
-#define b 2
-1: a(b b) // aaab 2 2 gets expanded, not b.
-
-#undef a
-#undef b
-#define a(n) n ## aaa
-#define b 2
-2: a(b b) // 2 baaa 2 gets expanded, not b.
-
-#define baaa xx
-3: a(b b) // 2 xx
-
diff --git a/clang/test/Preprocessor/macro_paste_hashhash.c b/clang/test/Preprocessor/macro_paste_hashhash.c
deleted file mode 100644
index 4ebf55e41f39..000000000000
--- a/clang/test/Preprocessor/macro_paste_hashhash.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E %s | grep '^"x ## y";$'
-#define hash_hash # ## #
-#define mkstr(a) # a
-#define in_between(a) mkstr(a)
-#define join(c, d) in_between(c hash_hash d)
-join(x, y);
-
diff --git a/clang/test/Preprocessor/macro_paste_mscomment.c b/clang/test/Preprocessor/macro_paste_mscomment.c
deleted file mode 100644
index 858337a879b8..000000000000
--- a/clang/test/Preprocessor/macro_paste_mscomment.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -P -E -fms-extensions %s | sed '/^#.\+/d' | tr -d '\n' |
-// RUN: grep '^int foo;int bar;int baz;$' | count 1
-// This horrible stuff should preprocess into (other than whitespace):
-// int foo;
-// int bar;
-// int baz;
-
-int foo;
-
-#define comment /##/ dead tokens live here
-comment This is stupidity
-
-int bar;
-
-#define nested(x) int x comment cute little dead tokens...
-
-nested(baz) rise of the dead tokens
-
-;
-
diff --git a/clang/test/Preprocessor/macro_paste_none.c b/clang/test/Preprocessor/macro_paste_none.c
deleted file mode 100644
index 2ba2820b16c3..000000000000
--- a/clang/test/Preprocessor/macro_paste_none.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -E %s | grep '!!'
-
-#define A(B,C) B ## C
-
-!A(,)!
-
diff --git a/clang/test/Preprocessor/macro_paste_simple.c b/clang/test/Preprocessor/macro_paste_simple.c
deleted file mode 100644
index 82b75daf5714..000000000000
--- a/clang/test/Preprocessor/macro_paste_simple.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -E | grep "barbaz123"
-
-#define FOO bar ## baz ## 123
-
-FOO
diff --git a/clang/test/Preprocessor/macro_paste_spacing.c b/clang/test/Preprocessor/macro_paste_spacing.c
deleted file mode 100644
index 471ebcc01559..000000000000
--- a/clang/test/Preprocessor/macro_paste_spacing.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -E | grep "^xy$"
-
-#define A x ## y
-blah
-
-A
-
diff --git a/clang/test/Preprocessor/macro_rescan.c b/clang/test/Preprocessor/macro_rescan.c
deleted file mode 100644
index 2ceb2923ca0d..000000000000
--- a/clang/test/Preprocessor/macro_rescan.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -E %s | grep 'ei_1 = (17 +1);' &&
-// RUN: clang -E %s | grep 'ei_2 = (M1)(17);'
-
-#define M1(a) (a+1)
-#define M2(b) b
-
-int ei_1 = M2(M1)(17); /* becomes int ei_1 = (17+1); */
-int ei_2 = (M2(M1))(17); /* becomes int ei_2 = (M1)(17); */
-
diff --git a/clang/test/Preprocessor/macro_rescan2.c b/clang/test/Preprocessor/macro_rescan2.c
deleted file mode 100644
index 4fae444002d1..000000000000
--- a/clang/test/Preprocessor/macro_rescan2.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang %s -E | grep 'a: 2\*f(9)' &&
-// RUN: clang %s -E | grep 'b: 2\*9\*g'
-
-#define f(a) a*g
-#define g f
-a: f(2)(9)
-
-#undef f
-#undef g
-
-#define f(a) a*g
-#define g(a) f(a)
-
-b: f(2)(9)
-
diff --git a/clang/test/Preprocessor/macro_rescan_varargs.c b/clang/test/Preprocessor/macro_rescan_varargs.c
deleted file mode 100644
index 3c79d0e99312..000000000000
--- a/clang/test/Preprocessor/macro_rescan_varargs.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -E %s | grep -F "1: F, (, 'a', 'b', );" &&
-// RUN: clang -E %s | grep -F "2: 'a' + 'b';"
-#define LPAREN (
-#define RPAREN )
-#define F(x, y) x + y
-#define ELLIP_FUNC(...) __VA_ARGS__
-
-1: ELLIP_FUNC(F, LPAREN, 'a', 'b', RPAREN); /* 1st invocation */
-2: ELLIP_FUNC(F LPAREN 'a', 'b' RPAREN); /* 2nd invocation */
-
diff --git a/clang/test/Preprocessor/macro_rparen_scan.c b/clang/test/Preprocessor/macro_rparen_scan.c
deleted file mode 100644
index d4e62837ae69..000000000000
--- a/clang/test/Preprocessor/macro_rparen_scan.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -E %s | grep '^3 ;$'
-
-/* Right paren scanning, hard case. Should expand to 3. */
-#define i(x) 3
-#define a i(yz
-#define b )
-a b ) ;
-
diff --git a/clang/test/Preprocessor/macro_rparen_scan2.c b/clang/test/Preprocessor/macro_rparen_scan2.c
deleted file mode 100644
index a9ca9d1bb452..000000000000
--- a/clang/test/Preprocessor/macro_rparen_scan2.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -E %s | grep -F 'static int glob = (1 + 1 );'
-
-#define R_PAREN )
-
-#define FUNC(a) a
-
-static int glob = (1 + FUNC(1 R_PAREN );
-
diff --git a/clang/test/Preprocessor/macro_space.c b/clang/test/Preprocessor/macro_space.c
deleted file mode 100644
index 553fddb68f69..000000000000
--- a/clang/test/Preprocessor/macro_space.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -E | grep '! ,'
-
-#define XX
-! XX,
-
diff --git a/clang/test/Preprocessor/mi_opt.c b/clang/test/Preprocessor/mi_opt.c
deleted file mode 100644
index 96029dc95abd..000000000000
--- a/clang/test/Preprocessor/mi_opt.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: not clang -fsyntax-only %s
-// PR1900
-// This test should get a redefinition error from m_iopt.h: the MI opt
-// shouldn't apply.
-
-#define MACRO
-#include "mi_opt.h"
-#undef MACRO
-#define MACRO || 1
-#include "mi_opt.h"
-
diff --git a/clang/test/Preprocessor/mi_opt.h b/clang/test/Preprocessor/mi_opt.h
deleted file mode 100644
index a82aa6af0f9c..000000000000
--- a/clang/test/Preprocessor/mi_opt.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#if !defined foo MACRO
-#define foo
-int x = 2;
-#endif
diff --git a/clang/test/Preprocessor/output_paste_avoid.c b/clang/test/Preprocessor/output_paste_avoid.c
deleted file mode 100644
index 7fe8788a267d..000000000000
--- a/clang/test/Preprocessor/output_paste_avoid.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -E %s | grep '+ + - - + + = = =' &&
-// RUN: clang -E %s | not grep -F '...' &&
-// RUN: clang -E %s | not grep -F 'L"str"'
-
-// This should print as ".. ." to avoid turning into ...
-#define y(a) ..a
-y(.)
-
-#define PLUS +
-#define EMPTY
-#define f(x) =x=
-+PLUS -EMPTY- PLUS+ f(=)
-
-
-// Should expand to L "str" not L"str"
-#define test(x) L#x
-test(str)
-
diff --git a/clang/test/Preprocessor/paste_bad.c b/clang/test/Preprocessor/paste_bad.c
deleted file mode 100644
index 89e879957e4f..000000000000
--- a/clang/test/Preprocessor/paste_bad.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// GCC PR 20077
-// RUN: not clang -E %s &&
-// RUN: not clang -E %s 2>&1 | grep error: | wc -l | grep 10
-
-#define a a ## ## /* { dg-error "end of a macro expansion" } */
-#define b() b ## ## /* { dg-error "end of a macro expansion" } */
-#define c c ## /* { dg-error "end of a macro expansion" } */
-#define d() d ## /* { dg-error "end of a macro expansion" } */
-
-
-#define e ## ## e /* { dg-error "end of a macro expansion" } */
-#define f() ## ## f /* { dg-error "end of a macro expansion" } */
-#define g ## g /* { dg-error "end of a macro expansion" } */
-#define h() ## h /* { dg-error "end of a macro expansion" } */
-#define i ## /* { dg-error "end of a macro expansion" } */
-#define j() ## /* { dg-error "end of a macro expansion" } */
-
diff --git a/clang/test/Preprocessor/poison.c b/clang/test/Preprocessor/poison.c
deleted file mode 100644
index 5df4b47918f9..000000000000
--- a/clang/test/Preprocessor/poison.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -E 2>&1 | grep error
-
-#pragma GCC poison rindex
-rindex(some_string, 'h');
diff --git a/clang/test/Preprocessor/poison_expansion.c b/clang/test/Preprocessor/poison_expansion.c
deleted file mode 100644
index 3444bace4d62..000000000000
--- a/clang/test/Preprocessor/poison_expansion.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s -E 2>&1 | not grep error
-
-#define strrchr rindex
-#pragma GCC poison rindex
-
-// Can poison multiple times.
-#pragma GCC poison rindex
-
-strrchr(some_string, 'h');
diff --git a/clang/test/Preprocessor/pr2086.c b/clang/test/Preprocessor/pr2086.c
deleted file mode 100644
index ddf2c166cdda..000000000000
--- a/clang/test/Preprocessor/pr2086.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -E %s
-
-#define test
-#include "pr2086.h"
-#define test
-#include "pr2086.h"
-
-#ifdef test
-#error
-#endif
-
diff --git a/clang/test/Preprocessor/pr2086.h b/clang/test/Preprocessor/pr2086.h
deleted file mode 100644
index b98b996d6cca..000000000000
--- a/clang/test/Preprocessor/pr2086.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef test
-#endif
-
-#ifdef test
-#undef test
-#endif
diff --git a/clang/test/Preprocessor/pragma_unknown.c b/clang/test/Preprocessor/pragma_unknown.c
deleted file mode 100644
index ca2bea10e19c..000000000000
--- a/clang/test/Preprocessor/pragma_unknown.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -E %s | grep '#pragma foo bar'
-
-// GCC doesn't expand macro args for unrecognized pragmas.
-#define bar xX
-#pragma foo bar
-
diff --git a/clang/test/Preprocessor/print_line_track.c b/clang/test/Preprocessor/print_line_track.c
deleted file mode 100644
index 567da3c1a213..000000000000
--- a/clang/test/Preprocessor/print_line_track.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* RUN: clang -E %s | grep 'a 3' &&
- * RUN: clang -E %s | grep 'b 14' &&
- * RUN: clang -E -P %s | grep 'a 3' &&
- * RUN: clang -E -P %s | grep 'b 14'
- * PR1848
-*/
-
-#define t(x) x
-
-t(a
-3)
-
-t(b
-__LINE__)
-
diff --git a/clang/test/Preprocessor/stringize_misc.c b/clang/test/Preprocessor/stringize_misc.c
deleted file mode 100644
index b8e4480ef836..000000000000
--- a/clang/test/Preprocessor/stringize_misc.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -E %s | grep -F '"f(1, 2)" "g((x=y++, y))"' &&
-// RUN: clang -E %s | grep -F '"{a=1" "b=2;}"' &&
-// RUN: clang -E %s | grep -F '"<" "["' &&
-// RUN: clang -E %s | grep -F '"(,)" "(...)"' &&
-// RUN: clang -E %s | grep -F '{a=1 c=3; b=2;}' &&
-// RUN: clang -E %s | grep -F '"a COMMA b" "(a, b)"'
-
-#define M(x, y) #x #y
-
-M( f(1, 2), g((x=y++, y)))
-M( {a=1 , b=2;} ) /* A semicolon is not a comma */
-M( <, [ ) /* Passes the arguments < and [ */
-M( (,), (...) ) /* Passes the arguments (,) and (...) */
-
-#define START_END(start, end) start c=3; end
-
-START_END( {a=1 , b=2;} ) /* braces are not parentheses */
-
-/*
- * To pass a comma token as an argument it is
- * necessary to write:
- */
-#define COMMA ,
-
-M(a COMMA b, (a, b))
-
diff --git a/clang/test/Preprocessor/stringize_space.c b/clang/test/Preprocessor/stringize_space.c
deleted file mode 100644
index 8c83677d6794..000000000000
--- a/clang/test/Preprocessor/stringize_space.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -E %s | grep -- '-"" , - "" , -"" , - ""'
-
-#define A(b) -#b , - #b , -# b , - # b
-A()
diff --git a/clang/test/Preprocessor/stringize_space2.c b/clang/test/Preprocessor/stringize_space2.c
deleted file mode 100644
index cf81674065bb..000000000000
--- a/clang/test/Preprocessor/stringize_space2.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* RUN: clang -E %s | grep 'a c'
- */
-#define t(x) #x
-t(a
-c)
-
diff --git a/clang/test/Preprocessor/undef-error.c b/clang/test/Preprocessor/undef-error.c
deleted file mode 100644
index a2769345babf..000000000000
--- a/clang/test/Preprocessor/undef-error.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -pedantic-errors -verify
-// PR2045
-
-#define b
-/* expected-error {{extra tokens at end of #undef directive}} */ #undef a b
diff --git a/clang/test/Rewriter/block-test.c b/clang/test/Rewriter/block-test.c
deleted file mode 100644
index 0a6bde0886ad..000000000000
--- a/clang/test/Rewriter/block-test.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -rewrite-blocks %s -o -
-
-typedef void (^test_block_t)();
-
-int main(int argc, char **argv) {
- int a;
-
- void (^test_block_v)();
- void (^test_block_v2)(int, float);
-
- void (^test_block_v3)(void (^barg)(int));
-
- a = 77;
- test_block_v = ^(){ int local=1; printf("a=%d\n",a+local); };
- test_block_v();
- a++;
- test_block_v();
-
- __block int b;
-
- b = 88;
- test_block_v2 = ^(int x, float f){ printf("b=%d\n",b); };
- test_block_v2(1,2.0);
- b++;
- test_block_v2(3,4.0);
- return 7;
-}
diff --git a/clang/test/Rewriter/crash.m b/clang/test/Rewriter/crash.m
deleted file mode 100644
index 59f18f37c2c9..000000000000
--- a/clang/test/Rewriter/crash.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -rewrite-objc -o - %s
-// rdar://5950938
-@interface NSArray {}
-+ (id)arrayWithObjects:(id)firstObj, ...;
-@end
-
-@interface NSConstantString {}
-@end
-
-int main() {
- id foo = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12", 0];
- return 0;
-}
-
diff --git a/clang/test/Rewriter/id-test-3.m b/clang/test/Rewriter/id-test-3.m
deleted file mode 100644
index 121af3e588e0..000000000000
--- a/clang/test/Rewriter/id-test-3.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol P
-- (id<P>) Meth: (id<P>) Arg;
-@end
-
-@interface INTF<P>
-- (id<P>)IMeth;
-@end
-
-@implementation INTF
-- (id<P>)IMeth { return [(id<P>)self Meth: (id<P>)0]; }
-- (id<P>) Meth : (id<P>) Arg {}
-@end
diff --git a/clang/test/Rewriter/ivar-encoding-1.m b/clang/test/Rewriter/ivar-encoding-1.m
deleted file mode 100644
index fb504fd04c45..000000000000
--- a/clang/test/Rewriter/ivar-encoding-1.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface Intf
-{
- id ivar;
- id ivar1[12];
-
- id **ivar3;
-
- id (*ivar4) (id, id);
-}
-@end
-
-@implementation Intf
-@end
diff --git a/clang/test/Rewriter/ivar-encoding-2.m b/clang/test/Rewriter/ivar-encoding-2.m
deleted file mode 100644
index a5872d4285a9..000000000000
--- a/clang/test/Rewriter/ivar-encoding-2.m
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@implementation Intf
-{
- id ivar;
- id ivar1[12];
-
- id **ivar3;
-
- id (*ivar4) (id, id);
-}
-@end
diff --git a/clang/test/Rewriter/metadata-test-1.m b/clang/test/Rewriter/metadata-test-1.m
deleted file mode 100644
index 03586c54f3b3..000000000000
--- a/clang/test/Rewriter/metadata-test-1.m
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface Intf
-@end
-
-@implementation Intf(Category)
-- (void) CatMeth {}
-@end
-
-@implementation Another
-- (void) CatMeth {}
-@end
diff --git a/clang/test/Rewriter/metadata-test-2.m b/clang/test/Rewriter/metadata-test-2.m
deleted file mode 100644
index 9a53bda004d5..000000000000
--- a/clang/test/Rewriter/metadata-test-2.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-typedef struct _NSPoint {
- float x;
- float y;
-} NSPoint;
-
-@interface Intf
-- (void) MyMeth : (NSPoint) Arg1;
-@end
-
-@implementation Intf
-- (void) MyMeth : (NSPoint) Arg1{}
-@end
-
diff --git a/clang/test/Rewriter/method-encoding-1.m b/clang/test/Rewriter/method-encoding-1.m
deleted file mode 100644
index 6559c6b9bbb5..000000000000
--- a/clang/test/Rewriter/method-encoding-1.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol P1
-- (void) MyProtoMeth : (int **) arg1 : (void*) arg2;
-+ (void) MyProtoMeth : (int **) arg1 : (void*) arg2;
-@end
-
-@interface Intf <P1>
-- (char *) MyMeth : (double) arg1 : (char *[12]) arg2;
-- (id) address:(void *)location with:(unsigned **)arg2;
-@end
-
-@implementation Intf
-- (char *) MyMeth : (double) arg1 : (char *[12]) arg2{}
-- (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {}
-+ (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {}
-- (id) address:(void *)location with:(unsigned **)arg2{}
-@end
diff --git a/clang/test/Rewriter/objc-encoding-bug-1.m b/clang/test/Rewriter/objc-encoding-bug-1.m
deleted file mode 100644
index d2944370389a..000000000000
--- a/clang/test/Rewriter/objc-encoding-bug-1.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-typedef struct NSMethodFrameArgInfo {
- struct NSMethodFrameArgInfo *subInfo;
- struct NSMethodFrameArgInfo *an;
-} NSMethodFrameArgInfo;
-
-@interface NSMethodSignature
-- (NSMethodFrameArgInfo *)_argInfo;
-@end
-
-@implementation NSMethodSignature
-
-- (NSMethodFrameArgInfo *)_argInfo{
- return 0;
-}
-
-@end
-
diff --git a/clang/test/Rewriter/objc-ivar-receiver-1.m b/clang/test/Rewriter/objc-ivar-receiver-1.m
deleted file mode 100644
index 5a9365f376f6..000000000000
--- a/clang/test/Rewriter/objc-ivar-receiver-1.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -rewrite-objc %s -o - &&
-// RUN: clang -rewrite-objc %s -o - | grep 'newInv->_container'
-
-@interface NSMutableArray
-- (void)addObject:(id)addObject;
-@end
-
-@interface NSInvocation {
-@private
- id _container;
-}
-+ (NSInvocation *)invocationWithMethodSignature;
-
-@end
-
-@implementation NSInvocation
-
-+ (NSInvocation *)invocationWithMethodSignature {
- NSInvocation *newInv;
- id obj = newInv->_container;
- [newInv->_container addObject:0];
- return 0;
-}
-@end
diff --git a/clang/test/Rewriter/objc-string-concat-1.m b/clang/test/Rewriter/objc-string-concat-1.m
deleted file mode 100644
index bb3e835f6b24..000000000000
--- a/clang/test/Rewriter/objc-string-concat-1.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@class NSString;
-
-@interface NSConstantString;
-@end
-
-
-
-NSConstantString *t0 = @"123";
-NSConstantString *t = @"123" @"4567"; // concat
-NSConstantString *t1 = @"123" @"4567" /* COMMENT */ @"89"; // concat
-NSConstantString *t2 = @"123" @/* COMMENT */ "4567"; // concat
-
diff --git a/clang/test/Rewriter/objc-super-test.m b/clang/test/Rewriter/objc-super-test.m
deleted file mode 100644
index fc74843e8dfe..000000000000
--- a/clang/test/Rewriter/objc-super-test.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -rewrite-objc %s -o - | grep objc_msgSendSuper | grep MainMethod
-
-@interface SUPER
-- (int) MainMethod;
-@end
-
-@interface MyDerived : SUPER
-- (int) instanceMethod;
-@end
-
-@implementation MyDerived
-- (int) instanceMethod {
- return [super MainMethod];
-}
-@end
diff --git a/clang/test/Rewriter/objc-synchronized-1.m b/clang/test/Rewriter/objc-synchronized-1.m
deleted file mode 100644
index 5f8ae31d5d8c..000000000000
--- a/clang/test/Rewriter/objc-synchronized-1.m
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-id SYNCH_EXPR();
-void SYNCH_BODY();
-void SYNCH_BEFORE();
-void SYNC_AFTER();
-
-void foo(id sem)
-{
- SYNCH_BEFORE();
- @synchronized (SYNCH_EXPR()) {
- SYNCH_BODY();
- return;
- }
- SYNC_AFTER();
- @synchronized ([sem self]) {
- SYNCH_BODY();
- return;
- }
-}
diff --git a/clang/test/Rewriter/protocol-rewrite-1.m b/clang/test/Rewriter/protocol-rewrite-1.m
deleted file mode 100644
index 204f34a916a0..000000000000
--- a/clang/test/Rewriter/protocol-rewrite-1.m
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-typedef struct MyWidget {
- int a;
-} MyWidget;
-
-MyWidget gWidget = { 17 };
-
-@protocol MyProto
-- (MyWidget *)widget;
-@end
-
-@interface Foo
-@end
-
-@interface Bar: Foo <MyProto>
-@end
-
-@interface Container
-+ (MyWidget *)elementForView:(Foo *)view;
-@end
-
-@implementation Foo
-@end
-
-@implementation Bar
-- (MyWidget *)widget {
- return &gWidget;
-}
-@end
-
-@implementation Container
-+ (MyWidget *)elementForView:(Foo *)view
-{
- MyWidget *widget = (void*)0;
- if (@protocol(MyProto)) {
- widget = [(id <MyProto>)view widget];
- }
- return widget;
-}
-@end
-
-int main(void) {
- id view;
- MyWidget *w = [Container elementForView: view];
-
- return 0;
-}
diff --git a/clang/test/Rewriter/rewrite-api-bug.m b/clang/test/Rewriter/rewrite-api-bug.m
deleted file mode 100644
index 4d69eb0832e4..000000000000
--- a/clang/test/Rewriter/rewrite-api-bug.m
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface MyDerived
-- (void) instanceMethod;
-@end
-
-@implementation MyDerived
-- (void) instanceMethod {
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-foreach-1.m b/clang/test/Rewriter/rewrite-foreach-1.m
deleted file mode 100644
index a4e83a3bb0e3..000000000000
--- a/clang/test/Rewriter/rewrite-foreach-1.m
+++ /dev/null
@@ -1,37 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol P @end
-
-@interface MyList
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-int LOOP();
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- id el;
- for (el in self)
- { LOOP(); }
- for (id el1 in self)
- LOOP();
-
- for (el in (self))
- if (el)
- LOOP();
-
- for (el in ((self)))
- if (el)
- LOOP();
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-foreach-2.m b/clang/test/Rewriter/rewrite-foreach-2.m
deleted file mode 100644
index 8ef4e969e8f9..000000000000
--- a/clang/test/Rewriter/rewrite-foreach-2.m
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol P @end
-
-@interface MyList
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-int LOOP();
-int INNERLOOP();
-void END_LOOP();
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- id el;
- for (el in self)
- { LOOP();
- for (id el1 in self)
- INNER_LOOP();
-
- END_LOOP();
- }
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-foreach-3.m b/clang/test/Rewriter/rewrite-foreach-3.m
deleted file mode 100644
index 7bb4e9b02be8..000000000000
--- a/clang/test/Rewriter/rewrite-foreach-3.m
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol P @end
-
-@interface MyList
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-int LOOP();
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- MyList * el;
- for (el in self)
- { LOOP(); }
- for (MyList * el1 in self)
- LOOP();
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-foreach-4.m b/clang/test/Rewriter/rewrite-foreach-4.m
deleted file mode 100644
index c4d8bf605004..000000000000
--- a/clang/test/Rewriter/rewrite-foreach-4.m
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface MyList
-- (id) allKeys;
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-- (id) allKeys {}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-int LOOP();
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- MyList * el;
- for (el in [el allKeys]) { LOOP();
- }
-
- for (id el1 in[el allKeys]) { LOOP();
- }
- for (el in([el allKeys])) { LOOP();
- }
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-foreach-5.m b/clang/test/Rewriter/rewrite-foreach-5.m
deleted file mode 100644
index 0016da3fbe29..000000000000
--- a/clang/test/Rewriter/rewrite-foreach-5.m
+++ /dev/null
@@ -1,47 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface MyList
-- (id) allKeys;
-@end
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount
-{
- return 0;
-}
-- (id) allKeys {}
-@end
-
-@interface MyList (BasicTest)
-- (void)compilerTestAgainst;
-@end
-
-int LOOP();
-@implementation MyList (BasicTest)
-- (void)compilerTestAgainst {
- MyList * el;
- int i;
- for (el in [el allKeys]) {
- for (i = 0; i < 10; i++)
- if (i == 5)
- break;
-
- if (el == 0)
- break;
- if (el != self)
- continue;
- LOOP();
- }
-
- for (id el1 in[el allKeys]) {
- LOOP();
- for (el in self) {
- if (el)
- continue;
- }
- if (el1)
- break;
- }
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-foreach-6.m b/clang/test/Rewriter/rewrite-foreach-6.m
deleted file mode 100644
index 3bea346a7fb9..000000000000
--- a/clang/test/Rewriter/rewrite-foreach-6.m
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang %s -rewrite-objc -o=-
-// rdar://5716356
-// FIXME: Should be able to pipe into clang, but code is not
-// yet correct for other reasons: rdar://5716940
-
-@class NSNotification;
-@class NSMutableArray;
-
-void foo(NSMutableArray *notificationArray, id X) {
- for (NSNotification *notification in notificationArray)
- [X postNotification:notification];
-}
-
diff --git a/clang/test/Rewriter/rewrite-nest.m b/clang/test/Rewriter/rewrite-nest.m
deleted file mode 100644
index 1a8293568508..000000000000
--- a/clang/test/Rewriter/rewrite-nest.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface NSMapTable @end
-@interface NSEnumerator @end
-
-typedef unsigned int NSUInteger;
-
-@interface NSConcreteMapTable : NSMapTable {
-@public
- NSUInteger capacity;
-}
-@end
-
-@interface NSConcreteMapTableValueEnumerator : NSEnumerator {
- NSConcreteMapTable *mapTable;
-}
-@end
-
-@implementation NSConcreteMapTableValueEnumerator
-
-- nextObject {
- while (mapTable->capacity) {
- }
- return 0;
-}
-@end
-
diff --git a/clang/test/Rewriter/rewrite-protocol-type-1.m b/clang/test/Rewriter/rewrite-protocol-type-1.m
deleted file mode 100644
index 47610dff3ae7..000000000000
--- a/clang/test/Rewriter/rewrite-protocol-type-1.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol MyProto1
-@end
-
-@protocol MyProto2
-@end
-
-@interface INTF @end
-
-INTF <MyProto1> *g1;
-
-INTF <MyProto1, MyProto2> *g2, *g3;
-
-INTF <MyProto1> * Func(INTF <MyProto1> *p2, INTF<MyProto1> *p3, INTF *p4, INTF<MyProto1> *p5)
-{
- return p2;
-}
-
-INTF <MyProto1, MyProto2> * Func1(INTF *p2, INTF<MyProto1, MyProto2> *p3, INTF *p4, INTF<MyProto1> *p5)
-{
- return p3;
-}
-
diff --git a/clang/test/Rewriter/rewrite-try-catch.m b/clang/test/Rewriter/rewrite-try-catch.m
deleted file mode 100644
index be0bf0915890..000000000000
--- a/clang/test/Rewriter/rewrite-try-catch.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface Foo @end
-@interface GARF @end
-
-void foo() {
- @try { TRY(); }
- @catch (...) { SPLATCH(); @throw; }
-}
-
-int main()
-{
-
- @try {
- MYTRY();
- }
-
- @catch (Foo* localException) {
- MYCATCH();
- @throw;
- }
-
- // no catch clause
- @try { }
- @finally { }
-}
-
diff --git a/clang/test/Rewriter/static-type-protocol-1.m b/clang/test/Rewriter/static-type-protocol-1.m
deleted file mode 100644
index 4283d073b1c6..000000000000
--- a/clang/test/Rewriter/static-type-protocol-1.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@protocol Proto
-- (void) ProtoDidget;
-@end
-
-@protocol MyProto <Proto>
-- (void) widget;
-@end
-
-@interface Foo
-- (void)StillMode;
-@end
-
-@interface Container
-+ (void)MyMeth;
-@end
-
-@implementation Container
-+ (void)MyMeth
-{
- Foo *view;
- [(Foo <MyProto> *)view StillMode];
- [(Foo <MyProto> *)view widget];
- [(Foo <MyProto> *)view ProtoDidget];
-}
-@end
diff --git a/clang/test/Rewriter/undecl-objc-h.m b/clang/test/Rewriter/undecl-objc-h.m
deleted file mode 100644
index 938a39737619..000000000000
--- a/clang/test/Rewriter/undecl-objc-h.m
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-typedef struct S {
- int * pint;
- int size;
-}NSRec;
-
-@interface SUPER
-- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2;
-@end
-
-@interface MyDerived : SUPER
-{
- NSRec d;
-}
-- (int) instanceMethod;
-- (int) another : (int) arg;
-- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2;
-@end
-
-@implementation MyDerived
-- (int) instanceMethod {
- return [self another : [self MainMethod : d : d].size];
-}
-
-- (int) another : (int) arg { return arg; }
-- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2 { return Arg2; }
-@end
-
diff --git a/clang/test/Rewriter/undeclared-method-1.m b/clang/test/Rewriter/undeclared-method-1.m
deleted file mode 100644
index 67b970508b3e..000000000000
--- a/clang/test/Rewriter/undeclared-method-1.m
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface Derived @end
-
-int main(void) {
- Derived *v ;
- [v free];
- return 0;
-}
diff --git a/clang/test/Rewriter/undef-field-reference-1.m b/clang/test/Rewriter/undef-field-reference-1.m
deleted file mode 100644
index f91345eaa129..000000000000
--- a/clang/test/Rewriter/undef-field-reference-1.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@interface MyDerived
-{
-@public
- int IVAR;
-}
-@end
-
-MyDerived *pd;
-int main() {
- return pd->IVAR;
-}
-
-
diff --git a/clang/test/Rewriter/va-method.m b/clang/test/Rewriter/va-method.m
deleted file mode 100644
index 00065ebb9c15..000000000000
--- a/clang/test/Rewriter/va-method.m
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-#include <stdarg.h>
-
-@interface NSObject @end
-@interface XX : NSObject @end
-
-@implementation XX
-- (void)encodeValuesOfObjCTypes:(const char *)types, ... {
- va_list ap;
- va_start(ap, types);
- while (*types) ;
- va_end(ap);
-}
-
-@end
-
diff --git a/clang/test/Sema/PR2727.c b/clang/test/Sema/PR2727.c
deleted file mode 100644
index 1b3096f0b58a..000000000000
--- a/clang/test/Sema/PR2727.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -verify -fsyntax-only -std=c90 %s &&
-// RUN: clang -verify -fsyntax-only -std=c99 %s
-
-int f (int x)
-{
- // sizeof applied to a type should not delete the type.
- return sizeof (int[x]);
-}
diff --git a/clang/test/Sema/PR2728.c b/clang/test/Sema/PR2728.c
deleted file mode 100644
index 01a3be7b9e4c..000000000000
--- a/clang/test/Sema/PR2728.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -verify -fsyntax-only -std=c90 %s &&
-// RUN: clang -verify -fsyntax-only -std=c99 %s
-
-struct s
-{
- int a;
-};
-
-int a[__builtin_offsetof(struct s, a) == 0];
diff --git a/clang/test/Sema/address-constant.c b/clang/test/Sema/address-constant.c
deleted file mode 100644
index e1704b8b0e66..000000000000
--- a/clang/test/Sema/address-constant.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int i;
-int a[] = {0};
-struct { int i; } s;
-
-int *array[] = {&i, a, &s.i};
-
-extern void f(void);
-void (*f_addr)(void) = &f;
diff --git a/clang/test/Sema/address_spaces.c b/clang/test/Sema/address_spaces.c
deleted file mode 100644
index eda7b8a1064a..000000000000
--- a/clang/test/Sema/address_spaces.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-#define _AS1 __attribute__((address_space(1)))
-#define _AS2 __attribute__((address_space(2)))
-#define _AS3 __attribute__((address_space(3)))
-
-void foo(_AS3 float *a) {
- _AS2 *x;
- _AS1 float * _AS2 *B;
-
- int _AS1 _AS2 *Y; // expected-error {{multiple address spaces specified for type}}
- int *_AS1 _AS2 *Z; // expected-error {{multiple address spaces specified for type}}
-
- _AS1 int local; // expected-error {{automatic variable qualified with an address space}}
- _AS1 int array[5]; // expected-error {{automatic variable qualified with an address space}}
- _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
-
- *a = 5.0f;
-}
diff --git a/clang/test/Sema/annotate.c b/clang/test/Sema/annotate.c
deleted file mode 100644
index 4387d4f7a2c7..000000000000
--- a/clang/test/Sema/annotate.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-void __attribute__((annotate("foo"))) foo(float *a) {
- __attribute__((annotate("bar"))) int x;
- __attribute__((annotate(1))) int y; // expected-error {{argument to annotate attribute was not a string literal}}
- __attribute__((annotate("bar", 1))) int z; // expected-error {{attribute requires 1 argument(s)}}
-}
diff --git a/clang/test/Sema/arg-duplicate.c b/clang/test/Sema/arg-duplicate.c
deleted file mode 100644
index 81cb8fd9c29f..000000000000
--- a/clang/test/Sema/arg-duplicate.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int f3(y, x,
- x) // expected-error {{redefinition of parameter}}
- int y, x,
- x; // expected-error {{redefinition of parameter}}
-{
- return x + y;
-}
-
-void f4(void) {
- f3 (1, 1, 2, 3, 4); // expected-error {{too many arguments to function}}
-}
-
diff --git a/clang/test/Sema/arg-scope-c99.c b/clang/test/Sema/arg-scope-c99.c
deleted file mode 100644
index 2d386c45da5b..000000000000
--- a/clang/test/Sema/arg-scope-c99.c
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang -fsyntax-only -std=c99 -verify %s
-int bb(int sz, int ar[sz][sz]) { }
diff --git a/clang/test/Sema/arg-scope.c b/clang/test/Sema/arg-scope.c
deleted file mode 100644
index fc2bb70d0a15..000000000000
--- a/clang/test/Sema/arg-scope.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-int aa(int b, int x[sizeof b]) {}
-
-void foo(int i, int A[i]) {}
-
diff --git a/clang/test/Sema/array-constraint.c b/clang/test/Sema/array-constraint.c
deleted file mode 100644
index 8fa216d46a1b..000000000000
--- a/clang/test/Sema/array-constraint.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-struct s;
-struct s* t (struct s z[]) { // expected-error {{array has incomplete element type}}
- return z;
-}
-
-void ff() {
- struct s v, *p; // expected-error {{variable has incomplete type 'struct s'}}
-
- p = &v;
-}
-
-void *k (void l[2]) { // expected-error {{array has incomplete element type}}
- return l;
-}
-
-struct vari {
- int a;
- int b[];
-};
-
-struct vari *func(struct vari a[]) { // expected-error {{'struct vari' may not be used as an array element due to flexible array member}}
- return a;
-}
-
-int foo[](void); // expected-error {{'foo' declared as array of functions}}
-int foo2[1](void); // expected-error {{'foo2' declared as array of functions}}
-
-typedef int (*pfunc)(void);
-
-pfunc xx(int f[](void)) { // expected-error {{'f' declared as array of functions}}
- return f;
-}
-
-void check_size() {
- float f;
- int size_not_int[f]; // expected-error {{size of array has non-integer type 'float'}}
- int negative_size[1-2]; // expected-error{{array size is negative}}
- int zero_size[0]; // expected-warning{{zero size arrays are an extension}}
-}
-
-static int I;
-typedef int TA[I]; // expected-error {{arrays with static storage duration must have constant integer length}}
-
-void strFunc(char *);
-const char staticAry[] = "test";
-int checkStaticAry() {
- strFunc(staticAry); // expected-warning{{passing 'char const [5]' discards qualifiers, expected 'char *'}}
-}
-
-
diff --git a/clang/test/Sema/array-declared-as-incorrect-type.c b/clang/test/Sema/array-declared-as-incorrect-type.c
deleted file mode 100644
index e7dd458dc0c2..000000000000
--- a/clang/test/Sema/array-declared-as-incorrect-type.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-extern int a1[];
-int a1[1];
-
-extern int a2[]; // expected-error {{previous definition is here}}
-float a2[1]; // expected-error {{redefinition of 'a2'}}
-
-extern int a3[][2];
-int a3[1][2];
-
-extern int a4[][2]; // expected-error {{previous definition is here}}
-int a4[2]; // expected-error {{redefinition of 'a4'}}
-
-extern int a5[1][2][3]; // expected-error {{previous definition is here}}
-int a5[3][2][1]; // expected-error {{redefinition of 'a5'}}
diff --git a/clang/test/Sema/array-init.c b/clang/test/Sema/array-init.c
deleted file mode 100644
index bf3d83d2654c..000000000000
--- a/clang/test/Sema/array-init.c
+++ /dev/null
@@ -1,240 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-extern int foof() = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
-
-static int x, y, z;
-
-static int ary[] = { x, y, z }; // expected-error{{initializer element is not a compile-time constant}}
-int ary2[] = { x, y, z }; // expected-error{{initializer element is not a compile-time constant}}
-
-extern int fileScopeExtern[3] = { 1, 3, 5 }; // expected-warning{{'extern' variable has an initializer}}
-
-static int ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible pointer to integer conversion initializing 'char [4]', expected 'int'}}
-
-void func() {
- int x = 1;
-
- typedef int TInt = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
-
- int xComputeSize[] = { 1, 3, 5 };
-
- int x3[x] = { 1, 2 }; // expected-error{{variable-sized object may not be initialized}}
-
- int x4 = { 1, 2 }; // expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}}
-
- int y[4][3] = {
- { 1, 3, 5 },
- { 2, 4, 6 },
- { 3, 5, 7 },
- };
-
- int y2[4][3] = {
- 1, 3, 5, 2, 4, 6, 3, 5, 7
- };
-
- int y3[4][3] = {
- { 1, 3, 5 },
- { 2, 4, 6 },
- { 3, 5, 7 },
- { 4, 6, 8 },
- { 5 }, // expected-warning{{excess elements in array initializer}}
- };
-
- struct threeElements {
- int a,b,c;
- } z = { 1 };
-
- struct threeElements *p = 7; // expected-warning{{incompatible integer to pointer conversion initializing 'int', expected 'struct threeElements *'}}
-
- extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{'extern' variable cannot have an initializer}}
-
- static int x2[3] = { 1.0, "abc" , 5.8 }; // expected-warning{{incompatible pointer to integer conversion initializing 'char [4]', expected 'int'}}
-}
-
-void test() {
- int y1[3] = {
- { 1, 2, 3 } // expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}}
- };
- int y3[4][3] = {
- { 1, 3, 5 },
- { 2, 4, 6 },
- { 3, 5, 7 },
- { 4, 6, 8 },
- { }, // expected-warning{{use of GNU empty initializer extension}} expected-warning{{excess elements in array initializer}}
- };
- int y4[4][3] = {
- { 1, 3, 5, 2 }, // expected-warning{{excess elements in array initializer}}
- { 4, 6 },
- { 3, 5, 7 },
- { 4, 6, 8 },
- };
-}
-
-void allLegalAndSynonymous() {
- short q[4][3][2] = {
- { 1 },
- { 2, 3 },
- { 4, 5, 6 }
- };
- short q2[4][3][2] = {
- { 1, 0, 0, 0, 0, 0 },
- { 2, 3, 0, 0, 0, 0 },
- { 4, 5, 6 }
- };
- short q3[4][3][2] = {
- {
- { 1 },
- },
- {
- { 2, 3 },
- },
- {
- { 4, 5 },
- { 6 },
- },
- };
-}
-
-void legal() {
- short q[][3][2] = {
- { 1 },
- { 2, 3 },
- { 4, 5, 6 }
- };
-}
-
-unsigned char asso_values[] = { 34 };
-int legal2() {
- return asso_values[0];
-}
-
-void illegal() {
- short q2[4][][2] = { // expected-error{{array has incomplete element type 'short [][2]'}}
- { 1, 0, 0, 0, 0, 0 },
- { 2, 3, 0, 0, 0, 0 },
- { 4, 5, 6 }
- };
- short q3[4][3][] = { // expected-error{{array has incomplete element type 'short []'}}
- {
- { 1 },
- },
- {
- { 2, 3 },
- },
- {
- { 4, 5 },
- { 6 },
- },
- };
- int a[][] = { 1, 2 }; // expected-error{{array has incomplete element type 'int []'}}
-}
-
-typedef int AryT[];
-
-void testTypedef()
-{
- AryT a = { 1, 2 }, b = { 3, 4, 5 };
-}
-
-static char const xx[] = "test";
-static char const yy[5] = "test";
-static char const zz[3] = "test"; // expected-warning{{initializer-string for char array is too long}}
-
-void charArrays()
-{
- static char const test[] = "test";
- static char const test2[] = { "weird stuff" };
- static char const test3[] = { "test", "excess stuff" }; // expected-error{{excess elements in char array initializer}}
-
- char* cp[] = { "Hello" };
-
- char c[] = { "Hello" };
- int l[sizeof(c) == 6 ? 1 : -1];
-
- int i[] = { "Hello "}; // expected-warning{{incompatible pointer to integer conversion initializing 'char [7]', expected 'int'}}
- char c2[] = { "Hello", "Good bye" }; //expected-error{{excess elements in char array initializer}}
-
- int i2[1] = { "Hello" }; //expected-warning{{incompatible pointer to integer conversion initializing 'char [6]', expected 'int'}}
- char c3[5] = { "Hello" };
- char c4[4] = { "Hello" }; //expected-warning{{initializer-string for char array is too long}}
-
- int i3[] = {}; //expected-warning{{zero size arrays are an extension}} expected-warning{{use of GNU empty initializer extension}}
-}
-
-void variableArrayInit() {
- int a = 4;
- char strlit[a] = "foo"; //expected-error{{variable-sized object may not be initialized}}
- int b[a] = { 1, 2, 4 }; //expected-error{{variable-sized object may not be initialized}}
-}
-
-// Pure array tests
-float r1[10] = {{7}}; //expected-warning{{braces around scalar initializer}}
-float r2[] = {{8}}; //expected-warning{{braces around scalar initializer}}
-char r3[][5] = {1,2,3,4,5,6};
-char r3_2[sizeof r3 == 10 ? 1 : -1];
-float r4[1][2] = {1,{2},3,4}; //expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}}
-char r5[][5] = {"aa", "bbb", "ccccc"};
-char r6[sizeof r5 == 15 ? 1 : -1];
-const char r7[] = "zxcv";
-char r8[5] = "5char";
-char r9[5] = "6chars"; //expected-warning{{initializer-string for char array is too long}}
-
-int r11[0] = {}; //expected-warning{{zero size arrays are an extension}} expected-warning{{use of GNU empty initializer extension}}
-
-// Some struct tests
-void autoStructTest() {
-struct s1 {char a; char b;} t1;
-struct s2 {struct s1 c;} t2 = { t1 };
-// The following is a less than great diagnostic (though it's on par with EDG).
-struct s1 t3[] = {t1, t1, "abc", 0}; //expected-warning{{incompatible pointer to integer conversion initializing 'char [4]', expected 'char'}}
-int t4[sizeof t3 == 6 ? 1 : -1];
-}
-struct foo { int z; } w;
-int bar (void) {
- struct foo z = { w }; //expected-error{{incompatible type initializing 'struct foo', expected 'int'}}
- return z.z;
-}
-struct s3 {void (*a)(void);} t5 = {autoStructTest};
-// GCC extension; flexible array init. Once this is implemented, the warning should be removed.
-// Note that clang objc implementation depends on this extension.
-struct {int a; int b[];} t6 = {1, {1, 2, 3}}; //expected-warning{{excess elements in array initializer}}
-union {char a; int b;} t7[] = {1, 2, 3};
-int t8[sizeof t7 == (3*sizeof(int)) ? 1 : -1];
-
-struct bittest{int : 31, a, :21, :12, b;};
-struct bittest bittestvar = {1, 2, 3, 4}; //expected-warning{{excess elements in array initializer}}
-
-// Not completely sure what should happen here...
-int u1 = {}; //expected-warning{{use of GNU empty initializer extension}} expected-error{{scalar initializer cannot be empty}}
-int u2 = {{3}}; //expected-error{{too many braces around scalar initializer}}
-
-// PR2362
-void varArray() {
- int c[][x] = { 0 }; //expected-error{{variable-sized object may not be initialized}}
-}
-
-// PR2151
-int emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct extension}} expected-error{{initializer for aggregate with no elements}}
-
-int noNamedInit() {
-struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}}
-}
-struct {int a; int:5;} noNamedImplicit[] = {1,2,3};
-int noNamedImplicitCheck[sizeof(noNamedImplicit) == 3 * sizeof(*noNamedImplicit) ? 1 : -1];
-
-
-// ptrs are constant
-struct soft_segment_descriptor {
- int ssd_base;
-};
-static int dblfault_tss;
-
-union uniao { int ola; } xpto[1];
-
-struct soft_segment_descriptor gdt_segs[] = {
- {(int) &dblfault_tss},
- { (int)xpto},
-};
-
-static void sppp_ipv6cp_up();
-const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-warning{{excess elements in array initializer}}
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
deleted file mode 100644
index d29335a924ff..000000000000
--- a/clang/test/Sema/asm.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: clang %s -arch=i386 -verify -fsyntax-only
-
-void
-f()
-{
- int i;
-
- asm ("foo\n" : : "a" (i + 2));
- asm ("foo\n" : : "a" (f())); // expected-error {{invalid type 'void' in asm input}}
-
- asm ("foo\n" : "=a" (f())); // expected-error {{invalid lvalue in asm output}}
- asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}}
-
-}
-
-void
-clobbers()
-{
- asm ("nop" : : : "ax", "#ax", "%ax");
- asm ("nop" : : : "eax", "rax", "ah", "al");
- asm ("nop" : : : "0", "%0", "#0");
- asm ("nop" : : : "foo"); // expected-error {{unknown register name 'foo' in asm}}
- asm ("nop" : : : "52");
- asm ("nop" : : : "53"); // expected-error {{unknown register name '53' in asm}}
- asm ("nop" : : : "-1"); // expected-error {{unknown register name '-1' in asm}}
- asm ("nop" : : : "+1"); // expected-error {{unknown register name '+1' in asm}}
-}
-
-// rdar://6094010
-void test3() {
- int x;
- asm(L"foo" : "=r"(x)); // expected-error {{wide string}}
- asm("foo" : L"=r"(x)); // expected-error {{wide string}}
-}
-
diff --git a/clang/test/Sema/assign-null.c b/clang/test/Sema/assign-null.c
deleted file mode 100644
index 6972d9022363..000000000000
--- a/clang/test/Sema/assign-null.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#include <stddef.h>
-
-typedef void (*hookfunc)(void *arg);
-hookfunc hook;
-
-void clear_hook() {
- hook = NULL;
-}
diff --git a/clang/test/Sema/assign.c b/clang/test/Sema/assign.c
deleted file mode 100644
index 4ddb25a94afb..000000000000
--- a/clang/test/Sema/assign.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void *test1(void) { return 0; }
-
-void test2 (const struct {int a;} *x) {
- x->a = 10; // expected-error {{read-only variable is not assignable}}
-}
-
-typedef int arr[10];
-void test3() {
- const arr b;
- const int b2[10];
- b[4] = 1; // expected-error {{read-only variable is not assignable}}
- b2[4] = 1; // expected-error {{read-only variable is not assignable}}
-}
diff --git a/clang/test/Sema/ast-print.c b/clang/test/Sema/ast-print.c
deleted file mode 100644
index 34b0411cfe08..000000000000
--- a/clang/test/Sema/ast-print.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang %s -ast-print
-
-typedef void func_typedef();
-func_typedef xxx;
-
-typedef void func_t(int x);
-func_t a;
-
diff --git a/clang/test/Sema/attr-deprecated.c b/clang/test/Sema/attr-deprecated.c
deleted file mode 100644
index f018c3356fc4..000000000000
--- a/clang/test/Sema/attr-deprecated.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-int f() __attribute__((deprecated));
-void g() __attribute__((deprecated));
-void g();
-
-void z() __attribute__((bogusattr)); // todo-warning {{'bogusattr' attribute ignored}}
-
-extern int var __attribute__((deprecated));
-
-int a() {
- int (*ptr)() = f; // expected-warning {{'f' is deprecated}}
- f(); // expected-warning {{'f' is deprecated}}
-
- // test if attributes propagate to functions
- g(); // expected-warning {{'g' is deprecated}}
-
- return var; // expected-warning {{'var' is deprecated}}
-}
-
-// test if attributes propagate to variables
-extern int var;
-int w() {
- return var; // expected-warning {{'var' is deprecated}}
-}
diff --git a/clang/test/Sema/attr-mode.c b/clang/test/Sema/attr-mode.c
deleted file mode 100644
index 0f8d5da24a64..000000000000
--- a/clang/test/Sema/attr-mode.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef int i16_1 __attribute((mode(HI)));
-int i16_1_test[sizeof(i16_1) == 2 ? 1 : -1];
-typedef int i16_2 __attribute((__mode__(__HI__)));
-int i16_2_test[sizeof(i16_1) == 2 ? 1 : -1];
-
-typedef float f64 __attribute((mode(DF)));
-int f64_test[sizeof(f64) == 8 ? 1 : -1];
-
-typedef int invalid_1 __attribute((mode)); // expected-error{{attribute requires unquoted parameter}}
-typedef int invalid_2 __attribute((mode())); // expected-error{{attribute requires unquoted parameter}}
-typedef int invalid_3 __attribute((mode(II))); // expected-error{{unknown machine mode}}
-typedef struct {int i,j,k;} invalid_4 __attribute((mode(SI))); // expected-error{{mode attribute only supported for integer and floating-point types}}
-typedef float invalid_5 __attribute((mode(SI))); // expected-error{{type of machine mode does not match type of base type}}
-
-int **__attribute((mode(QI)))* i32; // expected-error{{mode attribute}}
diff --git a/clang/test/Sema/bitfield-layout.c b/clang/test/Sema/bitfield-layout.c
deleted file mode 100644
index 0ac5dd260a89..000000000000
--- a/clang/test/Sema/bitfield-layout.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -triple=i686-apple-darwin9
-
-#define CHECK_SIZE(kind, name, size) extern int name##1[sizeof(kind name) == size ? 1 : -1];
-#define CHECK_ALIGN(kind, name, size) extern int name##2[__alignof(kind name) == size ? 1 : -1];
-
-// Zero-width bit-fields
-struct a {char x; int : 0; char y;};
-CHECK_SIZE(struct, a, 5)
-CHECK_ALIGN(struct, a, 1)
-
-union b {char x; int : 0; char y;};
-CHECK_SIZE(union, b, 1)
-CHECK_ALIGN(union, b, 1)
-
-// Unnamed bit-field align
-struct c {char x; int : 20;};
-CHECK_SIZE(struct, c, 4)
-CHECK_ALIGN(struct, c, 1)
-
-union d {char x; int : 20;};
-CHECK_SIZE(union, d, 3)
-CHECK_ALIGN(union, d, 1)
-
-// Bit-field packing
-struct __attribute__((packed)) e {int x : 4, y : 30, z : 30;};
-CHECK_SIZE(struct, e, 8)
-CHECK_ALIGN(struct, e, 1)
-
-// Alignment on bit-fields
-struct f {__attribute((aligned(8))) int x : 30, y : 30, z : 30;};
-CHECK_SIZE(struct, f, 24)
-CHECK_ALIGN(struct, f, 8)
diff --git a/clang/test/Sema/block-args.c b/clang/test/Sema/block-args.c
deleted file mode 100644
index 42e2859c9753..000000000000
--- a/clang/test/Sema/block-args.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-void take(void*);
-
-void test() {
- take(^(int x){});
- take(^(int x, int y){});
- take(^(int x, int y){});
- take(^(int x, int x){}); // expected-error {{redefinition of parameter 'x'}}
-
-
- take(^(int x) { return x+1; });
-
- int (^CP)(int) = ^(int x) { return x*x; };
- take(CP);
-
- int arg;
- ^{return 1;}();
- ^{return 2;}(arg); // expected-error {{too many arguments to block call}}
- ^(void){return 3;}(1); // expected-error {{too many arguments to block call}}
- ^(){return 4;}(arg); // C style (...), ok.
- ^(int x, ...){return 5;}(arg, arg); // Explicit varargs, ok.
-}
-
-int main(int argc) {
- ^(int argCount) {
- argCount = 3;
- }(argc);
-}
diff --git a/clang/test/Sema/block-as-object.m b/clang/test/Sema/block-as-object.m
deleted file mode 100644
index 8afab4c3f7d0..000000000000
--- a/clang/test/Sema/block-as-object.m
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-@interface Whatever
-- copy;
-@end
-
-typedef long (^MyBlock)(id obj1, id obj2);
-
-void foo(MyBlock b) {
- id bar = [b copy];
-}
-
-void foo2(id b) {
-}
-
-void foo3(void (^block)(void)) {
- foo2(block);
- id x;
- foo(x);
-}
diff --git a/clang/test/Sema/block-byref-args.c b/clang/test/Sema/block-byref-args.c
deleted file mode 100644
index 9b568f058420..000000000000
--- a/clang/test/Sema/block-byref-args.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-#include <stdio.h>
-
-int main(int argc, char **argv) {
- __block void(*bobTheFunction)(void);
- __block void(^bobTheBlock)(void);
-
- bobTheBlock = ^{;};
-
- __block int JJJJ;
- __attribute__((__blocks__(byref))) int III;
-
- int (^XXX)(void) = ^{ return III+JJJJ; };
-
- return 0;
-}
-
diff --git a/clang/test/Sema/block-call.c b/clang/test/Sema/block-call.c
deleted file mode 100644
index 871dbf792bc0..000000000000
--- a/clang/test/Sema/block-call.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int (*FP)();
-int (^IFP) ();
-int (^II) (int);
-int main() {
- int (*FPL) (int) = FP; // C doesn't consider this an error.
-
- // For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error.
- int (^PFR) (int) = IFP; // expected-warning {{incompatible block pointer types initializing 'int (^)()', expected 'int (^)(int)'}}
- PFR = II; // OK
-
- int (^IFP) () = PFR; // expected-warning {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)()'}}
-
-
- const int (^CIC) () = IFP; // expected-warning {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}}
-
-
- const int (^CICC) () = CIC;
-
- int * const (^IPCC) () = 0;
-
- int * const (^IPCC1) () = IPCC;
-
- int * (^IPCC2) () = IPCC; // expected-warning {{incompatible block pointer types initializing 'int *const (^)()', expected 'int *(^)()'}}
-
- int (^IPCC3) (const int) = PFR; // expected-warning {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)(int const)'}}
-
-
- int (^IPCC4) (int, char (^CArg) (double));
-
-
- int (^IPCC5) (int, char (^CArg) (double)) = IPCC4;
-
- int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-warning {{incompatible block pointer types initializing 'int (^)(int, char (^)(double))', expected 'int (^)(int, char (^)(float))'}}
-
- IPCC2 = 0;
- IPCC2 = 1; // expected-error {{invalid conversion assigning integer 'int', expected block pointer 'int *(^)()'}}
- int (^x)() = 0;
- int (^y)() = 3; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}}
- int a = 1;
- int (^z)() = a+4; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}}
-}
-
-int blah() {
- int (^IFP) (float);
- char (^PCP)(double, double, char);
-
- IFP(1.0);
- IFP (1.0, 2.0); // expected-error {{too many arguments to block call}}
-
- char ch = PCP(1.0, 2.0, 'a');
- return PCP(1.0, 2.0); // expected-error {{too few arguments to block}}
-}
-
diff --git a/clang/test/Sema/block-literal.c b/clang/test/Sema/block-literal.c
deleted file mode 100644
index 7f1579d0cc7d..000000000000
--- a/clang/test/Sema/block-literal.c
+++ /dev/null
@@ -1,118 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-
-void I( void (^)(void));
-void (^noop)(void);
-
-void nothing();
-int printf(const char*, ...);
-
-typedef void (^T) (void);
-
-void takeclosure(T);
-int takeintint(int (^C)(int)) { return C(4); }
-
-T somefunction() {
- if (^{ })
- nothing();
-
- noop = ^{};
-
- noop = ^{printf("\nClosure\n"); };
-
- I(^{ });
-
- return ^{printf("\nClosure\n"); }; // expected-error {{returning block that lives on the local stack}}
-}
-void test2() {
- int x = 4;
-
- takeclosure(^{ printf("%d\n", x); });
-
- while (1) {
- takeclosure(^{
- break; // expected-error {{'break' statement not in loop or switch statement}}
- continue; // expected-error {{'continue' statement not in loop statement}}
- while(1) break; // ok
- goto foo; // expected-error {{goto not allowed}}
- });
- break;
- }
-
-foo:
- takeclosure(^{ x = 4; }); // expected-error {{variable is not assignable (missing __block type specifier)}}
- __block y = 7;
- takeclosure(^{ y = 8; });
-}
-
-
-void (^test3())(void) {
- return ^{}; // expected-error {{returning block that lives on the local stack}}
-}
-
-void test4() {
- void (^noop)(void) = ^{};
- void (*noop2)() = 0;
-}
-
-void myfunc(int (^block)(int)) {}
-
-void myfunc3(int *x);
-
-void test5() {
- int a;
-
- myfunc(^(int abcd) {
- myfunc3(&a);
- return 1;
- });
-}
-
-void *X;
-
-void test_arguments() {
- int y;
- int (^c)(char);
- (1 ? c : 0)('x');
- (1 ? 0 : c)('x');
-
- (1 ? c : c)('x');
-}
-
-static int global_x = 10;
-void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); };
-
-#if 0
-// Old syntax. FIXME: convert/test.
-void test_byref() {
- int i;
-
- X = ^{| g |}; // expected-error {{use of undeclared identifier 'g'}}
-
- X = ^{| i,i,i | };
-
- X = ^{|i| i = 0; };
-
-}
-
-// TODO: global closures someday.
-void *A = ^{};
-void *B = ^(int){ A = 0; };
-
-
-// Closures can not take return types at this point.
-void test_retvals() {
- // Explicit return value.
- ^int{}; // expected-error {{closure with explicit return type requires argument list}}
- X = ^void(){};
-
- // Optional specification of return type.
- X = ^char{ return 'x'; }; // expected-error {{closure with explicit return type requires argument list}}
-
- X = ^/*missing declspec*/ *() { return (void*)0; };
- X = ^void*() { return (void*)0; };
-
- //X = ^char(short c){ if (c) return c; else return (int)4; };
-
-}
-
-#endif
diff --git a/clang/test/Sema/block-misc.c b/clang/test/Sema/block-misc.c
deleted file mode 100644
index 77de4a6c9e2c..000000000000
--- a/clang/test/Sema/block-misc.c
+++ /dev/null
@@ -1,64 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-void donotwarn();
-
-int (^IFP) ();
-int (^II) (int);
-int test1() {
- int (^PFR) (int) = 0; // OK
- PFR = II; // OK
-
- if (PFR == II) // OK
- donotwarn();
-
- if (PFR == IFP) // expected-error {{comparison of distinct block types}}
- donotwarn();
-
- if (PFR == (int (^) (int))IFP) // OK
- donotwarn();
-
- if (PFR == 0) // OK
- donotwarn();
-
- if (PFR) // OK
- donotwarn();
-
- if (!PFR) // OK
- donotwarn();
-
- return PFR != IFP; // expected-error {{comparison of distinct block types}}
-}
-
-int test2(double (^S)()) {
- double (^I)(int) = (void*) S;
- (void*)I = (void *)S; // expected-error {{expression is not assignable}}
-
- void *pv = I;
-
- pv = S;
-
- I(1);
-
- return (void*)I == (void *)S;
-}
-
-int^ x; // expected-error {{block pointer to non-function type is invalid}}
-int^^ x1; // expected-error {{block pointer to non-function type is invalid}}
-
-int test3() {
- char *^ y; // expected-error {{block pointer to non-function type is invalid}}
-}
-
-
-
-enum {NSBIRLazilyAllocated = 0};
-
-int test4(int argc) { // rdar://6251437
- ^{
- switch (argc) {
- case NSBIRLazilyAllocated: // is an integer constant expression.
- default:
- break;
- }
- }();
- return 0;
-}
diff --git a/clang/test/Sema/block-return.c b/clang/test/Sema/block-return.c
deleted file mode 100644
index b88fb9b5be06..000000000000
--- a/clang/test/Sema/block-return.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-
-typedef void (^CL)(void);
-
-CL foo() {
-
- short y;
-
- short (^add1)(void) = ^{ return y+1; }; // expected-warning {{incompatible block pointer types initializing 'int (^)(void)', expected 'short (^)(void)'}}
-
- CL X = ^{
- if (2)
- return;
- return 1; // expected-error {{void block should not return a value}}
- };
- int (^Y) (void) = ^{
- if (3)
- return 1;
- else
- return; // expected-error {{non-void block should return a value}}
- };
-
- char *(^Z)(void) = ^{
- if (3)
- return "";
- else
- return (char*)0;
- };
-
- double (^A)(void) = ^ { // expected-warning {{incompatible block pointer types initializing 'float (^)(void)', expected 'double (^)(void)'}}
- if (1)
- return (float)1.0;
- else
- if (2)
- return (double)2.0; // expected-error {{incompatible type returning 'double', expected 'float'}}
- return 1; // expected-error {{incompatible type returning 'int', expected 'float'}}
- };
-
- char *(^B)(void) = ^{
- if (3)
- return "";
- else
- return 2; // expected-error {{incompatible type returning 'int', expected 'char *'}}
- };
- return ^{ return 1; }; // expected-warning {{incompatible block pointer types returning 'int (^)(void)', expected 'CL'}} expected-error {{returning block that lives on the local stack}}
-}
-
-typedef int (^CL2)(void);
-
-CL2 foo2() {
- return ^{ return 1; }; // expected-error {{returning block that lives on the local stack}}
-}
-
-typedef unsigned int * uintptr_t;
-typedef char Boolean;
-typedef int CFBasicHash;
-
-#define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
-
-typedef struct {
- Boolean (^isEqual)(const CFBasicHash *, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key);
-} CFBasicHashCallbacks;
-
-int foo3() {
- CFBasicHashCallbacks cb;
-
- Boolean (*value_equal)(uintptr_t, uintptr_t) = 0;
-
- cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) {
- return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2);
- };
-}
-
-static int funk(char *s) {
- if (^{} == ((void*)0))
- return 1;
- else
- return 0;
-}
-void foo4() {
- int (^xx)(const char *s) = ^(char *s) { return 1; }; // expected-warning {{incompatible block pointer types initializing 'int (^)(char *)', expected 'int (^)(char const *)'}}
- int (*yy)(const char *s) = funk; // expected-warning {{incompatible pointer types initializing 'int (char *)', expected 'int (*)(char const *)'}}
-
- int (^nested)(char *s) = ^(char *str) { void (^nest)(void) = ^(void) { printf("%s\n", str); }; next(); return 1; };
-}
diff --git a/clang/test/Sema/block-storageclass.c b/clang/test/Sema/block-storageclass.c
deleted file mode 100644
index 662bd738c839..000000000000
--- a/clang/test/Sema/block-storageclass.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-#include <stdio.h>
-void _Block_byref_release(void*src){}
-
-int main() {
- __block int X = 1234;
- __block const char * message = "HELLO";
-
- X = X - 1234;
-
- X += 1;
-
- printf ("%s(%d)\n", message, X);
- X -= 1;
-
- return X;
-}
diff --git a/clang/test/Sema/builtin-object-size.c b/clang/test/Sema/builtin-object-size.c
deleted file mode 100644
index 27a2782d0cf2..000000000000
--- a/clang/test/Sema/builtin-object-size.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s &&
-// RUN: clang -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
-
-int a[10];
-
-int f0() {
- return __builtin_object_size(&a); // expected-error {{too few arguments to function}}
-}
-int f1() {
- return (__builtin_object_size(&a, 0) +
- __builtin_object_size(&a, 1) +
- __builtin_object_size(&a, 2) +
- __builtin_object_size(&a, 3));
-}
-int f2() {
- return __builtin_object_size(&a, -1); // expected-error {{argument should be a value from 0 to 3}}
-}
-int f3() {
- return __builtin_object_size(&a, 4); // expected-error {{argument should be a value from 0 to 3}}
-}
-
-
-// rdar://6252231 - cannot call vsnprintf with va_list on x86_64
-void f4(const char *fmt, ...) {
- __builtin_va_list args;
- __builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args);
-}
-
diff --git a/clang/test/Sema/builtin-prefetch.c b/clang/test/Sema/builtin-prefetch.c
deleted file mode 100644
index 084e8a1317ed..000000000000
--- a/clang/test/Sema/builtin-prefetch.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int foo() {
- int a;
- __builtin_prefetch(&a);
- __builtin_prefetch(&a, 1);
- __builtin_prefetch(&a, 1, 2);
- __builtin_prefetch(&a, 1, 9, 3); // expected-error{{too many arguments to function}}, expected-error{{argument should be a value from 0 to 3}}
- __builtin_prefetch(&a, "hello", 2); // expected-error{{argument to __builtin_prefetch must be a constant integer}}
- __builtin_prefetch(&a, 2); // expected-error{{argument should be a value from 0 to 1}}
- __builtin_prefetch(&a, 0, 4); // expected-error{{argument should be a value from 0 to 3}}
- __builtin_prefetch(&a, -1, 4); // expected-error{{argument should be a value from 0 to 1}}, expected-error{{argument should be a value from 0 to 3}}
-}
diff --git a/clang/test/Sema/builtin-stackaddress.c b/clang/test/Sema/builtin-stackaddress.c
deleted file mode 100644
index c030ab364fe9..000000000000
--- a/clang/test/Sema/builtin-stackaddress.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-void* a(unsigned x) {
-return __builtin_return_address(0);
-}
-
-void b(unsigned x) {
-return __builtin_return_address(x); // expected-error{{the level argument for a stack address builtin must be constant}}
-}
-
-void* c(unsigned x) {
-return __builtin_frame_address(0);
-}
-
-void d(unsigned x) {
-return __builtin_frame_address(x); // expected-error{{the level argument for a stack address builtin must be constant}}
-}
diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c
deleted file mode 100644
index d02adf3165ac..000000000000
--- a/clang/test/Sema/builtins.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic -triple=i686-apple-darwin9
-// This test needs to set the target because it uses __builtin_ia32_vec_ext_v4si
-
-int test1(float a, int b) {
- return __builtin_isless(a, b);
-}
-int test2(int a, int b) {
- return __builtin_islessequal(a, b); // expected-error {{floating point type}}
-}
-
-int test3(double a, float b) {
- return __builtin_isless(a, b);
-}
-int test4(int* a, double b) {
- return __builtin_islessequal(a, b); // expected-error {{floating point type}}
-}
-
-int test5(float a, long double b) {
- return __builtin_isless(a, b, b); // expected-error {{too many arguments}}
-}
-int test6(float a, long double b) {
- return __builtin_islessequal(a); // expected-error {{too few arguments}}
-}
-
-
-#define CFSTR __builtin___CFStringMakeConstantString
-void cfstring() {
- CFSTR("\242"); // expected-warning {{ CFString literal contains non-ASCII character }}
- CFSTR("\0"); // expected-warning {{ CFString literal contains NUL character }}
- CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible integer to pointer conversion}}
- CFSTR("foo", "bar"); // expected-error {{ error: too many arguments to function }}
-}
-
-
-typedef __attribute__(( ext_vector_type(16) )) unsigned char uchar16; // expected-warning {{extension}}
-
-// rdar://5905347
-unsigned char foo( short v ) {
- uchar16 c;
- return __builtin_ia32_vec_ext_v4si( c ); // expected-error {{too few arguments to function}}
-}
-
diff --git a/clang/test/Sema/c89-2.c b/clang/test/Sema/c89-2.c
deleted file mode 100644
index 128046f6d29d..000000000000
--- a/clang/test/Sema/c89-2.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* RUN: not clang %s -std=c89 -pedantic-errors
- */
-
-/* We can't put expected-warning lines on #if lines. */
-
-#if 1LL /* expected-warning {{long long}} */
-#endif
diff --git a/clang/test/Sema/c89.c b/clang/test/Sema/c89.c
deleted file mode 100644
index 70949f0c82dc..000000000000
--- a/clang/test/Sema/c89.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* RUN: clang %s -std=c89 -pedantic -fsyntax-only -verify
- */
-void test1() {
- {
- int i;
- i = i + 1;
- int j; /* expected-warning {{mixing declarations and code}} */
- }
- {
- __extension__ int i;
- i = i + 1;
- int j; /* expected-warning {{mixing declarations and code}} */
- }
- {
- int i;
- i = i + 1;
- __extension__ int j; /* expected-warning {{mixing declarations and code}} */
- }
-}
-
-long long test2; /* expected-warning {{extension}} */
-
-
-void test3(int i) {
- int A[i]; /* expected-warning {{variable length array}} */
-}
-
-int test4 = 0LL; /* expected-warning {{long long}} */
-
-/* PR1999 */
-void test5(register);
-
-/* PR2041 */
-int *restrict;
-int *__restrict; /* expected-error {{expected identifier}} */
-
-
-/* Implicit int, always ok */
-test6() {}
-
-/* PR2012 */
-test7; /* expected-warning {{declaration specifier missing, defaulting to 'int'}} */
-
-void test8(int, x); /* expected-warning {{declaration specifier missing, defaulting to 'int'}} */
-
-typedef int sometype;
-int a(sometype, y) {return 0;} /* expected-warning {{declaration specifier missing, defaulting to 'int'}} */
-
-
-
-
-void bar (void *);
-void f11 (z) /* expected-error {{may not have 'void' type}} */
-void z;
-{ bar (&z); }
-
-typedef void T;
-void foo(T); /* typedef for void is allowed */
-
-void foo(void) {}
-
diff --git a/clang/test/Sema/callingconv.c b/clang/test/Sema/callingconv.c
deleted file mode 100644
index fa0af7683425..000000000000
--- a/clang/test/Sema/callingconv.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-void __attribute__((fastcall)) foo(float *a) {
-}
-
-void __attribute__((stdcall)) bar(float *a) {
-}
-
-void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{attribute requires 0 argument(s)}}
-}
diff --git a/clang/test/Sema/carbon.c b/clang/test/Sema/carbon.c
deleted file mode 100644
index 9c9c3780403c..000000000000
--- a/clang/test/Sema/carbon.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -fsyntax-only -print-stats
-#ifdef __APPLE__
-#include <Carbon/Carbon.h>
-#endif
-
diff --git a/clang/test/Sema/cast.c b/clang/test/Sema/cast.c
deleted file mode 100644
index 14bfe138f308..000000000000
--- a/clang/test/Sema/cast.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-
-typedef struct { unsigned long bits[(((1) + (64) - 1) / (64))]; } cpumask_t;
-cpumask_t x;
-void foo() {
- (void)x;
-}
-
diff --git a/clang/test/Sema/check-increment.c b/clang/test/Sema/check-increment.c
deleted file mode 100644
index 4447feb0b8e6..000000000000
--- a/clang/test/Sema/check-increment.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#include <stdio.h>
-typedef int *pint;
-int main() {
- int a[5] = {0};
- pint p = a;
- p++;
- printf("%d\n", *p);
-}
diff --git a/clang/test/Sema/compare.c b/clang/test/Sema/compare.c
deleted file mode 100644
index e1ebf575ac62..000000000000
--- a/clang/test/Sema/compare.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -pedantic -verify %s
-
-int test(char *C) { // nothing here should warn.
- return C != ((void*)0);
- return C != (void*)0;
- return C != 0;
-}
-
-int equal(char *a, const char *b)
-{
- return a == b;
-}
-
-int arrays(char (*a)[5], char(*b)[10], char(*c)[5]) {
- int d = (a == c);
- return a == b; // expected-warning {{comparison of distinct pointer types}}
-}
diff --git a/clang/test/Sema/complex-int.c b/clang/test/Sema/complex-int.c
deleted file mode 100644
index 1e58b5320cb9..000000000000
--- a/clang/test/Sema/complex-int.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-void a() {
-__complex__ int arr;
-__complex__ short brr;
-__complex__ unsigned xx;
-__complex__ signed yy;
-__complex__ int result;
-int ii;
-int aa = 1 + 1.0iF;
-
-result = arr*ii;
-result = ii*brr;
-
-result = arr*brr;
-result = xx*yy;
-
-switch (arr) { // expected-error{{statement requires expression of integer type ('_Complex int' invalid)}}
- case brr: ; // expected-error{{case label does not reduce to an integer constant}}
- case xx: ; // expected-error{{case label does not reduce to an integer constant}}
-}
-}
-
-void Tester() {
-__complex short a1;
-__complex int a2;
-__complex float a3;
-__complex double a4;
-short a5;
-int a6;
-float a7;
-double a8;
-#define TestPair(m,n) int x##m##n = a##m+a##n;
-#define TestPairs(m) TestPair(m,1) TestPair(m,2) \
- TestPair(m,3) TestPair(m,4) \
- TestPair(m,5) TestPair(m,6) \
- TestPair(m,7) TestPair(m,8)
-TestPairs(1); TestPairs(2);
-TestPairs(3); TestPairs(4);
-TestPairs(5); TestPairs(6);
-TestPairs(7); TestPairs(8);
-}
-
-// rdar://6097730
-void test3(_Complex int *x) {
- *x = ~*x;
-}
-
-void test4(_Complex float *x) {
- *x = ~*x;
-}
-
diff --git a/clang/test/Sema/compound-literal.c b/clang/test/Sema/compound-literal.c
deleted file mode 100644
index 1de0e0bec440..000000000000
--- a/clang/test/Sema/compound-literal.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-struct foo { int a, b; };
-
-static struct foo t = (struct foo){0,0};
-static struct foo t2 = {0,0};
-static struct foo t3 = t2; // -expected-error {{initializer element is not a compile-time constant}}
-static int *p = (int []){2,4};
-static int x = (int){1}; // -expected-warning{{braces around scalar initializer}}
-
-static int *p2 = (int []){2,x}; // -expected-error {{initializer element is not a compile-time constant}}
-static int *p3 = (int []){2,"x"}; // -expected-warning {{incompatible pointer to integer conversion initializing 'char [2]', expected 'int'}}
-
-typedef struct { } cache_t; // -expected-warning{{use of empty struct extension}}
-static cache_t clo_I1_cache = ((cache_t) { } ); // -expected-warning{{use of GNU empty initializer extension}}
-
-typedef struct Test {int a;int b;} Test;
-static Test* ll = &(Test) {0,0};
-
-extern void fooFunc(struct foo *pfoo);
-
-int main(int argc, char **argv) {
- int *l = (int []){x, *p, *p2};
- fooFunc(&(struct foo){ 1, 2 });
-}
-
-struct Incomplete;
-struct Incomplete* I1 = &(struct Incomplete){1, 2, 3}; // -expected-error {{variable has incomplete type}}
-void IncompleteFunc(unsigned x) {
- struct Incomplete* I2 = (struct foo[x]){1, 2, 3}; // -expected-error {{variable-sized object may not be initialized}}
- (void){1,2,3}; // -expected-error {{variable has incomplete type}}
- (void(void)) { 0 }; // -expected-error{{illegal initializer type ('void (void)')}}
-}
diff --git a/clang/test/Sema/conditional-expr.c b/clang/test/Sema/conditional-expr.c
deleted file mode 100644
index ae973d6b2b84..000000000000
--- a/clang/test/Sema/conditional-expr.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-void foo() {
- *(0 ? (double *)0 : (void *)0) = 0;
- // FIXME: GCC doesn't consider the the following two statements to be errors.
- *(0 ? (double *)0 : (void *)(int *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}}
- *(0 ? (double *)0 : (void *)(double *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}}
- *(0 ? (double *)0 : (int *)(void *)0) = 0; // expected-error {{incomplete type 'void' is not assignable}} expected-warning {{pointer type mismatch ('double *' and 'int *')}}
- *(0 ? (double *)0 : (double *)(void *)0) = 0;
- *((void *) 0) = 0; // expected-error {{incomplete type 'void' is not assignable}}
- double *dp;
- int *ip;
- void *vp;
-
- dp = vp;
- vp = dp;
- ip = dp; // expected-warning {{incompatible pointer types assigning 'double *', expected 'int *'}}
- dp = ip; // expected-warning {{incompatible pointer types assigning 'int *', expected 'double *'}}
- dp = 0 ? (double *)0 : (void *)0;
- vp = 0 ? (double *)0 : (void *)0;
- ip = 0 ? (double *)0 : (void *)0; // expected-warning {{incompatible pointer types assigning 'double *', expected 'int *'}}
-
- const int *cip;
- vp = (0 ? vp : cip); // expected-warning {{discards qualifiers}}
- vp = (0 ? cip : vp); // expected-warning {{discards qualifiers}}
-
- int i = 2;
- int (*pf)[2];
- int (*pv)[i];
- pf = (i ? pf : pv);
-
- enum {xxx,yyy,zzz} e, *ee;
- short x;
- ee = ee ? &x : ee ? &i : &e; // expected-warning {{pointer type mismatch}}
-
- typedef void *asdf;
- *(0 ? (asdf) 0 : &x) = 10;
-}
-
-int Postgresql() {
- char x;
- return ((((&x) != ((void *) 0)) ? (*(&x) = ((char) 1)) : (void) ((void *) 0)), (unsigned long) ((void *) 0)); // expected-warning {{C99 forbids conditional expressions with only one void side}}
-}
diff --git a/clang/test/Sema/conditional.c b/clang/test/Sema/conditional.c
deleted file mode 100644
index e1ad1a51ba99..000000000000
--- a/clang/test/Sema/conditional.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-const char* test1 = 1 ? "i" : 1 == 1 ? "v" : "r";
-
-void _efree(void *ptr);
-
-int _php_stream_free1()
-{
- return (1 ? free(0) : _efree(0)); // expected-error {{incompatible type returning 'void', expected 'int'}}
-}
-
-int _php_stream_free2()
-{
- return (1 ? _efree(0) : free(0)); // expected-error {{incompatible type returning 'void', expected 'int'}}
-}
diff --git a/clang/test/Sema/const-ptr-int-ptr-cast.c b/clang/test/Sema/const-ptr-int-ptr-cast.c
deleted file mode 100644
index 6bf44b05b358..000000000000
--- a/clang/test/Sema/const-ptr-int-ptr-cast.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-char *a = (void*)(unsigned long long)(void*)&a;
diff --git a/clang/test/Sema/constant-builtins.c b/clang/test/Sema/constant-builtins.c
deleted file mode 100644
index d6cf45755daa..000000000000
--- a/clang/test/Sema/constant-builtins.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify -pedantic
-
-// Math stuff
-
-float g0 = __builtin_huge_val();
-double g1 = __builtin_huge_valf();
-long double g2 = __builtin_huge_vall();
-float g3 = __builtin_inf();
-double g4 = __builtin_inff();
-long double g5 = __builtin_infl();
-
-// GCC misc stuff
-
-extern int f();
-
-int h0 = __builtin_types_compatible_p(int,float); // expected-warning {{extension}}
-//int h1 = __builtin_choose_expr(1, 10, f());
-//int h2 = __builtin_expect(0, 0);
-
-short somefunc();
-
-short t = __builtin_constant_p(5353) ? 42 : somefunc(); // expected-warning {{expression is not a constant, but is accepted as one by GNU extensions}}
-
diff --git a/clang/test/Sema/constructor-attribute.c b/clang/test/Sema/constructor-attribute.c
deleted file mode 100644
index 3f240b02e5a2..000000000000
--- a/clang/test/Sema/constructor-attribute.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int x __attribute__((constructor)); // expected-warning {{'constructor' attribute only applies to function types}}
-int f() __attribute__((constructor));
-int f() __attribute__((constructor(1)));
-int f() __attribute__((constructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
-int f() __attribute__((constructor(1.0))); // expected-error {{'constructor' attribute requires parameter 1 to be an integer constant}}
-
-int x __attribute__((destructor)); // expected-warning {{'destructor' attribute only applies to function types}}
-int f() __attribute__((destructor));
-int f() __attribute__((destructor(1)));
-int f() __attribute__((destructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
-int f() __attribute__((destructor(1.0))); // expected-error {{'destructor' attribute requires parameter 1 to be an integer constant}}
-
-
diff --git a/clang/test/Sema/darwin-align-cast.c b/clang/test/Sema/darwin-align-cast.c
deleted file mode 100644
index adf938f29bc1..000000000000
--- a/clang/test/Sema/darwin-align-cast.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef long unsigned int __darwin_size_t;
-typedef long __darwin_ssize_t;
-typedef __darwin_size_t size_t;
-typedef __darwin_ssize_t ssize_t;
-
-struct cmsghdr {};
-
-#if 0
-This code below comes from the following system headers:
-sys/socket.h:#define CMSG_SPACE(l) (__DARWIN_ALIGN(sizeof(struct
-cmsghdr)) + __DARWIN_ALIGN(l))
-
-i386/_param.h:#define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(p)
-+ __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
-#endif
-
-ssize_t sendFileDescriptor(int fd, void *data, size_t nbytes, int sendfd) {
- union {
- char control[(((__darwin_size_t)((char *)(sizeof(struct cmsghdr)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)) + ((__darwin_size_t)((char *)(sizeof(int)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)))];
- } control_un;
-}
-
diff --git a/clang/test/Sema/decl-invalid.c b/clang/test/Sema/decl-invalid.c
deleted file mode 100644
index b92146260ef1..000000000000
--- a/clang/test/Sema/decl-invalid.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-typedef union <anonymous> __mbstate_t; // expected-error: {{declaration of anonymous union must be a definition}}
-
-
-// PR2017
-void x();
-int a() {
- int r[x()]; // expected-error: {{size of array has non-integer type 'void'}}
-}
-
diff --git a/clang/test/Sema/declspec.c b/clang/test/Sema/declspec.c
deleted file mode 100644
index 1e84d6523e74..000000000000
--- a/clang/test/Sema/declspec.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-typedef char T[4];
-
-T foo(int n, int m) { } // expected-error {{cannot return array or function}}
-
-void foof(const char *, ...) __attribute__((__format__(__printf__, 1, 2))), barf (void);
-
-int typedef validTypeDecl() { } // expected-error {{function definition declared 'typedef'}}
-
-struct _zend_module_entry { }
-typedef struct _zend_function_entry { } // expected-error {{cannot combine with previous 'struct' declaration specifier}}
-static void buggy(int *x) { } // expected-error {{function definition declared 'typedef'}} \
- // expected-error {{cannot combine with previous 'typedef' declaration specifier}} \
- // expected-error {{cannot combine with previous 'struct' declaration specifier}}
-
-// Type qualifiers.
-typedef int f(void);
-typedef f* fptr;
-const f* v1; // expected-warning {{qualifier on function type 'f' has unspecified behavior}}
-__restrict__ f* v2; // expected-error {{restrict requires a pointer or reference ('f' is invalid)}}
-__restrict__ fptr v3; // expected-error {{pointer to function type ('f') may not be 'restrict' qualified}}
-f *__restrict__ v4; // expected-error {{pointer to function type ('f') may not be 'restrict' qualified}}
-
diff --git a/clang/test/Sema/default.c b/clang/test/Sema/default.c
deleted file mode 100644
index 4efac17cfd1f..000000000000
--- a/clang/test/Sema/default.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f5 (int z) {
- if (z)
- default: // expected-error {{not in switch statement}}
- ; // expected-warning {{if statement has empty body}}
-}
-
diff --git a/clang/test/Sema/default1.c b/clang/test/Sema/default1.c
deleted file mode 100644
index a72d0aef0cc3..000000000000
--- a/clang/test/Sema/default1.c
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-void f(int i = 0); // expected-error {{C does not support default arguments}}
diff --git a/clang/test/Sema/deref.c b/clang/test/Sema/deref.c
deleted file mode 100644
index 83f7f8389cd2..000000000000
--- a/clang/test/Sema/deref.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang -fsyntax-only -verify -std=c90 %s
-void
-foo (void)
-{
- struct b;
- struct b* x = 0;
- struct b* y = &*x;
-}
-
-void foo2 (void)
-{
- typedef int (*arrayptr)[];
- arrayptr x = 0;
- arrayptr y = &*x;
-}
-
-void foo3 (void)
-{
- void* x = 0;
- void* y = &*x; // expected-error{{address expression must be an lvalue or a function designator}}
-}
-
-extern const void cv1;
-
-const void *foo4 (void)
-{
- return &cv1;
-}
-
-extern void cv2;
-void *foo5 (void)
-{
- return &cv2; // expected-error{{address expression must be an lvalue or a function designator}}
-}
-
-typedef const void CVT;
-extern CVT cv3;
-
-const void *foo6 (void)
-{
- return &cv3;
-}
-
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
deleted file mode 100644
index ba93aaa2eecc..000000000000
--- a/clang/test/Sema/enum.c
+++ /dev/null
@@ -1,57 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic
-
-enum e {A,
- B = 42LL << 32, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
- C = -4, D = 12456 };
-
-enum f { a = -2147483648, b = 2147483647 }; // ok.
-
-enum g { // too negative
- c = -2147483649, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
- d = 2147483647 };
-enum h { e = -2147483648, // too pos
- f = 2147483648 // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
-};
-
-// minll maxull
-enum x // expected-warning {{enumeration values exceed range of largest integer}}
-{ y = -9223372036854775807LL-1, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
-z = 9223372036854775808ULL }; // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
-
-int test() {
- return sizeof(enum e) ;
-}
-
-enum gccForwardEnumExtension ve; // expected-error {{variable has incomplete type 'enum gccForwardEnumExtension'}} expected-warning{{ISO C forbids forward references to 'enum' types}}
-
-int test2(int i)
-{
- ve + i;
-}
-
-// PR2020
-union u0; // expected-error {{previous use is here}}
-enum u0 { U0A }; // expected-error {{error: use of 'u0' with tag type that does not match previous declaration}}
-
-
-// rdar://6095136
-extern enum some_undefined_enum ve2; // expected-warning {{ISO C forbids forward references to 'enum' types}}
-
-void test4() {
- for (; ve2;) // expected-error {{statement requires expression of scalar type}}
- ;
- (_Bool)ve2; // expected-error {{arithmetic or pointer type is required}}
-
- for (; ;ve2)
- ;
- (void)ve2;
- ve2; // expected-warning {{expression result unused}}
-}
-
-// PR2416
-enum someenum {}; // expected-warning {{use of empty enum extension}}
-
-// <rdar://problem/6093889>
-enum e0 { // expected-error {{previous definition is here}}
- E0 = sizeof(enum e0 { E1 }) // expected-error {{nested redefinition}}
-};
diff --git a/clang/test/Sema/expr-address-of.c b/clang/test/Sema/expr-address-of.c
deleted file mode 100644
index 58bc540a30d5..000000000000
--- a/clang/test/Sema/expr-address-of.c
+++ /dev/null
@@ -1,91 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-struct xx { int bitf:1; };
-
-struct entry { struct xx *whatever;
- int value;
- int bitf:1; };
-void add_one(int *p) { (*p)++; }
-
-void test() {
- register struct entry *p;
- add_one(&p->value);
- struct entry pvalue;
- add_one(&p->bitf); // expected-error {{address of bit-field requested}}
- add_one(&pvalue.bitf); // expected-error {{address of bit-field requested}}
- add_one(&p->whatever->bitf); // expected-error {{address of bit-field requested}}
-}
-
-void foo() {
- register int x[10];
- &x[10]; // expected-error {{address of register variable requested}}
-
- register int *y;
-
- int *x2 = &y; // expected-error {{address of register variable requested}}
- int *x3 = &y[10];
-}
-
-void testVectorComponentAccess() {
- typedef float v4sf __attribute__ ((vector_size (16)));
- static v4sf q;
- float* r = &q[0]; // expected-error {{address of vector requested}}
-}
-
-
-void f0() {
- register int *x0;
- int *_dummy0 = &(*x0);
-
- register int *x1;
- int *_dummy1 = &(*(x1 + 1));
-}
-
-void f1() {
- register int x0[10];
- int *_dummy0 = &(*x0); // expected-error {{address of register variable requested}}
-
- register int x1[10];
- int *_dummy1 = &(*(x1 + 1)); // expected-error {{address of register variable requested}}
-
- register int *x2;
- int *_dummy2 = &(*(x2 + 1));
-
- register int x3[10][10][10];
- int *_dummy3 = &x3[0][0]; // expected-error {{address of register variable requested}}
-
- register struct { int f0[10]; } x4;
- int *_dummy4 = &x4.f0[2]; // expected-error {{address of register variable requested}}
-}
-
-void f2() {
- register int *y;
-
- int *_dummy0 = &y; // expected-error {{address of register variable requested}}
- int *_dummy1 = &y[10];
-}
-
-void f3() {
- extern void f4();
- void (*_dummy0)() = &****f4;
-}
-
-void f4() {
- register _Complex int x;
-
- int *_dummy0 = &__real__ x; // expected-error {{address of register variable requested}}
-}
-
-void f5() {
- register int arr[2];
-
- /* This is just here because if we happened to support this as an
- lvalue we would need to give a warning. Note that gcc warns about
- this as a register before it warns about it as an invalid
- lvalue. */
- int *_dummy0 = &(int*) arr; // expected-error {{address expression must be an lvalue or a function designator}}
- int *_dummy1 = &(arr + 1); // expected-error {{address expression must be an lvalue or a function designator}}
-}
-
-void f6(register int x) {
- int * dummy0 = &x; // expected-error {{address of register variable requested}}
-}
diff --git a/clang/test/Sema/expr-comma-c89.c b/clang/test/Sema/expr-comma-c89.c
deleted file mode 100644
index 4949ee3a83fc..000000000000
--- a/clang/test/Sema/expr-comma-c89.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -std=c99
-// rdar://6095180
-
-#include <assert.h>
-struct s { char c[17]; };
-extern struct s foo(void);
-
-struct s a, b, c;
-
-int A[sizeof((foo().c)) == 17 ? 1 : -1];
-int B[sizeof((a.c)) == 17 ? 1 : -1];
-
-
-// comma does array/function promotion in c99.
-int X[sizeof(0, (foo().c)) == sizeof(char*) ? 1 : -1];
-int Y[sizeof(0, (a,b).c) == sizeof(char*) ? 1 : -1];
-int Z[sizeof(0, (a=b).c) == sizeof(char*) ? 1 : -1];
-
diff --git a/clang/test/Sema/expr-comma.c b/clang/test/Sema/expr-comma.c
deleted file mode 100644
index 849e8d5ae8b5..000000000000
--- a/clang/test/Sema/expr-comma.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -std=c89
-// rdar://6095180
-
-#include <assert.h>
-struct s { char c[17]; };
-extern struct s foo(void);
-
-struct s a, b, c;
-
-int A[sizeof((foo().c)) == 17 ? 1 : -1];
-int B[sizeof((a.c)) == 17 ? 1 : -1];
-
-
-// comma does not promote array/function in c90 unless they are lvalues.
-int W[sizeof(0, a.c) == sizeof(char*) ? 1 : -1];
-int X[sizeof(0, (foo().c)) == 17 ? 1 : -1];
-int Y[sizeof(0, (a,b).c) == 17 ? 1 : -1];
-int Z[sizeof(0, (a=b).c) == 17 ? 1 : -1];
diff --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c
deleted file mode 100644
index c98a7ed0c837..000000000000
--- a/clang/test/Sema/exprs.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang %s -verify -pedantic -fsyntax-only
-
-// PR1966
-_Complex double test1() {
- return __extension__ 1.0if;
-}
-
-_Complex double test2() {
- return 1.0if; // expected-warning {{imaginary constants are an extension}}
-}
-
-// rdar://6097308
-void test3() {
- int x;
- (__extension__ x) = 10;
-}
-
-// rdar://6162726
-void test4() {
- static int var;
- var =+ 5; // expected-warning {{use of unary operator that may be intended as compound assignment (+=)}}
- var =- 5; // expected-warning {{use of unary operator that may be intended as compound assignment (-=)}}
- var = +5;
- var = -5;
-}
-
diff --git a/clang/test/Sema/floating-point-compare.c b/clang/test/Sema/floating-point-compare.c
deleted file mode 100644
index ae0d0fe15091..000000000000
--- a/clang/test/Sema/floating-point-compare.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -fsyntax-only -Wfloat-equal -verify %s
-
-int f1(float x, float y) {
- return x == y; // expected-warning {{comparing floating point with ==}}
-}
-
-int f2(float x, float y) {
- return x != y; // expected-warning {{comparing floating point with ==}}
-}
-
-int f3(float x) {
- return x == x; // no-warning
-}
-
-int f4(float x) {
- return x == 0.0; // no-warning {{comparing}}
-}
-
-int f5(float x) {
- return x == __builtin_inf(); // no-warning
-}
-
-int f7(float x) {
- return x == 3.14159; // expected-warning {{comparing}}
-}
diff --git a/clang/test/Sema/for.c b/clang/test/Sema/for.c
deleted file mode 100644
index c08f532688b4..000000000000
--- a/clang/test/Sema/for.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// Check C99 6.8.5p3
-void b1 (void) { for (void (*f) (void);;); }
-void b2 (void) { for (void f (void);;); } // expected-error {{declaration of non-local variable}}
-void b3 (void) { for (static int f;;); } // expected-error {{declaration of non-local variable}}
-void b4 (void) { for (typedef int f;;); } // expected-error {{declaration of non-local variable}}
diff --git a/clang/test/Sema/format-attribute.c b/clang/test/Sema/format-attribute.c
deleted file mode 100644
index ecdef9dde1a3..000000000000
--- a/clang/test/Sema/format-attribute.c
+++ /dev/null
@@ -1,26 +0,0 @@
-//RUN: clang -fsyntax-only -verify %s
-
-#include <stdarg.h>
-
-void a(const char *a, ...) __attribute__((format(printf, 1,2))); // no-error
-void b(const char *a, ...) __attribute__((format(printf, 1,1))); // expected-error {{'format' attribute parameter 3 is out of bounds}}
-void c(const char *a, ...) __attribute__((format(printf, 0,2))); // expected-error {{'format' attribute parameter 2 is out of bounds}}
-void d(const char *a, int c) __attribute__((format(printf, 1,2))); // expected-error {{format attribute requires variadic function}}
-void e(char *str, int c, ...) __attribute__((format(printf, 2,3))); // expected-error {{format argument not a string type}}
-
-typedef const char* xpto;
-void f(xpto c, va_list list) __attribute__((format(printf, 1, 0))); // no-error
-void g(xpto c) __attribute__((format(printf, 1, 0))); // no-error
-
-void y(char *str) __attribute__((format(strftime, 1,0))); // no-error
-void z(char *str, int c, ...) __attribute__((format(strftime, 1,2))); // expected-error {{strftime format attribute requires 3rd parameter to be 0}}
-
-int (*f_ptr)(char*,...) __attribute__((format(printf, 1,2))); // no-error
-int (*f2_ptr)(double,...) __attribute__((format(printf, 1, 2))); // expected-error {{format argument not a string type}}
-
-struct _mystruct {
- int (*printf)(const char *format, ...) __attribute__((__format__(printf, 1, 2))); // no-error
- int (*printf2)(double format, ...) __attribute__((__format__(printf, 1, 2))); // expected-error {{format argument not a string type}}
-};
-
-typedef int (*f3_ptr)(char*,...) __attribute__((format(printf,1,0))); // no-error
diff --git a/clang/test/Sema/format-strings.c b/clang/test/Sema/format-strings.c
deleted file mode 100644
index 16d4943cda5f..000000000000
--- a/clang/test/Sema/format-strings.c
+++ /dev/null
@@ -1,81 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// Define this to get vasprintf on Linux
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdarg.h>
-
-char * global_fmt;
-
-void check_string_literal( FILE* fp, const char* s, char *buf, ... ) {
-
- char * b;
- va_list ap;
- va_start(ap,buf);
-
- printf(s); // expected-warning {{format string is not a string literal}}
- vprintf(s,ap); // // no-warning
- fprintf(fp,s); // expected-warning {{format string is not a string literal}}
- vfprintf(fp,s,ap); // no-warning
- asprintf(&b,s); // expected-warning {{format string is not a string lit}}
- vasprintf(&b,s,ap); // no-warning
- sprintf(buf,s); // expected-warning {{format string is not a string literal}}
- snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
- __builtin___sprintf_chk(buf,0,-1,s); // expected-warning {{format string is not a string literal}}
- __builtin___snprintf_chk(buf,2,0,-1,s); // expected-warning {{format string is not a string lit}}
- vsprintf(buf,s,ap); // no-warning
- vsnprintf(buf,2,s,ap); // no-warning
- vsnprintf(buf,2,global_fmt,ap); // expected-warning {{format string is not a string literal}}
- __builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning
- __builtin___vsnprintf_chk(buf,2,0,-1,global_fmt,ap); // expected-warning {{format string is not a string literal}}
-}
-
-void check_writeback_specifier()
-{
- int x;
- char *b;
-
- printf("%n",&x); // expected-warning {{'%n' in format string discouraged}}
- sprintf(b,"%d%%%n",1, &x); // expected-warning {{'%n' in format string dis}}
-}
-
-void check_invalid_specifier(FILE* fp, char *buf)
-{
- printf("%s%lb%d","unix",10,20); // expected-warning {{lid conversion '%lb'}}
- fprintf(fp,"%%%l"); // expected-warning {{lid conversion '%l'}}
- sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // no-warning
- snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning {{sion '%;'}}
-}
-
-void check_null_char_string(char* b)
-{
- printf("\0this is bogus%d",1); // expected-warning {{string contains '\0'}}
- snprintf(b,10,"%%%%%d\0%d",1,2); // expected-warning {{string contains '\0'}}
- printf("%\0d",1); // expected-warning {{string contains '\0'}}
-}
-
-void check_empty_format_string(char* buf, ...)
-{
- va_list ap;
- va_start(ap,buf);
- vprintf("",ap); // expected-warning {{format string is empty}}
- sprintf(buf,""); // expected-warning {{format string is empty}}
-}
-
-void check_wide_string(char* b, ...)
-{
- va_list ap;
- va_start(ap,b);
-
- printf(L"foo %d",2); // expected-warning {{incompatible pointer types}}, expected-warning {{should not be a wide string}}
- vasprintf(&b,L"bar %d",ap); // expected-warning {{incompatible pointer types}}, expected-warning {{should not be a wide string}}
-}
-
-void check_asterisk_precision_width(int x) {
- printf("%*d"); // expected-warning {{'*' specified field width is missing a matching 'int' argument}}
- printf("%.*d"); // expected-warning {{'.*' specified field precision is missing a matching 'int' argument}}
- printf("%*d",12,x); // no-warning
- printf("%*d","foo",x); // expected-warning {{field width should have type 'int', but argument has type 'char *'}}
- printf("%.*d","foo",x); // expected-warning {{field precision should have type 'int', but argument has type 'char *'}}
-}
diff --git a/clang/test/Sema/function-ptr.c b/clang/test/Sema/function-ptr.c
deleted file mode 100644
index 83e4d74b6ad1..000000000000
--- a/clang/test/Sema/function-ptr.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -verify -pedantic
-typedef int unary_int_func(int arg);
-unary_int_func *func;
-
-unary_int_func *set_func(void *p) {
- func = p; // expected-warning {{converts between void* and function pointer}}
- p = func; // expected-warning {{converts between void* and function pointer}}
-
- return p; // expected-warning {{converts between void* and function pointer}}
-}
-
diff --git a/clang/test/Sema/function.c b/clang/test/Sema/function.c
deleted file mode 100644
index 152205dd2443..000000000000
--- a/clang/test/Sema/function.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic
-// PR1892
-void f(double a[restrict][5]); // should promote to restrict ptr.
-void f(double (* restrict a)[5]);
-
-int foo (__const char *__path);
-int foo(__const char *__restrict __file);
-
-void func(const char*); //expected-error{{previous declaration is here}}
-void func(char*); //expected-error{{conflicting types for 'func'}}
-
-void g(int (*)(const void **, const void **));
-void g(int (*compar)()) {
-}
-
-void h(); //expected-error{{previous declaration is here}}
-void h (const char *fmt, ...) {} //expected-error{{conflicting types for 'h'}}
-
-// PR1965
-int t5(b); // expected-error {{parameter list without types}}
-int t6(int x, g); // expected-warning {{type specifier missing, defaults to 'int'}}
-
-int t7(, ); // expected-error {{expected parameter declarator}} expected-error {{expected parameter declarator}}
-int t8(, int a); // expected-error {{expected parameter declarator}}
-int t9(int a, ); // expected-error {{expected parameter declarator}}
-
-
-// PR2042
-void t10(){}
-void t11(){t10(1);}
-
diff --git a/clang/test/Sema/i-c-e1.c b/clang/test/Sema/i-c-e1.c
deleted file mode 100644
index cb4a9a33afdd..000000000000
--- a/clang/test/Sema/i-c-e1.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-void test1(int n, int* p) { *(n ? p : (void *)(7-7)) = 1; }
-void test2(int n, int* p) { *(n ? p : (void *)0) = 1; }
-
diff --git a/clang/test/Sema/i-c-e2.c b/clang/test/Sema/i-c-e2.c
deleted file mode 100644
index 1afb7c90c288..000000000000
--- a/clang/test/Sema/i-c-e2.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang %s -fsyntax-only -fpascal-strings
-
-char array[1024/(sizeof (long))];
-
-int x['\xBb' == (char) 187 ? 1: -1];
-
-// PR1992
-void func(int x)
-{
- switch (x) {
- case sizeof("abc"): break;
- case sizeof("loooong"): func(4);
- case sizeof("\ploooong"): func(4);
- }
-}
-
diff --git a/clang/test/Sema/if-empty-body.c b/clang/test/Sema/if-empty-body.c
deleted file mode 100644
index 376eb9865a06..000000000000
--- a/clang/test/Sema/if-empty-body.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f1(int a) {
- if (a); // expected-warning {{if statement has empty body}}
-}
-
-void f2(int a) {
- if (a) {}
-}
-
-void f3() {
- if (1)
- xx; // expected-error {{use of undeclared identifier}}
- return; // no empty body warning.
-}
-
diff --git a/clang/test/Sema/illegal-types.c b/clang/test/Sema/illegal-types.c
deleted file mode 100644
index 411f27262a74..000000000000
--- a/clang/test/Sema/illegal-types.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only -verify -std=c++98 %s
-
-void a (void []()); // expected-error{{'type name' declared as array of functions}}
-void b (void p[]()); // expected-error{{'p' declared as array of functions}}
-void c (int &[]); // expected-error{{'type name' declared as array of references}}
-void d (int &p[]); // expected-error{{'p' declared as array of references}}
-
diff --git a/clang/test/Sema/implicit-cast.c b/clang/test/Sema/implicit-cast.c
deleted file mode 100644
index fe83bd93e33e..000000000000
--- a/clang/test/Sema/implicit-cast.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-static char *test1(int cf) {
- return cf ? "abc" : 0;
-}
-static char *test2(int cf) {
- return cf ? 0 : "abc";
-}
diff --git a/clang/test/Sema/implicit-decl.c b/clang/test/Sema/implicit-decl.c
deleted file mode 100644
index ea40e61afb0d..000000000000
--- a/clang/test/Sema/implicit-decl.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-typedef int int32_t;
-typedef unsigned char Boolean;
-
-void func() {
- int32_t *vector[16];
- const char compDesc[16 + 1];
- int32_t compCount = 0;
- if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-error{{previous implicit declaration is here}}
- }
- return ((void *)0);
-}
-Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}}
- return 0;
-}
-
diff --git a/clang/test/Sema/implicit-def.c b/clang/test/Sema/implicit-def.c
deleted file mode 100644
index ea42d0c1c801..000000000000
--- a/clang/test/Sema/implicit-def.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* RUN: clang -fsyntax-only %s -std=c89 &&
- * RUN: not clang -fsyntax-only %s -std=c99 -pedantic-errors
- */
-
-int A() {
- return X();
-}
-
diff --git a/clang/test/Sema/implicit-int.c b/clang/test/Sema/implicit-int.c
deleted file mode 100644
index e4a215fb78fe..000000000000
--- a/clang/test/Sema/implicit-int.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-foo() {
-}
diff --git a/clang/test/Sema/incomplete-decl.c b/clang/test/Sema/incomplete-decl.c
deleted file mode 100644
index fedf2c69f7c0..000000000000
--- a/clang/test/Sema/incomplete-decl.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void b; // expected-error {{variable has incomplete type 'void'}}
-struct foo f; // expected-error {{variable has incomplete type 'struct foo'}}
-
-static void c; // expected-error {{variable has incomplete type 'void'}}
-static struct foo g; // expected-error {{variable has incomplete type 'struct foo'}}
-
-extern void d;
-extern struct foo e;
-
-int ary[];
-struct foo bary[]; // expected-error {{array has incomplete element type 'struct foo'}}
-
-void func() {
- int ary[]; // expected-error{{variable has incomplete type 'int []'}}
- void b; // expected-error {{variable has incomplete type 'void'}}
- struct foo f; // expected-error {{variable has incomplete type 'struct foo'}}
-}
-
-int h[];
-int (*i)[] = &h+1; // expected-error {{arithmetic on pointer to incomplete type 'int (*)[]'}}
-
diff --git a/clang/test/Sema/init-struct-qualified.c b/clang/test/Sema/init-struct-qualified.c
deleted file mode 100644
index 37637e108c38..000000000000
--- a/clang/test/Sema/init-struct-qualified.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only -verify < %s
-typedef float CGFloat;
-typedef struct _NSPoint { CGFloat x; CGFloat y; } NSPoint;
-typedef struct _NSSize { CGFloat width; CGFloat height; } NSSize;
-typedef struct _NSRect { NSPoint origin; NSSize size; } NSRect;
-
-extern const NSPoint NSZeroPoint;
-
-extern NSSize canvasSize();
-void func() {
- const NSRect canvasRect = { NSZeroPoint, canvasSize() };
-}
diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c
deleted file mode 100644
index 9f91c42f4461..000000000000
--- a/clang/test/Sema/init.c
+++ /dev/null
@@ -1,69 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-typedef void (* fp)(void);
-void foo(void);
-fp a[1] = { foo };
-
-int myArray[5] = {1, 2, 3, 4, 5};
-int *myPointer2 = myArray;
-int *myPointer = &(myArray[2]);
-
-
-extern int x;
-void *g = &x;
-int *h = &x;
-
-int test() {
-int a[10];
-int b[10] = a; // expected-error {{initialization with "{...}" expected}}
-}
-
-
-// PR2050
-struct cdiff_cmd {
- const char *name;
- unsigned short argc;
- int (*handler)();
-};
-int cdiff_cmd_open();
-struct cdiff_cmd commands[] = {
- {"OPEN", 1, &cdiff_cmd_open }
-};
-
-// PR2348
-static struct { int z; } s[2];
-int *t = &(*s).z;
-
-// PR2349
-short *a2(void)
-{
- short int b;
- static short *bp = &b; // expected-error {{initializer element is not a compile-time constant}}
-
- return bp;
-}
-
-int pbool(void) {
- typedef const _Bool cbool;
- _Bool pbool1 = (void *) 0;
- cbool pbool2 = &pbool;
- return pbool2;
-}
-
-
-// rdar://5870981
-union { float f; unsigned u; } u = { 1.0f };
-
-// rdar://6156694
-int f3(int x) { return x; }
-typedef void (*vfunc)(void);
-void *bar = (vfunc) f3;
-
-// PR2747
-struct sym_reg {
- char nc_gpreg;
-};
-int sym_fw1a_scr[] = {
- ((int)(&((struct sym_reg *)0)->nc_gpreg)) & 0,
- 8 * ((int)(&((struct sym_reg *)0)->nc_gpreg))
-};
diff --git a/clang/test/Sema/int-arith-convert.c b/clang/test/Sema/int-arith-convert.c
deleted file mode 100644
index 254c6c0591a5..000000000000
--- a/clang/test/Sema/int-arith-convert.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// Check types are the same through redeclaration
-unsigned long x;
-__typeof(1u+1l) x;
-
-unsigned y;
-__typeof(1+1u) y;
-__typeof(1u+1) y;
-
-long long z;
-__typeof(1ll+1u) z;
diff --git a/clang/test/Sema/invalid-decl.c b/clang/test/Sema/invalid-decl.c
deleted file mode 100644
index ccd3bc83659f..000000000000
--- a/clang/test/Sema/invalid-decl.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-void test() {
- char = 4; // expected-error {{expected identifier}} expected-error{{declarator requires an identifier}}
-
-}
-
-
-// PR2400
-typedef xtype (*zend_stream_fsizer_t)(void* handle); // expected-error {{function cannot return array or function type}}
-
-typedef struct _zend_module_entry zend_module_entry;
-struct _zend_module_entry {
- xtype globals_size; // expected-error {{field 'globals_size' declared as a function}}
-};
-
-zend_module_entry openssl_module_entry = {
- sizeof(zend_module_entry)
-};
-
diff --git a/clang/test/Sema/invalid-struct-init.c b/clang/test/Sema/invalid-struct-init.c
deleted file mode 100644
index a3dc687acb7c..000000000000
--- a/clang/test/Sema/invalid-struct-init.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-typedef struct _zend_module_entry zend_module_entry;
-struct _zend_module_entry {
- _efree((p)); // expected-error{{type name requires a specifier or qualifier}} \
- // expected-error{{field '_efree' declared as a function}}
-};
-typedef struct _zend_function_entry { } zend_function_entry;
-typedef struct _zend_pcre_globals { } zend_pcre_globals;
-zend_pcre_globals pcre_globals;
-
-static void zm_globals_ctor_pcre(zend_pcre_globals *pcre_globals ) { }
-static void zm_globals_dtor_pcre(zend_pcre_globals *pcre_globals ) { }
-static void zm_info_pcre(zend_module_entry *zend_module ) { }
-static int zm_startup_pcre(int type, int module_number ) { }
-
-static int zm_shutdown_pcre(int type, int module_number ) {
- zend_function_entry pcre_functions[] = {{ }; // expected-error{{expected '}'}} expected-error{{to match this '{'}}
- zend_module_entry pcre_module_entry = {
- sizeof(zend_module_entry), 20071006, 0, 0, ((void *)0), ((void *)0),
- "pcre", pcre_functions, zm_startup_pcre, zm_shutdown_pcre, ((void *)0),
- ((void *)0), zm_info_pcre, ((void *)0), sizeof(zend_pcre_globals), &pcre_globals,
- ((void (*)(void* ))(zm_globals_ctor_pcre)), ((void (*)(void* ))(zm_globals_dtor_pcre)),
- ((void *)0), 0, 0, ((void *)0), 0
- };
-}
diff --git a/clang/test/Sema/member-reference.c b/clang/test/Sema/member-reference.c
deleted file mode 100644
index 784d60020ad3..000000000000
--- a/clang/test/Sema/member-reference.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-struct simple { int i; };
-
-void f(void) {
- struct simple s[1];
- s->i = 1;
-}
-
diff --git a/clang/test/Sema/merge-decls.c b/clang/test/Sema/merge-decls.c
deleted file mode 100644
index 50ce4787699f..000000000000
--- a/clang/test/Sema/merge-decls.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-void foo(void);
-void foo(void) {}
-void foo(void);
-void foo(void); // expected-error{{previous declaration is here}}
-
-void foo(int); // expected-error {{conflicting types for 'foo'}}
-
-int funcdef()
-{
- return 0;
-}
-
-int funcdef();
-
-int funcdef2() { return 0; } // expected-error{{previous definition is here}}
-int funcdef2() { return 0; } // expected-error {{redefinition of 'funcdef2'}}
-
diff --git a/clang/test/Sema/ms-fuzzy-asm.c b/clang/test/Sema/ms-fuzzy-asm.c
deleted file mode 100644
index 5e387f380836..000000000000
--- a/clang/test/Sema/ms-fuzzy-asm.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s -verify -fms-extensions
-
-#define M __asm int 0x2c
-#define M2 int
-
-void t1(void) { M }
-void t2(void) { __asm int 0x2c }
-void t3(void) { __asm M2 0x2c }
-
diff --git a/clang/test/Sema/nonnull.c b/clang/test/Sema/nonnull.c
deleted file mode 100644
index 9a64ce4320b0..000000000000
--- a/clang/test/Sema/nonnull.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int f1(int x) __attribute__((nonnull)); // expected-warning{{'nonnull' attribute applied to function with no pointer arguments}}
-int f2(int *x) __attribute__ ((nonnull (1)));
-int f3(int *x) __attribute__ ((nonnull (0))); // expected-error {{'nonnull' attribute parameter 1 is out of bounds}}
-int f4(int *x, int *y) __attribute__ ((nonnull (1,2)));
-int f5(int *x, int *y) __attribute__ ((nonnull (2,1)));
-
diff --git a/clang/test/Sema/offsetof.c b/clang/test/Sema/offsetof.c
deleted file mode 100644
index b5adb31f22c9..000000000000
--- a/clang/test/Sema/offsetof.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
-
-typedef struct P { int i; float f; } PT;
-struct external_sun3_core
-{
- unsigned c_regs;
-
- PT X[100];
-
-};
-
-void swap()
-{
- int x;
- x = offsetof(struct external_sun3_core, c_regs);
- x = __builtin_offsetof(struct external_sun3_core, X[42].f);
-
- x = __builtin_offsetof(struct external_sun3_core, X[42].f2); // expected-error {{no member named 'f2'}}
- x = __builtin_offsetof(int, X[42].f2); // expected-error {{offsetof requires struct}}
-
- int a[__builtin_offsetof(struct external_sun3_core, X) == 4 ? 1 : -1];
- int b[__builtin_offsetof(struct external_sun3_core, X[42]) == 340 ? 1 : -1];
- int c[__builtin_offsetof(struct external_sun3_core, X[42].f2) == 344 ? 1 : -1]; // expected-error {{no member named 'f2'}}
-}
-
-
-struct s1 { int a; };
-extern int v1[offsetof (struct s1, a) == 0];
-
-struct s2 { int a; };
-extern int v2[__INTADDR__ (&((struct s2 *) 0)->a) == 0];
-
-struct s3 { int a; };
-extern int v3[__builtin_offsetof(struct s3, a) == 0];
diff --git a/clang/test/Sema/pointer-addition.c b/clang/test/Sema/pointer-addition.c
deleted file mode 100644
index f2fb973d1be0..000000000000
--- a/clang/test/Sema/pointer-addition.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic
-
-typedef struct S S;
-void a(S* b, void* c) {
- b++; // expected-error {{arithmetic on pointer to incomplete type}}
- b += 1; // expected-error {{arithmetic on pointer to incomplete type}}
- c++; // expected-warning {{use of GNU void* extension}}
- c += 1; // expected-warning {{use of GNU void* extension}}
- b = 1+b; // expected-error {{arithmetic on pointer to incomplete type}}
- /* The next couple tests are only pedantic warnings in gcc */
- void (*d)(S*,void*) = a;
- d += 1; // expected-error {{pointer to incomplete type}}
- d++; // expected-error {{pointer to incomplete type}}
-}
diff --git a/clang/test/Sema/pointer-subtract-compat.c b/clang/test/Sema/pointer-subtract-compat.c
deleted file mode 100644
index 4ed6abf8af71..000000000000
--- a/clang/test/Sema/pointer-subtract-compat.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic
-
-typedef const char rchar;
-int a(char* a, rchar* b) {
- return a-b;
-}
diff --git a/clang/test/Sema/predef.c b/clang/test/Sema/predef.c
deleted file mode 100644
index bd5e1a98b24b..000000000000
--- a/clang/test/Sema/predef.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void abcdefghi12(void) {
- const char (*ss)[12] = &__func__;
- static int arr[sizeof(__func__)==12 ? 1 : -1];
-}
-
-char *X = __func__; // expected-error {{predefined identifier is only valid}}
-
-void a() {
- __func__[0] = 'a'; // expected-error {{variable is not assignable}}
-}
diff --git a/clang/test/Sema/predefined-function.c b/clang/test/Sema/predefined-function.c
deleted file mode 100644
index daade82b465c..000000000000
--- a/clang/test/Sema/predefined-function.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-char *funk(int format);
-enum Test {A=-1};
-char *funk(enum Test x);
-
-int eli(float b); // expected-error {{previous declaration is here}}
-int b(int c) {return 1;}
-
-int foo();
-int foo()
-{
- int eli(int (int)); // expected-error {{conflicting types for 'eli'}}
- eli(b);
- return 0;
-}
-
-int bar();
-int bar(int i) // expected-error {{previous definition is here}}
-{
- return 0;
-}
-int bar() // expected-error {{redefinition of 'bar'}}
-{
- return 0;
-}
-
-#if 0
-int foobar(int); // expected-error {{previous declaration is here}}
-int foobar() // expected-error {{conflicting types for 'foobar'}}
-{
- return 0;
-}
-#endif
-
-int wibble(); // expected-error {{previous declaration is here}}
-float wibble() // expected-error {{conflicting types for 'wibble'}}
-{
- return 0.0f;
-}
diff --git a/clang/test/Sema/rdar6248119.m b/clang/test/Sema/rdar6248119.m
deleted file mode 100644
index ff402b296d84..000000000000
--- a/clang/test/Sema/rdar6248119.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-// Test case for:
-// <rdar://problem/6248119> @finally doesn't introduce a new scope
-
-void f0() {
- int i;
- @try {
- } @finally {
- int i = 0;
- }
-}
-
-void f1() {
- int i;
- @try {
- int i =0;
- } @finally {
- }
-}
-
-void f2() {
- int i;
- @try {
- } @catch(id e) {
- int i = 0;
- }
-}
diff --git a/clang/test/Sema/recover-goto.c b/clang/test/Sema/recover-goto.c
deleted file mode 100644
index 4bb7c51bbf9b..000000000000
--- a/clang/test/Sema/recover-goto.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-
-void a() {goto A; // expected-error {{use of undeclared label}}
-// expected-error {{expected '}'}}
diff --git a/clang/test/Sema/redefinition.c b/clang/test/Sema/redefinition.c
deleted file mode 100644
index c45779fdeeff..000000000000
--- a/clang/test/Sema/redefinition.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-int f(int) { } // expected-error{{previous definition is here}}
-int f(int);
-int f(int) { } // expected-error{{redefinition of 'f'}}
-
diff --git a/clang/test/Sema/self-comparison.c b/clang/test/Sema/self-comparison.c
deleted file mode 100644
index 023afb7926f0..000000000000
--- a/clang/test/Sema/self-comparison.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int foo(int x) {
- return x == x; // expected-warning {{self-comparison always results}}
-}
-
-int foo2(int x) {
- return (x) != (((x))); // expected-warning {{self-comparison always results}}
-}
-
-int qux(int x) {
- return x < x; // expected-warning {{self-comparison}}
-}
-
-int qux2(int x) {
- return x > x; // expected-warning {{self-comparison}}
-}
-
-int bar(float x) {
- return x == x; // no-warning
-}
-
-int bar2(float x) {
- return x != x; // no-warning
-}
diff --git a/clang/test/Sema/sentinel-attribute.c b/clang/test/Sema/sentinel-attribute.c
deleted file mode 100644
index a83cda771d2d..000000000000
--- a/clang/test/Sema/sentinel-attribute.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-int x __attribute__((sentinel)); //expected-warning{{'sentinel' attribute only applies to function or method types}}
-
-void f1(int a, ...) __attribute__ ((sentinel));
-void f2(int a, ...) __attribute__ ((sentinel(1)));
-
-void f3(int a, ...) __attribute__ ((sentinel("hello"))); //expected-error{{'sentinel' attribute requires parameter 1 to be an integer constant}}
-void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{attribute requires 0, 1 or 2 argument(s)}}
-void f4(int a, ...) __attribute__ ((sentinel(-1))); //expected-error{{parameter 1 less than zero}}
-void f4(int a, ...) __attribute__ ((sentinel(0, 2))); // expected-error{{parameter 2 not 0 or 1}}
-
-void f5(int a) __attribute__ ((sentinel)); //expected-warning{{'sentinel' attribute only supported for variadic functions}}
-
diff --git a/clang/test/Sema/shift.c b/clang/test/Sema/shift.c
deleted file mode 100644
index d5ae5c1e903a..000000000000
--- a/clang/test/Sema/shift.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-void test() {
- char c;
- c <<= 14;
-}
diff --git a/clang/test/Sema/static-init.c b/clang/test/Sema/static-init.c
deleted file mode 100644
index 2f1380062d32..000000000000
--- a/clang/test/Sema/static-init.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-static int f = 10;
-static int b = f; // expected-error {{initializer element is not a compile-time constant}}
-
-float r = (float) &r; // expected-error {{initializer element is not a compile-time constant}}
-long long s = (long long) &s;
-_Bool t = &t;
diff --git a/clang/test/Sema/stmt_exprs.c b/clang/test/Sema/stmt_exprs.c
deleted file mode 100644
index ee835a355dc7..000000000000
--- a/clang/test/Sema/stmt_exprs.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-typedef unsigned __uint32_t;
-
-#define __byte_swap_int_var(x) \
-__extension__ ({ register __uint32_t __X = (x); \
- __asm ("bswap %0" : "+r" (__X)); \
- __X; })
-
-int test(int _x) {
- return (__byte_swap_int_var(_x));
-}
-
-// PR2374
-int test2() { return ({L:5;}); }
-int test3() { return ({ {5;} }); } // expected-error {{incompatible type returning 'void', expected 'int'}}\
- // expected-warning {{expression result unused}}
-int test4() { return ({ ({5;}); }); }
-int test5() { return ({L1: L2: L3: 5;}); }
-int test6() { return ({5;}); }
-void test7() { ({5;}); } // expected-warning {{expression result unused}}
-
diff --git a/clang/test/Sema/struct-compat.c b/clang/test/Sema/struct-compat.c
deleted file mode 100644
index a4492d12e2a6..000000000000
--- a/clang/test/Sema/struct-compat.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* RUN: clang %s -fsyntax-only -pedantic -verify
- */
-
-extern struct {int a;} x; // expected-error{{previous definition is here}}
-extern struct {int a;} x; // expected-error{{redefinition of 'x'}}
-
-struct x;
-int a(struct x* b) {
-// Per C99 6.7.2.3, since the outer and inner "struct x"es have different
-// scopes, they don't refer to the same type, and are therefore incompatible
-struct x {int a;} *c = b; // expected-warning{{incompatible pointer types}}
-}
-
-struct x {int a;} r;
-int b() {
-struct x {char x;} s = r; // expected-error{{incompatible type initializing}}
-}
diff --git a/clang/test/Sema/struct-packed-align.c b/clang/test/Sema/struct-packed-align.c
deleted file mode 100644
index 8173f0f28272..000000000000
--- a/clang/test/Sema/struct-packed-align.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-// Packed structs.
-struct s {
- char a;
- int b __attribute__((packed));
- char c;
- int d;
-};
-
-extern int a1[sizeof(struct s) == 12 ? 1 : -1];
-extern int a2[__alignof(struct s) == 4 ? 1 : -1];
-
-struct __attribute__((packed)) packed_s {
- char a;
- int b __attribute__((packed));
- char c;
- int d;
-};
-
-extern int b1[sizeof(struct packed_s) == 10 ? 1 : -1];
-extern int b2[__alignof(struct packed_s) == 1 ? 1 : -1];
-
-struct fas {
- char a;
- int b[];
-};
-
-extern int c1[sizeof(struct fas) == 4 ? 1 : -1];
-extern int c2[__alignof(struct fas) == 4 ? 1 : -1];
-
-struct __attribute__((packed)) packed_fas {
- char a;
- int b[];
-};
-
-extern int d1[sizeof(struct packed_fas) == 1 ? 1 : -1];
-extern int d2[__alignof(struct packed_fas) == 1 ? 1 : -1];
-
-// Alignment
-
-struct __attribute__((aligned(8))) as1 {
- char c;
-};
-
-extern int e1[sizeof(struct as1) == 8 ? 1 : -1];
-extern int e2[__alignof(struct as1) == 8 ? 1 : -1];
-
-struct as2 {
- char c;
- int __attribute__((aligned(8))) a;
-};
-
-extern int f1[sizeof(struct as2) == 16 ? 1 : -1];
-extern int f2[__alignof(struct as2) == 8 ? 1 : -1];
-
-struct __attribute__((packed)) as3 {
- char c;
- int a;
- int __attribute__((aligned(8))) b;
-};
-
-extern int g1[sizeof(struct as3) == 16 ? 1 : -1];
-extern int g2[__alignof(struct as3) == 8 ? 1 : -1];
-
-
-// rdar://5921025
-struct packedtest {
- int ted_likes_cheese;
- void *args[] __attribute__((packed));
-};
-
-// Packed union
-union __attribute__((packed)) au4 {char c; int x;};
-extern int h1[sizeof(union au4) == 4 ? 1 : -1];
-extern int h2[__alignof(union au4) == 1 ? 1 : -1];
-
-// Aligned union
-union au5 {__attribute__((aligned(4))) char c;};
-extern int h1[sizeof(union au5) == 4 ? 1 : -1];
-extern int h2[__alignof(union au5) == 4 ? 1 : -1];
-
-// Alignment+packed
-struct as6 {char c; __attribute__((packed, aligned(2))) int x;};
-extern int i1[sizeof(struct as6) == 6 ? 1 : -1];
-extern int i2[__alignof(struct as6) == 2 ? 1 : -1];
-
-union au6 {char c; __attribute__((packed, aligned(2))) int x;};
-extern int k1[sizeof(union au6) == 4 ? 1 : -1];
-extern int k2[__alignof(union au6) == 2 ? 1 : -1];
-
-// Check postfix attributes
-union au7 {char c; int x;} __attribute__((packed));
-extern int l1[sizeof(union au7) == 4 ? 1 : -1];
-extern int l2[__alignof(union au7) == 1 ? 1 : -1];
-
-struct packed_fas2 {
- char a;
- int b[];
-} __attribute__((packed));
-
-extern int m1[sizeof(struct packed_fas2) == 1 ? 1 : -1];
-extern int m2[__alignof(struct packed_fas2) == 1 ? 1 : -1];
diff --git a/clang/test/Sema/switch-duplicate-defaults.c b/clang/test/Sema/switch-duplicate-defaults.c
deleted file mode 100644
index 9ef683b48b9d..000000000000
--- a/clang/test/Sema/switch-duplicate-defaults.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f (int z) {
- switch(z) {
- default: // expected-error {{first label is here}}
- default: // expected-error {{multiple default labels in one switch}}
- break;
- }
-}
-
diff --git a/clang/test/Sema/switch.c b/clang/test/Sema/switch.c
deleted file mode 100644
index 0e39175817ea..000000000000
--- a/clang/test/Sema/switch.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f (int z) {
- while (z) {
- default: z--; // expected-error {{statement not in switch}}
- }
-}
-
-void foo(int X) {
- switch (X) {
- case 42: ; // expected-error {{previous case value}}
- case 5000000000LL: // expected-warning {{overflow}}
- case 42: // expected-error {{duplicate case value}}
- ;
-
- case 100 ... 99: ; // expected-warning {{empty case range}}
-
- case 43: ; // expected-error {{previous case value}}
- case 43 ... 45: ; // expected-error {{duplicate case value}}
-
- case 100 ... 20000:; // expected-error {{previous case value}}
- case 15000 ... 40000000:; // expected-error {{duplicate case value}}
- }
-}
-
-void test3(void) {
- // empty switch;
- switch (0);
-}
-
diff --git a/clang/test/Sema/tentative-decls.c b/clang/test/Sema/tentative-decls.c
deleted file mode 100644
index 3a2fd5a235d4..000000000000
--- a/clang/test/Sema/tentative-decls.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-const int a [1] = {1};
-extern const int a[];
-
-extern const int b[];
-const int b [1] = {1};
-
-extern const int c[] = {1}; // expected-warning{{'extern' variable has an initializer}}
-const int c[];
-
-int i1 = 1; // expected-error{{previous definition is here}}
-int i1 = 2; // expected-error{{redefinition of 'i1'}} // expected-error{{previous definition is here}}
-int i1;
-int i1;
-extern int i1; // expected-error{{previous definition is here}}
-static int i1; // expected-error{{static declaration of 'i1' follows non-static declaration}} expected-error{{previous definition is here}}
-int i1 = 3; // expected-error{{redefinition of 'i1'}} expected-error{{non-static declaration of 'i1' follows static declaration}}
-
-__private_extern__ int pExtern;
-int pExtern = 0;
-
-int i4;
-int i4;
-extern int i4;
-
-int (*pToArray)[];
-int (*pToArray)[8];
-
-int redef[10];
-int redef[]; // expected-error{{previous definition is here}}
-int redef[11]; // expected-error{{redefinition of 'redef'}}
-
-void func() {
- extern int i1; // expected-error{{previous definition is here}}
- static int i1; // expected-error{{static declaration of 'i1' follows non-static declaration}}
-}
-
-void func2(void)
-{
- extern double *p;
- extern double *p;
-}
diff --git a/clang/test/Sema/text-diag.c b/clang/test/Sema/text-diag.c
deleted file mode 100644
index 2e3129184429..000000000000
--- a/clang/test/Sema/text-diag.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -fsyntax-only %s
-unsigned char *foo = "texto\
-que continua\
-e continua";
diff --git a/clang/test/Sema/transparent-union-pointer.c b/clang/test/Sema/transparent-union-pointer.c
deleted file mode 100644
index 58597b18096a..000000000000
--- a/clang/test/Sema/transparent-union-pointer.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-typedef union {
- union wait *__uptr;
- int *__iptr;
-} __WAIT_STATUS __attribute__ ((__transparent_union__));
-
-extern int wait (__WAIT_STATUS __stat_loc);
-
-void fastcgi_cleanup() {
- int status = 0;
- wait(&status);
-}
-
diff --git a/clang/test/Sema/typecheck-binop.c b/clang/test/Sema/typecheck-binop.c
deleted file mode 100644
index 8367565de2ea..000000000000
--- a/clang/test/Sema/typecheck-binop.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* RUN: clang %s -fsyntax-only -pedantic -verify
- */
-struct incomplete;
-
-int sub1(int *a, double *b) {
- return a - b; /* expected-error{{not pointers to compatible types}} */
-}
-
-void *sub2(struct incomplete *P) {
- return P-4; /* expected-error{{not a complete object type}} */
-}
-
-void *sub3(void *P) {
- return P-4; /* expected-warning{{GNU void* extension}} */
-}
-
-int sub4(void *P, void *Q) {
- return P-Q; /* expected-warning{{GNU void* extension}} */
-}
-
-int logicaland1(int a) {
- return a && (void)a; /* expected-error{{invalid operands}} */
-}
diff --git a/clang/test/Sema/typedef-prototype.c b/clang/test/Sema/typedef-prototype.c
deleted file mode 100644
index e646604ae389..000000000000
--- a/clang/test/Sema/typedef-prototype.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef int unary_int_func(int arg);
-unary_int_func add_one;
-
-int add_one(int arg) {
- return arg + 1;
-}
diff --git a/clang/test/Sema/typedef-redef.c b/clang/test/Sema/typedef-redef.c
deleted file mode 100644
index d3904dd147d1..000000000000
--- a/clang/test/Sema/typedef-redef.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang < %s -fsyntax-only -verify
-
-// size_t coming from a system header.
-#include <stddef.h>
-typedef __SIZE_TYPE__ size_t;
-
-
-
-typedef const int x; // expected-error {{previous definition is here}}
-extern x a;
-typedef int x; // expected-error {{typedef redefinition with different types}}
-extern x a;
-
diff --git a/clang/test/Sema/typedef-retain.c b/clang/test/Sema/typedef-retain.c
deleted file mode 100644
index 861e0771cc42..000000000000
--- a/clang/test/Sema/typedef-retain.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef float float4 __attribute__((vector_size(16)));
-typedef int int4 __attribute__((vector_size(16)));
-typedef int4* int4p;
-
-void test1(float4 a, int4 *result, int i) {
- result[i] = a; // expected-error {{assigning 'float4', expected 'int4'}}
-}
-
-void test2(float4 a, int4p result, int i) {
- result[i] = a; // expected-error {{assigning 'float4', expected 'int4'}}
-}
-
-// PR2039
-typedef int a[5];
-void test3() {
- typedef const a b;
- b r;
- r[0]=10; // expected-error {{read-only variable is not assignable}}
-}
-
-int test4(const a y) {
- y[0] = 10; // expected-error {{read-only variable is not assignable}}
-}
-
-// PR2189
-int test5() {
- const int s[5]; int t[5];
- return &s == &t; // expected-warning {{comparison of distinct pointer types}}
-}
-
-int test6() {
- const a s;
- a t;
- return &s == &t; // expected-warning {{comparison of distinct pointer types}}
-}
-
diff --git a/clang/test/Sema/typedef-variable-type.c b/clang/test/Sema/typedef-variable-type.c
deleted file mode 100644
index 4ced92626433..000000000000
--- a/clang/test/Sema/typedef-variable-type.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only -pedantic
-
-typedef int (*a)[!.0]; // expected-error{{arrays with static storage duration must have constant integer length}}
diff --git a/clang/test/Sema/unnamed-bitfield-init.c b/clang/test/Sema/unnamed-bitfield-init.c
deleted file mode 100644
index 3a3869ab6dfb..000000000000
--- a/clang/test/Sema/unnamed-bitfield-init.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef struct {
- int a; int : 24; char b;
-} S;
-
-S a = { 1, 2 };
diff --git a/clang/test/Sema/unused-expr.c b/clang/test/Sema/unused-expr.c
deleted file mode 100644
index b14daa702dd6..000000000000
--- a/clang/test/Sema/unused-expr.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int foo(int X, int Y);
-
-void bar(volatile int *VP, int *P, int A,
- _Complex double C, volatile _Complex double VC) {
-
- VP == P; // expected-warning {{expression result unused}}
- (void)A;
- (void)foo(1,2); // no warning.
-
- A == foo(1, 2); // expected-warning {{expression result unused}}
-
- foo(1,2)+foo(4,3); // expected-warning {{expression result unused}}
-
-
- *P; // expected-warning {{expression result unused}}
- *VP; // no warning.
- P[4]; // expected-warning {{expression result unused}}
- VP[4]; // no warning.
-
- // FIXME: SEMA explodes on these.
- //__real__ C;
- //__real__ VC;
-}
-
-extern void t1();
-extern void t2();
-void t3(int c) {
- c ? t1() : t2();
-}
-
-// This shouldn't warn: the expr at the end of the stmtexpr really is used.
-int stmt_expr(int x, int y) {
- return ({int _a = x, _b = y; _a > _b ? _a : _b; });
-}
-
-void nowarn(unsigned char* a, unsigned char* b)
-{
- unsigned char c = 1;
- *a |= c, *b += c;
-}
diff --git a/clang/test/Sema/usual-float.c b/clang/test/Sema/usual-float.c
deleted file mode 100644
index 9c1977ff2427..000000000000
--- a/clang/test/Sema/usual-float.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-typedef float CGFloat;
-
-extern void func(CGFloat);
-void foo(int dir, int n, int tindex) {
- const float PI = 3.142;
- CGFloat cgf = 3.4;
-
- float ang = (float) tindex * (-dir*2.0f*PI/n);
- func((CGFloat)cgf/65535.0f);
-}
diff --git a/clang/test/Sema/va_arg_x86_64.c b/clang/test/Sema/va_arg_x86_64.c
deleted file mode 100644
index 3e51b8628c3d..000000000000
--- a/clang/test/Sema/va_arg_x86_64.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -verify -triple=x86_64-unknown-freebsd7.0 %s
-
-// PR2631
-char* foo(char *fmt, __builtin_va_list ap)
-{
- return __builtin_va_arg((ap), char *);
-}
-
-// PR2692
-typedef __builtin_va_list va_list;
-static char *f (char * (*g) (char **, int), char **p, ...) {
- char *s;
- va_list v;
- s = g (p, __builtin_va_arg(v, int));
-}
-
diff --git a/clang/test/Sema/varargs.c b/clang/test/Sema/varargs.c
deleted file mode 100644
index 90568e029884..000000000000
--- a/clang/test/Sema/varargs.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s &&
-// RUN: clang -fsyntax-only -verify %s -triple x86_64-apple-darwin9
-
-void f1(int a)
-{
- __builtin_va_list ap;
-
- __builtin_va_start(ap, a, a); // expected-error {{too many arguments to function}}
- __builtin_va_start(ap, a); // expected-error {{'va_start' used in function with fixed args}}
-}
-
-void f2(int a, int b, ...)
-{
- __builtin_va_list ap;
-
- __builtin_va_start(ap, 10); // expected-warning {{second parameter of 'va_start' not last named argument}}
- __builtin_va_start(ap, a); // expected-warning {{second parameter of 'va_start' not last named argument}}
- __builtin_va_start(ap, b);
-}
-
-void f3(float a, ...)
-{
- __builtin_va_list ap;
-
- __builtin_va_start(ap, a);
- __builtin_va_start(ap, (a));
-}
diff --git a/clang/test/Sema/vector-assign.c b/clang/test/Sema/vector-assign.c
deleted file mode 100644
index be447120c51c..000000000000
--- a/clang/test/Sema/vector-assign.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only -flax-vector-conversions
-typedef unsigned int v2u __attribute__ ((vector_size (8)));
-typedef signed int v2s __attribute__ ((vector_size (8)));
-typedef signed int v1s __attribute__ ((vector_size (4)));
-typedef float v2f __attribute__ ((vector_size(8)));
-typedef signed short v4ss __attribute__ ((vector_size (8)));
-
-void f() {
- v2s v1;
- v2u v2;
- v1s v3;
- v2f v4;
- v4ss v5;
-
- v1 = v2;
- v1 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2s'}}
- v1 = v4;
- v1 = v5;
-
- v2 = v1;
- v2 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2u'}}
- v2 = v4;
- v2 = v5;
-
- v3 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v1s'}}
- v3 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v1s'}}
- v3 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v1s'}}
- v3 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v1s'}}
-
- v4 = v1;
- v4 = v2;
- v4 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2f'}}
- v4 = v5;
-
- v5 = v1;
- v5 = v2;
- v5 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v4ss'}}
- v5 = v4;
-}
-
-// PR2263
-float f2(__attribute__((vector_size(16))) float a, int b) {
- return a[b];
-}
-
diff --git a/clang/test/Sema/vector-cast.c b/clang/test/Sema/vector-cast.c
deleted file mode 100644
index 111430b1c1ef..000000000000
--- a/clang/test/Sema/vector-cast.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: clang -fsyntax-only %s -verify
-
-typedef long long t1 __attribute__ ((vector_size (8)));
-typedef char t2 __attribute__ ((vector_size (16)));
-typedef float t3 __attribute__ ((vector_size (16)));
-
-void f()
-{
- t1 v1;
- t2 v2;
- t3 v3;
-
- v2 = (t2)v1; // -expected-error {{invalid conversion between vector type \
-'t1' and 't2' of different size}}
- v1 = (t1)v2; // -expected-error {{invalid conversion between vector type \
-'t2' and 't1' of different size}}
- v3 = (t3)v2;
-
- v1 = (t1)(char *)10; // -expected-error {{invalid conversion between vector \
-type 't1' and scalar type 'char *'}}
- v1 = (t1)(long long)10;
- v1 = (t1)(short)10; // -expected-error {{invalid conversion between vector \
-type 't1' and integer type 'int' of different size}}
-
- long long r1 = (long long)v1;
- short r2 = (short)v1; // -expected-error {{invalid conversion between vector \
-type 't1' and integer type 'short' of different size}}
- char *r3 = (char *)v1; // -expected-error {{invalid conversion between vector\
- type 't1' and scalar type 'char *'}}
-}
diff --git a/clang/test/Sema/vector-init.c b/clang/test/Sema/vector-init.c
deleted file mode 100644
index 1e2ba012c8f2..000000000000
--- a/clang/test/Sema/vector-init.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-typedef __attribute__(( ext_vector_type(4) )) float float4;
-
-float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
diff --git a/clang/test/Sema/vla.c b/clang/test/Sema/vla.c
deleted file mode 100644
index 5f4857e31016..000000000000
--- a/clang/test/Sema/vla.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-int test1() {
- typedef int x[test1()]; // vla
- static int y = sizeof(x); // expected-error {{not a compile-time constant}}
-}
-
-// PR2347
-void f (unsigned int m)
-{
- int e[2][m];
-
- e[0][0] = 0;
-}
-
diff --git a/clang/test/Sema/void_arg.c b/clang/test/Sema/void_arg.c
deleted file mode 100644
index d0571fc4e122..000000000000
--- a/clang/test/Sema/void_arg.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* RUN: clang -fsyntax-only %s -verify
- */
-
-typedef void Void;
-
-void foo() {
- int X;
-
- X = sizeof(int (void a)); // expected-error {{argument may not have 'void' type}}
- X = sizeof(int (int, void)); // expected-error {{must be the first and only parameter}}
- X = sizeof(int (void, ...)); // expected-error {{must be the first and only parameter}}
-
- X = sizeof(int (Void a)); // expected-error {{argument may not have 'void' type}}
- X = sizeof(int (int, Void)); // expected-error {{must be the first and only parameter}}
- X = sizeof(int (Void, ...)); // expected-error {{must be the first and only parameter}}
-
- // Accept these.
- X = sizeof(int (void));
- X = sizeof(int (Void));
-}
-
-// this is ok.
-void bar(Void) {
-}
-
-void f(const void); // expected-error {{parameter must not have type qualifiers}}
diff --git a/clang/test/Sema/wchar_size.c b/clang/test/Sema/wchar_size.c
deleted file mode 100644
index a4041b976da9..000000000000
--- a/clang/test/Sema/wchar_size.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -triple=i686-apple-darwin9
-
-int check_wchar_size[sizeof(*L"") == 4 ? 1 : -1];
diff --git a/clang/test/SemaCXX/bool.cpp b/clang/test/SemaCXX/bool.cpp
deleted file mode 100644
index e35495ababfa..000000000000
--- a/clang/test/SemaCXX/bool.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// Bool literals can be enum values.
-enum {
- ReadWrite = false,
- ReadOnly = true
-};
diff --git a/clang/test/SemaCXX/carbon.cpp b/clang/test/SemaCXX/carbon.cpp
deleted file mode 100644
index 9c9c3780403c..000000000000
--- a/clang/test/SemaCXX/carbon.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -fsyntax-only -print-stats
-#ifdef __APPLE__
-#include <Carbon/Carbon.h>
-#endif
-
diff --git a/clang/test/SemaCXX/class-names.cpp b/clang/test/SemaCXX/class-names.cpp
deleted file mode 100644
index 22546ef3b47f..000000000000
--- a/clang/test/SemaCXX/class-names.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-class C { };
-
-C c;
-
-void D(int);
-
-class D {}; // expected-error{{previous use is here}}
-
-void foo()
-{
- D(5);
- class D d;
-}
-
-class D;
-
-enum D; // expected-error{{use of 'D' with tag type that does not match previous declaration}}
-
-class A * A;
-
-class A * a2;
-
-void bar()
-{
- A = 0;
-}
-
-void C(int);
-
-void bar2()
-{
- C(17);
-}
-
-extern int B;
-class B;
-class B {};
-int B;
-
-enum E { e1_val };
-E e1;
-
-void E(int);
-
-void bar3() {
- E(17);
-}
-
-enum E e2;
-
-enum E2 { E2 };
diff --git a/clang/test/SemaCXX/class.cpp b/clang/test/SemaCXX/class.cpp
deleted file mode 100644
index 1fbff69cb587..000000000000
--- a/clang/test/SemaCXX/class.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-class C {
-public:
- auto int errx; // expected-error {{error: storage class specified for a member declaration}}
- register int erry; // expected-error {{error: storage class specified for a member declaration}}
- extern int errz; // expected-error {{error: storage class specified for a member declaration}}
-
- static void sm() {
- sx = 0;
- this->x = 0; // expected-error {{error: invalid use of 'this' outside of a nonstatic member function}}
- x = 0; // expected-error {{error: invalid use of member 'x' in static member function}}
- }
-
- class NestedC {
- void m() {
- sx = 0;
- x = 0; // expected-error {{error: invalid use of nonstatic data member 'x'}}
- }
- };
-
- int b : 1, w : 2;
- int : 1, : 2;
- typedef int E : 1; // expected-error {{error: cannot declare 'E' to be a bit-field type}}
- static int sb : 1; // expected-error {{error: static member 'sb' cannot be a bit-field}}
- static int vs;
-
- typedef int func();
- func tm;
- func btm : 1; // expected-error {{error: bit-field 'btm' with non-integral type}}
- NestedC bc : 1; // expected-error {{error: bit-field 'bc' with non-integral type}}
-
- enum E { en1, en2 };
-
- int i = 0; // expected-error {{error: 'i' can only be initialized if it is a static const integral data member}}
- static int si = 0; // expected-error {{error: 'si' can only be initialized if it is a static const integral data member}}
- static const NestedC ci = 0; // expected-error {{error: 'ci' can only be initialized if it is a static const integral data member}}
- static const int nci = vs; // expected-error {{error: initializer element is not a compile-time constant}}
- static const int vi = 0;
- static const E evi = 0;
-
- void m() {
- sx = 0;
- this->x = 0;
- y = 0;
- this = 0; // expected-error {{error: expression is not assignable}}
- }
-
- int f1(int p) {
- A z = 6;
- return p + x + this->y + z;
- }
-
- typedef int A;
-
-private:
- int x,y;
- static int sx;
-};
-
-class C2 {
- void f() {
- static int lx;
- class LC1 {
- int m() { return lx; }
- };
- class LC2 {
- int m() { return lx; }
- };
- }
-};
diff --git a/clang/test/SemaCXX/condition.cpp b/clang/test/SemaCXX/condition.cpp
deleted file mode 100644
index b2f716f88405..000000000000
--- a/clang/test/SemaCXX/condition.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void test() {
- int x;
- if (x) ++x;
- if (int x=0) ++x;
-
- typedef int arr[10];
- while (arr x=0) ; // expected-error: {{an array type is not allowed here}} expected-error: {{initialization with "{...}" expected for array}}
- while (int f()=0) ; // expected-error: {{a function type is not allowed here}}
-
- struct S {} s;
- if (s) ++x; // expected-error: {{expression must have bool type (or be convertible to bool) ('struct S' invalid)}}
- while (struct S x=s) ; // expected-error: {{expression must have bool type (or be convertible to bool) ('struct S' invalid)}}
- do ; while (s); // expected-error: {{expression must have bool type (or be convertible to bool) ('struct S' invalid)}}
- for (;s;) ; // expected-error: {{expression must have bool type (or be convertible to bool) ('struct S' invalid)}}
- switch (s) {} // expected-error: {{statement requires expression of integer type ('struct S' invalid)}}
-
- while (struct S {} x=0) ; // expected-error: {{types may not be defined in conditions}} expected-error: {{incompatible type}} expected-error: {{expression must have bool type}}
- while (struct {} x=0) ; // expected-error: {{types may not be defined in conditions}} expected-error: {{incompatible type}} expected-error: {{expression must have bool type}}
- switch (enum {E} x=0) ; // expected-error: {{types may not be defined in conditions}}
-
- if (int x=0) { // expected-error: {{previous definition is here}}
- int x; // expected-error: {{redefinition of 'x'}}
- }
- else
- int x; // expected-error: {{redefinition of 'x'}}
- while (int x=0) int x; // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
- while (int x=0) { int x; } // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
- for (int x; int x=0; ) ; // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
- for (int x; ; ) int x; // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
- for (; int x=0; ) int x; // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
- for (; int x=0; ) { int x; } // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
- switch (int x=0) { default: int x; } // expected-error: {{redefinition of 'x'}} expected-error: {{previous definition is here}}
-}
diff --git a/clang/test/SemaCXX/decl-expr-ambiguity.cpp b/clang/test/SemaCXX/decl-expr-ambiguity.cpp
deleted file mode 100644
index 3459d771ab1e..000000000000
--- a/clang/test/SemaCXX/decl-expr-ambiguity.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic-errors %s
-
-void f() {
- int a;
- struct S { int m; };
- typedef S *T;
-
- // Expressions.
- T(a)->m = 7;
- int(a)++; // expected-error {{invalid lvalue in increment/decrement expression}}
- __extension__ int(a)++; // expected-error {{invalid lvalue in increment/decrement expression}}
- typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}}
- void(a), ++a; // expected-warning {{statement was disambiguated as expression}} expected-warning {{expression result unused}}
- if (int(a)+1) {}
- for (int(a)+1;;) {}
- a = sizeof(int()+1);
- a = sizeof(int(1));
- typeof(int()+1) a2;
- (int(1)); // expected-warning {{expression result unused}}
-
- // type-id
- (int())1; // expected-error {{used type 'int ()' where arithmetic or pointer type is required}}
-
- // Declarations.
- T(*d)(int(p)); // expected-warning {{statement was disambiguated as declaration}} expected-error {{previous definition is here}}
- T(d)[5]; // expected-warning {{statement was disambiguated as declaration}} expected-error {{redefinition of 'd'}}
- typeof(int[])(f) = { 1, 2 }; // expected-warning {{statement was disambiguated as declaration}}
- void(b)(int);
- int(d2) __attribute__(()); // expected-warning {{statement was disambiguated as declaration}}
- if (int(a)=1) {}
- int(d3(int())); // expected-warning {{statement was disambiguated as declaration}}
-}
-
-class C { };
-void fn(int(C)) { } // void fn(int(*fp)(C c)) { }
- // not: void fn(int C);
-int g(C);
-
-void foo() {
- fn(1); // expected-error {{incompatible integer to pointer conversion passing 'int', expected 'int (*)(class C)'}}
- fn(g); // OK
-}
diff --git a/clang/test/SemaCXX/default1.cpp b/clang/test/SemaCXX/default1.cpp
deleted file mode 100644
index fe019c847a70..000000000000
--- a/clang/test/SemaCXX/default1.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-void f(int i);
-void f(int i = 0); // expected-error {{previous definition is here}}
-void f(int i = 17); // expected-error {{redefinition of default argument}}
-
-
-void g(int i, int j, int k = 3);
-void g(int i, int j = 2, int k);
-void g(int i = 1, int j, int k);
-
-void h(int i, int j = 2, int k = 3,
- int l, // expected-error {{missing default argument on parameter 'l'}}
- int, // expected-error {{missing default argument on parameter}}
- int n);// expected-error {{missing default argument on parameter 'n'}}
-
-struct S { } s;
-void i(int = s) { } // expected-error {{incompatible type}}
diff --git a/clang/test/SemaCXX/default2.cpp b/clang/test/SemaCXX/default2.cpp
deleted file mode 100644
index d3e999c34c6d..000000000000
--- a/clang/test/SemaCXX/default2.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-void f(int i, int j, int k = 3);
-void f(int i, int j, int k);
-void f(int i, int j = 2, int k);
-void f(int i, int j, int k);
-void f(int i = 1, int j, int k);
-void f(int i, int j, int k);
-
-void i()
-{
- f();
- f(0);
- f(0, 1);
- f(0, 1, 2);
-}
-
-
-int f1(int i, int i, int j) { // expected-error {{redefinition of parameter 'i'}}
- i = 17;
- return j;
-}
-
-int x;
-void g(int x, int y = x); // expected-error {{default argument references parameter 'x'}}
-
-void h()
-{
- int i;
- extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}}
-}
-
-void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}}
-
-void nondecl(int (*f)(int x = 5)) // {expected-error {{default arguments can only be specified}}}
-{
- void (*f2)(int = 17) // {expected-error {{default arguments can only be specified}}}
- = (void (*)(int = 42))f; // {expected-error {{default arguments can only be specified}}}
-}
diff --git a/clang/test/SemaCXX/direct-initializer.cpp b/clang/test/SemaCXX/direct-initializer.cpp
deleted file mode 100644
index bb0aab6500a1..000000000000
--- a/clang/test/SemaCXX/direct-initializer.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-int x(1);
-
-void f() {
- int x(1);
- for (int x(1);;) {}
-}
diff --git a/clang/test/SemaCXX/do-while-scope.cpp b/clang/test/SemaCXX/do-while-scope.cpp
deleted file mode 100644
index 94a3116c571e..000000000000
--- a/clang/test/SemaCXX/do-while-scope.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void test() {
- int x;
- do
- int x;
- while (1);
-}
diff --git a/clang/test/SemaCXX/inherit.cpp b/clang/test/SemaCXX/inherit.cpp
deleted file mode 100644
index 82d8db38cfd8..000000000000
--- a/clang/test/SemaCXX/inherit.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-class A { };
-
-class B1 : A { };
-
-class B2 : virtual A { };
-
-class B3 : virtual virtual A { }; // expected-error{{duplicate 'virtual' in base specifier}}
-
-class C : public B1, private B2 { };
-
-
-class D;
-
-class E : public D { }; // expected-error{{base class has incomplete type}}
-
-typedef int I;
-
-class F : public I { }; // expected-error{{base specifier must name a class}}
-
-union U1 : public A { }; // expected-error{{unions cannot have base classes}}
-
-union U2 {};
-
-class G : public U2 { }; // expected-error{{unions cannot be base classes}}
diff --git a/clang/test/SemaCXX/namespace.cpp b/clang/test/SemaCXX/namespace.cpp
deleted file mode 100644
index 62251d3535e4..000000000000
--- a/clang/test/SemaCXX/namespace.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-namespace A { // expected-error {{error: previous definition is here}}
- int A;
- void f() { A = 0; }
-}
-
-void f() { A = 0; } // expected-error {{error: unexpected namespace name 'A': expected expression}}
-int A; // expected-error {{error: redefinition of 'A' as different kind of symbol}}
-class A; // expected-error {{error: redefinition of 'A' as different kind of symbol}}
-
-class B {}; // expected-error {{error: previous definition is here}}
-namespace B {} // expected-error {{error: redefinition of 'B' as different kind of symbol}}
-
-void C(); // expected-error {{error: previous definition is here}}
-namespace C {} // expected-error {{error: redefinition of 'C' as different kind of symbol}}
-
-namespace D {
- class D {};
-}
-
-namespace S1 {
- int x;
-
- namespace S2 {
-
- namespace S3 {
- B x;
- }
- }
-}
-
-namespace S1 {
- void f() {
- x = 0;
- }
-
- namespace S2 {
-
- namespace S3 {
- void f() {
- x = 0; // expected-error {{error: incompatible type assigning 'int', expected 'class B'}}
- }
- }
-
- int y;
- }
-}
-
-namespace S1 {
- namespace S2 {
- namespace S3 {
- void f3() {
- y = 0;
- }
- }
- }
-}
diff --git a/clang/test/SemaCXX/references.cpp b/clang/test/SemaCXX/references.cpp
deleted file mode 100644
index 3637573b445e..000000000000
--- a/clang/test/SemaCXX/references.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang -fsyntax-only %s
-int g(int);
-
-void f() {
- int i;
- int &r = i;
- r = 1;
- int *p = &r;
- int &rr = r;
- int (&rg)(int) = g;
- rg(i);
- int a[3];
- int (&ra)[3] = a;
- ra[1] = i;
- int *Q;
- int *& P = Q;
- P[1] = 1;
-}
-
-typedef int t[1];
-void test2() {
- t a;
- t& b = a;
-
-
- int c[3];
- int (&rc)[3] = c;
-}
diff --git a/clang/test/SemaCXX/return-stack-addr.cpp b/clang/test/SemaCXX/return-stack-addr.cpp
deleted file mode 100644
index c7d1a7f3d6b1..000000000000
--- a/clang/test/SemaCXX/return-stack-addr.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-
-int* ret_local() {
- int x = 1;
- return &x; // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_array() {
- int x[10];
- return x; // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_array_element(int i) {
- int x[10];
- return &x[i]; // expected-warning {{address of stack memory}}
-}
-
-int *ret_local_array_element_reversed(int i) {
- int x[10];
- return &i[x]; // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_array_element_const_index() {
- int x[10];
- return &x[2]; // expected-warning {{address of stack memory}}
-}
-
-int& ret_local_ref() {
- int x = 1;
- return x; // expected-warning {{reference to stack memory}}
-}
-
-int* ret_local_addrOf() {
- int x = 1;
- return &*&x; // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_addrOf_paren() {
- int x = 1;
- return (&(*(&x))); // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_addrOf_ptr_arith() {
- int x = 1;
- return &*(&x+1); // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_addrOf_ptr_arith2() {
- int x = 1;
- return &*(&x+1); // expected-warning {{address of stack memory}}
-}
-
-int* ret_local_field() {
- struct { int x; } a;
- return &a.x; // expected-warning {{address of stack memory}}
-}
-
-int& ret_local_field_ref() {
- struct { int x; } a;
- return a.x; // expected-warning {{reference to stack memory}}
-}
-
-int* ret_conditional(bool cond) {
- int x = 1;
- int y = 2;
- return cond ? &x : &y; // expected-warning {{address of stack memory}}
-}
-
-int* ret_conditional_rhs(int *x, bool cond) {
- int y = 1;
- return cond ? x : &y; // expected-warning {{address of stack memory}}
-}
-
-void* ret_c_cast() {
- int x = 1;
- return (void*) &x; // expected-warning {{address of stack memory}}
-}
-
-int* ret_static_var() {
- static int x = 1;
- return &x; // no warning.
-}
-
-int z = 1;
-
-int* ret_global() {
- return &z; // no warning.
-}
-
-int* ret_parameter(int x) {
- return &x; // expected-warning {{address of stack memory}}
-}
-
-
-int* ret_cpp_static_cast(short x) {
- return static_cast<int*>(&x); // expected-warning {{address of stack memory}}
-}
-
-int* ret_cpp_reinterpret_cast(double x) {
- return reinterpret_cast<int*>(&x); // expected-warning {{address of stack me}}
-}
-
-int* ret_cpp_reinterpret_cast_no_warning(double x) {
- return reinterpret_cast<int*>(x); // no-warning
-}
-
-int* ret_cpp_const_cast(const int x) {
- return const_cast<int*>(&x); // expected-warning {{address of stack memory}}
-}
-
-// TODO: test case for dynamic_cast. clang does not yet have
-// support for C++ classes to write such a test case.
diff --git a/clang/test/SemaCXX/static-initializers.cpp b/clang/test/SemaCXX/static-initializers.cpp
deleted file mode 100644
index 0da412ab2906..000000000000
--- a/clang/test/SemaCXX/static-initializers.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-int f()
-{
- return 10;
-}
-
-void g()
-{
- static int a = f();
-}
-
-static int b = f();
diff --git a/clang/test/SemaCXX/this.cpp b/clang/test/SemaCXX/this.cpp
deleted file mode 100644
index b8bf4b7d3aaf..000000000000
--- a/clang/test/SemaCXX/this.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-int x = this; // expected-error {{error: invalid use of 'this' outside of a nonstatic member function}}
-
-void f() {
- int x = this; // expected-error {{error: invalid use of 'this' outside of a nonstatic member function}}
-}
diff --git a/clang/test/SemaCXX/type-convert-construct.cpp b/clang/test/SemaCXX/type-convert-construct.cpp
deleted file mode 100644
index 64191a29d93e..000000000000
--- a/clang/test/SemaCXX/type-convert-construct.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-void f() {
- float v1 = float(1);
- int v2 = typeof(int)(1,2); // expected-error {{function-style cast to a builtin type can only take one argument}}
- typedef int arr[];
- int v3 = arr(); // expected-error {{array types cannot be value-initialized}}
- int v4 = int();
- int v5 = int; // expected-error {{expected '(' for function-style cast or type construction}}
- typedef int T;
- int *p;
- bool v6 = T(0) == p;
- char *str;
- str = "a string";
- wchar_t *wstr;
- wstr = L"a wide string";
-}
diff --git a/clang/test/SemaCXX/wchar_t.cpp b/clang/test/SemaCXX/wchar_t.cpp
deleted file mode 100644
index e3cd77a195fa..000000000000
--- a/clang/test/SemaCXX/wchar_t.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -fsyntax-only -pedantic -verify %s
-wchar_t x;
-
-void f(wchar_t p) {
- wchar_t x;
- unsigned wchar_t y; // expected-warning {{'wchar_t' cannot be signed or unsigned}}
- signed wchar_t z; // expected-warning {{'wchar_t' cannot be signed or unsigned}}
- ++x;
-}
diff --git a/clang/test/SemaObjC/DoubleMethod.m b/clang/test/SemaObjC/DoubleMethod.m
deleted file mode 100644
index 70c7ed55f1e2..000000000000
--- a/clang/test/SemaObjC/DoubleMethod.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Subclass
-{
- int ivar;
-}
-
-- (void) method;
-- (void) method;
-@end
-
-@implementation Subclass
-- (void) method {;} // expected-error {{previous declaration is here}}
-- (void) method {;} // expected-error {{duplicate declaration of method 'method'}}
-@end
-
-int main (void) {
- return 0;
-}
diff --git a/clang/test/SemaObjC/alias-test-1.m b/clang/test/SemaObjC/alias-test-1.m
deleted file mode 100644
index fdaccf3f8bcc..000000000000
--- a/clang/test/SemaObjC/alias-test-1.m
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@compatibility_alias alias4 foo; // expected-warning {{cannot find interface declaration for 'foo'}}
-
-@class class2; // expected-error {{previous declaration is here}}
-@class class3;
-
-typedef int I; // expected-warning {{previous declaration is here}}
-
-@compatibility_alias alias1 I; // expected-warning {{cannot find interface declaration for 'I'}}
-
-@compatibility_alias alias class2;
-@compatibility_alias alias class3; // expected-error {{conflicting types for alias 'alias'}}
-
-
-typedef int alias2; // expected-error {{previous declaration is here}}
-@compatibility_alias alias2 class3; // expected-error {{conflicting types for alias 'alias2'}}
-
-alias *p;
-class2 *p2;
-
-int foo ()
-{
-
- if (p == p2) {
- int alias = 1;
- }
-
- alias *p3;
- return p3 == p2;
-}
diff --git a/clang/test/SemaObjC/alias-test-2.m b/clang/test/SemaObjC/alias-test-2.m
deleted file mode 100644
index 0a17846685cd..000000000000
--- a/clang/test/SemaObjC/alias-test-2.m
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Super @end
-
-@interface MyWpModule @end
-
-@compatibility_alias MyAlias MyWpModule;
-
-@compatibility_alias AliasForSuper Super;
-
-@interface MyAlias : AliasForSuper // expected-error {{duplicate interface declaration for class 'MyWpModule'}}
-@end
-
-@implementation MyAlias : AliasForSuper
-@end
-
diff --git a/clang/test/SemaObjC/argument-checking.m b/clang/test/SemaObjC/argument-checking.m
deleted file mode 100644
index 820a2f09c794..000000000000
--- a/clang/test/SemaObjC/argument-checking.m
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-struct S { int a; };
-
-extern int charStarFunc(char *);
-extern int charFunc(char);
-
-@interface Test
-+alloc;
--(int)charStarMeth:(char *)s;
--structMeth:(struct S)s;
--structMeth:(struct S)s :(struct S)s2;
-@end
-
-void test() {
- id obj = [Test alloc];
- struct S sInst;
-
- charStarFunc(1); // expected-warning {{incompatible integer to pointer conversion passing 'int', expected 'char *'}}
- charFunc("abc"); // expected-warning {{incompatible pointer to integer conversion passing 'char [4]', expected 'char'}}
-
- [obj charStarMeth:1]; // expected-warning {{incompatible integer to pointer conversion sending 'int'}}
- [obj structMeth:1]; // expected-error {{incompatible type sending 'int'}}
- [obj structMeth:sInst :1]; // expected-error {{incompatible type sending 'int'}}
-}
diff --git a/clang/test/SemaObjC/at-defs.m b/clang/test/SemaObjC/at-defs.m
deleted file mode 100644
index 5bbdd6a715e3..000000000000
--- a/clang/test/SemaObjC/at-defs.m
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-@interface Test {
- double a;
-}
-@end
-@implementation Test
-@end
-@interface TestObject : Test {
-@public
- float bar;
- int foo;
-}
-@end
-@implementation TestObject
-@end
-struct wibble {
- @defs(TestObject)
-};
-
-
-int main(void)
-{
- TestObject * a = (id)malloc(100);
- a->foo = 12;
- printf("12: %d\n", ((struct wibble*)a)->foo);
- printf("%d: %d\n", ((char*)&(((struct wibble*)a)->foo)) - (char*)a, ((char*)&(a->foo)) - (char*)a);
- return 0;
-}
diff --git a/clang/test/SemaObjC/bad-receiver-1.m b/clang/test/SemaObjC/bad-receiver-1.m
deleted file mode 100644
index 8376a5ced7ac..000000000000
--- a/clang/test/SemaObjC/bad-receiver-1.m
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface I
-- (id) retain;
-@end
-
-void __raiseExc1() {
- [objc_lookUpClass("NSString") retain]; // expected-error {{ "bad receiver type 'int'" }}
-}
diff --git a/clang/test/SemaObjC/category-1.m b/clang/test/SemaObjC/category-1.m
deleted file mode 100644
index 1cae2300e0ea..000000000000
--- a/clang/test/SemaObjC/category-1.m
+++ /dev/null
@@ -1,56 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface MyClass1 @end
-
-@protocol p1,p2,p3;
-
-@interface MyClass1 (Category1) <p1> // expected-warning {{cannot find protocol definition for 'p1'}}
-@end
-
-@interface MyClass1 (Category1) // expected-warning {{duplicate interface declaration for category 'MyClass1(Category1)'}}
-@end
-
-@interface MyClass1 (Category3)
-@end
-
-@interface MyClass1 (Category4) @end
-@interface MyClass1 (Category5) @end
-@interface MyClass1 (Category6) @end
-@interface MyClass1 (Category7) @end
-@interface MyClass1 (Category8) @end
-
-
-@interface MyClass1 (Category4) @end // expected-warning {{duplicate interface declaration for category 'MyClass1(Category4)'}}
-@interface MyClass1 (Category7) @end // expected-warning {{duplicate interface declaration for category 'MyClass1(Category7)'}}
-@interface MyClass1 (Category8) @end // expected-warning {{duplicate interface declaration for category 'MyClass1(Category8)'}}
-
-
-@protocol p3 @end
-
-@interface MyClass1 (Category) <p2, p3> @end // expected-warning {{cannot find protocol definition for 'p2'}}
-
-@interface MyClass (Category) @end // expected-error {{cannot find interface declaration for 'MyClass'}}
-
-@class MyClass2;
-
-@interface MyClass2 (Category) @end // expected-error {{cannot find interface declaration for 'MyClass2'}}
-
-@interface XCRemoteComputerManager
-@end
-
-@interface XCRemoteComputerManager()
-@end
-
-@interface XCRemoteComputerManager()
-@end
-
-@interface XCRemoteComputerManager(x)
-@end
-
-@interface XCRemoteComputerManager(x) // expected-warning {{duplicate interface declaration for category 'XCRemoteComputerManager(x)'}}
-@end
-
-@implementation XCRemoteComputerManager
-@end
-
-
diff --git a/clang/test/SemaObjC/category-method-lookup.m b/clang/test/SemaObjC/category-method-lookup.m
deleted file mode 100644
index a70900846009..000000000000
--- a/clang/test/SemaObjC/category-method-lookup.m
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Foo
-@end
-@implementation Foo
-@end
-
-@implementation Foo(Whatever)
-+(float)returnsFloat { return 7.0; }
-@end
-
-@interface Foo (MoreStuff)
-+(int)returnsInt;
-@end
-
-@implementation Foo (MoreStuff)
-+(int)returnsInt {
- return 0;
-}
-
-+(void)returnsNothing {
-}
--(int)callsReturnsInt {
- float f = [Foo returnsFloat]; // GCC doesn't find this method (which is a bug IMHO).
- [Foo returnsNothing];
- return [Foo returnsInt];
-}
-@end
-
-int main() {return 0;}
-
diff --git a/clang/test/SemaObjC/check-dup-decl-methods-1.m b/clang/test/SemaObjC/check-dup-decl-methods-1.m
deleted file mode 100644
index 36a98a24a462..000000000000
--- a/clang/test/SemaObjC/check-dup-decl-methods-1.m
+++ /dev/null
@@ -1,38 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface SUPER
-- (int) meth;
-+ (int) foobar;
-@end
-
-@interface T @end
-
-@interface class1 : SUPER
-- (int) meth; // expected-error {{previous declaration is here}}
-- (int*) meth; // expected-error {{duplicate declaration of method 'meth'}}
-- (T*) meth1;
-- (T*) meth1;
-+ (T*) meth1;
-@end
-
-@interface class1(cat)
-- (int) catm : (char)ch1; // expected-error {{previous declaration is here}}
-- (int) catm1 : (char)ch : (int)i;
-- (int) catm : (char*)ch1; // expected-error {{duplicate declaration of method 'catm:'}}
-+ (int) catm1 : (char)ch : (int)i;
-+ (T*) meth1;
-@end
-
-@interface class1(cat1)
-+ (int) catm1 : (char)ch : (int)i; // expected-error {{previous declaration is here}}
-+ (T*) meth1; // expected-error {{previous declaration is here}}
-+ (int) catm1 : (char)ch : (int*)i; // expected-error {{duplicate declaration of method 'catm1::'}}
-+ (T**) meth1; // expected-error {{duplicate declaration of method 'meth1'}}
-+ (int) foobar;
-@end
-
-@protocol P
-- (int) meth; // expected-error {{previous declaration is here}}
-- (int*) meth; // expected-error {{duplicate declaration of method 'meth'}}
-@end
-
diff --git a/clang/test/SemaObjC/check-dup-objc-decls-1.m b/clang/test/SemaObjC/check-dup-objc-decls-1.m
deleted file mode 100644
index e3902bdcca32..000000000000
--- a/clang/test/SemaObjC/check-dup-objc-decls-1.m
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Foo // expected-error {{previous definition is here}}
-@end
-
-float Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
-
-@class Bar; // expected-error {{previous definition is here}}
-
-typedef int Bar; // expected-error {{redefinition of 'Bar' as different kind of symbol}}
-
-@implementation FooBar // expected-warning {{cannot find interface declaration for 'FooBar'}}
-@end
-
-
-typedef int OBJECT; // expected-error {{previous definition is here}}
-
-@class OBJECT ; // expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
-
-
-typedef int Gorf; // expected-error {{previous definition is here}}
-
-@interface Gorf @end // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
-
-void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
-{
- int Bar, Foo, FooBar;
-}
diff --git a/clang/test/SemaObjC/class-conforming-protocol-1.m b/clang/test/SemaObjC/class-conforming-protocol-1.m
deleted file mode 100644
index 6afee0d3d4d7..000000000000
--- a/clang/test/SemaObjC/class-conforming-protocol-1.m
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol P1 @end
-@protocol P2 @end
-@protocol P3 @end
-
-@interface INTF
-- (INTF*) METH1; // expected-error {{previous declaration is here}}
-- (INTF<P1>*) METH1; // expected-error {{duplicate declaration of method 'METH1'}}
-
-- (INTF<P1,P2>*) METH2;
-- (INTF<P2,P1>*) METH2; // expected-error {{previous declaration is here}}
-- (INTF<P2,P1,P3>*) METH2; // expected-error {{duplicate declaration of method 'METH2'}}
-
-- (INTF<P2,P1,P3>*) METH3;
-- (INTF<P3,P1,P2, P3>*) METH3;
-
-@end
-
-INTF<P2,P1,P3>* p1;
-
diff --git a/clang/test/SemaObjC/class-def-test-1.m b/clang/test/SemaObjC/class-def-test-1.m
deleted file mode 100644
index 3dc687b99a6d..000000000000
--- a/clang/test/SemaObjC/class-def-test-1.m
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol SUPER;
-
-@interface SUPER <SUPER> @end // expected-warning {{cannot find protocol definition for 'SUPER'}}
-
-typedef int INTF; // expected-error {{previous definition is here}}
-
-@interface INTF @end // expected-error {{redefinition of 'INTF' as different kind of symbol}}
-
-@interface OBJECT @end // expected-error {{previous definition is here}}
-
-@interface INTF1 : OBJECT @end
-
-@interface INTF1 : OBJECT @end // expected-error {{duplicate interface declaration for class 'INTF1'}}
-
-typedef int OBJECT; // expected-error {{previous definition is here}} \
- expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
-
-@interface INTF2 : OBJECT @end // expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
-
-
-@protocol PROTO;
-
-@interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}}
-
diff --git a/clang/test/SemaObjC/class-impl-1.m b/clang/test/SemaObjC/class-impl-1.m
deleted file mode 100644
index dedce58d2c0f..000000000000
--- a/clang/test/SemaObjC/class-impl-1.m
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef int INTF3; // expected-error {{previous definition is here}}
-
-@interface SUPER @end // expected-error {{previous definition is here}}
-
-@interface OBJECT @end
-
-@interface INTF : OBJECT
-@end
-
-@implementation INTF @end
-
-@implementation INTF // expected-error {{reimplementation of class 'INTF'}}
-@end
-
-
-@interface INTF1 : OBJECT
-@end
-
-@implementation INTF1 : SUPER // expected-error {{conflicting super class name 'SUPER'}}
-@end
-
-@interface INTF2
-@end
-
-@implementation INTF2 : SUPR // expected-error {{cannot find interface declaration for 'SUPR', superclass of 'INTF2'}}
-@end
-
-@implementation INTF3 @end // expected-error {{redefinition of 'INTF3' as different kind of symbol}}
-
-@implementation INTF4 @end // expected-warning {{cannot find interface declaration for 'INTF4'}}
-
diff --git a/clang/test/SemaObjC/class-proto-1.m b/clang/test/SemaObjC/class-proto-1.m
deleted file mode 100644
index da6811eeb8dd..000000000000
--- a/clang/test/SemaObjC/class-proto-1.m
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface INTF1 @end
-
-@protocol p1,p2,p3;
-
-@protocol p1;
-
-@protocol PROTO1
-- (INTF1<p1>*) meth;
-@end
-
-@protocol p1 @end
-
-@interface I1 <p1> @end
-
-@interface E1 <p2> @end // expected-warning {{cannot find protocol definition for 'p2'}}
-
-@protocol p2 @end
-
-
-@interface I2 <p1,p2> @end
-
-@interface E2 <p1,p2,p3> @end // expected-warning {{cannot find protocol definition for 'p3'}}
-
-@class U1, U2;
-
-@interface E3 : U1 @end // expected-error {{cannot find interface declaration for 'U1', superclass of 'E3'}}
-
-
-@interface I3 : E3 @end
-
-@interface U2 @end
-
-@interface I4 : U2 <p1,p2>
-@end
diff --git a/clang/test/SemaObjC/cocoa.m b/clang/test/SemaObjC/cocoa.m
deleted file mode 100644
index 7cb1b5295c5b..000000000000
--- a/clang/test/SemaObjC/cocoa.m
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -print-stats
-#ifdef __APPLE__
-#include <Cocoa/Cocoa.h>
-#endif
-
diff --git a/clang/test/SemaObjC/compatible-protocol-qualified-types.m b/clang/test/SemaObjC/compatible-protocol-qualified-types.m
deleted file mode 100644
index 2e7eb6c43b82..000000000000
--- a/clang/test/SemaObjC/compatible-protocol-qualified-types.m
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: clang -pedantic -fsyntax-only -verify %s
-typedef signed char BOOL;
-
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-@end
-
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-
-@interface NSObject <NSObject> {}
-@end
-
-typedef float CGFloat;
-
-@interface NSResponder : NSObject <NSCoding> {}
-@end
-
-@protocol XCSelectionSource;
-
-@interface XCSelection : NSResponder {}
-- (NSObject <XCSelectionSource> *) source;
-@end
-
-extern NSString * const XCActiveSelectionLevel;
-
-@interface XCActionManager : NSResponder {}
-+defaultActionManager;
--selectionAtLevel:(NSString *const)s;
-@end
-
-@implementation XDMenuItemsManager // expected-warning {{cannot find interface declaration for 'XDMenuItemsManager'}}
-+ (void)initialize {
- id<XCSelectionSource, NSObject> source =
- [[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source];
-}
-@end
diff --git a/clang/test/SemaObjC/comptypes-1.m b/clang/test/SemaObjC/comptypes-1.m
deleted file mode 100644
index e47bc63565fc..000000000000
--- a/clang/test/SemaObjC/comptypes-1.m
+++ /dev/null
@@ -1,89 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-#define nil (void *)0;
-#define Nil (void *)0;
-
-extern void foo();
-
-@protocol MyProtocol
-- (void) foo;
-@end
-
-@interface MyClass
-@end
-
-@interface MyOtherClass <MyProtocol>
-- (void) foo;
-@end
-
-int main()
-{
- id obj = nil;
- id<MyProtocol> obj_p = nil;
- MyClass *obj_c = nil;
- MyOtherClass *obj_cp = nil;
- Class obj_C = Nil;
-
- /* Assigning to an 'id' variable should never
- generate a warning. */
- obj = obj_p; /* Ok */
- obj = obj_c; /* Ok */
- obj = obj_cp; /* Ok */
- obj = obj_C; /* Ok */
-
- /* Assigning to a 'MyClass *' variable should always generate a
- warning, unless done from an 'id'. */
- obj_c = obj; /* Ok */
- obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning 'MyOtherClass *', expected 'MyClass *'}}
- obj_c = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'MyClass *'}}
-
- /* Assigning to an 'id<MyProtocol>' variable should generate a
- warning if done from a 'MyClass *' (which doesn't implement
- MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
- (which implements MyProtocol). */
- obj_p = obj; /* Ok */
- obj_p = obj_c; // expected-error {{incompatible type assigning 'MyClass *', expected 'id<MyProtocol>'}}
- obj_p = obj_cp; /* Ok */
- obj_p = obj_C; // expected-error {{incompatible type assigning 'Class', expected 'id<MyProtocol>'}}
-
- /* Assigning to a 'MyOtherClass *' variable should always generate
- a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
- MyOtherClass implements MyProtocol). */
- obj_cp = obj; /* Ok */
- obj_cp = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'MyOtherClass *'}}
- obj_cp = obj_p; /* Ok */
- obj_cp = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'MyOtherClass *'}}
-
- /* Any comparison involving an 'id' must be without warnings. */
- if (obj == obj_p) foo() ; /* Ok */ /*Bogus warning here in 2.95.4*/
- if (obj_p == obj) foo() ; /* Ok */
- if (obj == obj_c) foo() ; /* Ok */
- if (obj_c == obj) foo() ; /* Ok */
- if (obj == obj_cp) foo() ; /* Ok */
- if (obj_cp == obj) foo() ; /* Ok */
- if (obj == obj_C) foo() ; /* Ok */
- if (obj_C == obj) foo() ; /* Ok */
-
- /* Any comparison between 'MyClass *' and anything which is not an 'id'
- must generate a warning. */
- if (obj_p == obj_c) foo() ; // expected-error {{invalid operands to binary expression ('id<MyProtocol>' and 'MyClass *')}}
-
- if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}}
- if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
-
- if (obj_c == obj_C) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'Class')}}
- if (obj_C == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('Class' and 'MyClass *')}}
-
- /* Any comparison between 'MyOtherClass *' (which implements
- MyProtocol) and an 'id' implementing MyProtocol are Ok. */
- if (obj_cp == obj_p) foo() ; /* Ok */
- if (obj_p == obj_cp) foo() ; /* Ok */
-
-
- if (obj_p == obj_C) foo() ; // expected-error {{invalid operands to binary expression ('id<MyProtocol>' and 'Class')}}
- if (obj_C == obj_p) foo() ; // expected-error {{invalid operands to binary expression ('Class' and 'id<MyProtocol>')}}
- if (obj_cp == obj_C) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'Class')}}
- if (obj_C == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('Class' and 'MyOtherClass *')}}
-
- return 0;
-}
diff --git a/clang/test/SemaObjC/comptypes-2.m b/clang/test/SemaObjC/comptypes-2.m
deleted file mode 100644
index d063d95cc242..000000000000
--- a/clang/test/SemaObjC/comptypes-2.m
+++ /dev/null
@@ -1,37 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#define nil (void *)0;
-#define Nil (void *)0;
-
-@protocol MyProtocol
-- (void) foo;
-@end
-
-@interface MyClass
-@end
-
-int main()
-{
- id obj = nil;
- id<MyProtocol> obj_p = nil;
- MyClass *obj_c = nil;
- Class obj_C = Nil;
-
- /* All these casts should generate no warnings. */
-
- obj = (id)obj_p;
- obj = (id)obj_c;
- obj = (id)obj_C;
- obj_c = (MyClass *)obj;
- obj_c = (MyClass *)obj_p;
- obj_c = (MyClass *)obj_C;
- obj_p = (id<MyProtocol>)obj;
- obj_p = (id<MyProtocol>)obj_c;
- obj_p = (id<MyProtocol>)obj_C;
- obj_C = (Class)obj;
- obj_C = (Class)obj_p;
- obj_C = (Class)obj_c;
-
-
- return 0;
-}
diff --git a/clang/test/SemaObjC/comptypes-3.m b/clang/test/SemaObjC/comptypes-3.m
deleted file mode 100644
index 1e271c8340eb..000000000000
--- a/clang/test/SemaObjC/comptypes-3.m
+++ /dev/null
@@ -1,64 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#define nil (void *)0;
-
-extern void foo();
-
-@protocol MyProtocolA
-- (void) methodA;
-@end
-
-@protocol MyProtocolB
-- (void) methodB;
-@end
-
-@protocol MyProtocolAB <MyProtocolA, MyProtocolB>
-@end
-
-@protocol MyProtocolAC <MyProtocolA>
-- (void) methodC;
-@end
-
-int main()
-{
- id<MyProtocolA> obj_a = nil;
- id<MyProtocolB> obj_b = nil;
- id<MyProtocolAB> obj_ab = nil;
- id<MyProtocolAC> obj_ac = nil;
-
- obj_a = obj_b; // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolA>'}}
- obj_a = obj_ab; /* Ok */
- obj_a = obj_ac; /* Ok */
-
- obj_b = obj_a; // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolB>'}}
- obj_b = obj_ab; /* Ok */
- obj_b = obj_ac; // expected-error {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolB>'}}
-
- obj_ab = obj_a; // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAB>'}}
- obj_ab = obj_b; // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAB>'}}
- obj_ab = obj_ac; // expected-error {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolAB>'}}
-
- obj_ac = obj_a; // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAC>'}}
- obj_ac = obj_b; // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}}
- obj_ac = obj_ab; // expected-error {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}}
-
- if (obj_a == obj_b) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
- if (obj_b == obj_a) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
-
- if (obj_a == obj_ab) foo (); /* Ok */
- if (obj_ab == obj_a) foo (); /* Ok */
-
- if (obj_a == obj_ac) foo (); /* Ok */
- if (obj_ac == obj_a) foo (); /* Ok */
-
- if (obj_b == obj_ab) foo (); /* Ok */
- if (obj_ab == obj_b) foo (); /* Ok */
-
- if (obj_b == obj_ac) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolAC>')}}
- if (obj_ac == obj_b) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolB>')}}
-
- if (obj_ab == obj_ac) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}}
- if (obj_ac == obj_ab) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}}
-
- return 0;
-}
diff --git a/clang/test/SemaObjC/comptypes-4.m b/clang/test/SemaObjC/comptypes-4.m
deleted file mode 100644
index bda9050164be..000000000000
--- a/clang/test/SemaObjC/comptypes-4.m
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-extern void foo();
-
-@protocol MyProtocol @end
-
-@interface MyClass @end
-
-int main()
-{
- MyClass <MyProtocol> *obj_p;
- MyClass *obj_cp;
-
- obj_cp = obj_p;
- obj_p = obj_cp;
-
- if (obj_cp == obj_p)
- foo();
-
- if (obj_p == obj_cp)
- foo();
-
-}
-
-
diff --git a/clang/test/SemaObjC/comptypes-5.m b/clang/test/SemaObjC/comptypes-5.m
deleted file mode 100644
index f12fa9ab5d44..000000000000
--- a/clang/test/SemaObjC/comptypes-5.m
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: clang -fsyntax-only -pedantic -verify %s
-
-#define nil (void *)0;
-
-extern void foo();
-
-@protocol MyProtocol
-- (void) method;
-@end
-
-@interface MyClass
-@end
-
-@interface MyClass (Addition) <MyProtocol>
-- (void) method;
-@end
-
-@interface MyOtherClass : MyClass
-@end
-
-int main()
-{
- id <MyProtocol> obj_id_p = nil;
- MyClass *obj_c_cat_p = nil;
- MyOtherClass *obj_c_super_p = nil;
- MyOtherClass<MyProtocol> *obj_c_super_p_q = nil;
- MyClass<MyProtocol> *obj_c_cat_p_q = nil;
-
- obj_c_cat_p = obj_id_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'MyClass *'}}
- obj_c_super_p = obj_id_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'MyOtherClass *'}}
- obj_id_p = obj_c_cat_p; /* Ok */
- obj_id_p = obj_c_super_p; /* Ok */
-
- if (obj_c_cat_p == obj_id_p) foo(); /* Ok */
- if (obj_c_super_p == obj_id_p) foo() ; /* Ok */
- if (obj_id_p == obj_c_cat_p) foo(); /* Ok */
- if (obj_id_p == obj_c_super_p) foo(); /* Ok */
-
- obj_c_cat_p = obj_c_super_p; // ok.
- obj_c_cat_p = obj_c_super_p_q; // ok.
- obj_c_super_p = obj_c_cat_p_q; // expected-warning {{incompatible pointer types}}
- obj_c_cat_p_q = obj_c_super_p;
- return 0;
-}
diff --git a/clang/test/SemaObjC/comptypes-6.m b/clang/test/SemaObjC/comptypes-6.m
deleted file mode 100644
index 2edb181e83bc..000000000000
--- a/clang/test/SemaObjC/comptypes-6.m
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-@interface Derived
-@end
-
-@interface Object @end
-
-extern Object* foo(void);
-
-static Derived *test(void)
-{
- Derived *m = foo(); // expected-warning {{incompatible pointer types initializing 'Object *', expected 'Derived *'}}
-
- return m;
-}
-
diff --git a/clang/test/SemaObjC/comptypes-7.m b/clang/test/SemaObjC/comptypes-7.m
deleted file mode 100644
index ef3a7790a3d3..000000000000
--- a/clang/test/SemaObjC/comptypes-7.m
+++ /dev/null
@@ -1,70 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-#define nil (void *)0;
-#define Nil (void *)0;
-
-extern void foo();
-
-@protocol MyProtocol
-- (void) method;
-@end
-
-@interface MyClass
-@end
-
-int main()
-{
- id obj = nil;
- id <MyProtocol> obj_p = nil;
- MyClass *obj_c = nil;
- Class obj_C = Nil;
-
- int i = 0;
- int *j = nil;
-
- /* These should all generate warnings. */
-
- obj = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id'}}
- obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}}
-
- obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id<MyProtocol>'}}
- obj_p = j; // expected-error {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}}
-
- obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'MyClass *'}}
- obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}}
-
- obj_C = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'Class'}}
- obj_C = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'Class'}}
-
- i = obj; // expected-warning {{incompatible pointer to integer conversion assigning 'id', expected 'int'}}
- i = obj_p; // expected-warning {{incompatible pointer to integer conversion assigning 'id<MyProtocol>', expected 'int'}}
- i = obj_c; // expected-warning {{incompatible pointer to integer conversion assigning 'MyClass *', expected 'int'}}
- i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning 'Class', expected 'int'}}
-
- j = obj; // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}}
- j = obj_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}}
- j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'int *'}}
- j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'int *'}}
-
- if (obj == i) foo() ; // expected-warning {{comparison between pointer and integer ('id' and 'int')}}
- if (i == obj) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id')}}
- if (obj == j) foo() ; // expected-warning {{comparison of distinct pointer types ('id' and 'int *')}}
- if (j == obj) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'id')}}
-
- if (obj_c == i) foo() ; // expected-warning {{comparison between pointer and integer ('MyClass *' and 'int')}}
- if (i == obj_c) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'MyClass *')}}
- if (obj_c == j) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'int *')}}
- if (j == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'MyClass *')}}
-
- if (obj_p == i) foo() ; // expected-warning {{comparison between pointer and integer ('id<MyProtocol>' and 'int')}}
- if (i == obj_p) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id<MyProtocol>')}}
- if (obj_p == j) foo() ; // expected-error {{invalid operands to binary expression ('id<MyProtocol>' and 'int *')}}
- if (j == obj_p) foo() ; // expected-error {{invalid operands to binary expression ('int *' and 'id<MyProtocol>')}}
-
- if (obj_C == i) foo() ; // expected-warning {{comparison between pointer and integer ('Class' and 'int')}}
- if (i == obj_C) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'Class')}}
- if (obj_C == j) foo() ; // expected-warning {{comparison of distinct pointer types ('Class' and 'int *')}}
- if (j == obj_C) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'Class')}}
-
- return 0;
-}
diff --git a/clang/test/SemaObjC/comptypes-8.m b/clang/test/SemaObjC/comptypes-8.m
deleted file mode 100644
index c22e88c88050..000000000000
--- a/clang/test/SemaObjC/comptypes-8.m
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-@protocol MyProtocol
-@end
-
-id<MyProtocol> obj_p = 0;
-
-int main()
-{
- obj_p = 0;
-}
-
diff --git a/clang/test/SemaObjC/comptypes-9.m b/clang/test/SemaObjC/comptypes-9.m
deleted file mode 100644
index 4f0a277e74e1..000000000000
--- a/clang/test/SemaObjC/comptypes-9.m
+++ /dev/null
@@ -1,86 +0,0 @@
-// RUN: clang -fsyntax-only %s
-// FIXME: This test case tests the patch applied in: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20080602/006017.html
-// Eventually that logic should be treated as an extension.
-
-typedef signed char BOOL;
-typedef int NSInteger;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-@end
-
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSMutableCopying
-- (id)mutableCopyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-
-@interface NSObject <NSObject> {}
-@end
-
-@class NSArray;
-
-typedef struct {} NSFastEnumerationState;
-
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-
-@class NSString;
-
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-- (id)objectAtIndex:(NSUInteger)index;
-@end
-
-typedef unsigned short unichar;
-
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
-- (NSUInteger)length;
-@end
-
-@interface NSSimpleCString : NSString
-{}
-
-@end
-
-@interface NSConstantString : NSSimpleCString @end
-
-extern void *_NSConstantStringClassReference;
-
-@interface NSResponder : NSObject <NSCoding> {}
-@end
-
-@class NSDate, NSDictionary, NSError, NSException, NSNotification;
-
-@interface NSWindowController : NSResponder <NSCoding> {}
-@end
-
-@class PBXBuildLog, PBXBuildLogItem, PBXBuildLogContainerItem, XCWorkQueueCommand, XCBuildLogContainerItemMutationState;
-
-@protocol PBXBuildLogContainerItems <NSObject>
-- (PBXBuildLog *)buildLog;
-@end
-
-@interface PBXBuildLogItem : NSObject {}
-- (id <PBXBuildLogContainerItems>)superitem;
-@end
-@interface PBXBuildResultsModule
-@end
-
-@implementation PBXBuildResultsModule
-- (void) revealItems
-{
- PBXBuildLogItem *objItem;
- PBXBuildLogItem *superitem = [objItem superitem];
-}
-@end
diff --git a/clang/test/SemaObjC/comptypes-a.m b/clang/test/SemaObjC/comptypes-a.m
deleted file mode 100644
index bd8a7490c413..000000000000
--- a/clang/test/SemaObjC/comptypes-a.m
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-typedef signed char BOOL;
-typedef int NSInteger;
-
-@class NSString;
-
-@protocol PBXCompletionItem
-- (NSString *) name;
-- (NSInteger)priority;
-@end
-
-extern NSInteger codeAssistantCaseCompareItems(id a, id b, void *context);
-
-NSInteger codeAssistantCaseCompareItems(id<PBXCompletionItem> a, id<PBXCompletionItem> b, void *context)
-{
-}
-
-#if 0
-FIXME: clang needs to compare each method prototype with its definition (see below).
-
-GCC produces the following correct warnning:
-[snaroff:llvm/tools/clang] snarofflocal% cc -c test/Sema/objc-types-compatible.m
-test/Sema/objc-types-compatible.m: In function ‘-[TedWantsToVerifyObjCDoesTheRightThing compareThis:withThat:]’:
-test/Sema/objc-types-compatible.m:26: warning: conflicting types for ‘-(id)compareThis:(id <PBXCompletionItem>)a withThat:(id <PBXCompletionItem>)b’
-test/Sema/objc-types-compatible.m:20: warning: previous declaration of ‘-(id)compareThis:(int)a withThat:(id)b’
-#endif
-
-@interface TedWantsToVerifyObjCDoesTheRightThing
-
-- compareThis:(int)a withThat:(id)b;
-
-@end
-
-@implementation TedWantsToVerifyObjCDoesTheRightThing
-
-- compareThis:(id<PBXCompletionItem>)a withThat:(id<PBXCompletionItem>)b {
- return self;
-}
-
-@end
diff --git a/clang/test/SemaObjC/conditional-expr-2.m b/clang/test/SemaObjC/conditional-expr-2.m
deleted file mode 100644
index d8a266309374..000000000000
--- a/clang/test/SemaObjC/conditional-expr-2.m
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface A
-@end
-@interface B
-@end
-
-void f0(int cond, A *a, B *b) {
- // Ensure that we can still send a message to result of incompatible
- // conditional expression.
- [ (cond ? a : b) test ]; // expected-warning {{method '-test' not found}}
-}
diff --git a/clang/test/SemaObjC/conditional-expr-3.m b/clang/test/SemaObjC/conditional-expr-3.m
deleted file mode 100644
index de7b828a9807..000000000000
--- a/clang/test/SemaObjC/conditional-expr-3.m
+++ /dev/null
@@ -1,63 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol P0
-@end
-@protocol P1
-@end
-@protocol P2
-@end
-
-@interface A <P0>
-@end
-
-@interface B : A
-@end
-
-void bar(id x);
-void barP0(id<P0> x);
-void barP1(id<P1> x);
-void barP2(id<P2> x);
-
-void f0(A *a) {
- id l = a;
-}
-
-void f1(id x, A *a) {
- id<P0> l = a;
-}
-
-void f2(id<P1> x) {
- id<P0> l = x; // expected-error {{incompatible type initializing 'id<P1>', expected 'id<P0>'}}
-}
-
-void f3(A *a) {
- id<P1> l = a; // expected-error {{incompatible type initializing 'A *', expected 'id<P1>'}}
-}
-
-void f4(int cond, id x, A *a) {
- bar(cond ? x : a);
-}
-
-void f5(int cond, A *a, B *b) {
- bar(cond ? a : b);
-}
-
-void f6(int cond, id x, A *a) {
- bar(cond ? (id<P0, P1>) x : a);
-}
-
-void f7(int cond, id x, A *a) {
- bar(cond ? a : (id<P0, P1>) x);
-}
-
-void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) {
- barP0(cond ? x0 : x1);
-}
-
-void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) {
- barP1(cond ? x0 : x1);
-}
-
-void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) {
- barP2(cond ? x0 : x1);
-}
diff --git a/clang/test/SemaObjC/conditional-expr-4.m b/clang/test/SemaObjC/conditional-expr-4.m
deleted file mode 100644
index 8fdcf97afd3f..000000000000
--- a/clang/test/SemaObjC/conditional-expr-4.m
+++ /dev/null
@@ -1,78 +0,0 @@
-// RUN: clang -fsyntax-only %s
-// XFAIL
-// <rdar://problem/6212771>
-
-#define nil ((void*) 0)
-
-@interface A
-@property int x;
-@end
-
-@interface B : A
-@end
-
-// Basic checks...
-id f0(int cond, id a, void *b) {
- return cond ? a : b;
-}
-A *f0_a(int cond, A *a, void *b) {
- return cond ? a : b;
-}
-
-id f1(int cond, id a) {
- return cond ? a : nil;
-}
-A *f1_a(int cond, A *a) {
- return cond ? a : nil;
-}
-
-// Check interaction with qualified id
-
-@protocol P0 @end
-
-id f2(int cond, id<P0> a, void *b) {
- return cond ? a : b;
-}
-
-id f3(int cond, id<P0> a) {
- return cond ? a : nil;
-}
-
-// Check that result actually has correct type.
-
-// Using properties is one way to find the compiler internal type of a
-// conditional expression. Simple assignment doesn't work because if
-// the type is id then it can be implicitly promoted.
-@protocol P1
-@property int x;
-@end
-
-int f5(int cond, id<P1> a, id<P1> b) {
- // This should result in something with id type, currently. This is
- // almost certainly wrong and should be fixed.
- return (cond ? a : b).x; // expected-error {{member reference base type ('id') is not a structure or union}}
-}
-int f5_a(int cond, A *a, A *b) {
- return (cond ? a : b).x;
-}
-int f5_b(int cond, A *a, B *b) {
- return (cond ? a : b).x;
-}
-
-int f6(int cond, id<P1> a, void *b) {
- // This should result in something with id type, currently.
- return (cond ? a : b).x; // expected-error {{member reference base type ('id') is not a structure or union}}
-}
-
-int f7(int cond, id<P1> a) {
- return (cond ? a : nil).x;
-}
-
-int f8(int cond, id<P1> a, A *b) {
- // GCC regards this as a warning (comparison of distinct Objective-C types lacks a cast)
- return a == b; // expected-error {{invalid operands to binary expression}}
-}
-
-int f9(int cond, id<P1> a, A *b) {
- return (cond ? a : b).x; // expected-error {{incompatible operand types}}
-}
diff --git a/clang/test/SemaObjC/conditional-expr.m b/clang/test/SemaObjC/conditional-expr.m
deleted file mode 100644
index 2884fb4c988b..000000000000
--- a/clang/test/SemaObjC/conditional-expr.m
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-@protocol NSObject
-@end
-
-@protocol DTOutputStreams <NSObject>
-@end
-
-@interface DTFilterOutputStream <DTOutputStreams>
-- nextOutputStream;
-@end
-
-@implementation DTFilterOutputStream
-- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
- id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
- self = nextOutputStream;
- return nextOutputStream ? nextOutputStream : self;
-}
-- nextOutputStream {
- return self;
-}
-@end
-
-@interface DTFilterOutputStream2
-- nextOutputStream;
-@end
-
-@implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'nextOutputStream' not found}}
-- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
- id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
- // GCC warns about both of these.
- self = nextOutputStream; // expected-error {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}}
- return nextOutputStream ? nextOutputStream : self;
-}
-@end
-
-// No @interface declaration for DTFilterOutputStream3
-@implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}}
-- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
- id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
- // GCC warns about both of these as well (no errors).
- self = nextOutputStream; // expected-error {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}}
- return nextOutputStream ? nextOutputStream : self;
-}
-@end
diff --git a/clang/test/SemaObjC/conflicting-ivar-test-1.m b/clang/test/SemaObjC/conflicting-ivar-test-1.m
deleted file mode 100644
index 6f24e8cb3aa6..000000000000
--- a/clang/test/SemaObjC/conflicting-ivar-test-1.m
+++ /dev/null
@@ -1,86 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface INTF
-{
-@public
- int IVAR; // expected-error {{previous definition is here}}
-}
-@end
-
-@implementation INTF
-{
-@private
-
- int XIVAR; // expected-error {{conflicting instance variable name 'XIVAR'}}
-}
-@end
-
-
-
-@interface INTF1
-{
-@public
- int IVAR;
- int IVAR1; // expected-error {{inconsistent number of instance variables specified}}
-}
-@end
-
-@implementation INTF1
-{
-@private
-
- int IVAR;
-}
-@end
-
-
-@interface INTF2
-{
-@public
- int IVAR;
-}
-@end
-
-@implementation INTF2
-{
-@private
-
- int IVAR;
- int IVAR1; // expected-error {{inconsistent number of instance variables specified}}
-}
-@end
-
-
-@interface INTF3
-{
-@public
- int IVAR; // expected-error {{previous definition is here}}
-}
-@end
-
-@implementation INTF3
-{
-@private
-
- short IVAR; // expected-error {{conflicting instance variable type}}
-}
-@end
-
-@implementation INTF4 // expected-warning {{cannot find interface declaration for 'INTF4'}}
-{
-@private
-
- short IVAR;
-}
-@end
-
-@interface INTF5
-{
- char * ch;
-}
-@end
-
-@implementation INTF5
-{
-}
-@end
diff --git a/clang/test/SemaObjC/const-id.m b/clang/test/SemaObjC/const-id.m
deleted file mode 100644
index 9087e4ce7df6..000000000000
--- a/clang/test/SemaObjC/const-id.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-int main() {
- const id foo;
- [foo bar]; // expected-warning {{method '-bar' not found (return type defaults to 'id')}}
- return 0;
-}
-
diff --git a/clang/test/SemaObjC/enhanced-proto-2.m b/clang/test/SemaObjC/enhanced-proto-2.m
deleted file mode 100644
index 82e23c4b63fc..000000000000
--- a/clang/test/SemaObjC/enhanced-proto-2.m
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang -verify %s
-
-@protocol MyProto1
-@optional
-- (void) FOO;
-@optional
-- (void) FOO;
-@optional
-- (void) REQ;
-@optional
-@end
-
-@interface MyProto2 <MyProto1>
-- (void) FOO2;
-- (void) FOO3;
-@end
-
-@implementation MyProto2
-- (void) FOO2{}
-- (void) FOO3{}
-@end
diff --git a/clang/test/SemaObjC/foreach-1.m b/clang/test/SemaObjC/foreach-1.m
deleted file mode 100644
index 17c0379b2535..000000000000
--- a/clang/test/SemaObjC/foreach-1.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@class NSArray;
-
-void f(NSArray *a)
-{
- for (int i in a); // expected-error{{selector element type ('int') is not a valid object}}
- for ((id)2 in a); // expected-error{{selector element is not a valid lvalue}}
- for (2 in a); // expected-error{{selector element is not a valid lvalue}}
-} \ No newline at end of file
diff --git a/clang/test/SemaObjC/format-strings-objc.m b/clang/test/SemaObjC/format-strings-objc.m
deleted file mode 100644
index 42c21705b50b..000000000000
--- a/clang/test/SemaObjC/format-strings-objc.m
+++ /dev/null
@@ -1,43 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-//===----------------------------------------------------------------------===//
-// The following code is reduced using delta-debugging from
-// Foundation.h (Mac OS X).
-//
-// It includes the basic definitions for the test cases below.
-// Not including Foundation.h directly makes this test case both svelt and
-// portable to non-Mac platforms.
-//===----------------------------------------------------------------------===//
-
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-@class NSString, Protocol;
-extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-typedef float CGFloat;
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; @end
-@interface NSSimpleCString : NSString {} @end
-@interface NSConstantString : NSSimpleCString @end
-extern void *_NSConstantStringClassReference;
-
-typedef const struct __CFString * CFStringRef;
-extern void CFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(CFString, 1, 2)));
-
-//===----------------------------------------------------------------------===//
-// Test cases.
-//===----------------------------------------------------------------------===//
-
-void check_nslog(unsigned k) {
- NSLog(@"%d%%", k); // no-warning
- NSLog(@"%s%lb%d", "unix", 10,20); // expected-warning {{lid conversion '%lb'}}
-}
-
-// Check type validation
-extern void NSLog2(int format, ...) __attribute__((format(__NSString__, 1, 2))); // expected-error {{format argument not an NSString}}
-extern void CFStringCreateWithFormat2(int *format, ...) __attribute__((format(CFString, 1, 2))); // expected-error {{format argument not a CFString}}
diff --git a/clang/test/SemaObjC/forward-class-1.m b/clang/test/SemaObjC/forward-class-1.m
deleted file mode 100644
index 2b9369ba5f8a..000000000000
--- a/clang/test/SemaObjC/forward-class-1.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@class FOO, BAR;
-@class FOO, BAR;
-
-@interface INTF : FOO // expected-error {{cannot find interface declaration for 'FOO', superclass of 'INTF'}}
-@end
-
-@interface FOO
-- (BAR*) Meth1;
-- (FOO*) Meth2;
-@end
-
-@interface INTF1 : FOO
-@end
-
-@interface INTF2 : INTF1
-@end
-
-
-@class INTF1, INTF2;
-
-@interface INTF2 : INTF1 // expected-error {{duplicate interface declaration for class 'INTF2'}}
-@end
diff --git a/clang/test/SemaObjC/gcc-cast-ext.m b/clang/test/SemaObjC/gcc-cast-ext.m
deleted file mode 100644
index 866aee9069e9..000000000000
--- a/clang/test/SemaObjC/gcc-cast-ext.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang %s -verify -fms-extensions
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-typedef struct _NSRange { } NSRange;
-
-@class PBXFileReference;
-
-@interface PBXDocBookmark
-+ alloc;
-- autorelease;
-@end
-
-// GCC allows pointer expressions in integer constant expressions.
-struct {
- char control[((int)(char *)2)];
-} xx;
-
-@implementation PBXDocBookmark // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'autorelease' not found}} expected-warning {{method definition for 'alloc' not found}}
-
-+ (id)bookmarkWithFileReference:(PBXFileReference *)fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor
-{
- NSRange r = (NSRange)range;
- return [[[self alloc] initWithFileReference:fileRef gylphRange:(NSRange)range anchor:(NSString *)htmlAnchor] autorelease]; // expected-warning {{method '-initWithFileReference:gylphRange:anchor:' not found (return type defaults to 'id')}}
-}
-@end
diff --git a/clang/test/SemaObjC/id_builtin.m b/clang/test/SemaObjC/id_builtin.m
deleted file mode 100644
index d7c916146fd1..000000000000
--- a/clang/test/SemaObjC/id_builtin.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-// id is now builtin. There should be no errors.
-id obj;
-
-@interface Foo
-
-- defaultToId;
-
-@end
diff --git a/clang/test/SemaObjC/incompatible-protocol-qualified-types.m b/clang/test/SemaObjC/incompatible-protocol-qualified-types.m
deleted file mode 100644
index ad8c45e5e0a8..000000000000
--- a/clang/test/SemaObjC/incompatible-protocol-qualified-types.m
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: clang -pedantic -fsyntax-only -verify %s
-
-@protocol MyProto1
-@end
-
-@protocol MyProto2
-@end
-
-@interface INTF @end
-
-INTF <MyProto1> * Func(INTF <MyProto1, MyProto2> *p2)
-{
- return p2;
-}
-
-
-INTF <MyProto1> * Func1(INTF <MyProto1, MyProto2> *p2)
-{
- return p2;
-}
-
-INTF <MyProto1, MyProto2> * Func2(INTF <MyProto1> *p2)
-{
- Func(p2); // expected-warning {{incompatible pointer types passing 'INTF<MyProto1> *', expected 'INTF<MyProto1,MyProto2> *}}
- return p2; // expected-warning {{incompatible pointer types returning 'INTF<MyProto1> *', expected 'INTF<MyProto1,MyProto2> *}}
-}
-
-
-
-INTF <MyProto1> * Func3(INTF <MyProto2> *p2)
-{
- return p2; // expected-warning {{incompatible pointer types returning 'INTF<MyProto2> *', expected 'INTF<MyProto1> *}}
-}
-
-
-INTF <MyProto1, MyProto2> * Func4(INTF <MyProto2, MyProto1> *p2)
-{
- return p2;
-}
-
diff --git a/clang/test/SemaObjC/interface-1.m b/clang/test/SemaObjC/interface-1.m
deleted file mode 100644
index ea7705050548..000000000000
--- a/clang/test/SemaObjC/interface-1.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-// rdar://5957506
-
-@interface NSWhatever :
-NSObject // expected-error {{cannot find interface declaration for 'NSObject'}}
-<NSCopying> // expected-error {{cannot find protocol declaration for 'NSCopying'}}
-@end
-
-
-// rdar://6095245
-@interface A
-{
- int x
-} // expected-error {{expected ';' at end of declaration list}}
-@end
-
-
-// rdar://4304469
-@interface INT1
-@end
-
-void test2() {
- INT1 b[3]; // expected-warning {{array of interface 'INT1' should probably be an array of pointers}}
- INT1 *c = &b[0];
- ++c;
-}
-
diff --git a/clang/test/SemaObjC/interface-layout.m b/clang/test/SemaObjC/interface-layout.m
deleted file mode 100644
index 637de8e3ac6c..000000000000
--- a/clang/test/SemaObjC/interface-layout.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-typedef struct objc_object {} *id;
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-
-@protocol NSObject
-- (BOOL) isEqual:(id) object;
-@end
-
-@protocol NSCopying
-- (id) copyWithZone:(NSZone *) zone;
-@end
-
-@interface NSObject < NSObject > {}
-@end
-
-extern id NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone * zone);
-
-@interface MyClassBase : NSObject < NSCopying > {}
-@end
-
-@interface MyClassDirectNode : MyClassBase < NSCopying >
-{
- @public NSUInteger attributeRuns[((1024 - 16 - sizeof (MyClassBase)) / (sizeof (NSUInteger) + sizeof (void *)))];
-}
-@end
diff --git a/clang/test/SemaObjC/invalid-code.m b/clang/test/SemaObjC/invalid-code.m
deleted file mode 100644
index 27d4147cc698..000000000000
--- a/clang/test/SemaObjC/invalid-code.m
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-// rdar://6124613
-void test1() {
- void *p = @1; // expected-error {{unexpected '@' in program}}
-}
-
diff --git a/clang/test/SemaObjC/invalid-objc-decls-1.m b/clang/test/SemaObjC/invalid-objc-decls-1.m
deleted file mode 100644
index fa18079d0755..000000000000
--- a/clang/test/SemaObjC/invalid-objc-decls-1.m
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Super @end
-Super s1; // expected-error{{statically allocated Objective-C object 's1'}}
-
-extern Super e1; // expected-error{{statically allocated Objective-C object 'e1'}}
-
-struct S {
- Super s1; // expected-error{{statically allocated Objective-C object 's1'}}
-};
-
-@protocol P1 @end
-
-@interface INTF
-{
- Super ivar1; // expected-error{{statically allocated Objective-C object 'ivar1'}}
-}
-@end
-
-@interface MyIntf
-{
- Super<P1> ivar1; // expected-error{{statically allocated Objective-C object 'ivar1'}}
-}
-@end
-
-Super foo(Super parm1) {
- Super p1; // expected-error{{statically allocated Objective-C object 'p1'}}
- return p1;
-}
diff --git a/clang/test/SemaObjC/ivar-lookup.m b/clang/test/SemaObjC/ivar-lookup.m
deleted file mode 100644
index e599e9da016a..000000000000
--- a/clang/test/SemaObjC/ivar-lookup.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-@interface Test {
- int x;
-}
-
--(void) setX: (int) d;
-@end
-
-extern struct foo x;
-
-@implementation Test
-
--(void) setX: (int) n {
- x = n;
-}
-
-@end
diff --git a/clang/test/SemaObjC/ivar-sem-check-1.m b/clang/test/SemaObjC/ivar-sem-check-1.m
deleted file mode 100644
index 4e810a29a812..000000000000
--- a/clang/test/SemaObjC/ivar-sem-check-1.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-struct S;
-typedef int FOO();
-
-@interface INTF
-{
- struct F {} JJ;
- int arr[]; // expected-error {{field 'arr' has incomplete type}}
- struct S IC; // expected-error {{field 'IC' has incomplete type}}
- struct T { // expected-error {{previous definition is here}}
- struct T {} X; // expected-error {{nested redefinition of 'struct'}}
- }YYY;
- FOO BADFUNC; // expected-error {{field 'BADFUNC' declared as a function}}
- int kaka; // expected-error {{previous definition is here}}
- int kaka; // expected-error {{duplicate member 'kaka'}}
- char ch[]; // expected-error {{field 'ch' has incomplete type}}
-}
-@end
diff --git a/clang/test/SemaObjC/legacy-implementation-1.m b/clang/test/SemaObjC/legacy-implementation-1.m
deleted file mode 100644
index 76434471d149..000000000000
--- a/clang/test/SemaObjC/legacy-implementation-1.m
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@implementation INTF // expected-warning {{cannot find interface declaration for 'INTF'}}
-@end
-
-INTF* pi;
-
-INTF* FUNC()
-{
- return pi;
-}
diff --git a/clang/test/SemaObjC/message.m b/clang/test/SemaObjC/message.m
deleted file mode 100644
index 69a6535a4a9c..000000000000
--- a/clang/test/SemaObjC/message.m
+++ /dev/null
@@ -1,70 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface foo
-- (void)meth;
-@end
-
-@implementation foo
-- (void) contents {} // No declaration in @interface!
-- (void) meth { [self contents]; }
-@end
-
-typedef struct _NSPoint {
- float x;
- float y;
-} NSPoint;
-
-typedef struct _NSSize {
- float width;
- float height;
-} NSSize;
-
-typedef struct _NSRect {
- NSPoint origin;
- NSSize size;
-} NSRect;
-
-@interface AnyClass
-- (NSRect)rect;
-@end
-
-@class Helicopter;
-
-static void func(Helicopter *obj) {
- // Note that the proto for "rect" is found in the global pool even when
- // a statically typed object's class interface isn't in scope! This
- // behavior isn't very desirable, however wee need it for GCC compatibility.
- NSRect r = [obj rect];
-}
-
-@interface NSObject @end
-
-extern Class NSClassFromObject(id object);
-
-@interface XX : NSObject
-@end
-
-@implementation XX
-
-+ _privateMethod {
- return self;
-}
-
-- (void) xx {
- [NSClassFromObject(self) _privateMethod];
-}
-@end
-
-@implementation XX (Private)
-- (void) yy {
- [NSClassFromObject(self) _privateMethod];
-}
-@end
-
-@interface I0
--(void) nonVararg: (int) x;
-@end
-
-int f0(I0 *ob) {
- [ ob nonVararg: 0, 1, 2]; // expected-error {{too many arguments to function}}
-}
diff --git a/clang/test/SemaObjC/method-attributes.m b/clang/test/SemaObjC/method-attributes.m
deleted file mode 100644
index d16d6ffe7879..000000000000
--- a/clang/test/SemaObjC/method-attributes.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-@class NSString;
-
-@interface A
--t1 __attribute__((noreturn));
-- (NSString *)stringByAppendingFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
-@end
diff --git a/clang/test/SemaObjC/method-def-1.m b/clang/test/SemaObjC/method-def-1.m
deleted file mode 100644
index c1cd6294b7e3..000000000000
--- a/clang/test/SemaObjC/method-def-1.m
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface foo
-- (int)meth;
-@end
-
-@implementation foo
-- (int) meth { return [self meth]; }
-@end
-
-// PR2708
-@interface MyClass
-+- (void)myMethod; // expected-error {{expected selector for Objective-C method}}
-- (vid)myMethod2; // expected-error {{expected a type}}
-@end
-
-@implementation MyClass
-- (void)myMethod { }
-- (void)myMethod2 { }
-@end
-
diff --git a/clang/test/SemaObjC/method-def-2.m b/clang/test/SemaObjC/method-def-2.m
deleted file mode 100644
index d31a2b58b9d6..000000000000
--- a/clang/test/SemaObjC/method-def-2.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -ast-print %s
-extern void abort(void);
-#define CHECK_IF(expr) if(!(expr)) abort()
-
-static double d = 4.5920234e2;
-
-@interface Foo
--(void) brokenType: (int)x floatingPoint: (double)y;
-@end
-
-
-@implementation Foo
--(void) brokenType: (int)x floatingPoint: (double)y
-{
- CHECK_IF(x == 459);
- CHECK_IF(y == d);
-}
-@end
-
diff --git a/clang/test/SemaObjC/method-encoding-2.m b/clang/test/SemaObjC/method-encoding-2.m
deleted file mode 100644
index 08a579b0a878..000000000000
--- a/clang/test/SemaObjC/method-encoding-2.m
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s
-// TODO: We don't support rewrite of method definitions
-
-@interface Intf
-- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2;
-- (id) another:(void *)location with:(unsigned **)arg2;
-@end
-
-@implementation Intf
-- (in out bycopy id) address:(byref inout void *)location with:(out oneway unsigned **)arg2{}
-- (id) another:(void *)location with:(unsigned **)arg2 {}
-@end
diff --git a/clang/test/SemaObjC/method-lookup-2.m b/clang/test/SemaObjC/method-lookup-2.m
deleted file mode 100644
index 4ebdb8e4524d..000000000000
--- a/clang/test/SemaObjC/method-lookup-2.m
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-
-@protocol NSObject
-- (BOOL) isEqual:(id) object;
-@end
-
-@interface NSObject < NSObject > {} @end
-
-@class NSString, NSPort;
-
-@interface NSPortNameServer:NSObject
-+ (NSPortNameServer *) systemDefaultPortNameServer;
-@end
-
-@interface NSMachBootstrapServer:NSPortNameServer + (id) sharedInstance; @end
-
-enum {
- NSWindowsNTOperatingSystem = 1, NSWindows95OperatingSystem, NSSolarisOperatingSystem, NSHPUXOperatingSystem, NSMACHOperatingSystem, NSSunOSOperatingSystem, NSOSF1OperatingSystem
-};
-
-@interface NSRunLoop:NSObject {} @end
-
-@interface NSRunLoop(NSRunLoopConveniences)
-- (void) run;
-@end
-
-extern NSString *const NSWillBecomeMultiThreadedNotification;
-
-@interface SenTestTool:NSObject {}
-@end
-
-@implementation SenTestTool
-+ (void) initialize {}
-+(SenTestTool *) sharedInstance {}
--(int) run {}
-+(int) run {
- return[[self sharedInstance] run];
-}
-@end
diff --git a/clang/test/SemaObjC/method-lookup-3.m b/clang/test/SemaObjC/method-lookup-3.m
deleted file mode 100644
index a1815fa386e2..000000000000
--- a/clang/test/SemaObjC/method-lookup-3.m
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-typedef struct { int y; } Abstract;
-
-typedef struct { int x; } Alternate;
-
-#define INTERFERE_TYPE Alternate*
-
-@protocol A
-@property Abstract *x; // expected-warning{{using}}
-@end
-
-@interface B
-@property Abstract *y; // expected-warning{{using}}
-@end
-
-@interface B (Category)
-@property Abstract *z; // expected-warning{{using}}
-@end
-
-@interface InterferencePre
--(void) x; // expected-warning{{also found}}
--(void) y; // expected-warning{{also found}}
--(void) z; // expected-warning{{also found}}
--(void) setX: (INTERFERE_TYPE) arg; // expected-warning{{also found}}
--(void) setY: (INTERFERE_TYPE) arg; // expected-warning{{also found}}
--(void) setZ: (INTERFERE_TYPE) arg; // expected-warning{{also found}}
-@end
-
-void f0(id a0) {
- Abstract *l = [a0 x]; // expected-warning {{multiple methods named 'x' found}}
-}
-
-void f1(id a0) {
- Abstract *l = [a0 y]; // expected-warning {{multiple methods named 'y' found}}
-}
-
-void f2(id a0) {
- Abstract *l = [a0 z]; // expected-warning {{multiple methods named 'z' found}}
-}
-
-void f3(id a0, Abstract *a1) {
- [ a0 setX: a1]; // expected-warning {{multiple methods named 'setX:' found}}
-}
-
-void f4(id a0, Abstract *a1) {
- [ a0 setY: a1]; // expected-warning {{multiple methods named 'setY:' found}}
-}
-
-void f5(id a0, Abstract *a1) {
- [ a0 setZ: a1]; // expected-warning {{multiple methods named 'setZ:' found}}
-}
diff --git a/clang/test/SemaObjC/method-lookup.m b/clang/test/SemaObjC/method-lookup.m
deleted file mode 100644
index 4dfbc7466275..000000000000
--- a/clang/test/SemaObjC/method-lookup.m
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-typedef int NSInteger;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-- (BOOL)respondsToSelector:(SEL)s;
-@end
-
-@interface NSObject <NSObject> {}
-@end
-
-@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
-
-@protocol PBXCompletionItem
-- (NSString *) name;
-- (NSInteger)priority;
-- setPriority:(NSInteger)p;
-@end
-
-@implementation PBXCodeAssistant // expected-warning{{cannot find interface declaration for 'PBXCodeAssistant'}}
-static NSMutableArray * recentCompletions = ((void *)0);
-+ (float) factorForRecentCompletion:(NSString *) completion
-{
- for (NSObject<PBXCompletionItem> * item in [self completionItems]) // expected-warning{{method '-completionItems' not found (return type defaults to 'id')}}
- {
- if ([item respondsToSelector:@selector(setPriority:)])
- {
- [(id)item setPriority:[item priority] / [PBXCodeAssistant factorForRecentCompletion:[item name]]];
- }
- }
-}
-@end
-
diff --git a/clang/test/SemaObjC/method-not-defined.m b/clang/test/SemaObjC/method-not-defined.m
deleted file mode 100644
index 62a8be72e7dc..000000000000
--- a/clang/test/SemaObjC/method-not-defined.m
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Foo
-@end
-
-void test() {
- Foo *fooObj;
- id obj;
-
- [[Foo alloc] init]; // expected-warning {{method '+alloc' not found (return type defaults to 'id')}} expected-warning {{method '-init' not found (return type defaults to 'id')}}
- [fooObj notdefined]; // expected-warning {{method '-notdefined' not found (return type defaults to 'id')}}
- [obj whatever:1 :2 :3]; // expected-warning {{method '-whatever:::' not found (return type defaults to 'id'))}}
-}
diff --git a/clang/test/SemaObjC/method-undef-category-warn-1.m b/clang/test/SemaObjC/method-undef-category-warn-1.m
deleted file mode 100644
index 792c24d748f5..000000000000
--- a/clang/test/SemaObjC/method-undef-category-warn-1.m
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface MyClass1
-@end
-
-@protocol P
-- (void) Pmeth;
-- (void) Pmeth1;
-@end
-
-@interface MyClass1(CAT) <P>
-- (void) meth2;
-@end
-
-@implementation MyClass1(CAT) // expected-warning {{incomplete implementation}} \
- expected-warning {{method definition for 'meth2' not found}} \
- expected-warning {{method definition for 'Pmeth' not found}}
-- (void) Pmeth1{}
-@end
-
-@interface MyClass1(DOG) <P>
-- (void)ppp;
-@end
-
-@implementation MyClass1(DOG) // expected-warning {{incomplete implementation}} \
- expected-warning {{method definition for 'ppp' not found}} \
- expected-warning {{method definition for 'Pmeth1' not found}}
-- (void) Pmeth {}
-@end
-
-@implementation MyClass1(CAT1)
-@end
diff --git a/clang/test/SemaObjC/method-undefined-warn-1.m b/clang/test/SemaObjC/method-undefined-warn-1.m
deleted file mode 100644
index 9e646f82f73a..000000000000
--- a/clang/test/SemaObjC/method-undefined-warn-1.m
+++ /dev/null
@@ -1,42 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface INTF
-- (void) meth;
-- (void) meth : (int) arg1;
-- (int) int_meth;
-+ (int) cls_meth;
-+ (void) cls_meth1 : (int) arg1;
-@end
-
-@implementation INTF // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}}
-- (void) meth {}
-- (void) meth : (int) arg2{}
-- (void) cls_meth1 : (int) arg2{}
-@end
-
-@interface INTF1
-- (void) meth;
-- (void) meth : (int) arg1;
-- (int) int_meth;
-+ (int) cls_meth;
-+ (void) cls_meth1 : (int) arg1;
-@end
-
-@implementation INTF1 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'int_meth' not found}} expected-warning {{method definition for 'cls_meth' not found}} expected-warning {{method definition for 'cls_meth1:' not found}}
-- (void) meth {}
-- (void) meth : (int) arg2{}
-- (void) cls_meth1 : (int) arg2{}
-@end
-
-@interface INTF2
-- (void) meth;
-- (void) meth : (int) arg1;
-- (void) cls_meth1 : (int) arg1;
-@end
-
-@implementation INTF2
-- (void) meth {}
-- (void) meth : (int) arg2{}
-- (void) cls_meth1 : (int) arg2{}
-@end
-
diff --git a/clang/test/SemaObjC/missing-method-context.m b/clang/test/SemaObjC/missing-method-context.m
deleted file mode 100644
index 20437b70ec16..000000000000
--- a/clang/test/SemaObjC/missing-method-context.m
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-- (void)compilerTestAgainst; // expected-error {{missing context for method declaration}}
-
-void xx(); // expected-error {{expected method body}}
diff --git a/clang/test/SemaObjC/objc-gc-attr.m b/clang/test/SemaObjC/objc-gc-attr.m
deleted file mode 100644
index 1f2db346a1bd..000000000000
--- a/clang/test/SemaObjC/objc-gc-attr.m
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-static id __attribute((objc_gc(weak))) a;
-static id __attribute((objc_gc(strong))) b;
-
-static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
-static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
-static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute requires 1 argument(s)}}
-static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}}
diff --git a/clang/test/SemaObjC/property-1.m b/clang/test/SemaObjC/property-1.m
deleted file mode 100644
index 6d13a7b8c6a9..000000000000
--- a/clang/test/SemaObjC/property-1.m
+++ /dev/null
@@ -1,47 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface I
-{
- int IVAR;
- int name;
-}
-@property int d1;
-@property id prop_id; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}}
-@property int name;
-@end
-
-@interface I(CAT)
-@property int d1;
-@end
-
-@implementation I
-@synthesize d1; // expected-error {{synthesized property 'd1' must either be named the same as}}
-@dynamic bad; // expected-error {{property implementation must have its declaration in interface 'I'}}
-@synthesize prop_id; // expected-error {{synthesized property 'prop_id' must either be named the same}}
-@synthesize prop_id = IVAR; // expected-error {{type of property 'prop_id' does not match type of ivar 'IVAR'}}
-@synthesize name; // OK! property with same name as an accessible ivar of same name
-@end
-
-@implementation I(CAT) // expected-warning {{incomplete implementation}}, expected-warning {{method definition for 'd1' not found}}, // expected-warning {{method definition for 'setD1:' not found}}
-@synthesize d1; // expected-error {{@synthesize not allowed in a category's implementation}}
-@dynamic bad; // expected-error {{property implementation must have its declaration in the category 'CAT'}}
-@end
-
-@implementation E // expected-warning {{cannot find interface declaration for 'E'}}
-@dynamic d; // expected-error {{property implementation must have its declaration in interface 'E'}}
-@end
-
-@implementation Q(MYCAT) // expected-error {{cannot find interface declaration for 'Q'}}
-@dynamic d; // expected-error {{property implementation in a category with no category declaration}}
-@end
-
-@interface Foo
-@property double bar;
-@end
-
-int main() {
- id foo;
- double bar = [foo bar];
- return 0;
-}
-
diff --git a/clang/test/SemaObjC/property-10.m b/clang/test/SemaObjC/property-10.m
deleted file mode 100644
index 69a5ae80fe35..000000000000
--- a/clang/test/SemaObjC/property-10.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-// Check property attribute consistency.
-
-@interface I0
-@property(readonly, readwrite) int p0; // expected-error {{property attributes 'readonly' and 'readwrite' are mutually exclusive}}
-
-@property(retain) int p1; // expected-error {{property with 'retain' attribute must be of object type}}
-
-@property(copy) int p2; // expected-error {{property with 'copy' attribute must be of object type}}
-
-@property(assign, copy) id p3_0; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}}
-@property(assign, retain) id p3_1; // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}}
-@property(copy, retain) id p3_2; // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}}
-@property(assign, copy, retain) id p3_3; // expected-error {{property attributes 'assign' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}}
-
-@property id p4; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}}
-@end
diff --git a/clang/test/SemaObjC/property-2.m b/clang/test/SemaObjC/property-2.m
deleted file mode 100644
index 4472a8f6955d..000000000000
--- a/clang/test/SemaObjC/property-2.m
+++ /dev/null
@@ -1,63 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface Tester
-@property char PropertyAtomic_char;
-@property short PropertyAtomic_short;
-@property int PropertyAtomic_int;
-@property long PropertyAtomic_long;
-@property long long PropertyAtomic_longlong;
-@property float PropertyAtomic_float;
-@property double PropertyAtomic_double;
-@property(assign) id PropertyAtomic_id;
-@property(retain) id PropertyAtomicRetained_id;
-@property(copy) id PropertyAtomicRetainedCopied_id;
-@property(retain) id PropertyAtomicRetainedGCOnly_id;
-@property(copy) id PropertyAtomicRetainedCopiedGCOnly_id;
-@end
-
-@implementation Tester
-@dynamic PropertyAtomic_char;
-@dynamic PropertyAtomic_short;
-@dynamic PropertyAtomic_int;
-@dynamic PropertyAtomic_long;
-@dynamic PropertyAtomic_longlong;
-@dynamic PropertyAtomic_float;
-@dynamic PropertyAtomic_double;
-@dynamic PropertyAtomic_id;
-@dynamic PropertyAtomicRetained_id;
-@dynamic PropertyAtomicRetainedCopied_id;
-@dynamic PropertyAtomicRetainedGCOnly_id;
-@dynamic PropertyAtomicRetainedCopiedGCOnly_id;
-@end
-
-@interface SubClass : Tester
-{
- char PropertyAtomic_char;
- short PropertyAtomic_short;
- int PropertyAtomic_int;
- long PropertyAtomic_long;
- long long PropertyAtomic_longlong;
- float PropertyAtomic_float;
- double PropertyAtomic_double;
- id PropertyAtomic_id;
- id PropertyAtomicRetained_id;
- id PropertyAtomicRetainedCopied_id;
- id PropertyAtomicRetainedGCOnly_id;
- id PropertyAtomicRetainedCopiedGCOnly_id;
-}
-@end
-
-@implementation SubClass
-@synthesize PropertyAtomic_char;
-@synthesize PropertyAtomic_short;
-@synthesize PropertyAtomic_int;
-@synthesize PropertyAtomic_long;
-@synthesize PropertyAtomic_longlong;
-@synthesize PropertyAtomic_float;
-@synthesize PropertyAtomic_double;
-@synthesize PropertyAtomic_id;
-@synthesize PropertyAtomicRetained_id;
-@synthesize PropertyAtomicRetainedCopied_id;
-@synthesize PropertyAtomicRetainedGCOnly_id;
-@synthesize PropertyAtomicRetainedCopiedGCOnly_id;
-@end
diff --git a/clang/test/SemaObjC/property-3.m b/clang/test/SemaObjC/property-3.m
deleted file mode 100644
index b22059c23823..000000000000
--- a/clang/test/SemaObjC/property-3.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -verify %s
-
-@interface I
-{
- id d1;
-}
-@property (readwrite, copy) id d1;
-@property (readwrite, copy) id d2;
-@end
-
-@interface NOW : I
-@property (readonly, retain) id d1; // expected-warning {{attribute 'readonly' of property 'd1' restricts attribute 'readwrite' of property inherited from 'I'}} expected-warning {{property 'd1' 'copy' attribute does not match the property inherited from'I'}}
-@property (readwrite, copy) I* d2; // expected-warning {{property type 'I *' does not match property type inherited from 'I'}}
-@end
diff --git a/clang/test/SemaObjC/property-4.m b/clang/test/SemaObjC/property-4.m
deleted file mode 100644
index b5a8f8b1ccb3..000000000000
--- a/clang/test/SemaObjC/property-4.m
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: clang -verify %s
-
-@interface Object
-@end
-
-@protocol ProtocolObject
-@property int class;
-@property (copy) id MayCauseError;
-@end
-
-@protocol ProtocolDerivedGCObject <ProtocolObject>
-@property int Dclass;
-@end
-
-@interface GCObject : Object <ProtocolDerivedGCObject> {
- int ifield;
- int iOwnClass;
- int iDclass;
-}
-@property int OwnClass;
-@end
-
-@interface ReleaseObject : GCObject <ProtocolObject> {
- int newO;
- int oldO;
-}
-@property (retain) id MayCauseError; // expected-warning {{property 'MayCauseError' 'copy' attribute does not match the property inherited from'GCObject'}} \
- expected-warning {{property 'MayCauseError' 'copy' attribute does not match the property inherited from'ProtocolObject'}}
-@end
-
diff --git a/clang/test/SemaObjC/property-5.m b/clang/test/SemaObjC/property-5.m
deleted file mode 100644
index 70ef315b22d7..000000000000
--- a/clang/test/SemaObjC/property-5.m
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang -verify %s
-
-@protocol P1 @end
-@protocol P2 @end
-@protocol P3 @end
-
-@interface NSData @end
-
-@interface MutableNSData : NSData @end
-
-@interface Base : NSData <P1>
-@property(readonly) id ref;
-@property(readonly) Base *p_base;
-@property(readonly) NSData *nsdata;
-@property(readonly) NSData * m_nsdata;
-@end
-
-@interface Data : Base <P1, P2>
-@property(readonly) NSData *ref; // expected-warning {{property type 'NSData *' does not match property type inherited from 'Base'}}
-@property(readonly) Data *p_base; // expected-warning {{property type 'Data *' does not match property type inherited from 'Base'}}
-@property(readonly) MutableNSData * m_nsdata; // expected-warning {{property type 'MutableNSData *' does not match property type inherited from 'Base'}}
-@end
-
-@interface MutedData: Data
-@property(readonly) id p_base; // expected-warning {{property type 'id' does not match property type inherited from 'Data'}}
-@end
-
-@interface ConstData : Data <P1, P2, P3>
-@property(readonly) ConstData *p_base; // expected-warning {{property type 'ConstData *' does not match property type inherited from 'Data'}}
-@end
-
-void foo(Base *b, id x) {
- [ b setRef: x ]; // expected-warning {{method '-setRef:' not found}}
-}
diff --git a/clang/test/SemaObjC/property-6.m b/clang/test/SemaObjC/property-6.m
deleted file mode 100644
index a51994d3d49e..000000000000
--- a/clang/test/SemaObjC/property-6.m
+++ /dev/null
@@ -1,69 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-# 1 "<command line>"
-# 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-+ class;
-@end
-
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSMutableCopying
-- (id)mutableCopyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-
-@interface NSObject <NSObject> {}
-@end
-
-typedef struct {} NSFastEnumerationState;
-
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-@end
-
-@interface NSMutableArray : NSArray
-- (void)addObject:(id)anObject;
-+ (id)arrayWithCapacity:(int)numItems;
-@end
-
-@interface NSBundle : NSObject {}
-+ (NSBundle *)bundleForClass:(Class)aClass;
-- (NSString *)bundlePath;
-- (void)setBundlePath:(NSString *)x;
-@end
-
-@interface NSException : NSObject <NSCopying, NSCoding> {}
-@end
-
-@class NSArray, NSDictionary, NSError, NSString, NSURL;
-
-@interface DTPlugInManager : NSObject
-@end
-
-@implementation DTPlugInManager
-+ (DTPlugInManager *)defaultPlugInManager {
- @try {
- NSMutableArray *plugInPaths = [NSMutableArray arrayWithCapacity:100];
- NSBundle *frameworkBundle = [NSBundle bundleForClass:[DTPlugInManager class]];
- frameworkBundle.bundlePath = 0;
- [plugInPaths addObject:frameworkBundle.bundlePath];
- }
- @catch (NSException *exception) {}
-}
-@end
diff --git a/clang/test/SemaObjC/property-7.m b/clang/test/SemaObjC/property-7.m
deleted file mode 100644
index ef7a98ad89c0..000000000000
--- a/clang/test/SemaObjC/property-7.m
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-typedef struct _NSZone NSZone;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-@end
-
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-
-@interface NSObject <NSObject> {}
-@end
-
-@class NSString, NSData, NSMutableData, NSMutableDictionary, NSMutableArray;
-
-@interface SCMObject : NSObject <NSCopying> {}
- @property(assign) SCMObject *__attribute__((objc_gc(weak))) parent;
-@end
-
-@interface SCMNode : SCMObject
-{
- NSString *_name;
-}
-@property(copy) NSString *name;
-@end
-
-@implementation SCMNode
- @synthesize name = _name;
- - (void) setParent:(SCMNode*) inParent {
- super.parent = inParent;
- }
-@end
diff --git a/clang/test/SemaObjC/property-8.m b/clang/test/SemaObjC/property-8.m
deleted file mode 100644
index 8ca0afc1ed43..000000000000
--- a/clang/test/SemaObjC/property-8.m
+++ /dev/null
@@ -1,74 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-
-@interface NSObject <NSObject> {} @end
-
-typedef float CGFloat;
-
-typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3 } NSFastEnumerationState;
-
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-
-@class NSString;
-
-@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-@end
-
-extern NSString * const NSBundleDidLoadNotification;
-
-@interface NSObject(NSKeyValueObserving)
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
-- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
-@end
-
-enum { NSCaseInsensitivePredicateOption = 0x01, NSDiacriticInsensitivePredicateOption = 0x02 };
-
-@interface NSResponder : NSObject <NSCoding> {}
-@end
-
-extern NSString * const NSFullScreenModeAllScreens;
-@interface NSWindowController : NSResponder <NSCoding> {}
-@end
-
-extern NSString *NSAlignmentBinding ;
-
-@interface _XCOQQuery : NSObject {}
-@end
-
-extern NSString *PBXWindowDidChangeFirstResponderNotification;
-
-@interface PBXModule : NSWindowController {}
-@end
-
-@class _XCOQHelpTextBackgroundView;
-@interface PBXOpenQuicklyModule : PBXModule
-{
-@private
- _XCOQQuery *_query;
-}
-@end
-
-@interface PBXOpenQuicklyModule ()
-@property(readwrite, retain) _XCOQQuery *query;
-@end
-
-@implementation PBXOpenQuicklyModule
-@synthesize query = _query;
-- (void) _clearQuery
-{
- [self.query removeObserver: self forKeyPath: @"matches"];
-}
-@end
-
diff --git a/clang/test/SemaObjC/property-9-impl-method.m b/clang/test/SemaObjC/property-9-impl-method.m
deleted file mode 100644
index bb13d01b74ac..000000000000
--- a/clang/test/SemaObjC/property-9-impl-method.m
+++ /dev/null
@@ -1,63 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-// rdar://5967199
-
-typedef signed char BOOL;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL) isEqual:(id) object;
-@end
-
-@protocol NSCoding
-- (void) encodeWithCoder:(NSCoder *) aCoder;
-@end
-
-@interface NSObject < NSObject > {}
-@end
-
-typedef float CGFloat;
-typedef struct _NSPoint {} NSSize;
-typedef struct _NSRect {} NSRect;
-typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3} NSRectEdge;
-extern void NSDivideRect(NSRect inRect, NSRect * slice, NSRect * rem, CGFloat amount, NSRectEdge edge);
-
-@interface NSResponder:NSObject < NSCoding > {}
-@end
-
-@protocol NSAnimatablePropertyContainer
-- (id) animator;
-@end
-
-extern NSString *NSAnimationTriggerOrderIn;
-
-@interface NSView:NSResponder < NSAnimatablePropertyContainer > {}
--(NSRect) bounds;
-@end
-
-enum {
- NSBackgroundStyleLight = 0, NSBackgroundStyleDark, NSBackgroundStyleRaised, NSBackgroundStyleLowered
-};
-
-@interface NSTabView:NSView {}
-@end
-
-@ class OrganizerTabHeader;
-
-@interface OrganizerTabView:NSTabView {}
-@property(assign)
-NSSize minimumSize;
-@end
-
-@interface OrganizerTabView()
-@property(readonly) OrganizerTabHeader *tabHeaderView;
-@property(readonly) NSRect headerRect;
-@end
-
-@implementation OrganizerTabView
-@dynamic tabHeaderView, headerRect, minimumSize;
--(CGFloat) tabAreaThickness {}
--(NSRectEdge) rectEdgeForTabs {
- NSRect dummy, result = {};
- NSDivideRect(self.bounds, &result, &dummy, self.tabAreaThickness, self.rectEdgeForTabs);
-}
-
diff --git a/clang/test/SemaObjC/props-on-prots.m b/clang/test/SemaObjC/props-on-prots.m
deleted file mode 100644
index aa5be257954c..000000000000
--- a/clang/test/SemaObjC/props-on-prots.m
+++ /dev/null
@@ -1,65 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL) isEqual:(id) object;
-@end
-
-@protocol NSCoding
-- (void) encodeWithCoder:(NSCoder *) aCoder;
-@end
-
-@interface NSObject < NSObject > {} @end
-
-typedef float CGFloat;
-
-@interface NSResponder:NSObject < NSCoding > {} @end
-
-@class XCElementView;
-
-typedef struct _XCElementInset {} XCElementInset;
-
-@protocol XCElementP < NSObject >
--(BOOL) vertical;
-@end
-
-@protocol XCElementDisplayDelegateP;
-@protocol XCElementTabMarkerP;
-
-typedef NSObject < XCElementTabMarkerP > XCElementTabMarker;
-
-@protocol XCElementTabberP < XCElementP >
--(void) setMarker:(XCElementTabMarker *) marker;
-@end
-
-typedef NSObject < XCElementTabberP > XCElementTabber;
-
-@protocol XCElementTabMarkerP < NSObject >
-@property(nonatomic)
-BOOL variableSized;
-@end
-
-@protocol XCElementJustifierP < XCElementP >
--(void) setHJustification:(CGFloat) hJust;
-@end
-
-typedef NSObject < XCElementJustifierP > XCElementJustifier;
-@interface XCElementImp:NSObject < XCElementP > {}
-@end
-
-@class XCElementImp;
-
-@interface XCElementTabberImp:XCElementImp < XCElementTabberP > {
- XCElementTabMarker *_marker;
-}
-@end
-
-@implementation XCElementTabberImp
-- (void) setMarker:(XCElementTabMarker *) marker {
- if (_marker && _marker.variableSized) {
- }
-}
-- vertical { return self; }
-- (BOOL)isEqual:x { return 1; }
-@end
diff --git a/clang/test/SemaObjC/protocol-archane.m b/clang/test/SemaObjC/protocol-archane.m
deleted file mode 100644
index 19736cdf5054..000000000000
--- a/clang/test/SemaObjC/protocol-archane.m
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-// rdar://5986251
-
-@protocol SomeProtocol
-- (void) bar;
-@end
-
-void foo(id x) {
- bar((short<SomeProtocol>)x); // expected-error {{expected ')'}} expected-error {{to match this '('}}
- bar((<SomeProtocol>)x); // expected-warning {{protocol qualifiers without 'id' is archaic}}
-
- [(<SomeProtocol>)x bar]; // expected-warning {{protocol qualifiers without 'id' is archaic}}
-}
-
-@protocol MyProtocol
-- (void)doSomething;
-@end
-
-@interface MyClass
-- (void)m1:(id <MyProtocol> const)arg1;
-
-// FIXME: provide a better diagnostic (no typedef).
-- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short typedef' is invalid}}
-@end \ No newline at end of file
diff --git a/clang/test/SemaObjC/protocol-expr-1.m b/clang/test/SemaObjC/protocol-expr-1.m
deleted file mode 100644
index dff2866020d5..000000000000
--- a/clang/test/SemaObjC/protocol-expr-1.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol fproto;
-
-@protocol p1
-@end
-
-@class cl;
-
-int main()
-{
- Protocol *proto = @protocol(p1);
- Protocol *fproto = @protocol(fproto);
-}
-
diff --git a/clang/test/SemaObjC/protocol-expr-neg-1.m b/clang/test/SemaObjC/protocol-expr-neg-1.m
deleted file mode 100644
index 427e74417ab4..000000000000
--- a/clang/test/SemaObjC/protocol-expr-neg-1.m
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@class Protocol;
-
-@protocol fproto;
-
-@protocol p1
-@end
-
-@class cl;
-
-int main()
-{
- Protocol *proto = @protocol(p1);
- Protocol *fproto = @protocol(fproto);
- Protocol *pp = @protocol(i); // expected-error {{cannot find protocol declaration for 'i'}}
- Protocol *p1p = @protocol(cl); // expected-error {{cannot find protocol declaration for 'cl'}}
-}
-
diff --git a/clang/test/SemaObjC/protocol-id-test-1.m b/clang/test/SemaObjC/protocol-id-test-1.m
deleted file mode 100644
index 765500e10d81..000000000000
--- a/clang/test/SemaObjC/protocol-id-test-1.m
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -verify %s
-
-@interface FF
-- (void) Meth;
-@end
-
-@protocol P
-@end
-
-@interface INTF<P>
-- (void)IMeth;
-@end
-
-@implementation INTF
-- (void)IMeth {INTF<P> *pi; [pi Meth]; } // expected-warning {{method '-Meth' not found in protocol (return type defaults to 'id')}}
-@end
diff --git a/clang/test/SemaObjC/protocol-id-test-2.m b/clang/test/SemaObjC/protocol-id-test-2.m
deleted file mode 100644
index 525d2cca9e9d..000000000000
--- a/clang/test/SemaObjC/protocol-id-test-2.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -verify %s
-
-@protocol P
-@end
-
-@interface INTF<P>
-- (void)IMeth;
- - (void) Meth;
-@end
-
-@implementation INTF
-- (void)IMeth { [(id<P>)self Meth]; } // expected-warning {{method '-Meth' not found in protocol (return type defaults to 'id')}}
-- (void) Meth {}
-@end
diff --git a/clang/test/SemaObjC/protocol-id-test-3.m b/clang/test/SemaObjC/protocol-id-test-3.m
deleted file mode 100644
index 8c2beee989c7..000000000000
--- a/clang/test/SemaObjC/protocol-id-test-3.m
+++ /dev/null
@@ -1,94 +0,0 @@
-// RUN: clang -pedantic -fsyntax-only -verify %s
-
-@protocol MyProto1
-@end
-
-@protocol MyProto2
-@end
-
-@interface INTF @end
-
-id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2)
-{
- return p2;
-}
-
-
-
-
- id<MyProto1> Gunc(id <MyProto1, MyProto2>p2)
-{
- return p2;
-}
-
-
- id<MyProto1> Gunc1(id <MyProto1, MyProto2>p2)
-{
- return p2;
-}
-
-id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2)
-{
- Func(p2); // expected-error {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
- return p2; // expected-error {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}}
-}
-
-
-
-id<MyProto1> Gunc3(id <MyProto2>p2)
-{
- return p2; // expected-error {{incompatible type returning 'id<MyProto2>', expected 'id<MyProto1>'}}
-}
-
-
-id<MyProto1, MyProto2> Gunc4(id <MyProto2, MyProto1>p2)
-{
- return p2;
-}
-
-
-
-INTF<MyProto1> * Hunc(id <MyProto1, MyProto2>p2)
-{
- return p2;
-}
-
-
-INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2)
-{
- return p2;
-}
-
-INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2)
-{
- Func(p2); // expected-error {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
- return p2; // expected-error {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
-}
-
-INTF<MyProto1> * Hunc3(id <MyProto2>p2)
-{
- return p2; // expected-error {{incompatible type returning 'id<MyProto2>', expected 'INTF<MyProto1> *'}}
-}
-
-
-INTF<MyProto1, MyProto2> * Hunc4(id <MyProto2, MyProto1>p2)
-{
- return p2;
-}
-
-id Iunc(id <MyProto1, MyProto2>p2)
-{
- return p2;
-}
-
-
-id<MyProto1> Iunc1(id p2)
-{
- return p2;
-}
-
-id<MyProto1, MyProto2> Iunc2(id p2)
-{
- Iunc(p2);
- return p2;
-}
diff --git a/clang/test/SemaObjC/protocol-implementation-inherited.m b/clang/test/SemaObjC/protocol-implementation-inherited.m
deleted file mode 100644
index 42c499580988..000000000000
--- a/clang/test/SemaObjC/protocol-implementation-inherited.m
+++ /dev/null
@@ -1,56 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol P0
--bar;
-@end
-
-@interface A <P0>
-@end
-
-// Interface conforms to inherited protocol
-
-@interface B0 : A <P0>
-@end
-
-@implementation B0
-@end
-
-// Interface conforms to a protocol which extends another. The other
-// protocol is inherited, and extended methods are implemented.
-
-@protocol P1 <P0>
--foo;
-@end
-
-@interface B1 : A <P1>
-@end
-
-@implementation B1
--foo {};
-@end
-
-// Interface conforms to a protocol whose methods are provided by an
-// alternate inherited protocol.
-
-@protocol P2
--bar;
-@end
-
-@interface B2 : A <P2>
-@end
-
-@implementation B2
-@end
-
-// Interface conforms to a protocol whose methods are provided by a base class.
-
-@interface A1
--bar;
-@end
-
-@interface B3 : A1 <P2>
-@end
-
-@implementation B3
-@end
-
diff --git a/clang/test/SemaObjC/protocol-test-1.m b/clang/test/SemaObjC/protocol-test-1.m
deleted file mode 100644
index 6fb28b533cf7..000000000000
--- a/clang/test/SemaObjC/protocol-test-1.m
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol PROTO1
-@required
-- (int) FooBar;
-@optional
-- (void) MyMethod1;
-+ (int) S;
-@end
-
-@interface INTF1
-@required // expected-error {{@required may be specified in protocols only}}
-- (int) FooBar;
-- (int) FooBar1;
-- (int) FooBar2;
-@optional // expected-error {{@optional may be specified in protocols only}}
-+ (int) C;
-
-- (int)I;
-@end
diff --git a/clang/test/SemaObjC/protocol-test-2.m b/clang/test/SemaObjC/protocol-test-2.m
deleted file mode 100644
index 1a7fc9ce3ccf..000000000000
--- a/clang/test/SemaObjC/protocol-test-2.m
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface INTF1 @end
-
-@protocol p1,p2,p3;
-
-@protocol p1;
-
-@protocol PROTO1
-- (INTF1<p1>*) meth;
-@end
-
-@protocol PROTO2<p1> // expected-warning {{cannot find protocol definition for 'p1'}}
-@end
-
-@protocol p1 @end
-
-@protocol PROTO<p1>
-@end
-
-@protocol PROTO<p1> // expected-error {{duplicate protocol declaration of 'PROTO'}}
-@end
-
-@protocol PROTO3<p1, p1>
-@end
-
-@protocol p2 <p1>
-@end
-
-@protocol PROTO4 <p1, p2, PROTO, PROTO3, p3> // expected-warning {{cannot find protocol definition for 'p3'}}
-@end
diff --git a/clang/test/SemaObjC/rdr-6211479-array-property.m b/clang/test/SemaObjC/rdr-6211479-array-property.m
deleted file mode 100644
index 8b7067fbe2af..000000000000
--- a/clang/test/SemaObjC/rdr-6211479-array-property.m
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-// XFAIL
-// <rdar://problem/6211479>
-
-typedef int T[2];
-
-@interface A
-@property(assign) T p2; // expected-error {{FIXME: property has invalid type}}
-@end
diff --git a/clang/test/SemaObjC/selector-1.m b/clang/test/SemaObjC/selector-1.m
deleted file mode 100644
index 476568f6caa4..000000000000
--- a/clang/test/SemaObjC/selector-1.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -verify %s
-
-int main() {
- SEL s = @selector(retain);
- SEL s1 = @selector(meth1:);
- SEL s2 = @selector(retainArgument::);
- SEL s3 = @selector(retainArgument:::::);
- SEL s4 = @selector(retainArgument:with:);
- SEL s5 = @selector(meth1:with:with:);
- SEL s6 = @selector(getEnum:enum:bool:);
- SEL s7 = @selector(char:float:double:unsigned:short:long:);
-
- SEL s9 = @selector(:enum:bool:);
-}
diff --git a/clang/test/SemaObjC/selector-overload.m b/clang/test/SemaObjC/selector-overload.m
deleted file mode 100644
index 7bd25444c7e9..000000000000
--- a/clang/test/SemaObjC/selector-overload.m
+++ /dev/null
@@ -1,47 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-@interface NSObject
-+ alloc;
-- init;
-@end
-
-struct D {
- double d;
-};
-
-@interface Foo : NSObject
-
-- method:(int)a;
-- method:(int)a;
-
-@end
-
-@interface Bar : NSObject
-
-- method:(void *)a;
-
-@end
-
-@interface Car : NSObject
-
-- method:(struct D)a;
-
-@end
-
-@interface Zar : NSObject
-
-- method:(float)a;
-
-@end
-
-@interface Rar : NSObject
-
-- method:(float)a;
-
-@end
-
-int main() {
- id xx = [[Car alloc] init]; // expected-warning {{incompatible types assigning 'int' to 'id'}}
-
- [xx method:4];
-}
diff --git a/clang/test/SemaObjC/static-ivar-ref-1.m b/clang/test/SemaObjC/static-ivar-ref-1.m
deleted file mode 100644
index d01a7fb6da0c..000000000000
--- a/clang/test/SemaObjC/static-ivar-ref-1.m
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: clang -ast-print %s
-
-@interface current
-{
- int ivar;
- int ivar1;
- int ivar2;
-}
-@end
-
-current *pc;
-
-int foo()
-{
- return pc->ivar2 + (*pc).ivar + pc->ivar1;
-}
diff --git a/clang/test/SemaObjC/string.m b/clang/test/SemaObjC/string.m
deleted file mode 100644
index e3974ad8f662..000000000000
--- a/clang/test/SemaObjC/string.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only &&
-// RUN: clang %s -verify -fsyntax-only -DDECLAREIT
-
-// a declaration of NSConstantString is not required.
-#ifdef DECLAREIT
-@interface NSConstantString;
-@end
-#endif
-
-
-
-id s = @"123"; // simple
-id t = @"123" @"456"; // concat
-id u = @"123" @ blah; // expected-error: {{unexpected token}}
-
diff --git a/clang/test/SemaObjC/synchronized.m b/clang/test/SemaObjC/synchronized.m
deleted file mode 100644
index 365da92dd4b1..000000000000
--- a/clang/test/SemaObjC/synchronized.m
+++ /dev/null
@@ -1,75 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-@end
-
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSMutableCopying
-- (id)mutableCopyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-
-@interface NSObject <NSObject> {} @end
-
-typedef float CGFloat;
-typedef struct { int a; } NSFastEnumerationState;
-
-@protocol NSFastEnumeration
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
-@end
-
-typedef unsigned short unichar;
-
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
-- (NSUInteger)length;
-@end
-
-@interface NSSimpleCString : NSString {} @end
-
-@interface NSConstantString : NSSimpleCString @end
-
-extern void *_NSConstantStringClassReference;
-
-@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
-- (NSUInteger)count;
-@end
-
-@interface NSMutableDictionary : NSDictionary
-- (void)removeObjectForKey:(id)aKey;
-@end
-
-@class NSArray, NSSet, NSHashTable;
-
-@protocol PBXTrackableTask <NSObject>
-- (float) taskPercentComplete;
-- taskIdentifier;
-@end
-
-@interface PBXTrackableTaskManager : NSObject {
- NSMutableDictionary *_trackableTasks;
-}
-@end
-
-NSString *XCExecutableDebugTaskIdentifier = @"XCExecutableDebugTaskIdentifier";
-
-@implementation PBXTrackableTaskManager
-- (id) init {}
-- (void) unregisterTask:(id <PBXTrackableTask>) task {
- @synchronized (self) {
- id taskID = [task taskIdentifier];
- id task = [_trackableTasks objectForKey:taskID]; // expected-warning{{method '-objectForKey:' not found (return type defaults to 'id')}}
- }
-}
-@end
-
diff --git a/clang/test/SemaObjC/try-catch.m b/clang/test/SemaObjC/try-catch.m
deleted file mode 100644
index e4c20b734380..000000000000
--- a/clang/test/SemaObjC/try-catch.m
+++ /dev/null
@@ -1,37 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-typedef struct _NSZone NSZone;
-
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject
-- (BOOL)isEqual:(id)object;
-@end
-
-@protocol NSCopying
-- (id)copyWithZone:(NSZone *)zone;
-@end
-
-@protocol NSCoding
-- (void)encodeWithCoder:(NSCoder *)aCoder;
-@end
-
-@interface NSObject <NSObject> {}
-@end
-
-@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale;
-
-@interface NSException : NSObject <NSCopying, NSCoding> {}
-@end
-
-@class ASTNode, XCRefactoringParser, Transform, TransformInstance, XCRefactoringSelectionInfo;
-
-@interface XCRefactoringTransformation : NSObject {}
-@end
-
-@implementation XCRefactoringTransformation
-- (NSDictionary *)setUpInfoForTransformKey:(NSString *)transformKey outError:(NSError **)outError; {
- @try {}
- // the exception name is optional (weird)
- @catch (NSException *) {}
-}
diff --git a/clang/test/SemaObjC/typedef-class.m b/clang/test/SemaObjC/typedef-class.m
deleted file mode 100644
index 1bb3f87aa5ae..000000000000
--- a/clang/test/SemaObjC/typedef-class.m
+++ /dev/null
@@ -1,78 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-
-@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
-
-@protocol NSObject - (BOOL) isEqual:(id) object; @end
-@protocol NSCopying - (id) copyWithZone:(NSZone *) zone; @end
-@protocol NSCoding - (void) encodeWithCoder:(NSCoder *) aCoder; @end
-
-@interface NSObject < NSObject > {}
-+(id) alloc;
-@end
-
-typedef float CGFloat;
-
-@interface NSTask:NSObject
-- (id) init;
-@end
-
-typedef NSUInteger NSControlSize;
-typedef struct __CFlags {} _CFlags;
-
-@interface NSCell:NSObject < NSCopying, NSCoding > {}
-@end
-
-@interface NSActionCell:NSCell {} @end
-
-@class NSAttributedString, NSFont, NSImage, NSSound;
-
-typedef struct _XCElementInset {} XCElementInset;
-
-@protocol XCElementP < NSObject >
--(BOOL) vertical;
-@end
-
-@protocol XCElementDisplayDelegateP;
-@protocol XCElementDisplayDelegateP < NSObject >
--(void) configureForControlSize:(NSControlSize)size font:(NSFont *)font addDefaultSpace:(XCElementInset) additionalSpace;
-@end
-
-@protocol XCElementSpacerP < XCElementP >
-@end
-
-typedef NSObject < XCElementSpacerP > XCElementSpacer;
-
-@protocol XCElementTogglerP < XCElementP > -(void) setDisplayed:(BOOL) displayed;
-@end
-
-typedef NSObject < XCElementTogglerP > XCElementToggler;
-
-@interface XCElementRootFace:NSObject {} @end
-
-@interface XCElementFace:XCElementRootFace {} @end
-
-@class XCElementToggler;
-
-@interface XCRASlice:XCElementFace {} @end
-
-@class XCElementSpacings;
-
-@interface XCElementDisplay:NSObject < XCElementDisplayDelegateP > {} @end
-@interface XCElementDisplayRect:XCElementDisplay {} @end
-
-typedef XCElementDisplayRect XCElementGraphicsRect;
-
-@interface XCElementDisplayFillerImage:XCElementDisplay {} @end
-
-@implementation XCRASlice
-- (void) addSliceWithLabel:(NSString *)label statusKey:(NSString *)statusKey disclosed:(BOOL)disclosed
-{
- static XCElementGraphicsRect *_sGraphicsDelegate = ((void *) 0);
- if (!_sGraphicsDelegate) {
- _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
- }
-}
-@end
diff --git a/clang/test/SemaObjC/undef-protocol-methods-1.m b/clang/test/SemaObjC/undef-protocol-methods-1.m
deleted file mode 100644
index 9ad3593c6c4d..000000000000
--- a/clang/test/SemaObjC/undef-protocol-methods-1.m
+++ /dev/null
@@ -1,42 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol P1
-- (void) P1proto;
-+ (void) ClsP1Proto;
-- (void) DefP1proto;
-@end
-@protocol P2
-- (void) P2proto;
-+ (void) ClsP2Proto;
-@end
-
-@protocol P3<P2>
-- (void) P3proto;
-+ (void) ClsP3Proto;
-+ (void) DefClsP3Proto;
-@end
-
-@protocol PROTO<P1, P3>
-- (void) meth;
-- (void) meth : (int) arg1;
-+ (void) cls_meth : (int) arg1;
-@end
-
-@interface INTF <PROTO>
-@end
-
-@implementation INTF // expected-warning {{incomplete implementation}} \
- expected-warning {{method definition for 'meth' not found}} \
- expected-warning {{method definition for 'meth:' not found}} \
- expected-warning {{method definition for 'cls_meth:' not found}} \
- expected-warning {{method definition for 'P3proto' not found}} \
- expected-warning {{method definition for 'ClsP3Proto' not found}} \
- expected-warning {{method definition for 'P2proto' not found}} \
- expected-warning {{method definition for 'ClsP2Proto' not found}} \
- expected-warning {{method definition for 'ClsP1Proto' not found}} \
- expected-warning {{method definition for 'P1proto' not found}}
-- (void) DefP1proto{}
-
-+ (void) DefClsP3Proto{}
-
-@end
diff --git a/clang/test/SemaObjC/undef-superclass-1.m b/clang/test/SemaObjC/undef-superclass-1.m
deleted file mode 100644
index 7e12463654f3..000000000000
--- a/clang/test/SemaObjC/undef-superclass-1.m
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@class SUPER, Y;
-
-@interface INTF :SUPER // expected-error {{cannot find interface declaration for 'SUPER', superclass of 'INTF'}}
-@end
-
-@interface SUPER @end
-
-@interface INTF1 : SUPER
-@end
-
-@interface INTF2 : INTF1
-@end
-
-@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}}
-@end
-
-@interface INTF1 // expected-error {{duplicate interface declaration for class 'INTF1'}}
-@end
-
-@implementation SUPER
-- (void)dealloc {
- [super dealloc]; // expected-error {{no super class declared in @interface for 'SUPER'}}
-}
-@end
diff --git a/clang/test/SemaObjC/undefined-protocol-type-1.m b/clang/test/SemaObjC/undefined-protocol-type-1.m
deleted file mode 100644
index 117f418ab1c1..000000000000
--- a/clang/test/SemaObjC/undefined-protocol-type-1.m
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@protocol p1, p4;
-@protocol p2 @end
-
-@interface T
-- (T<p2, p3, p1, p4>*) meth; // expected-error {{cannot find protocol declaration for 'p3'}}
-- (T<p2, p3, p1, p4>*) meth; // expected-error {{cannot find protocol declaration for 'p3'}}
-@end
diff --git a/clang/test/SemaObjC/unused.m b/clang/test/SemaObjC/unused.m
deleted file mode 100644
index cbe15a1abb57..000000000000
--- a/clang/test/SemaObjC/unused.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-#include <stdio.h>
-
-@interface Greeter
-+ (void) hello;
-@end
-
-@implementation Greeter
-+ (void) hello {
- fprintf(stdout, "Hello, World!\n");
-}
-@end
-
-int main (void) {
- [Greeter hello];
- return 0;
-}
-
diff --git a/clang/test/SemaObjC/va-method-1.m b/clang/test/SemaObjC/va-method-1.m
deleted file mode 100644
index 077982abbf51..000000000000
--- a/clang/test/SemaObjC/va-method-1.m
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#include <stdarg.h>
-
-@interface NSObject @end
-@interface XX : NSObject @end
-
-@implementation XX
-- (void)encodeValuesOfObjCTypes:(const char *)types, ... {
- va_list ap;
- va_start(ap, types);
- while (*types) ;
- va_end(ap);
-}
-
-@end
-
diff --git a/clang/test/SemaObjCXX/cocoa.mm b/clang/test/SemaObjCXX/cocoa.mm
deleted file mode 100644
index 7cb1b5295c5b..000000000000
--- a/clang/test/SemaObjCXX/cocoa.mm
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang %s -print-stats
-#ifdef __APPLE__
-#include <Cocoa/Cocoa.h>
-#endif
-
diff --git a/clang/test/SemaObjCXX/reserved-keyword-selectors.mm b/clang/test/SemaObjCXX/reserved-keyword-selectors.mm
deleted file mode 100644
index 79f747fe8a19..000000000000
--- a/clang/test/SemaObjCXX/reserved-keyword-selectors.mm
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface A
-- (void)asm;
-- (void)bool;
-- (void)catch;
-- (void)class;
-- (void)const_cast;
-- (void)delete;
-- (void)dynamic_cast;
-- (void)explicit;
-- (void)export;
-- (void)false;
-- (void)friend;
-- (void)mutable;
-- (void)namespace;
-- (void)new;
-- (void)operator;
-- (void)private;
-- (void)protected;
-- (void)public;
-- (void)reinterpret_cast;
-- (void)static_cast;
-- (void)template;
-- (void)this;
-- (void)throw;
-- (void)true;
-- (void)try;
-- (void)typename;
-- (void)typeid;
-- (void)using;
-- (void)virtual;
-- (void)wchar_t;
-@end
-
diff --git a/clang/test/Serialization/complex.c b/clang/test/Serialization/complex.c
deleted file mode 100644
index f622264842d6..000000000000
--- a/clang/test/Serialization/complex.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: clang %s --test-pickling 2>&1 | grep -q 'SUCCESS'
-
-int main(void)
-{
- double _Complex a = 5;
- double _Complex b = 42;
-
- return a * b != b * a;
-}
-
-_Complex double bar(int);
-void test(_Complex double*);
-void takecomplex(_Complex double);
-
-void test2(int c) {
- _Complex double X;
- X = bar(1);
- test(&X);
- takecomplex(X);
-}
-
-_Complex double g1, g2;
-_Complex float cf;
-double D;
-
-void test3() {
- g1 = g1 + g2;
- g1 = g1 - g2;
- g1 = g1 * g2;
- g1 = +-~g1;
-
- double Gr = __real g1;
-
- cf += D;
- D += cf;
- cf /= g1;
- g1 = g1 + D;
- g1 = D + g1;
-}
-
-void t1() {
- (__real__ cf) = 4.0;
-}
-
-void t2() {
- (__imag__ cf) = 4.0;
-}
-
diff --git a/clang/test/Serialization/stmt_exprs.c b/clang/test/Serialization/stmt_exprs.c
deleted file mode 100644
index 46aa69d04674..000000000000
--- a/clang/test/Serialization/stmt_exprs.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s --test-pickling 2>&1 | grep -q 'SUCCESS'
-
-typedef unsigned __uint32_t;
-
-#define __byte_swap_int_var(x) \
-__extension__ ({ register __uint32_t __X = (x); \
- __asm ("bswap %0" : "+r" (__X)); \
- __X; })
-
-int test(int _x) {
- return (__byte_swap_int_var(_x));
-} \ No newline at end of file
diff --git a/clang/test/TestRunner.sh b/clang/test/TestRunner.sh
deleted file mode 100755
index a2e0fe5c9a32..000000000000
--- a/clang/test/TestRunner.sh
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/sh
-#
-# TestRunner.sh - This script is used to run arbitrary unit tests. Unit
-# tests must contain the command used to run them in the input file, starting
-# immediately after a "RUN:" string.
-#
-# This runner recognizes and replaces the following strings in the command:
-#
-# %s - Replaced with the input name of the program, or the program to
-# execute, as appropriate.
-# %prcontext - prcontext.tcl script
-# %t - temporary file name (derived from testcase name)
-#
-
-FILENAME=$1
-TESTNAME=$1
-SUBST=$1
-
-OUTPUT=Output/$1.out
-
-# create the output directory if it does not already exist
-mkdir -p `dirname $OUTPUT` > /dev/null 2>&1
-
-if test $# != 1; then
- # If more than one parameter is passed in, there must be three parameters:
- # The filename to read from (already processed), the command used to execute,
- # and the file to output to.
- SUBST=$2
- OUTPUT=$3
- TESTNAME=$3
-fi
-
-ulimit -t 40
-
-# Verify the script contains a run line.
-grep -q 'RUN:' $FILENAME || (
- echo "******************** TEST '$TESTNAME' HAS NO RUN LINE! ********************"
- exit 1
-)
-
-# Run under valgrind if the VG environment variable has been set.
-CLANG=$CLANG
-if [ ! -n "$CLANG" ]; then
- CLANG="clang"
-fi
-if [ -n "$VG" ]; then
- rm -f $OUTPUT.vg
- CLANG="valgrind --leak-check=full --quiet --log-file=$OUTPUT.vg $CLANG"
-fi
-
-SCRIPT=$OUTPUT.script
-TEMPOUTPUT=$OUTPUT.tmp
-grep 'RUN:' $FILENAME | \
- sed -e "s|^.*RUN:\(.*\)$|\1|g" \
- -e "s|clang|$CLANG|g" \
- -e "s|%s|$SUBST|g" \
- -e "s|%prcontext|prcontext.tcl|g" \
- -e "s|%t|$TEMPOUTPUT|g" > $SCRIPT
-
-IS_XFAIL=0
-if (grep -q XFAIL $FILENAME); then
- IS_XFAIL=1
- printf "XFAILED '$TESTNAME': "
- grep XFAIL $FILENAME
-fi
-
-/bin/sh $SCRIPT > $OUTPUT 2>&1
-SCRIPT_STATUS=$?
-
-if [ -n "$VG" ]; then
- [ ! -s $OUTPUT.vg ]
- VG_STATUS=$?
-else
- VG_STATUS=0
-fi
-
-if [ $IS_XFAIL -ne 0 ]; then
- if [ $SCRIPT_STATUS -ne 0 ]; then
- SCRIPT_STATUS=0
- else
- SCRIPT_STATUS=1
- fi
-fi
-
-if [ $SCRIPT_STATUS -ne 0 -o $VG_STATUS -ne 0 ]; then
- echo "******************** TEST '$TESTNAME' FAILED! ********************"
- echo "Command: "
- cat $SCRIPT
- if [ $SCRIPT_STATUS -eq 0 ]; then
- echo "Output:"
- elif [ $IS_XFAIL -ne 0 ]; then
- echo "Incorrect Output (Expected Failure):"
- else
- echo "Incorrect Output:"
- fi
- cat $OUTPUT
- if [ $VG_STATUS -ne 0 ]; then
- echo "Valgrind Output:"
- cat $OUTPUT.vg
- fi
- echo "******************** TEST '$TESTNAME' FAILED! ********************"
- exit 1
-fi
-
diff --git a/clang/tools/scan-view/Reporter.py b/clang/tools/scan-view/Reporter.py
deleted file mode 100644
index d2c107b62e1c..000000000000
--- a/clang/tools/scan-view/Reporter.py
+++ /dev/null
@@ -1,244 +0,0 @@
-"""Methods for reporting bugs."""
-
-import subprocess, sys, os
-
-__all__ = ['ReportFailure', 'BugReport', 'getReporters']
-
-#
-
-class ReportFailure(Exception):
- """Generic exception for failures in bug reporting."""
- def __init__(self, value):
- self.value = value
-
-# Collect information about a bug.
-
-class BugReport:
- def __init__(self, title, description, files):
- self.title = title
- self.description = description
- self.files = files
-
-# Reporter interfaces.
-
-import os
-
-import email, mimetypes, smtplib
-from email import encoders
-from email.message import Message
-from email.mime.base import MIMEBase
-from email.mime.multipart import MIMEMultipart
-from email.mime.text import MIMEText
-
-#===------------------------------------------------------------------------===#
-# ReporterParameter
-#===------------------------------------------------------------------------===#
-
-class ReporterParameter:
- def __init__(self, n):
- self.name = n
- def getName(self):
- return self.name
- def getValue(self,r,bugtype,getConfigOption):
- return getConfigOption(r.getName(),self.getName())
- def saveConfigValue(self):
- return True
-
-class TextParameter (ReporterParameter):
- def getHTML(self,r,bugtype,getConfigOption):
- return """\
-<tr>
-<td class="form_clabel">%s:</td>
-<td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
-</tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption))
-
-class SelectionParameter (ReporterParameter):
- def __init__(self, n, values):
- ReporterParameter.__init__(self,n)
- self.values = values
-
- def getHTML(self,r,bugtype,getConfigOption):
- default = self.getValue(r,bugtype,getConfigOption)
- return """\
-<tr>
-<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
-%s
-</select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\
-<option value="%s"%s>%s</option>"""%(o[0],
- o[0] == default and ' selected="selected"' or '',
- o[1]) for o in self.values]))
-
-#===------------------------------------------------------------------------===#
-# Reporters
-#===------------------------------------------------------------------------===#
-
-class EmailReporter:
- def getName(self):
- return 'Email'
-
- def getParameters(self):
- return map(lambda x:TextParameter(x),['To', 'From', 'SMTP Server', 'SMTP Port'])
-
- # Lifted from python email module examples.
- def attachFile(self, outer, path):
- # Guess the content type based on the file's extension. Encoding
- # will be ignored, although we should check for simple things like
- # gzip'd or compressed files.
- ctype, encoding = mimetypes.guess_type(path)
- if ctype is None or encoding is not None:
- # No guess could be made, or the file is encoded (compressed), so
- # use a generic bag-of-bits type.
- ctype = 'application/octet-stream'
- maintype, subtype = ctype.split('/', 1)
- if maintype == 'text':
- fp = open(path)
- # Note: we should handle calculating the charset
- msg = MIMEText(fp.read(), _subtype=subtype)
- fp.close()
- else:
- fp = open(path, 'rb')
- msg = MIMEBase(maintype, subtype)
- msg.set_payload(fp.read())
- fp.close()
- # Encode the payload using Base64
- encoders.encode_base64(msg)
- # Set the filename parameter
- msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
- outer.attach(msg)
-
- def fileReport(self, report, parameters):
- mainMsg = """\
-BUG REPORT
----
-Title: %s
-Description: %s
-"""%(report.title, report.description)
-
- if not parameters.get('To'):
- raise ReportFailure('No "To" address specified.')
- if not parameters.get('From'):
- raise ReportFailure('No "From" address specified.')
-
- msg = MIMEMultipart()
- msg['Subject'] = 'BUG REPORT: %s'%(report.title)
- # FIXME: Get config parameters
- msg['To'] = parameters.get('To')
- msg['From'] = parameters.get('From')
- msg.preamble = mainMsg
-
- msg.attach(MIMEText(mainMsg, _subtype='text/plain'))
- for file in report.files:
- self.attachFile(msg, file)
-
- try:
- s = smtplib.SMTP(host=parameters.get('SMTP Server'),
- port=parameters.get('SMTP Port'))
- s.sendmail(msg['From'], msg['To'], msg.as_string())
- s.close()
- except:
- raise ReportFailure('Unable to send message via SMTP.')
-
- return "Message sent!"
-
-class BugzillaReporter:
- def getName(self):
- return 'Bugzilla'
-
- def getParameters(self):
- return map(lambda x:TextParameter(x),['URL','Product'])
-
- def fileReport(self, report, parameters):
- raise NotImplementedError
-
-
-class RadarClassificationParameter(SelectionParameter):
- def __init__(self):
- SelectionParameter.__init__(self,"Classification",
- [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'],
- ['3', 'Performance'], ['4', 'UI/Usability'],
- ['6', 'Serious Bug'], ['7', 'Other']])
-
- def saveConfigValue(self):
- return False
-
- def getValue(self,r,bugtype,getConfigOption):
- if bugtype.startswith("leak"):
- return '3'
- else:
- return '7'
-
-class RadarReporter:
- @staticmethod
- def isAvailable():
- # FIXME: Find this .scpt better
- path = os.path.join(os.path.dirname(__file__),'Resources/GetRadarVersion.scpt')
- try:
- p = subprocess.Popen(['osascript',path],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- except:
- return False
- data,err = p.communicate()
- res = p.wait()
- # FIXME: Check version? Check for no errors?
- return res == 0
-
- def getName(self):
- return 'Radar'
-
- def getParameters(self):
- return [ TextParameter('Component'), TextParameter('Component Version'),
- RadarClassificationParameter() ]
-
- def fileReport(self, report, parameters):
- component = parameters.get('Component', '')
- componentVersion = parameters.get('Component Version', '')
- classification = parameters.get('Classification', '')
- personID = ""
- diagnosis = ""
- config = ""
-
- if not component.strip():
- component = 'Bugs found by clang Analyzer'
- if not componentVersion.strip():
- componentVersion = 'X'
-
- script = os.path.join(os.path.dirname(__file__),'Resources/FileRadar.scpt')
- args = ['osascript', script, component, componentVersion, classification, personID, report.title,
- report.description, diagnosis, config] + map(os.path.abspath, report.files)
-# print >>sys.stderr, args
- try:
- p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- except:
- raise ReportFailure("Unable to file radar (AppleScript failure).")
- data, err = p.communicate()
- res = p.wait()
-
- if res:
- raise ReportFailure("Unable to file radar (AppleScript failure).")
-
- try:
- values = eval(data)
- except:
- raise ReportFailure("Unable to process radar results.")
-
- # We expect (int: bugID, str: message)
- if len(values) != 2 or not isinstance(values[0], int):
- raise ReportFailure("Unable to process radar results.")
-
- bugID,message = values
- bugID = int(bugID)
-
- if not bugID:
- raise ReportFailure(message)
-
- return "Filed: <a href=\"rdar://%d/\">%d</a>"%(bugID,bugID)
-
-###
-
-def getReporters():
- reporters = []
- if RadarReporter.isAvailable():
- reporters.append(RadarReporter())
- reporters.append(EmailReporter())
- return reporters
-
diff --git a/clang/tools/scan-view/Resources/FileRadar.scpt b/clang/tools/scan-view/Resources/FileRadar.scpt
deleted file mode 100644
index eaccdf506bc1..000000000000
--- a/clang/tools/scan-view/Resources/FileRadar.scpt
+++ /dev/null
Binary files differ
diff --git a/clang/tools/scan-view/Resources/GetRadarVersion.scpt b/clang/tools/scan-view/Resources/GetRadarVersion.scpt
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/clang/tools/scan-view/Resources/GetRadarVersion.scpt
+++ /dev/null
diff --git a/clang/tools/scan-view/Resources/bugcatcher.ico b/clang/tools/scan-view/Resources/bugcatcher.ico
deleted file mode 100644
index 22d39b592036..000000000000
--- a/clang/tools/scan-view/Resources/bugcatcher.ico
+++ /dev/null
Binary files differ
diff --git a/clang/tools/scan-view/ScanView.py b/clang/tools/scan-view/ScanView.py
deleted file mode 100644
index 837adae0f763..000000000000
--- a/clang/tools/scan-view/ScanView.py
+++ /dev/null
@@ -1,770 +0,0 @@
-import BaseHTTPServer
-import SimpleHTTPServer
-import os
-import sys
-import urllib, urlparse
-import posixpath
-import StringIO
-import re
-import shutil
-import threading
-import time
-import socket
-import itertools
-
-import Reporter
-import ConfigParser
-
-###
-# Various patterns matched or replaced by server.
-
-kReportFileRE = re.compile('(.*/)?report-(.*)\\.html')
-
-kBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->')
-
-# <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" -->
-
-kReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->')
-kReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"')
-
-kReportReplacements = []
-
-# Add custom javascript.
-kReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\
-<script language="javascript" type="text/javascript">
-function load(url) {
- if (window.XMLHttpRequest) {
- req = new XMLHttpRequest();
- } else if (window.ActiveXObject) {
- req = new ActiveXObject("Microsoft.XMLHTTP");
- }
- if (req != undefined) {
- req.open("GET", url, true);
- req.send("");
- }
-}
-</script>"""))
-
-# Insert additional columns.
-kReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'),
- '<td></td><td></td>'))
-
-# Insert report bug and open file links.
-kReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'),
- ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' +
- '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>')))
-
-kReportReplacements.append((re.compile('<!-- REPORTHEADER -->'),
- '<h3><a href="/">Summary</a> > Report %(report)s</h3>'))
-
-kReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'),
- '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>'))
-
-# Insert report crashes link.
-
-# Disabled for the time being until we decide exactly when this should
-# be enabled. Also the radar reporter needs to be fixed to report
-# multiple files.
-
-#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'),
-# '<br>These files will automatically be attached to ' +
-# 'reports filed here: <a href="report_crashes">Report Crashes</a>.'))
-
-###
-# Other simple parameters
-
-kResources = posixpath.join(posixpath.dirname(__file__), 'Resources')
-kConfigPath = os.path.expanduser('~/.scanview.cfg')
-
-###
-
-__version__ = "0.1"
-
-__all__ = ["create_server"]
-
-class ReporterThread(threading.Thread):
- def __init__(self, report, reporter, parameters, server):
- threading.Thread.__init__(self)
- self.report = report
- self.server = server
- self.reporter = reporter
- self.parameters = parameters
- self.success = False
- self.status = None
-
- def run(self):
- result = None
- try:
- if self.server.options.debug:
- print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],)
- self.status = self.reporter.fileReport(self.report, self.parameters)
- self.success = True
- time.sleep(3)
- if self.server.options.debug:
- print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],)
- except Reporter.ReportFailure,e:
- self.status = e.value
- except Exception,e:
- s = StringIO.StringIO()
- import traceback
- print >>s,'<b>Unhandled Exception</b><br><pre>'
- traceback.print_exc(e,file=s)
- print >>s,'</pre>'
- self.status = s.getvalue()
-
-class ScanViewServer(BaseHTTPServer.HTTPServer):
- def __init__(self, address, handler, root, reporters, options):
- BaseHTTPServer.HTTPServer.__init__(self, address, handler)
- self.root = root
- self.reporters = reporters
- self.options = options
- self.halted = False
- self.config = None
- self.load_config()
-
- def load_config(self):
- self.config = ConfigParser.RawConfigParser()
-
- # Add defaults
- self.config.add_section('ScanView')
- for r in self.reporters:
- self.config.add_section(r.getName())
- for p in r.getParameters():
- if p.saveConfigValue():
- self.config.set(r.getName(), p.getName(), '')
-
- # Ignore parse errors
- try:
- self.config.read([kConfigPath])
- except:
- pass
-
- # Save on exit
- import atexit
- atexit.register(lambda: self.save_config())
-
- def save_config(self):
- # Ignore errors (only called on exit).
- try:
- f = open(kConfigPath,'w')
- self.config.write(f)
- f.close()
- except:
- pass
-
- def halt(self):
- self.halted = True
- if self.options.debug:
- print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],)
-
- def serve_forever(self):
- while not self.halted:
- if self.options.debug > 1:
- print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],)
- try:
- self.handle_request()
- except OSError,e:
- print 'OSError',e.errno
-
- def finish_request(self, request, client_address):
- if self.options.autoReload:
- import ScanView
- self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler
- BaseHTTPServer.HTTPServer.finish_request(self, request, client_address)
-
- def handle_error(self, request, client_address):
- # Ignore socket errors
- info = sys.exc_info()
- if info and isinstance(info[1], socket.error):
- if self.options.debug > 1:
- print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],)
- return
- BaseHTTPServer.HTTPServer.handle_error(self, request, client_address)
-
-# Borrowed from Quixote, with simplifications.
-def parse_query(qs, fields=None):
- if fields is None:
- fields = {}
- for chunk in filter(None, qs.split('&')):
- if '=' not in chunk:
- name = chunk
- value = ''
- else:
- name, value = chunk.split('=', 1)
- name = urllib.unquote(name.replace('+', ' '))
- value = urllib.unquote(value.replace('+', ' '))
- item = fields.get(name)
- if item is None:
- fields[name] = [value]
- else:
- item.append(value)
- return fields
-
-class ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
- server_version = "ScanViewServer/" + __version__
- dynamic_mtime = time.time()
-
- def do_HEAD(self):
- try:
- SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self)
- except Exception,e:
- self.handle_exception(e)
-
- def do_GET(self):
- try:
- SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
- except Exception,e:
- self.handle_exception(e)
-
- def do_POST(self):
- """Serve a POST request."""
- try:
- length = self.headers.getheader('content-length') or "0"
- try:
- length = int(length)
- except:
- length = 0
- content = self.rfile.read(length)
- fields = parse_query(content)
- f = self.send_head(fields)
- if f:
- self.copyfile(f, self.wfile)
- f.close()
- except Exception,e:
- self.handle_exception(e)
-
- def log_message(self, format, *args):
- if self.server.options.debug:
- sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" %
- (sys.argv[0],
- self.address_string(),
- self.log_date_time_string(),
- format%args))
-
- def load_report(self, report):
- path = os.path.join(self.server.root, 'report-%s.html'%report)
- data = open(path).read()
- keys = {}
- for item in kBugKeyValueRE.finditer(data):
- k,v = item.groups()
- keys[k] = v
- return keys
-
- def load_crashes(self):
- path = posixpath.join(self.server.root, 'index.html')
- data = open(path).read()
- problems = []
- for item in kReportCrashEntryRE.finditer(data):
- fieldData = item.group(1)
- fields = dict([i.groups() for i in
- kReportCrashEntryKeyValueRE.finditer(fieldData)])
- problems.append(fields)
- return problems
-
- def handle_exception(self, exc):
- import traceback
- s = StringIO.StringIO()
- print >>s, "INTERNAL ERROR\n"
- traceback.print_exc(exc, s)
- f = self.send_string(s.getvalue(), 'text/plain')
- if f:
- self.copyfile(f, self.wfile)
- f.close()
-
- def get_scalar_field(self, name):
- if name in self.fields:
- return self.fields[name][0]
- else:
- return None
-
- def submit_bug(self, c):
- title = self.get_scalar_field('title')
- description = self.get_scalar_field('description')
- report = self.get_scalar_field('report')
- reporterIndex = self.get_scalar_field('reporter')
- files = []
- for fileID in self.fields.get('files',[]):
- try:
- i = int(fileID)
- except:
- i = None
- if i is None or i<0 or i>=len(c.files):
- return (False, 'Invalid file ID')
- files.append(c.files[i])
-
- if not title:
- return (False, "Missing title.")
- if not description:
- return (False, "Missing description.")
- try:
- reporterIndex = int(reporterIndex)
- except:
- return (False, "Invalid report method.")
-
- # Get the reporter and parameters.
- reporter = self.server.reporters[reporterIndex]
- parameters = {}
- for o in reporter.getParameters():
- name = '%s_%s'%(reporter.getName(),o.getName())
- if name not in self.fields:
- return (False,
- 'Missing field "%s" for %s report method.'%(name,
- reporter.getName()))
- parameters[o.getName()] = self.get_scalar_field(name)
-
- # Update config defaults.
- if report != 'None':
- self.server.config.set('ScanView', 'reporter', reporterIndex)
- for o in reporter.getParameters():
- if o.saveConfigValue():
- name = o.getName()
- self.server.config.set(reporter.getName(), name, parameters[name])
-
- # Create the report.
- bug = Reporter.BugReport(title, description, files)
-
- # Kick off a reporting thread.
- t = ReporterThread(bug, reporter, parameters, self.server)
- t.start()
-
- # Wait for thread to die...
- while t.isAlive():
- time.sleep(.25)
- submitStatus = t.status
-
- return (t.success, t.status)
-
- def send_report_submit(self):
- report = self.get_scalar_field('report')
- c = self.get_report_context(report)
- if c.reportSource is None:
- reportingFor = "Report Crashes > "
- fileBug = """\
-<a href="/report_crashes">File Bug</a> > """%locals()
- else:
- reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource,
- report)
- fileBug = '<a href="/report/%s">File Bug</a> > ' % report
- title = self.get_scalar_field('title')
- description = self.get_scalar_field('description')
-
- res,message = self.submit_bug(c)
-
- if res:
- statusClass = 'SubmitOk'
- statusName = 'Succeeded'
- else:
- statusClass = 'SubmitFail'
- statusName = 'Failed'
-
- result = """
-<head>
- <title>Bug Submission</title>
- <link rel="stylesheet" type="text/css" href="/scanview.css" />
-</head>
-<body>
-<h3>
-<a href="/">Summary</a> >
-%(reportingFor)s
-%(fileBug)s
-Submit</h3>
-<form name="form" action="">
-<table class="form">
-<tr><td>
-<table class="form_group">
-<tr>
- <td class="form_clabel">Title:</td>
- <td class="form_value">
- <input type="text" name="title" size="50" value="%(title)s" disabled>
- </td>
-</tr>
-<tr>
- <td class="form_label">Description:</td>
- <td class="form_value">
-<textarea rows="10" cols="80" name="description" disabled>
-%(description)s
-</textarea>
- </td>
-</table>
-</td></tr>
-</table>
-</form>
-<h1 class="%(statusClass)s">Submission %(statusName)s</h1>
-%(message)s
-<p>
-<hr>
-<a href="/">Return to Summary</a>
-</body>
-</html>"""%locals()
- return self.send_string(result)
-
- def send_open_report(self, report):
- try:
- keys = self.load_report(report)
- except IOError:
- return self.send_error(400, 'Invalid report.')
-
- file = keys.get('FILE')
- if not file or not posixpath.exists(file):
- return self.send_error(400, 'File does not exist: "%s"' % file)
-
- import startfile
- if self.server.options.debug:
- print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0],
- file)
-
- status = startfile.open(file)
- if status:
- res = 'Opened: "%s"' % file
- else:
- res = 'Open failed: "%s"' % file
-
- return self.send_string(res, 'text/plain')
-
- def get_report_context(self, report):
- class Context:
- pass
- if report is None or report == 'None':
- data = self.load_crashes()
- # Don't allow empty reports.
- if not data:
- raise ValueError, 'No crashes detected!'
- c = Context()
- c.title = 'clang static analyzer failures'
-
- stderrSummary = ""
- for item in data:
- if 'stderr' in item:
- path = posixpath.join(self.server.root, item['stderr'])
- if os.path.exists(path):
- lns = itertools.islice(open(path), 0, 10)
- stderrSummary += '%s\n--\n%s' % (item.get('src',
- '<unknown>'),
- ''.join(lns))
-
- c.description = """\
-The clang static analyzer failed on these inputs:
-%s
-
-STDERR Summary
---------------
-%s
-""" % ('\n'.join([item.get('src','<unknown>') for item in data]),
- stderrSummary)
- c.reportSource = None
- c.navMarkup = "Report Crashes > "
- c.files = []
- for item in data:
- c.files.append(item.get('src',''))
- c.files.append(posixpath.join(self.server.root,
- item.get('file','')))
- c.files.append(posixpath.join(self.server.root,
- item.get('clangfile','')))
- c.files.append(posixpath.join(self.server.root,
- item.get('stderr','')))
- c.files.append(posixpath.join(self.server.root,
- item.get('info','')))
- # Just in case something failed, ignore files which don't
- # exist.
- c.files = [f for f in c.files
- if os.path.exists(f) and os.path.isfile(f)]
- else:
- # Check that this is a valid report.
- path = posixpath.join(self.server.root, 'report-%s.html' % report)
- if not posixpath.exists(path):
- raise ValueError, 'Invalid report ID'
- keys = self.load_report(report)
- c = Context()
- c.title = keys.get('DESC','clang error (unrecognized')
- c.description = """\
-Bug reported by the clang static analyzer.
-
-Description: %s
-File: %s
-Line: %s
-"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>'))
- c.reportSource = 'report-%s.html' % report
- c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource,
- report)
-
- c.files = [path]
- return c
-
- def send_report(self, report, configOverrides=None):
- def getConfigOption(section, field):
- if (configOverrides is not None and
- section in configOverrides and
- field in configOverrides[section]):
- return configOverrides[section][field]
- return self.server.config.get(section, field)
-
- # report is None is used for crashes
- try:
- c = self.get_report_context(report)
- except ValueError, e:
- return self.send_error(400, e.message)
-
- title = c.title
- description= c.description
- reportingFor = c.navMarkup
- if c.reportSource is None:
- extraIFrame = ""
- else:
- extraIFrame = """\
-<iframe src="/%s" width="100%%" height="40%%"
- scrolling="auto" frameborder="1">
- <a href="/%s">View Bug Report</a>
-</iframe>""" % (c.reportSource, c.reportSource)
-
- reporterSelections = []
- reporterOptions = []
-
- try:
- active = int(getConfigOption('ScanView','reporter'))
- except:
- active = 0
- for i,r in enumerate(self.server.reporters):
- selected = (i == active)
- if selected:
- selectedStr = ' selected'
- else:
- selectedStr = ''
- reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName()))
- options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()])
- display = ('none','')[selected]
- reporterOptions.append("""\
-<tr id="%sReporterOptions" style="display:%s">
- <td class="form_label">%s Options</td>
- <td class="form_value">
- <table class="form_inner_group">
-%s
- </table>
- </td>
-</tr>
-"""%(r.getName(),display,r.getName(),options))
- reporterSelections = '\n'.join(reporterSelections)
- reporterOptionsDivs = '\n'.join(reporterOptions)
- reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters]))
-
- if c.files:
- fieldSize = min(5, len(c.files))
- attachFileOptions = '\n'.join(["""\
-<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)])
- attachFileRow = """\
-<tr>
- <td class="form_label">Attach:</td>
- <td class="form_value">
-<select style="width:100%%" name="files" multiple size=%d>
-%s
-</select>
- </td>
-</tr>
-""" % (min(5, len(c.files)), attachFileOptions)
- else:
- attachFileRow = ""
-
- result = """<html>
-<head>
- <title>File Bug</title>
- <link rel="stylesheet" type="text/css" href="/scanview.css" />
-</head>
-<script language="javascript" type="text/javascript">
-var reporters = %(reportersArray)s;
-function updateReporterOptions() {
- index = document.getElementById('reporter').selectedIndex;
- for (var i=0; i < reporters.length; ++i) {
- o = document.getElementById(reporters[i] + "ReporterOptions");
- if (i == index) {
- o.style.display = "";
- } else {
- o.style.display = "none";
- }
- }
-}
-</script>
-<body onLoad="updateReporterOptions()">
-<h3>
-<a href="/">Summary</a> >
-%(reportingFor)s
-File Bug</h3>
-<form name="form" action="/report_submit" method="post">
-<input type="hidden" name="report" value="%(report)s">
-
-<table class="form">
-<tr><td>
-<table class="form_group">
-<tr>
- <td class="form_clabel">Title:</td>
- <td class="form_value">
- <input type="text" name="title" size="50" value="%(title)s">
- </td>
-</tr>
-<tr>
- <td class="form_label">Description:</td>
- <td class="form_value">
-<textarea rows="10" cols="80" name="description">
-%(description)s
-</textarea>
- </td>
-</tr>
-
-%(attachFileRow)s
-
-</table>
-<br>
-<table class="form_group">
-<tr>
- <td class="form_clabel">Method:</td>
- <td class="form_value">
- <select id="reporter" name="reporter" onChange="updateReporterOptions()">
- %(reporterSelections)s
- </select>
- </td>
-</tr>
-%(reporterOptionsDivs)s
-</table>
-<br>
-</td></tr>
-<tr><td class="form_submit">
- <input align="right" type="submit" name="Submit" value="Submit">
-</td></tr>
-</table>
-</form>
-
-%(extraIFrame)s
-
-</body>
-</html>"""%locals()
-
- return self.send_string(result)
-
- def send_head(self, fields=None):
- if (self.server.options.onlyServeLocal and
- self.client_address[0] != '127.0.0.1'):
- return self.send_error('401', 'Unauthorized host.')
-
- if fields is None:
- fields = {}
- self.fields = fields
-
- o = urlparse.urlparse(self.path)
- self.fields = parse_query(o.query, fields)
- path = posixpath.normpath(urllib.unquote(o.path))
-
- # Split the components and strip the root prefix.
- components = path.split('/')[1:]
-
- # Special case some top-level entries.
- if components:
- name = components[0]
- if len(components)==2:
- if name=='report':
- return self.send_report(components[1])
- elif name=='open':
- return self.send_open_report(components[1])
- elif len(components)==1:
- if name=='quit':
- self.server.halt()
- return self.send_string('Goodbye.', 'text/plain')
- elif name=='report_submit':
- return self.send_report_submit()
- elif name=='report_crashes':
- overrides = { 'ScanView' : {},
- 'Radar' : {},
- 'Email' : {} }
- for i,r in enumerate(self.server.reporters):
- if r.getName() == 'Radar':
- overrides['ScanView']['reporter'] = i
- break
- overrides['Radar']['Component'] = 'llvm - checker'
- overrides['Radar']['Component Version'] = 'X'
- return self.send_report(None, overrides)
- elif name=='favicon.ico':
- return self.send_path(posixpath.join(kResources,'bugcatcher.ico'))
-
- # Match directory entries.
- if components[-1] == '':
- components[-1] = 'index.html'
-
- suffix = '/'.join(components)
-
- # The summary may reference source files on disk using rooted
- # paths. Make sure these resolve correctly for now.
- # FIXME: This isn't a very good idea... we should probably
- # mark rooted paths somehow.
- if os.path.exists(posixpath.join('/', suffix)):
- path = posixpath.join('/', suffix)
- else:
- path = posixpath.join(self.server.root, suffix)
-
- if self.server.options.debug > 1:
- print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0],
- path)
- return self.send_path(path)
-
- def send_404(self):
- self.send_error(404, "File not found")
- return None
-
- def send_path(self, path):
- ctype = self.guess_type(path)
- if ctype.startswith('text/'):
- # Patch file instead
- return self.send_patched_file(path, ctype)
- else:
- mode = 'rb'
- try:
- f = open(path, mode)
- except IOError:
- return self.send_404()
- return self.send_file(f, ctype)
-
- def send_file(self, f, ctype):
- # Patch files to add links, but skip binary files.
- self.send_response(200)
- self.send_header("Content-type", ctype)
- fs = os.fstat(f.fileno())
- self.send_header("Content-Length", str(fs[6]))
- self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
- self.end_headers()
- return f
-
- def send_string(self, s, ctype='text/html', headers=True, mtime=None):
- if headers:
- self.send_response(200)
- self.send_header("Content-type", ctype)
- self.send_header("Content-Length", str(len(s)))
- if mtime is None:
- mtime = self.dynamic_mtime
- self.send_header("Last-Modified", self.date_time_string(mtime))
- self.end_headers()
- return StringIO.StringIO(s)
-
- def send_patched_file(self, path, ctype):
- # Allow a very limited set of variables. This is pretty gross.
- variables = {}
- variables['report'] = ''
- m = kReportFileRE.match(path)
- if m:
- variables['report'] = m.group(2)
-
- try:
- f = open(path,'r')
- except IOError:
- return self.send_404()
- fs = os.fstat(f.fileno())
- data = f.read()
- for a,b in kReportReplacements:
- data = a.sub(b % variables, data)
- return self.send_string(data, ctype, mtime=fs.st_mtime)
-
-
-def create_server(address, options, root):
- import Reporter
-
- reporters = Reporter.getReporters()
-
- return ScanViewServer(address, ScanViewRequestHandler,
- root,
- reporters,
- options)
diff --git a/clang/tools/scan-view/scan-view b/clang/tools/scan-view/scan-view
deleted file mode 100755
index 06197465e6d2..000000000000
--- a/clang/tools/scan-view/scan-view
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env python
-
-"""The clang static analyzer results viewer.
-"""
-
-import sys
-import posixpath
-import thread
-import time
-import urllib
-import webbrowser
-
-# How long to wait for server to start.
-kSleepTimeout = .05
-kMaxSleeps = 100
-
-# Default server parameters
-
-kDefaultHost = '127.0.0.1'
-kDefaultPort = 8181
-kMaxPortsToTry = 100
-
-###
-
-def url_is_up(url):
- try:
- o = urllib.urlopen(url)
- except IOError:
- return False
- o.close()
- return True
-
-def start_browser(port, options):
- import urllib, webbrowser
-
- url = 'http://%s:%d'%(options.host, port)
-
- # Wait for server to start...
- if options.debug:
- sys.stderr.write('%s: Waiting for server.' % sys.argv[0])
- sys.stderr.flush()
- for i in range(kMaxSleeps):
- if url_is_up(url):
- break
- if options.debug:
- sys.stderr.write('.')
- sys.stderr.flush()
- time.sleep(kSleepTimeout)
- else:
- print >>sys.stderr,'WARNING: Unable to detect that server started.'
-
- if options.debug:
- print >>sys.stderr,'%s: Starting webbrowser...' % sys.argv[0]
- webbrowser.open(url)
-
-def run(port, options, root):
- import ScanView
- try:
- print 'Starting scan-view at: http://%s:%d'%(options.host,
- port)
- print ' Use Ctrl-C to exit.'
- httpd = ScanView.create_server((options.host, port),
- options, root)
- httpd.serve_forever()
- except KeyboardInterrupt:
- pass
-
-def port_is_open(port):
- import SocketServer
- try:
- t = SocketServer.TCPServer((kDefaultHost,port),None)
- except:
- return False
- t.server_close()
- return True
-
-def main():
- from optparse import OptionParser
- parser = OptionParser('usage: %prog [options] <results directory>')
- parser.set_description(__doc__)
- parser.add_option(
- '--host', dest="host", default=kDefaultHost, type="string",
- help="Host interface to listen on. (default=%s)" % kDefaultHost)
- parser.add_option(
- '--port', dest="port", default=None, type="int",
- help="Port to listen on. (default=%s)" % kDefaultPort)
- parser.add_option("--debug", dest="debug", default=0,
- action="count",
- help="Print additional debugging information.")
- parser.add_option("--auto-reload", dest="autoReload", default=False,
- action="store_true",
- help="Automatically update module for each request.")
- parser.add_option("--no-browser", dest="startBrowser", default=True,
- action="store_false",
- help="Don't open a webbrowser on startup.")
- parser.add_option("--allow-all-hosts", dest="onlyServeLocal", default=True,
- action="store_false",
- help='Allow connections from any host (access restricted to "127.0.0.1" by default)')
- (options, args) = parser.parse_args()
-
- if len(args) != 1:
- parser.error('No results directory specified.')
- root, = args
-
- # Make sure this directory is in a reasonable state to view.
- if not posixpath.exists(posixpath.join(root,'index.html')):
- parser.error('Invalid directory, analysis results not found!')
-
- # Find an open port. We aren't particularly worried about race
- # conditions here. Note that if the user specified a port we only
- # use that one.
- if options.port is not None:
- port = options.port
- else:
- for i in range(kMaxPortsToTry):
- if port_is_open(kDefaultPort + i):
- port = kDefaultPort + i
- break
- else:
- parser.error('Unable to find usable port in [%d,%d)'%(kDefaultPort,
- kDefaultPort+kMaxPortsToTry))
-
- # Kick off thread to wait for server and start web browser, if
- # requested.
- if options.startBrowser:
- t = thread.start_new_thread(start_browser, (port,options))
-
- run(port, options, root)
-
-if __name__ == '__main__':
- main()
diff --git a/clang/tools/scan-view/startfile.py b/clang/tools/scan-view/startfile.py
deleted file mode 100644
index e8fbe2d5a84e..000000000000
--- a/clang/tools/scan-view/startfile.py
+++ /dev/null
@@ -1,203 +0,0 @@
-"""Utility for opening a file using the default application in a cross-platform
-manner. Modified from http://code.activestate.com/recipes/511443/.
-"""
-
-__version__ = '1.1x'
-__all__ = ['open']
-
-import os
-import sys
-import webbrowser
-import subprocess
-
-_controllers = {}
-_open = None
-
-
-class BaseController(object):
- '''Base class for open program controllers.'''
-
- def __init__(self, name):
- self.name = name
-
- def open(self, filename):
- raise NotImplementedError
-
-
-class Controller(BaseController):
- '''Controller for a generic open program.'''
-
- def __init__(self, *args):
- super(Controller, self).__init__(os.path.basename(args[0]))
- self.args = list(args)
-
- def _invoke(self, cmdline):
- if sys.platform[:3] == 'win':
- closefds = False
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- else:
- closefds = True
- startupinfo = None
-
- if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or
- sys.platform == 'darwin'):
- inout = file(os.devnull, 'r+')
- else:
- # for TTY programs, we need stdin/out
- inout = None
-
- # if possible, put the child precess in separate process group,
- # so keyboard interrupts don't affect child precess as well as
- # Python
- setsid = getattr(os, 'setsid', None)
- if not setsid:
- setsid = getattr(os, 'setpgrp', None)
-
- pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout,
- stderr=inout, close_fds=closefds,
- preexec_fn=setsid, startupinfo=startupinfo)
-
- # It is assumed that this kind of tools (gnome-open, kfmclient,
- # exo-open, xdg-open and open for OSX) immediately exit after lauching
- # the specific application
- returncode = pipe.wait()
- if hasattr(self, 'fixreturncode'):
- returncode = self.fixreturncode(returncode)
- return not returncode
-
- def open(self, filename):
- if isinstance(filename, basestring):
- cmdline = self.args + [filename]
- else:
- # assume it is a sequence
- cmdline = self.args + filename
- try:
- return self._invoke(cmdline)
- except OSError:
- return False
-
-
-# Platform support for Windows
-if sys.platform[:3] == 'win':
-
- class Start(BaseController):
- '''Controller for the win32 start progam through os.startfile.'''
-
- def open(self, filename):
- try:
- os.startfile(filename)
- except WindowsError:
- # [Error 22] No application is associated with the specified
- # file for this operation: '<URL>'
- return False
- else:
- return True
-
- _controllers['windows-default'] = Start('start')
- _open = _controllers['windows-default'].open
-
-
-# Platform support for MacOS
-elif sys.platform == 'darwin':
- _controllers['open']= Controller('open')
- _open = _controllers['open'].open
-
-
-# Platform support for Unix
-else:
-
- import commands
-
- # @WARNING: use the private API of the webbrowser module
- from webbrowser import _iscommand
-
- class KfmClient(Controller):
- '''Controller for the KDE kfmclient program.'''
-
- def __init__(self, kfmclient='kfmclient'):
- super(KfmClient, self).__init__(kfmclient, 'exec')
- self.kde_version = self.detect_kde_version()
-
- def detect_kde_version(self):
- kde_version = None
- try:
- info = commands.getoutput('kde-config --version')
-
- for line in info.splitlines():
- if line.startswith('KDE'):
- kde_version = line.split(':')[-1].strip()
- break
- except (OSError, RuntimeError):
- pass
-
- return kde_version
-
- def fixreturncode(self, returncode):
- if returncode is not None and self.kde_version > '3.5.4':
- return returncode
- else:
- return os.EX_OK
-
- def detect_desktop_environment():
- '''Checks for known desktop environments
-
- Return the desktop environments name, lowercase (kde, gnome, xfce)
- or "generic"
-
- '''
-
- desktop_environment = 'generic'
-
- if os.environ.get('KDE_FULL_SESSION') == 'true':
- desktop_environment = 'kde'
- elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
- desktop_environment = 'gnome'
- else:
- try:
- info = commands.getoutput('xprop -root _DT_SAVE_MODE')
- if ' = "xfce4"' in info:
- desktop_environment = 'xfce'
- except (OSError, RuntimeError):
- pass
-
- return desktop_environment
-
-
- def register_X_controllers():
- if _iscommand('kfmclient'):
- _controllers['kde-open'] = KfmClient()
-
- for command in ('gnome-open', 'exo-open', 'xdg-open'):
- if _iscommand(command):
- _controllers[command] = Controller(command)
-
- def get():
- controllers_map = {
- 'gnome': 'gnome-open',
- 'kde': 'kde-open',
- 'xfce': 'exo-open',
- }
-
- desktop_environment = detect_desktop_environment()
-
- try:
- controller_name = controllers_map[desktop_environment]
- return _controllers[controller_name].open
-
- except KeyError:
- if _controllers.has_key('xdg-open'):
- return _controllers['xdg-open'].open
- else:
- return webbrowser.open
-
-
- if os.environ.get("DISPLAY"):
- register_X_controllers()
- _open = get()
-
-
-def open(filename):
- '''Open a file or an URL in the registered default application.'''
-
- return _open(filename)
diff --git a/clang/utils/CheckBuiltinMacros.sh b/clang/utils/CheckBuiltinMacros.sh
deleted file mode 100755
index 6a8573c0c146..000000000000
--- a/clang/utils/CheckBuiltinMacros.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-set -ex
-
-if [ -z "$CC" ]; then
- CC="gcc"
-fi
-
-SRCLANG=c
-MACROLIST=macro-list.txt
-CCDEFS=cc-definitions.txt
-CLANGDEFS=clang-definitions.txt
-
-# Gather list of macros as "NAME" = NAME.
-$CC -dM -E -x $SRCLANG /dev/null -o - | \
-grep "#define" | sort -f | sed -e "s/#define \([^ ]*\) .*/\"\1\" = \1/" > $MACROLIST
-
-$CC -E -x $SRCLANG $MACROLIST > $CCDEFS
-
-clang -E -x $SRCLANG $MACROLIST > $CLANGDEFS
-
-diff $CCDEFS $CLANGDEFS
-
-
diff --git a/clang/utils/FindSpecRefs b/clang/utils/FindSpecRefs
deleted file mode 100755
index a537fe1f843d..000000000000
--- a/clang/utils/FindSpecRefs
+++ /dev/null
@@ -1,885 +0,0 @@
-#!/usr/bin/python
-
-import os
-import re
-import time
-from pprint import pprint
-
-###
-
-c99URL = 'http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf'
-c99TOC = [('Foreword', 'xi'),
-('Introduction', 'xiv'),
-('1. Scope', '1'),
-('2. Normative references', '2'),
-('3. Terms, definitions, and symbols', '3'),
-('4. Conformance', '7'),
-('5. Environment', '9'),
-('5.1 Conceptual models', '9'),
-('5.1.1 Translation environment', '9'),
-('5.1.2 Execution environments', '11'),
-('5.2 Environmental considerations', '17'),
-('5.2.1 Character sets', '17'),
-('5.2.2 Character display semantics', '19'),
-('5.2.3 Signals and interrupts', '20'),
-('5.2.4 Environmental limits', '20'),
-('6. Language', '29'),
-('6.1 Notation', '29'),
-('6.2 Concepts', '29'),
-('6.2.1 Scopes of identifiers', '29'),
-('6.2.2 Linkages of identifiers', '30'),
-('6.2.3 Name spaces of identifiers', '31'),
-('6.2.4 Storage durations of objects', '32'),
-('6.2.5 Types', '33'),
-('6.2.6 Representations of types', '37'),
-('6.2.7 Compatible type and composite type', '40'),
-('6.3 Conversions', '42'),
-('6.3.1 Arithmetic operands', '42'),
-('6.3.2 Other operands', '46'),
-('6.4 Lexical elements', '49'),
-('6.4.1 Keywords', '50'),
-('6.4.2 Identifiers', '51'),
-('6.4.3 Universal character names', '53'),
-('6.4.4 Constants', '54'),
-('6.4.5 String literals', '62'),
-('6.4.6 Punctuators', '63'),
-('6.4.7 Header names', '64'),
-('6.4.8 Preprocessing numbers', '65'),
-('6.4.9 Comments', '66'),
-('6.5 Expressions', '67'),
-('6.5.1 Primary expressions', '69'),
-('6.5.2 Postfix operators', '69'),
-('6.5.3 Unary operators', '78'),
-('6.5.4 Cast operators', '81'),
-('6.5.5 Multiplicative operators', '82'),
-('6.5.6 Additive operators', '82'),
-('6.5.7 Bitwise shift operators', '84'),
-('6.5.8 Relational operators', '85'),
-('6.5.9 Equality operators', '86'),
-('6.5.10 Bitwise AND operator', '87'),
-('6.5.11 Bitwise exclusive OR operator', '88'),
-('6.5.12 Bitwise inclusive OR operator', '88'),
-('6.5.13 Logical AND operator', '89'),
-('6.5.14 Logical OR operator', '89'),
-('6.5.15 Conditional operator', '90'),
-('6.5.16 Assignment operators', '91'),
-('6.5.17 Comma operator', '94'),
-('6.6 Constant expressions', '95'),
-('6.7 Declarations', '97'),
-('6.7.1 Storage-class specifiers', '98'),
-('6.7.2 Type specifiers', '99'),
-('6.7.3 Type qualifiers', '108'),
-('6.7.4 Function specifiers', '112'),
-('6.7.5 Declarators', '114'),
-('6.7.6 Type names', '122'),
-('6.7.7 Type definitions', '123'),
-('6.7.8 Initialization', '125'),
-('6.8 Statements and blocks', '131'),
-('6.8.1 Labeled statements', '131'),
-('6.8.2 Compound statement', '132'),
-('6.8.3 Expression and null statements', '132'),
-('6.8.4 Selection statements', '133'),
-('6.8.5 Iteration statements', '135'),
-('6.8.6 Jump statements', '136'),
-('6.9 External definitions', '140'),
-('6.9.1 Function definitions', '141'),
-('6.9.2 External object definitions', '143'),
-('6.10 Preprocessing directives', '145'),
-('6.10.1 Conditional inclusion', '147'),
-('6.10.2 Source file inclusion', '149'),
-('6.10.3 Macro replacement', '151'),
-('6.10.4 Line control', '158'),
-('6.10.5 Error directive', '159'),
-('6.10.6 Pragma directive', '159'),
-('6.10.7 Null directive', '160'),
-('6.10.8 Predefined macro names', '160'),
-('6.10.9 Pragma operator', '161'),
-('6.11 Future language directions', '163'),
-('6.11.1 Floating types', '163'),
-('6.11.2 Linkages of identifiers', '163'),
-('6.11.3 External names', '163'),
-('6.11.4 Character escape sequences', '163'),
-('6.11.5 Storage-class specifiers', '163'),
-('6.11.6 Function declarators', '163'),
-('6.11.7 Function definitions', '163'),
-('6.11.8 Pragma directives', '163'),
-('6.11.9 Predefined macro names', '163'),
-('7. Library', '164'),
-('7.1 Introduction', '164'),
-('7.1.1 Definitions of terms', '164'),
-('7.1.2 Standard headers', '165'),
-('7.1.3 Reserved identifiers', '166'),
-('7.1.4 Use of library functions', '166'),
-('7.2 Diagnostics <assert.h>', '169'),
-('7.2.1 Program diagnostics', '169'),
-('7.3 Complex arithmetic <complex.h>', '170'),
-('7.3.1 Introduction', '170'),
-('7.3.2 Conventions', '170'),
-('7.3.3 Branch cuts', '171'),
-('7.3.4 The CX_LIMITED_RANGE pragma', '171'),
-('7.3.5 Trigonometric functions', '172'),
-('7.3.6 Hyperbolic functions', '174'),
-('7.3.7 Exponential and logarithmic functions', '176'),
-('7.3.8 Power and absolute-value functions', '177'),
-('7.3.9 Manipulation functions', '178'),
-('7.4 Character handling <ctype.h>', '181'),
-('7.4.1 Character classification functions', '181'),
-('7.4.2 Character case mapping functions', '184'),
-('7.5 Errors <errno.h>', '186'),
-('7.6 Floating-point environment <fenv.h>', '187'),
-('7.6.1 The FENV_ACCESS pragma', '189'),
-('7.6.2 Floating-point exceptions', '190'),
-('7.6.3 Rounding', '193'),
-('7.6.4 Environment', '194'),
-('7.7 Characteristics of floating types <float.h>', '197'),
-('7.8 Format conversion of integer types <inttypes.h>', '198'),
-('7.8.1 Macros for format specifiers', '198'),
-('7.8.2 Functions for greatest-width integer types', '199'),
-('7.9 Alternative spellings <iso646.h>', '202'),
-('7.10 Sizes of integer types <limits.h>', '203'),
-('7.11 Localization <locale.h>', '204'),
-('7.11.1 Locale control', '205'),
-('7.11.2 Numeric formatting convention inquiry', '206'),
-('7.12 Mathematics <math.h>', '212'),
-('7.12.1 Treatment of error conditions', '214'),
-('7.12.2 The FP_CONTRACT pragma', '215'),
-('7.12.3 Classification macros', '216'),
-('7.12.4 Trigonometric functions', '218'),
-('7.12.5 Hyperbolic functions', '221'),
-('7.12.6 Exponential and logarithmic functions', '223'),
-('7.12.7 Power and absolute-value functions', '228'),
-('7.12.8 Error and gamma functions', '230'),
-('7.12.9 Nearest integer functions', '231'),
-('7.12.10 Remainder functions', '235'),
-('7.12.11 Manipulation functions', '236'),
-('7.12.12 Maximum, minimum, and positive difference functions', '238'),
-('7.12.13 Floating multiply-add', '239'),
-('7.12.14 Comparison macros', '240'),
-('7.13 Nonlocal jumps <setjmp.h>', '243'),
-('7.13.1 Save calling environment', '243'),
-('7.13.2 Restore calling environment', '244'),
-('7.14 Signal handling <signal.h>', '246'),
-('7.14.1 Specify signal handling', '247'),
-('7.14.2 Send signal', '248'),
-('7.15 Variable arguments <stdarg.h>', '249'),
-('7.15.1 Variable argument list access macros', '249'),
-('7.16 Boolean type and values <stdbool.h>', '253'),
-('7.17 Common definitions <stddef.h>', '254'),
-('7.18 Integer types <stdint.h>', '255'),
-('7.18.1 Integer types', '255'),
-('7.18.2 Limits of specified-width integer types', '257'),
-('7.18.3 Limits of other integer types', '259'),
-('7.18.4 Macros for integer constants', '260'),
-('7.19 Input/output <stdio.h>', '262'),
-('7.19.1 Introduction', '262'),
-('7.19.2 Streams', '264'),
-('7.19.3 Files', '266'),
-('7.19.4 Operations on files', '268'),
-('7.19.5 File access functions', '270'),
-('7.19.6 Formatted input/output functions', '274'),
-('7.19.7 Character input/output functions', '296'),
-('7.19.8 Direct input/output functions', '301'),
-('7.19.9 File positioning functions', '302'),
-('7.19.10 Error-handling functions', '304'),
-('7.20 General utilities <stdlib.h>', '306'),
-('7.20.1 Numeric conversion functions', '307'),
-('7.20.2 Pseudo-random sequence generation functions', '312'),
-('7.20.3 Memory management functions', '313'),
-('7.20.4 Communication with the environment', '315'),
-('7.20.5 Searching and sorting utilities', '318'),
-('7.20.6 Integer arithmetic functions', '320'),
-('7.20.7 Multibyte/wide character conversion functions', '321'),
-('7.20.8 Multibyte/wide string conversion functions', '323'),
-('7.21 String handling <string.h>', '325'),
-('7.21.1 String function conventions', '325'),
-('7.21.2 Copying functions', '325'),
-('7.21.3 Concatenation functions', '327'),
-('7.21.4 Comparison functions', '328'),
-('7.21.5 Search functions', '330'),
-('7.21.6 Miscellaneous functions', '333'),
-('7.22 Type-generic math <tgmath.h>', '335'),
-('7.23 Date and time <time.h>', '338'),
-('7.23.1 Components of time', '338'),
-('7.23.2 Time manipulation functions', '339'),
-('7.23.3 Time conversion functions', '341'),
-('7.24 Extended multibyte and wide character utilities <wchar.h>', '348'),
-('7.24.1 Introduction', '348'),
-('7.24.2 Formatted wide character input/output functions', '349'),
-('7.24.3 Wide character input/output functions', '367'),
-('7.24.4 General wide string utilities', '371'),
-('7.24.5 Wide character time conversion functions', '385'),
-('7.24.6 Extended multibyte/wide character conversion utilities', '386'),
-('7.25 Wide character classification and mapping utilities <wctype.h>',
- '393'),
-('7.25.1 Introduction', '393'),
-('7.25.2 Wide character classification utilities', '394'),
-('7.25.3 Wide character case mapping utilities', '399'),
-('7.26 Future library directions', '401'),
-('7.26.1 Complex arithmetic <complex.h>', '401'),
-('7.26.2 Character handling <ctype.h>', '401'),
-('7.26.3 Errors <errno.h>', '401'),
-('7.26.4 Format conversion of integer types <inttypes.h>', '401'),
-('7.26.5 Localization <locale.h>', '401'),
-('7.26.6 Signal handling <signal.h>', '401'),
-('7.26.7 Boolean type and values <stdbool.h>', '401'),
-('7.26.8 Integer types <stdint.h>', '401'),
-('7.26.9 Input/output <stdio.h>', '402'),
-('7.26.10 General utilities <stdlib.h>', '402'),
-('7.26.11 String handling <string.h>', '402'),
-('<wchar.h>', '402'),
-('<wctype.h>', '402'),
-('Annex A (informative) Language syntax summary', '403'),
-('A.1 Lexical grammar', '403'),
-('A.2 Phrase structure grammar', '409'),
-('A.3 Preprocessing directives', '416'),
-('Annex B (informative) Library summary', '418'),
-('B.1 Diagnostics <assert.h>', '418'),
-('B.2 Complex <complex.h>', '418'),
-('B.3 Character handling <ctype.h>', '420'),
-('B.4 Errors <errno.h>', '420'),
-('B.5 Floating-point environment <fenv.h>', '420'),
-('B.6 Characteristics of floating types <float.h>', '421'),
-('B.7 Format conversion of integer types <inttypes.h>', '421'),
-('B.8 Alternative spellings <iso646.h>', '422'),
-('B.9 Sizes of integer types <limits.h>', '422'),
-('B.10 Localization <locale.h>', '422'),
-('B.11 Mathematics <math.h>', '422'),
-('B.12 Nonlocal jumps <setjmp.h>', '427'),
-('B.13 Signal handling <signal.h>', '427'),
-('B.14 Variable arguments <stdarg.h>', '427'),
-('B.15 Boolean type and values <stdbool.h>', '427'),
-('B.16 Common definitions <stddef.h>', '428'),
-('B.17 Integer types <stdint.h>', '428'),
-('B.18 Input/output <stdio.h>', '428'),
-('B.19 General utilities <stdlib.h>', '430'),
-('B.20 String handling <string.h>', '432'),
-('B.21 Type-generic math <tgmath.h>', '433'),
-('B.22 Date and time <time.h>', '433'),
-('B.23 Extended multibyte/wide character utilities <wchar.h>', '434'),
-('B.24 Wide character classification and mapping utilities <wctype.h>',
- '436'),
-('Annex C (informative) Sequence points', '438'),
-('Annex D (normative) Universal character names for identifiers', '439'),
-('Annex E (informative) Implementation limits', '441'),
-('Annex F (normative) IEC 60559 floating-point arithmetic', '443'),
-('F.1 Introduction', '443'),
-('F.2 Types', '443'),
-('F.3 Operators and functions', '444'),
-('F.4 Floating to integer conversion', '446'),
-('F.5 Binary-decimal conversion', '446'),
-('F.6 Contracted expressions', '447'),
-('F.7 Floating-point environment', '447'),
-('F.8 Optimization', '450'),
-('F.9 Mathematics <math.h>', '453'),
-('Annex G (informative) IEC 60559-compatible complex arithmetic', '466'),
-('G.1 Introduction', '466'),
-('G.2 Types', '466'),
-('G.3 Conventions', '466'),
-('G.4 Conversions', '467'),
-('G.5 Binary operators', '467'),
-('G.6 Complex arithmetic <complex.h>', '471'),
-('G.7 Type-generic math <tgmath.h>', '479'),
-('Annex H (informative) Language independent arithmetic', '480'),
-('H.1 Introduction', '480'),
-('H.2 Types', '480'),
-('H.3 Notification', '484'),
-('Annex I (informative) Common warnings', '486'),
-('Annex J (informative) Portability issues', '488'),
-('J.1 Unspecified behavior', '488'),
-('J.2 Undefined behavior', '491'),
-('J.3 Implementation-defined behavior', '504'),
-('J.4 Locale-specific behavior', '511'),
-('J.5 Common extensions', '512'),
-('Bibliography', '515'),
-('Index', '517')]
-
-cXXURL = 'http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf'
-cXXTOC = [('Contents', 'ii'),
-('List of Tables', 'ix'),
-('1 General', '1'),
-('1.1 Scope', '1'),
-('1.2 Normative references', '1'),
-('1.3 Definitions', '2'),
-('1.4 Implementation compliance', '4'),
-('1.5 Structure of this International Standard', '5'),
-('1.6 Syntax notation', '5'),
-('1.7 The C++ memory model', '6'),
-('1.8 The C++ object model', '6'),
-('1.9 Program execution', '7'),
-('1.10 Multi-threaded executions and data races', '10'),
-('1.11 Acknowledgments', '13'),
-('2 Lexical conventions', '15'),
-('2.1 Phases of translation', '15'),
-('2.2 Character sets', '16'),
-('2.3 Trigraph sequences', '17'),
-('2.4 Preprocessing tokens', '17'),
-('2.5 Alternative tokens', '18'),
-('2.6 Tokens', '19'),
-('2.7 Comments', '19'),
-('2.8 Header names', '19'),
-('2.9 Preprocessing numbers', '20'),
-('2.10 Identifiers', '20'),
-('2.11 Keywords', '20'),
-('2.12 Operators and punctuators', '21'),
-('2.13 Literals', '21'),
-('3 Basic concepts', '29'),
-('3.1 Declarations and definitions', '29'),
-('3.2 One definition rule', '31'),
-('3.3 Declarative regions and scopes', '33'),
-('3.4 Name lookup', '38'),
-('3.5 Program and linkage', '51'),
-('3.6 Start and termination', '54'),
-('3.7 Storage duration', '58'),
-('3.8 Object Lifetime', '62'),
-('3.9 Types', '65'),
-('3.10 Lvalues and rvalues', '70'),
-('3.11 Alignment', '72'),
-('4 Standard conversions', '73'),
-('4.1 Lvalue-to-rvalue conversion', '74'),
-('4.2 Array-to-pointer conversion', '74'),
-('4.3 Function-to-pointer conversion', '74'),
-('4.4 Qualification conversions', '74'),
-('4.5 Integral promotions', '75'),
-('4.6 Floating point promotion', '76'),
-('4.7 Integral conversions', '76'),
-('4.8 Floating point conversions', '76'),
-('4.9 Floating-integral conversions', '77'),
-('4.10 Pointer conversions', '77'),
-('4.11 Pointer to member conversions', '77'),
-('4.12 Boolean conversions', '78'),
-('4.13 Integer conversion rank', '78'),
-('5 Expressions', '79'),
-('5.1 Primary expressions', '80'),
-('5.2 Postfix expressions', '85'),
-('5.3 Unary expressions', '96'),
-('5.4 Explicit type conversion (cast notation)', '104'),
-('5.5 Pointer-to-member operators', '105'),
-('5.6 Multiplicative operators', '106'),
-('5.7 Additive operators', '106'),
-('5.8 Shift operators', '107'),
-('5.9 Relational operators', '108'),
-('5.10 Equality operators', '109'),
-('5.11 Bitwise AND operator', '110'),
-('5.12 Bitwise exclusive OR operator', '110'),
-('5.13 Bitwise inclusive OR operator', '110'),
-('5.14 Logical AND operator', '110'),
-('5.15 Logical OR operator', '110'),
-('5.16 Conditional operator', '111'),
-('5.17 Assignment and compound assignment operators', '112'),
-('5.18 Comma operator', '113'),
-('5.19 Constant expressions', '113'),
-('6 Statements', '116'),
-('6.1 Labeled statement', '116'),
-('6.2 Expression statement', '116'),
-('6.3 Compound statement or block', '116'),
-('6.4 Selection statements', '117'),
-('6.5 Iteration statements', '118'),
-('6.6 Jump statements', '121'),
-('6.7 Declaration statement', '122'),
-('6.8 Ambiguity resolution', '123'),
-('7 Declarations', '125'),
-('7.1 Specifiers', '126'),
-('7.2 Enumeration declarations', '140'),
-('7.3 Namespaces', '143'),
-('7.4 The asm declaration', '156'),
-('7.5 Linkage specifications', '156'),
-('8 Declarators', '160'),
-('8.1 Type names', '161'),
-('8.2 Ambiguity resolution', '161'),
-('8.3 Meaning of declarators', '163'),
-('8.4 Function definitions', '175'),
-('8.5 Initializers', '177'),
-('9 Classes', '191'),
-('9.1 Class names', '193'),
-('9.2 Class members', '194'),
-('9.3 Member functions', '197'),
-('9.4 Static members', '200'),
-('9.5 Unions', '202'),
-('9.6 Bit-fields', '203'),
-('9.7 Nested class declarations', '204'),
-('9.8 Local class declarations', '205'),
-('9.9 Nested type names', '206'),
-('10 Derived classes', '207'),
-('10.1 Multiple base classes', '208'),
-('10.2 Member name lookup', '210'),
-('10.3 Virtual functions', '213'),
-('10.4 Abstract classes', '217'),
-('11 Member access control', '219'),
-('11.1 Access specifiers', '221'),
-('11.2 Accessibility of base classes and base class members', '222'),
-('11.3 Access declarations', '224'),
-('11.4 Friends', '225'),
-('11.5 Protected member access', '228'),
-('11.6 Access to virtual functions', '229'),
-('11.7 Multiple access', '230'),
-('11.8 Nested classes', '230'),
-('12 Special member functions', '231'),
-('12.1 Constructors', '231'),
-('12.2 Temporary objects', '233'),
-('12.3 Conversions', '235'),
-('12.4 Destructors', '238'),
-('12.5 Free store', '240'),
-('12.6 Initialization', '242'),
-('12.7 Construction and destruction', '247'),
-('12.8 Copying class objects', '250'),
-('12.9 Inheriting Constructors', '255'),
-('13 Overloading', '259'),
-('13.1 Overloadable declarations', '259'),
-('13.2 Declaration matching', '261'),
-('13.3 Overload resolution', '262'),
-('13.4 Address of overloaded function', '281'),
-('13.5 Overloaded operators', '282'),
-('13.6 Built-in operators', '286'),
-('14 Templates', '290'),
-('14.1 Template parameters', '291'),
-('14.2 Names of template specializations', '294'),
-('14.3 Template arguments', '296'),
-('14.4 Type equivalence', '302'),
-('14.5 Template declarations', '303'),
-('14.6 Name resolution', '318'),
-('14.7 Template instantiation and specialization', '331'),
-('14.8 Function template specializations', '343'),
-('15 Exception handling', '363'),
-('15.1 Throwing an exception', '364'),
-('15.2 Constructors and destructors', '366'),
-('15.3 Handling an exception', '366'),
-('15.4 Exception specifications', '368'),
-('15.5 Special functions', '371'),
-('15.6 Exceptions and access', '372'),
-('16 Preprocessing directives', '373'),
-('16.1 Conditional inclusion', '375'),
-('16.2 Source file inclusion', '376'),
-('16.3 Macro replacement', '377'),
-('16.4 Line control', '382'),
-('16.5 Error directive', '383'),
-('16.6 Pragma directive', '383'),
-('16.7 Null directive', '383'),
-('16.8 Predefined macro names', '383'),
-('16.9 Pragma operator', '384'),
-('17 Library introduction', '386'),
-('17.1 General', '386'),
-('17.2 Overview', '386'),
-('17.3 Definitions', '386'),
-('17.4 Additional definitions', '390'),
-('17.5 Method of description (Informative)', '390'),
-('17.6 Library-wide requirements', '396'),
-('18 Language support library', '407'),
-('18.1 Types', '407'),
-('18.2 Implementation properties', '408'),
-('18.3 Integer types', '417'),
-('18.4 Start and termination', '418'),
-('18.5 Dynamic memory management', '420'),
-('18.6 Type identification', '424'),
-('18.7 Exception handling', '427'),
-('18.8 Initializer lists', '432'),
-('18.9 Other runtime support', '434'),
-('19 Diagnostics library', '435'),
-('19.1 Exception classes', '435'),
-('19.2 Assertions', '439'),
-('19.3 Error numbers', '440'),
-('19.4 System error support', '440'),
-('20 General utilities library', '452'),
-('20.1 Requirements', '452'),
-('20.2 Utility components', '457'),
-('20.3 Compile-time rational arithmetic', '463'),
-('20.4 Tuples', '465'),
-('20.5 Metaprogramming and type traits', '473'),
-('20.6 Function objects', '486'),
-('20.7 Memory', '509'),
-('20.8 Time utilities', '548'),
-('20.9 Date and time functions', '562'),
-('21 Strings library', '563'),
-('21.1 Character traits', '563'),
-('21.2 String classes', '569'),
-('21.3 Class template basic_string', '572'),
-('21.4 Numeric Conversions', '599'),
-('21.5 Null-terminated sequence utilities', '600'),
-('22 Localization library', '604'),
-('22.1 Locales', '604'),
-('22.2 Standard locale categories', '617'),
-('22.3 Standard code conversion facets', '657'),
-('22.4 C Library Locales', '659'),
-('23 Containers library', '660'),
-('23.1 Container requirements', '660'),
-('23.2 Sequence containers', '681'),
-('23.3 Associative containers', '719'),
-('23.4 Unordered associative containers', '744'),
-('24 Iterators library', '759'),
-('24.1 Iterator requirements', '759'),
-('24.2 Header <iterator> synopsis', '764'),
-('24.3 Iterator primitives', '767'),
-('24.4 Predefined iterators', '770'),
-('24.5 Stream iterators', '784'),
-('25 Algorithms library', '792'),
-('25.1 Non-modifying sequence operations', '802'),
-('25.2 Mutating sequence operations', '806'),
-('25.3 Sorting and related operations', '815'),
-('25.4 C library algorithms', '829'),
-('26 Numerics library', '831'),
-('26.1 Numeric type requirements', '831'),
-('26.2 The floating-point environment', '832'),
-('26.3 Complex numbers', '833'),
-('26.4 Random number generation', '842'),
-('26.5 Numeric arrays', '884'),
-('26.6 Generalized numeric operations', '904'),
-('26.7 C Library', '907'),
-('27 Input/output library', '912'),
-('27.1 Iostreams requirements', '912'),
-('27.2 Forward declarations', '912'),
-('27.3 Standard iostream objects', '915'),
-('27.4 Iostreams base classes', '916'),
-('27.5 Stream buffers', '934'),
-('27.6 Formatting and manipulators', '944'),
-('27.7 String-based streams', '972'),
-('27.8 File-based streams', '984'),
-('28 Regular expressions library', '1000'),
-('28.1 Definitions', '1000'),
-('28.2 Requirements', '1000'),
-('28.3 Regular expressions summary', '1002'),
-('28.4 Header <regex> synopsis', '1003'),
-('28.5 Namespace std::regex_constants', '1009'),
-('28.6 Class regex_error', '1012'),
-('28.7 Class template regex_traits', '1012'),
-('28.8 Class template basic_regex', '1015'),
-('28.9 Class template sub_match', '1020'),
-('28.10Class template match_results', '1025'),
-('28.11Regular expression algorithms', '1029'),
-('28.12Regular expression Iterators', '1033'),
-('28.13Modified ECMAScript regular expression grammar', '1039'),
-('29 Atomic operations library', '1042'),
-('29.1 Order and Consistency', '1044'),
-('29.2 Lock-free Property', '1046'),
-('29.3 Atomic Types', '1046'),
-('29.4 Operations on Atomic Types', '1051'),
-('29.5 Flag Type and Operations', '1054'),
-('30 Thread support library', '1057'),
-('30.1 Requirements', '1057'),
-('30.2 Threads', '1058'),
-('30.3 Mutual exclusion', '1063'),
-('30.4 Condition variables', '1077'),
-('A Grammar summary', '1085'),
-('A.1 Keywords', '1085'),
-('A.2 Lexical conventions', '1085'),
-('A.3 Basic concepts', '1089'),
-('A.4 Expressions', '1090'),
-('A.5 Statements', '1093'),
-('A.6 Declarations', '1094'),
-('A.7 Declarators', '1097'),
-('A.8 Classes', '1098'),
-('A.9 Derived classes', '1099'),
-('A.10 Special member functions', '1099'),
-('A.11 Overloading', '1100'),
-('A.12 Templates', '1100'),
-('A.13 Exception handling', '1101'),
-('A.14 Preprocessing directives', '1101'),
-('B Implementation quantities', '1103'),
-('C Compatibility', '1105'),
-('C.1 C++ and ISO C', '1105'),
-('C.2 Standard C library', '1114'),
-('D Compatibility features', '1119'),
-('D.1 Increment operator with bool operand', '1119'),
-('D.2 static keyword', '1119'),
-('D.3 Access declarations', '1119'),
-('D.4 Implicit conversion from const strings', '1119'),
-('D.5 C standard library headers', '1119'),
-('D.6 Old iostreams members', '1120'),
-('D.7 char* streams', '1121'),
-('D.8 Binders', '1130'),
-('D.9 auto_ptr', '1132'),
-('E Universal-character-names', '1135'),
-('F Cross references', '1137'),
-('Index', '1153')]
-
-kDocuments = {
- 'C99' : (c99URL, c99TOC, 12),
- 'C++' : (cXXURL, cXXTOC, 12),
-}
-
-def findClosestTOCEntry(data, target):
- offset = data[2]
- best = None
- for (name,page) in data[1]:
- if ' ' in name:
- section,name = name.split(' ',1)
- if section == 'Annex':
- section,name = name.split(' ',1)
- section = 'Annex '+section
- else:
- section = None
- try:
- page = int(page) + offset
- except:
- page = 1
- try:
- spec = SpecIndex.fromstring(section)
- except:
- spec = None
-
- # Meh, could be better...
- if spec is not None:
- dist = spec - target
- if best is None or dist < best[0]:
- best = (dist, (section, name, page))
- return best[1]
-
-# What a hack. Slow to boot.
-doxyLineRefRE = re.compile(r"<a name=\"l([0-9]+)\"></a>")
-def findClosestLineReference(clangRoot, doxyName, target):
- try:
- f = open(os.path.join(clangRoot, 'docs', 'doxygen', 'html', doxyName))
- except:
- return None
-
- best = None
- for m in doxyLineRefRE.finditer(f.read()):
- line = int(m.group(1), 10)
- dist = abs(line - target)
- if best is None or dist < best[0]:
- best = (dist,'l'+m.group(1))
- f.close()
- if best is not None:
- return best[1]
- return None
-
-###
-
-nameAndSpecRefRE = re.compile(r"(C99|C90|C\+\+|H\&S) (([0-9]+)(\.[0-9]+)*(p[0-9]+)?)")
-loneSpecRefRE = re.compile(r" (([0-9]+)(\.[0-9]+){2,100}(p[0-9]+)?)")
-def scanFile(path, filename):
- try:
- f = open(path)
- except IOError:
- print >>sys.stderr,'WARNING: Unable to open:',path
- return
-
- for i,ln in enumerate(f):
- ignore = set()
- for m in nameAndSpecRefRE.finditer(ln):
- section = m.group(2)
- name = m.group(1)
- if section.endswith('.'):
- section = section[:-1]
- yield RefItem(name, section, filename, path, i+1)
- ignore.add(section)
- for m in loneSpecRefRE.finditer(ln):
- section = m.group(1)
- if section.endswith('.'):
- section = section[:-1]
- if section not in ignore:
- yield RefItem(None, section, filename, path, i+1)
-
-###
-
-class SpecIndex:
- @staticmethod
- def fromstring(str):
- secs = str.split('.')
- paragraph = None
- if 'p' in secs[-1]:
- secs[-1],p = secs[-1].split('p',1)
- paragraph = int(p)
- indices = map(int, secs)
- return SpecIndex(indices, paragraph)
-
- def __init__(self, indices, paragraph=None):
- assert len(indices)>0
- self.indices = tuple(indices)
- self.paragraph = paragraph
-
- def __str__(self):
- s = '.'.join(map(str,self.indices))
- if self.paragraph is not None:
- s += '.p%d'%(self.paragraph,)
- return s
-
- def __repr__(self):
- return 'SpecIndex(%s, %s)'%(self.indices, self.paragraph)
-
- def __cmp__(self, b):
- return cmp((self.indices,self.paragraph),
- (b.indices,b.paragraph))
-
- def __hash__(self):
- return hash((self.indices,self.paragraph))
-
- def __sub__(self, indices):
- def sub(a,b):
- a = a or 0
- b = b or 0
- return abs(a-b)
- return map(sub,self.indices,indices)
-
-class RefItem:
- def __init__(self, name, section, filename, path, line):
- self.name = name
- self.section = SpecIndex.fromstring(section)
- self.filename = filename
- self.path = path
- self.line = line
-
- def __str__(self):
- if self.name is not None:
- return '%s %s'%(self.name, self.section)
- else:
- return '--- %s'%(self.section,)
-
- def __repr__(self):
- return 'RefItem(%s, %r, "%s", "%s", %d)'%(self.name,
- self.section,
- self.filename,
- self.path,
- self.line)
-
- def __cmp__(self, b):
- return cmp((self.name,self.section,self.filename,self.path,self.line),
- (b.name,b.section,self.filename,self.path,self.line))
-
- def __hash__(self):
- return hash((self.name,self.section,self.filename,self.path,self.line))
-
-###
-
-def sorted(l):
- l = list(l)
- l.sort()
- return l
-
-def getRevision(path):
- import subprocess
- p = subprocess.Popen(['svn', 'info', path],
- stdin=open('/dev/null','r'),
- stdout=subprocess.PIPE)
- for ln in p.stdout.read(1024).split('\n'):
- if ln.startswith('Revision:'):
- return ln.split(':',1)[1].strip()
- return None
-
-def buildRefTree(references):
- root = (None, {}, [])
-
- def getNode(keys):
- if not keys:
- return root
- key,parent = keys[-1],getNode(keys[:-1])
- node = parent[1].get(key)
- if node is None:
- parent[1][key] = node = (key, {}, [])
- return node
-
- for ref in references:
- n = getNode((ref.name,) + ref.section.indices)
- n[2].append(ref)
-
- def flatten((key, children, data)):
- children = sorted(map(flatten,children.values()))
- return (key, children, sorted(data))
-
- return flatten(root)
-
-def preorder(node,parents=(),first=True):
- (key,children,data) = node
- if first:
- yield parents+(node,)
- for c in children:
- for item in preorder(c, parents+(node,)):
- yield item
-
-def main():
- global options
- from optparse import OptionParser
- parser = OptionParser("usage: %prog [options] CLANG_ROOT <output-dir>")
-
- (options, args) = parser.parse_args()
-
- if len(args) != 2:
- parser.error("incorrect number of arguments")
-
- references = []
- root,outputDir = args
- for (dirpath, dirnames, filenames) in os.walk(root):
- for filename in filenames:
- name,ext = os.path.splitext(filename)
- if ext in ('.c', '.cpp', '.h', '.def'):
- fullpath = os.path.join(dirpath, filename)
- references.extend(list(scanFile(fullpath, filename)))
-
- refTree = buildRefTree(references)
-
- specs = {}
- for ref in references:
- spec = specs[ref.name] = specs.get(ref.name,{})
- items = spec[ref.section] = spec.get(ref.section,[])
- items.append(ref)
-
- print 'Found %d references.'%(len(references),)
-
- referencesPath = os.path.join(outputDir,'references.html')
- print 'Writing: %s'%(referencesPath,)
- f = open(referencesPath,'w')
- print >>f, '<html><head><title>clang: Specification References</title></head>'
- print >>f, '<body>'
- print >>f, '\t<h2>Specification References</h2>'
- for i,node in enumerate(refTree[1]):
- specName = node[0] or 'Unknown'
- print >>f, '<a href="#spec%d">%s</a><br>'%(i,specName)
- for i,node in enumerate(refTree[1]):
- specName = node[0] or 'Unknown'
- print >>f, '<hr>'
- print >>f, '<a name="spec%d">'%(i,)
- print >>f, '<h3>Document: %s</h3>'%(specName or 'Unknown',)
- print >>f, '<table border="1" cellspacing="2" width="80%">'
- print >>f, '<tr><th width="20%">Name</th><th>References</th></tr>'
- docData = kDocuments.get(specName)
- for path in preorder(node,first=False):
- if not path[-1][2]:
- continue
- components = '.'.join([str(p[0]) for p in path[1:]])
- print >>f, '\t<tr>'
- tocEntry = None
- if docData is not None:
- tocEntry = findClosestTOCEntry(docData, [p[0] for p in path[1:]])
- if tocEntry is not None:
- section,name,page = tocEntry
- # If section is exact print the TOC name
- if page is not None:
- linkStr = '<a href="%s#page=%d">%s</a> (pg.%d)'%(docData[0],page,components,page)
- else:
- linkStr = components
- if section == components:
- print >>f, '\t\t<td valign=top>%s<br>%s</td>'%(linkStr,name)
- else:
- print >>f, '\t\t<td valign=top>%s</td>'%(linkStr,)
- else:
- print >>f, '\t\t<td valign=top>%s</td>'%(components,)
- print >>f, '\t\t<td valign=top>'
- for item in path[-1][2]:
- # XXX total hack
- relativePath = item.path[len(root):]
- if relativePath.startswith('/'):
- relativePath = relativePath[1:]
- # XXX this is broken, how does doxygen mangle w/ multiple
- # refs? Can we just read its map?
- filename = os.path.basename(relativePath)
- doxyName = '%s-source.html'%(filename.replace('.','_8'),)
- # Grrr, why can't doxygen write line number references.
- lineReference = findClosestLineReference(root,doxyName,item.line)
- if lineReference is not None:
- linkStr = 'http://clang.llvm.org/doxygen/%s#%s'%(doxyName,lineReference)
- else:
- linkStr = 'http://clang.llvm.org/doxygen/%s'%(doxyName,)
- if item.section.paragraph is not None:
- paraText = '&nbsp;(p%d)'%(item.section.paragraph,)
- else:
- paraText = ''
- print >>f,'<a href="%s">%s:%d</a>%s<br>'%(linkStr,relativePath,item.line,paraText)
- print >>f, '\t\t</td>'
- print >>f, '\t</tr>'
- print >>f, '</table>'
- print >>f, '<hr>'
- print >>f, 'Generated: %s<br>'%(time.strftime('%Y-%m-%d %H:%M'),)
- print >>f, 'SVN Revision: %s'%(getRevision(root),)
- print >>f, '</body>'
- f.close()
-
-if __name__=='__main__':
- main()
diff --git a/clang/utils/ccc b/clang/utils/ccc
deleted file mode 100755
index 2ffdcfc35d9b..000000000000
--- a/clang/utils/ccc
+++ /dev/null
@@ -1,378 +0,0 @@
-#!/usr/bin/env python
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This script attempts to be a drop-in replacement for gcc.
-#
-##===----------------------------------------------------------------------===##
-
-import os
-import sys
-import subprocess
-
-def checkenv(name, alternate=None):
- """checkenv(var, alternate=None) - Return the given environment var,
- or alternate if it is undefined or empty."""
- v = os.getenv(name)
- if v and v.strip():
- return v.strip()
- return alternate
-
-def checkbool(name, default=False):
- v = os.getenv(name)
- if v:
- try:
- return bool(int(v))
- except:
- pass
- return default
-
-CCC_ECHO = checkbool('CCC_ECHO')
-CCC_NATIVE = checkbool('CCC_NATIVE','1')
-CCC_FALLBACK = checkbool('CCC_FALLBACK')
-CCC_LANGUAGES = checkenv('CCC_LANGUAGES','c,c++,c-cpp-output,objective-c,objective-c++,objective-c-cpp-output')
-if CCC_LANGUAGES:
- CCC_LANGUAGES = set([s.strip() for s in CCC_LANGUAGES.split(',')])
-
-# We want to support use as CC or LD, so we need different defines.
-CLANG = checkenv('CLANG', 'clang')
-LLC = checkenv('LLC', 'llc')
-AS = checkenv('AS', 'as')
-CC = checkenv('CCC_CC', 'cc')
-LD = checkenv('CCC_LD', 'c++')
-
-def error(message):
- print >> sys.stderr, 'ccc: ' + message
- sys.exit(1)
-
-def quote(arg):
- if '"' in arg or ' ' in arg:
- return repr(arg)
- return arg
-
-def stripoutput(args):
- """stripoutput(args) -> (output_name, newargs)
-
- Remove the -o argument from the arg list and return the output
- filename and a new argument list. Assumes there will be at most
- one -o option. If no output argument is found the result is (None,
- args)."""
- for i,a in enumerate(args):
- if a.startswith('-o'):
- if a=='-o':
- if i+1<len(args):
- return args[i+1],args[:i]+args[i+2:]
- elif a.startswith('-o='):
- opt,arg = a.split('=',1)
- return arg,args[:i]+args[i+1:]
- return None,args
-
-def run(args):
- if CCC_ECHO:
- print ' '.join(map(quote, args))
- sys.stdout.flush()
- code = subprocess.call(args)
- if code > 255:
- code = 1
- if code:
- sys.exit(code)
-
-def remove(path):
- """remove(path) -> bool - Attempt to remove the file at path (if any).
-
- The result indicates if the remove was successful. A warning is
- printed if there is an error removing the file."""
- if os.path.exists(path):
- try:
- os.remove(path)
- except:
- print >>sys.stderr, 'WARNING: Unable to remove temp "%s"'%(path,)
- return False
- return True
-
-def preprocess(args):
- command = [CLANG,'-E']
- run(command + args)
-
-def compile_fallback(args):
- command = [CC,'-c']
- run(command + args)
-
-def compile(args, native, save_temps=False):
- if native:
- output,args = stripoutput(args)
- if not output:
- raise ValueError,'Expected to always have explicit -o in compile()'
-
- # I prefer suffixing these to changing the extension, which is
- # more likely to overwrite other things. We could of course
- # use temp files.
- bc_output = output + '.bc'
- s_output = output + '.s'
- command = [CLANG,'-emit-llvm-bc']
- try:
- run(command + args + ['-o', bc_output])
- # FIXME: What controls relocation model?
- run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
- run([AS, '-o', output, s_output])
- finally:
- if not save_temps:
- remove(bc_output)
- remove(s_output)
- else:
- command = [CLANG,'-emit-llvm-bc']
- run(command + args)
-
-def checked_compile(args, native, language, save_temps):
- if CCC_LANGUAGES and language and language not in CCC_LANGUAGES:
- print >>sys.stderr, 'NOTE: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
- compile_fallback(args)
- elif CCC_FALLBACK:
- try:
- compile(args, native, save_temps)
- except:
- print >>sys.stderr, 'WARNING: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
- compile_fallback(args)
- else:
- compile(args, native, save_temps)
-
-def link(args, native):
- if native:
- run([LD] + args)
- else:
- command = ['llvm-ld', '-native', '-disable-internalize']
- run(command + args)
-
-def extension(path):
- return path.split(".")[-1]
-
-def changeextension(path, newext):
- i = path.rfind('.')
- if i < 0:
- return path
- j = path.rfind('/', 0, i)
- if j < 0:
- return path[:i] + "." + newext
- return path[j+1:i] + "." + newext
-
-def inferlanguage(extension):
- if extension == "c":
- return "c"
- elif extension in ["cpp", "cc"]:
- return "c++"
- elif extension == "i":
- return "c-cpp-output"
- elif extension == "m":
- return "objective-c"
- elif extension == "mm":
- return "objective-c++"
- elif extension == "mi":
- return "objective-c-cpp-output"
- elif extension == "s":
- return "assembler"
- elif extension == "S":
- return "assembler-with-cpp"
- else:
- return ""
-
-def inferaction(args):
- if '-E' in args:
- return 'preprocess'
- if '-c' in args:
- return 'compile'
- for arg in args:
- if arg.startswith('-print-prog-name'):
- return 'pring-prog-name'
- return 'link'
-
-def main(args):
- action = inferaction(args)
- output = ''
- compile_opts = []
- link_opts = []
- files = []
- save_temps = 0
- language = ''
- native = CCC_NATIVE
-
- i = 0
- while i < len(args):
- arg = args[i]
-
- if '=' in arg:
- argkey,argvalue = arg.split('=',1)
- else:
- argkey,argvalue = arg,None
-
- # Modes ccc supports
- if arg == '-save-temps':
- save_temps = 1
- if arg == '-emit-llvm' or arg == '--emit-llvm':
- native = False
-
- # Options with no arguments that should pass through
- if arg in ['-v', '-fobjc-gc', '-fobjc-gc-only', '-fnext-runtime',
- '-fgnu-runtime']:
- compile_opts.append(arg)
- link_opts.append(arg)
-
- # Options with one argument that should be ignored
- if arg in ['--param', '-u']:
- i += 1
-
- # Preprocessor options with one argument that should be ignored
- if arg in ['-MT', '-MF']:
- i += 1
-
- # Prefix matches for the compile mode
- if arg[:2] in ['-D', '-I', '-U', '-F']:
- if not arg[2:]:
- arg += args[i+1]
- i += 1
- compile_opts.append(arg)
- if argkey in ('-std', '-mmacosx-version-min'):
- compile_opts.append(arg)
-
- # Options with one argument that should pass through to compiler
- if arg in [ '-include', '-idirafter', '-iprefix',
- '-iquote', '-isystem', '-iwithprefix',
- '-iwithprefixbefore']:
- compile_opts.append(arg)
- compile_opts.append(args[i+1])
- i += 1
-
- # Options with no arguments that should pass through
- if (arg in ('-dynamiclib', '-bundle', '-headerpad_max_install_names') or
- arg.startswith('-Wl,')):
- link_opts.append(arg)
-
- # Options with one argument that should pass through
- if arg in ('-framework', '-multiply_defined', '-bundle_loader',
- '-e', '-install_name',
- '-unexported_symbols_list', '-exported_symbols_list',
- '-compatibility_version', '-current_version', '-init',
- '-seg1addr', '-dylib_file'):
- link_opts.append(arg)
- link_opts.append(args[i+1])
- i += 1
-
- # Options with one argument that should pass through to both
- if arg in ['-isysroot', '-arch']:
- compile_opts.append(arg)
- compile_opts.append(args[i+1])
- link_opts.append(arg)
- link_opts.append(args[i+1])
- i += 1
-
- # Options with three arguments that should pass through
- if arg in ('-sectorder',):
- link_opts.extend(args[i:i+4])
- i += 3
-
- # Prefix matches for the link mode
- if arg[:2] in ['-l', '-L', '-F', '-R']:
- link_opts.append(arg)
-
- # Enable threads
- if arg == '-pthread':
- link_opts.append('-lpthread')
-
- # Input files
- if arg == '-filelist':
- f = open(args[i+1])
- for line in f:
- files.append(line.strip())
- f.close()
- i += 1
- if arg == '-x':
- language = args[i+1]
- i += 1
- if arg[0] != '-':
- files.append(arg)
-
- # Output file
- if arg == '-o':
- output = args[i+1]
- i += 1
-
- i += 1
-
- if action == 'print-prog-name':
- # assume we can handle everything
- print sys.argv[0]
- return
-
- if not files:
- error('no input files')
-
- if action == 'preprocess' or save_temps:
- for i, file in enumerate(files):
- if not language:
- language = inferlanguage(extension(file))
- if save_temps and action != 'preprocess':
- # Need a temporary output file
- if language == 'c':
- poutput = changeextension(file, "i");
- elif language == 'objective-c':
- poutput = changeextension(file, "mi");
- else:
- poutput = changeextension(file, "tmp." + extension(file))
- files[i] = poutput
- else:
- poutput = output
- args = []
- if language:
- args.extend(['-x', language])
- if poutput:
- args += ['-o', poutput, file] + compile_opts
- else:
- args += [file] + compile_opts
- preprocess(args)
- # Discard the explicit language after used once
- language = ''
-
- if action == 'compile' or save_temps:
- for i, file in enumerate(files):
- if not language:
- language = inferlanguage(extension(file))
- if save_temps and action != "compile":
- # Need a temporary output file
- coutput = changeextension(file, "o");
- files[i] = coutput
- elif not output:
- coutput = changeextension(file, "o")
- else:
- coutput = output
- args = []
- if language:
- args.extend(['-x', language])
- args += ['-o', coutput, file] + compile_opts
- checked_compile(args, native, language, save_temps)
- language = ''
-
- if action == 'link':
- for i, file in enumerate(files):
- if not language:
- language = inferlanguage(extension(file))
- ext = extension(file)
- if ext != "o" and ext != "a" and ext != "so":
- out = changeextension(file, "o")
- args = []
- if language:
- args.extend(['-x', language])
- args = ['-o', out, file] + compile_opts
- checked_compile(args, native, language, save_temps)
- language = ''
- files[i] = out
- if not output:
- output = 'a.out'
- args = ['-o', output] + link_opts + files
- link(args, native)
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/clang/utils/ccc-analyzer b/clang/utils/ccc-analyzer
deleted file mode 100755
index d99c7c7c33b7..000000000000
--- a/clang/utils/ccc-analyzer
+++ /dev/null
@@ -1,440 +0,0 @@
-#!/usr/bin/env perl
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# A script designed to interpose between the build system and gcc. It invokes
-# both gcc and the static analyzer.
-#
-##===----------------------------------------------------------------------===##
-
-use strict;
-use warnings;
-use Cwd qw/ getcwd abs_path /;
-use File::Temp qw/ tempfile /;
-use File::Path qw / mkpath /;
-
-my $CC = $ENV{'CCC_CC'};
-if (!defined $CC) { $CC = "gcc"; }
-
-##----------------------------------------------------------------------------##
-# Process Clang Crashes.
-##----------------------------------------------------------------------------##
-
-sub GetPPExt {
- my $Lang = shift;
- if ($Lang =~ /objective-c/) { return ".mi"; }
- return ".i";
-}
-
-sub ProcessClangFailure {
- my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
- my $Dir = "$HtmlDir/crashes";
- mkpath $Dir;
-
- # Generate the preprocessed file with cc (i.e., gcc).
- my ($PPH, $PPFile) = tempfile("clang_crash_XXXXXX",
- SUFFIX => GetPPExt($Lang),
- DIR => $Dir);
-
- system $CC, @$Args, "-E", "-o", $PPFile;
- close ($PPH);
-
- # Generate the preprocessed file with clang.
- my $PPFile_Clang = $PPFile;
- $PPFile_Clang =~ s/[.](.+)$/.clang.$1/;
- system $Clang, @$Args, "-E", "-o", "$PPFile_Clang";
-
- # Create the info file.
- open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
- print OUT abs_path($file), "\n";
- print OUT "$ErrorType\n";
- print OUT "@$Args\n";
- close OUT;
- `uname -a >> $PPFile.info.txt 2>&1`;
- `$CC -v >> $PPFile.info.txt 2>&1`;
- system 'mv',$ofile,"$PPFile.stderr.txt";
-}
-
-##----------------------------------------------------------------------------##
-# Running the analyzer.
-##----------------------------------------------------------------------------##
-
-sub Analyze {
- my ($Clang, $Args, $Lang, $Output, $Verbose, $HtmlDir, $file, $Analyses) = @_;
-
- # Skip anything related to C++.
- return if ($Lang =~ /c[+][+]/);
-
- my $RunAnalyzer = 0;
- my $Cmd;
- my @CmdArgs;
- my @CmdArgsSansAnalyses;
-
- if ($Lang =~ /header/) {
- exit 0 if (!defined ($Output));
- $Cmd = 'cp';
- push @CmdArgs,$file;
- # Remove the PCH extension.
- $Output =~ s/[.]gch$//;
- push @CmdArgs,$Output;
- @CmdArgsSansAnalyses = @CmdArgs;
- }
- else {
- $Cmd = $Clang;
- push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))';
- push @CmdArgs,@$Args;
- @CmdArgsSansAnalyses = @CmdArgs;
- push @CmdArgs,(split /\s/,$Analyses);
- $RunAnalyzer = 1;
- }
-
- my @PrintArgs;
- my $dir;
-
- if ($Verbose) {
- $dir = getcwd();
- print STDERR "\n[LOCATION]: $dir\n";
- push @PrintArgs,"'$Cmd'";
- foreach my $arg (@CmdArgs) { push @PrintArgs,"\'$arg\'"; }
- }
-
- if ($Verbose == 1) {
- # We MUST print to stderr. Some clients use the stdout output of
- # gcc for various purposes.
- print STDERR join(' ',@PrintArgs);
- print STDERR "\n";
- }
- elsif ($Verbose == 2) {
- print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n";
- }
-
- if ($RunAnalyzer and defined($HtmlDir)) {
- push @CmdArgs,'-o';
- push @CmdArgs,$HtmlDir;
- }
-
- if (defined $ENV{'CCC_UBI'}) {
- push @CmdArgs,"--analyzer-viz-egraph-ubigraph";
- }
-
- # Capture the STDERR of clang and send it to a temporary file.
- # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR.
- # We save the output file in the 'crashes' directory if clang encounters
- # any problems with the file.
- pipe (FROM_CHILD, TO_PARENT);
- my $pid = fork();
- if ($pid == 0) {
- close FROM_CHILD;
- open(STDOUT,">&", \*TO_PARENT);
- open(STDERR,">&", \*TO_PARENT);
- exec $Cmd, @CmdArgs;
- }
-
- close TO_PARENT;
- my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
-
- while (<FROM_CHILD>) {
- print $ofh $_;
- print STDERR $_;
- }
-
- waitpid($pid,0);
- my $Result = $?;
-
- # Did the command die because of a signal?
- if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) {
- ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
- "Crash", $ofile);
- }
- elsif ($Result) {
- ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
- "Parser Rejects", $ofile);
- }
-
- `rm -f $ofile`;
-}
-
-##----------------------------------------------------------------------------##
-# Lookup tables.
-##----------------------------------------------------------------------------##
-
-my %CompileOptionMap = (
- '-nostdinc' => 0,
- '-fobjc-gc-only' => 0,
- '-fobjc-gc' => 0,
- '-include' => 1,
- '-idirafter' => 1,
- '-iprefix' => 1,
- '-iquote' => 1,
- '-isystem' => 1,
- '-iwithprefix' => 1,
- '-iwithprefixbefore' => 1
-);
-
-my %LinkerOptionMap = (
- '-framework' => 1
-);
-
-my %CompilerLinkerOptionMap = (
- '-isysroot' => 1,
- '-arch' => 1,
- '-v' => 0,
- '-fpascal-strings' => 0,
- '-mmacosx-version-min' => 0 # This is really a 1 argument, but always has '='
-);
-
-my %IgnoredOptionMap = (
- '-MT' => 1, # Ignore these preprocessor options.
- '-MF' => 1,
-
- '-fsyntax-only' => 0,
- '-save-temps' => 0,
- '-install_name' => 1,
- '-exported_symbols_list' => 1,
- '-current_version' => 1,
- '-compatibility_version' => 1,
- '-init' => 1,
- '-e' => 1,
- '-seg1addr' => 1,
- '-bundle_loader' => 1,
- '-multiply_defined' => 1,
- '-sectorder' => 3,
- '--param' => 1,
- '-u' => 1
-);
-
-my %LangMap = (
- 'c' => 'c',
- 'cpp' => 'c++',
- 'cc' => 'c++',
- 'i' => 'c-cpp-output',
- 'm' => 'objective-c',
- 'mi' => 'objective-c-cpp-output'
-);
-
-my %UniqueOptions = (
- '-isysroot' => 0
-);
-
-##----------------------------------------------------------------------------##
-# Main Logic.
-##----------------------------------------------------------------------------##
-
-my $Action = 'link';
-my @CompileOpts;
-my @LinkOpts;
-my @Files;
-my $Lang;
-my $Output;
-my %Uniqued;
-
-# Forward arguments to gcc.
-my $Status = system($CC,@ARGV);
-if ($Status) { exit($Status >> 8); }
-
-# Get the analysis options.
-my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'};
-if (!defined($Analyses)) { $Analyses = '-checker-cfref'; }
-
-# Determine the level of verbosity.
-my $Verbose = 0;
-if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; }
-if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; }
-
-# Determine what clang executable to use.
-my $Clang = $ENV{'CLANG'};
-if (!defined $Clang) { $Clang = 'clang'; }
-
-# Get the HTML output directory.
-my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
-
-my %ArchsSeen;
-
-# Process the arguments.
-foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
- my $Arg = $ARGV[$i];
-
- # Modes ccc-analyzer supports
- if ($Arg eq '-E') { $Action = 'preprocess'; }
- elsif ($Arg eq '-c') { $Action = 'compile'; }
- elsif ($Arg =~ /^-print-prog-name/) { exit 0; }
-
- # Specially handle duplicate cases of -arch
- if ($Arg eq "-arch") {
- my $arch = $ARGV[$i+1];
- $ArchsSeen{$arch} = 1;
- ++$i;
- next;
- }
-
- # Options with possible arguments that should pass through to compiler.
- if (defined $CompileOptionMap{$Arg}) {
- my $Cnt = $CompileOptionMap{$Arg};
- push @CompileOpts,$Arg;
- while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; }
- next;
- }
-
- # Options with possible arguments that should pass through to linker.
- if (defined $LinkerOptionMap{$Arg}) {
- my $Cnt = $LinkerOptionMap{$Arg};
- push @LinkOpts,$Arg;
- while ($Cnt > 0) { ++$i; --$Cnt; push @LinkOpts, $ARGV[$i]; }
- next;
- }
-
- # Options with possible arguments that should pass through to both compiler
- # and the linker.
- if (defined $CompilerLinkerOptionMap{$Arg}) {
- my $Cnt = $CompilerLinkerOptionMap{$Arg};
-
- # Check if this is an option that should have a unique value, and if so
- # determine if the value was checked before.
- if ($UniqueOptions{$Arg}) {
- if (defined $Uniqued{$Arg}) {
- $i += $Cnt;
- next;
- }
- $Uniqued{$Arg} = 1;
- }
-
- push @CompileOpts,$Arg;
- push @LinkOpts,$Arg;
-
- while ($Cnt > 0) {
- ++$i; --$Cnt;
- push @CompileOpts, $ARGV[$i];
- push @LinkOpts, $ARGV[$i];
- }
- next;
- }
-
- # Ignored options.
- if (defined $IgnoredOptionMap{$Arg}) {
- my $Cnt = $IgnoredOptionMap{$Arg};
- while ($Cnt > 0) {
- ++$i; --$Cnt;
- }
- next;
- }
-
- # Compile mode flags.
- if ($Arg =~ /^-[D,I,U](.*)$/) {
- my $Tmp = $Arg;
- if ($1 eq '') {
- # FIXME: Check if we are going off the end.
- ++$i;
- $Tmp = $Arg . $ARGV[$i];
- }
- push @CompileOpts,$Tmp;
- next;
- }
-
- # Language.
- if ($Arg eq '-x') {
- $Lang = $ARGV[$i+1];
- ++$i; next;
- }
-
- # Output file.
- if ($Arg eq '-o') {
- ++$i;
- $Output = $ARGV[$i];
- next;
- }
-
- # Get the link mode.
- if ($Arg =~ /^-[l,L,O]/) {
- if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
- elsif ($Arg eq '-Os') { push @LinkOpts,'-O2'; }
- else { push @LinkOpts,$Arg; }
- next;
- }
-
- if ($Arg =~ /^-std=/) {
- push @CompileOpts,$Arg;
- next;
- }
-
-# if ($Arg =~ /^-f/) {
-# # FIXME: Not sure if the remaining -fxxxx options have no arguments.
-# push @CompileOpts,$Arg;
-# push @LinkOpts,$Arg; # FIXME: Not sure if these are link opts.
-# }
-
- # Get the compiler/link mode.
- if ($Arg =~ /^-F(.+)$/) {
- my $Tmp = $Arg;
- if ($1 eq '') {
- # FIXME: Check if we are going off the end.
- ++$i;
- $Tmp = $Arg . $ARGV[$i];
- }
- push @CompileOpts,$Tmp;
- push @LinkOpts,$Tmp;
- next;
- }
-
- # Input files.
- if ($Arg eq '-filelist') {
- # FIXME: Make sure we aren't walking off the end.
- open(IN, $ARGV[$i+1]);
- while (<IN>) { s/\015?\012//; push @Files,$_; }
- close(IN);
- ++$i; next;
- }
-
- if (!($Arg =~ /^-/)) {
- push @Files,$Arg; next;
- }
-}
-
-if ($Action eq 'compile' or $Action eq 'link') {
- foreach my $file (@Files) {
- # Determine the language for the file.
- my $FileLang = $Lang;
-
- if (!defined($FileLang)) {
- # Infer the language from the extension.
- if ($file =~ /[.]([^.]+)$/) {
- $FileLang = $LangMap{$1};
- }
- }
-
- next if (!defined $FileLang);
-
- my @AnalyzeArgs;
-
- if ($FileLang ne 'unknown') {
- push @AnalyzeArgs,'-x';
- push @AnalyzeArgs,$FileLang;
- }
-
- push @AnalyzeArgs,@CompileOpts;
- push @AnalyzeArgs,$file;
-
- my @Archs = keys %ArchsSeen;
- if (scalar @Archs) {
- foreach my $arch (@Archs) {
- my @NewArgs;
- push @NewArgs, '-arch';
- push @NewArgs, $arch;
- push @NewArgs, @AnalyzeArgs;
- Analyze($Clang, \@NewArgs, $FileLang, $Output,
- $Verbose, $HtmlDir, $file, $Analyses);
- }
- }
- else {
- Analyze($Clang, \@AnalyzeArgs, $FileLang, $Output,
- $Verbose, $HtmlDir, $file, $Analyses);
- }
- }
-}
-
-exit($Status >> 8);
-
diff --git a/clang/utils/scan-build b/clang/utils/scan-build
deleted file mode 100755
index 160b00ce8a9c..000000000000
--- a/clang/utils/scan-build
+++ /dev/null
@@ -1,1101 +0,0 @@
-#!/usr/bin/env perl
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# A script designed to wrap a build so that all calls to gcc are intercepted
-# and piped to the static analyzer.
-#
-##===----------------------------------------------------------------------===##
-
-use strict;
-use warnings;
-use FindBin qw($RealBin);
-use Digest::MD5;
-use File::Basename;
-use Term::ANSIColor;
-use Term::ANSIColor qw(:constants);
-use Cwd;
-use Sys::Hostname;
-use File::Basename;
-
-my $Verbose = 0; # Verbose output from this script.
-my $Prog = "scan-build";
-my $BuildName;
-my $BuildDate;
-my $CXX; # Leave undefined initially.
-
-my $TERM = $ENV{'TERM'};
-my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
- and defined $ENV{'SCAN_BUILD_COLOR'});
-
-my $UserName = HtmlEscape(getpwuid($<) || 'unknown');
-my $HostName = HtmlEscape(hostname() || 'unknown');
-my $CurrentDir = HtmlEscape(getcwd());
-my $CurrentDirSuffix = basename($CurrentDir);
-
-my $CmdArgs;
-
-my $HtmlTitle;
-
-my $Date = localtime();
-
-##----------------------------------------------------------------------------##
-# Diagnostics
-##----------------------------------------------------------------------------##
-
-sub Diag {
- if ($UseColor) {
- print BOLD, MAGENTA "$Prog: @_";
- print RESET;
- }
- else {
- print "$Prog: @_";
- }
-}
-
-sub DiagCrashes {
- my $Dir = shift;
- Diag ("The analyzer crashed on some source files.\n");
- Diag ("Preprocessed versions of crashed files were deposited in '$Dir/crashes'.\n");
- Diag ("Please consider submitting a bug report using these files:\n");
- Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n")
-}
-
-sub DieDiag {
- if ($UseColor) {
- print BOLD, RED "$Prog: ";
- print RESET, RED @_;
- print RESET;
- }
- else {
- print "$Prog: ", @_;
- }
- exit(0);
-}
-
-##----------------------------------------------------------------------------##
-# Some initial preprocessing of Clang options.
-##----------------------------------------------------------------------------##
-
-my $ClangSB = "$RealBin/clang";
-my $Clang = $ClangSB;
-
-if (! -x $ClangSB) {
- $Clang = "clang";
-}
-
-my %AvailableAnalyses;
-
-# Query clang for analysis options.
-open(PIPE, "-|", $Clang, "--help") or
- DieDiag("Cannot execute '$Clang'");
-
-my $FoundAnalysis = 0;
-
-while(<PIPE>) {
- if ($FoundAnalysis == 0) {
- if (/Available Source Code Analyses/) {
- $FoundAnalysis = 1;
- }
-
- next;
- }
-
- if (/^\s\s\s\s([^\s]+)\s(.+)$/) {
- next if ($1 =~ /-dump/ or $1 =~ /-view/
- or $1 =~ /-checker-simple/ or $1 =~ /-warn-uninit/);
-
- $AvailableAnalyses{$1} = $2;
- next;
- }
-
- last;
-}
-
-close (PIPE);
-
-my %AnalysesDefaultEnabled = (
- '-warn-dead-stores' => 1,
- '-checker-cfref' => 1,
- '-warn-objc-methodsigs' => 1,
- '-warn-objc-missing-dealloc' => 1,
- '-warn-objc-unused-ivars' => 1,
-);
-
-##----------------------------------------------------------------------------##
-# GetHTMLRunDir - Construct an HTML directory name for the current sub-run.
-##----------------------------------------------------------------------------##
-
-sub GetHTMLRunDir {
-
- die "Not enough arguments." if (@_ == 0);
- my $Dir = shift @_;
-
- my $TmpMode = 0;
- if (!defined $Dir) {
- $Dir = "/tmp";
- $TmpMode = 1;
- }
-
- # Get current date and time.
-
- my @CurrentTime = localtime();
-
- my $year = $CurrentTime[5] + 1900;
- my $day = $CurrentTime[3];
- my $month = $CurrentTime[4] + 1;
-
- my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day);
-
- # Determine the run number.
-
- my $RunNumber;
-
- if (-d $Dir) {
-
- if (! -r $Dir) {
- DieDiag("directory '$Dir' exists but is not readable.\n");
- }
-
- # Iterate over all files in the specified directory.
-
- my $max = 0;
-
- opendir(DIR, $Dir);
- my @FILES = grep { -d "$Dir/$_" } readdir(DIR);
- closedir(DIR);
-
- foreach my $f (@FILES) {
-
- # Strip the prefix '$Prog-' if we are dumping files to /tmp.
- if ($TmpMode) {
- next if (!($f =~ /^$Prog-(.+)/));
- $f = $1;
- }
-
-
- my @x = split/-/, $f;
- next if (scalar(@x) != 4);
- next if ($x[0] != $year);
- next if ($x[1] != $month);
- next if ($x[2] != $day);
-
- if ($x[3] > $max) {
- $max = $x[3];
- }
- }
-
- $RunNumber = $max + 1;
- }
- else {
-
- if (-x $Dir) {
- DieDiag("'$Dir' exists but is not a directory.\n");
- }
-
- if ($TmpMode) {
- DieDiag("The directory '/tmp' does not exist or cannot be accessed.");
- }
-
- # $Dir does not exist. It will be automatically created by the
- # clang driver. Set the run number to 1.
-
- $RunNumber = 1;
- }
-
- die "RunNumber must be defined!" if (!defined $RunNumber);
-
- # Append the run number.
- my $NewDir;
- if ($TmpMode) {
- $NewDir = "$Dir/$Prog-$DateString-$RunNumber";
- }
- else {
- $NewDir = "$Dir/$DateString-$RunNumber";
- }
- system 'mkdir','-p',$NewDir;
- return $NewDir;
-}
-
-sub SetHtmlEnv {
-
- die "Wrong number of arguments." if (scalar(@_) != 2);
-
- my $Args = shift;
- my $Dir = shift;
-
- die "No build command." if (scalar(@$Args) == 0);
-
- my $Cmd = $$Args[0];
-
- if ($Cmd =~ /configure/) {
- return;
- }
-
- if ($Verbose) {
- Diag("Emitting reports for this run to '$Dir'.\n");
- }
-
- $ENV{'CCC_ANALYZER_HTML'} = $Dir;
-}
-
-##----------------------------------------------------------------------------##
-# ComputeDigest - Compute a digest of the specified file.
-##----------------------------------------------------------------------------##
-
-sub ComputeDigest {
- my $FName = shift;
- DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);
-
- # Use Digest::MD5. We don't have to be cryptographically secure. We're
- # just looking for duplicate files that come from a non-malicious source.
- # We use Digest::MD5 because it is a standard Perl module that should
- # come bundled on most systems.
- open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n");
- binmode FILE;
- my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest;
- close(FILE);
-
- # Return the digest.
- return $Result;
-}
-
-##----------------------------------------------------------------------------##
-# UpdatePrefix - Compute the common prefix of files.
-##----------------------------------------------------------------------------##
-
-my $Prefix;
-
-sub UpdatePrefix {
- my $x = shift;
- my $y = basename($x);
- $x =~ s/\Q$y\E$//;
-
- # Ignore /usr, /Library, /System, /Developer
- return if ( $x =~ /^\/usr/ or $x =~ /^\/Library/
- or $x =~ /^\/System/ or $x =~ /^\/Developer/);
-
- if (!defined $Prefix) {
- $Prefix = $x;
- return;
- }
-
- chop $Prefix while (!($x =~ /^\Q$Prefix/));
-}
-
-sub GetPrefix {
- return $Prefix;
-}
-
-##----------------------------------------------------------------------------##
-# UpdateInFilePath - Update the path in the report file.
-##----------------------------------------------------------------------------##
-
-sub UpdateInFilePath {
- my $fname = shift;
- my $regex = shift;
- my $newtext = shift;
-
- open (RIN, $fname) or die "cannot open $fname";
- open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp";
-
- while (<RIN>) {
- s/$regex/$newtext/;
- print ROUT $_;
- }
-
- close (ROUT);
- close (RIN);
- system("mv", "$fname.tmp", $fname);
-}
-
-##----------------------------------------------------------------------------##
-# ScanFile - Scan a report file for various identifying attributes.
-##----------------------------------------------------------------------------##
-
-# Sometimes a source file is scanned more than once, and thus produces
-# multiple error reports. We use a cache to solve this problem.
-
-my %AlreadyScanned;
-
-sub ScanFile {
-
- my $Index = shift;
- my $Dir = shift;
- my $FName = shift;
-
- # Compute a digest for the report file. Determine if we have already
- # scanned a file that looks just like it.
-
- my $digest = ComputeDigest("$Dir/$FName");
-
- if (defined $AlreadyScanned{$digest}) {
- # Redundant file. Remove it.
- system ("rm", "-f", "$Dir/$FName");
- return;
- }
-
- $AlreadyScanned{$digest} = 1;
-
- # At this point the report file is not world readable. Make it happen.
- system ("chmod", "644", "$Dir/$FName");
-
- # Scan the report file for tags.
- open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n");
-
- my $BugDesc = "";
- my $BugFile = "";
- my $BugCategory;
- my $BugPathLength = 1;
- my $BugLine = 0;
- my $found = 0;
-
- while (<IN>) {
-
- last if ($found == 5);
-
- if (/<!-- BUGDESC (.*) -->$/) {
- $BugDesc = $1;
- ++$found;
- }
- elsif (/<!-- BUGFILE (.*) -->$/) {
- $BugFile = $1;
- UpdatePrefix($BugFile);
- ++$found;
- }
- elsif (/<!-- BUGPATHLENGTH (.*) -->$/) {
- $BugPathLength = $1;
- ++$found;
- }
- elsif (/<!-- BUGLINE (.*) -->$/) {
- $BugLine = $1;
- ++$found;
- }
- elsif (/<!-- BUGCATEGORY (.*) -->$/) {
- $BugCategory = $1;
- ++$found;
- }
- }
-
- close(IN);
-
- if (!defined $BugCategory) {
- $BugCategory = "Other";
- }
-
- push @$Index,[ $FName, $BugCategory, $BugDesc, $BugFile, $BugLine,
- $BugPathLength ];
-}
-
-##----------------------------------------------------------------------------##
-# CopyFiles - Copy resource files to target directory.
-##----------------------------------------------------------------------------##
-
-sub CopyFiles {
-
- my $Dir = shift;
-
- DieDiag("Cannot find 'sorttable.js'.\n")
- if (! -r "$RealBin/sorttable.js");
-
- system ("cp", "$RealBin/sorttable.js", "$Dir");
-
- DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n")
- if (! -r "$Dir/sorttable.js");
-
- DieDiag("Cannot find 'scanview.css'.\n")
- if (! -r "$RealBin/scanview.css");
-
- system ("cp", "$RealBin/scanview.css", "$Dir");
-
- DieDiag("Could not copy 'scanview.css' to '$Dir'.\n")
- if (! -r "$Dir/scanview.css");
-}
-
-##----------------------------------------------------------------------------##
-# Postprocess - Postprocess the results of an analysis scan.
-##----------------------------------------------------------------------------##
-
-sub Postprocess {
-
- my $Dir = shift;
- my $BaseDir = shift;
-
- die "No directory specified." if (!defined $Dir);
-
- if (! -d $Dir) {
- Diag("No bugs found.\n");
- return 0;
- }
-
- opendir(DIR, $Dir);
- my $Crashes = 0;
- my @files = grep { if ($_ eq "crashes") { $Crashes++; }
- /^report-.*\.html$/; } readdir(DIR);
- closedir(DIR);
-
- if (scalar(@files) == 0 and $Crashes == 0) {
- Diag("Removing directory '$Dir' because it contains no reports.\n");
- system ("rm", "-fR", $Dir);
- return 0;
- }
-
- # Scan each report file and build an index.
- my @Index;
- foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); }
-
- # Scan the crashes directory and use the information in the .info files
- # to update the common prefix directory.
- if (-d "$Dir/crashes") {
- opendir(DIR, "$Dir/crashes");
- my @files = grep { /[.]info.txt$/; } readdir(DIR);
- closedir(DIR);
- foreach my $file (@files) {
- open IN, "$Dir/crashes/$file" or DieDiag("cannot open $file\n");
- my $Path = <IN>;
- if (defined $Path) { UpdatePrefix($Path); }
- close IN;
- }
- }
-
- # Generate an index.html file.
- my $FName = "$Dir/index.html";
- open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n");
-
- # Print out the header.
-
-print OUT <<ENDTEXT;
-<html>
-<head>
-<title>${HtmlTitle}</title>
-<link type="text/css" rel="stylesheet" href="scanview.css"/>
-<script src="sorttable.js"></script>
-<script language='javascript' type="text/javascript">
-function SetDisplay(RowClass, DisplayVal)
-{
- var Rows = document.getElementsByTagName("tr");
- for ( var i = 0 ; i < Rows.length; ++i ) {
- if (Rows[i].className == RowClass) {
- Rows[i].style.display = DisplayVal;
- }
- }
-}
-
-function ToggleDisplay(CheckButton, ClassName) {
- if (CheckButton.checked) {
- SetDisplay(ClassName, "");
- }
- else {
- SetDisplay(ClassName, "none");
- }
-}
-</script>
-<!-- SUMMARYENDHEAD -->
-</head>
-<body>
-<h1>${HtmlTitle}</h1>
-
-<table>
-<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr>
-<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr>
-<tr><th>Command Line:</th><td>${CmdArgs}</td></tr>
-<tr><th>Date:</th><td>${Date}</td></tr>
-ENDTEXT
-
-print OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n"
- if (defined($BuildName) && defined($BuildDate));
-
-print OUT <<ENDTEXT;
-</table>
-ENDTEXT
-
- if (scalar(@files)) {
- # Print out the summary table.
- my %Totals;
-
- for my $row ( @Index ) {
- my $bug_type = ($row->[2]);
- my $bug_category = ($row->[1]);
- my $key = "$bug_category:$bug_type";
-
- if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; }
- else { $Totals{$key}->[0]++; }
- }
-
- print OUT "<h2>Bug Summary</h2>";
-
- if (defined $BuildName) {
- print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n"
- }
-
-print OUT <<ENDTEXT;
-<table>
-<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead>
-ENDTEXT
-
- my $last_category;
-
- for my $key (
- sort {
- my $x = $Totals{$a};
- my $y = $Totals{$b};
- my $res = $x->[1] cmp $y->[1];
- $res = $x->[2] cmp $y->[2] if ($res == 0);
- $res
- } keys %Totals )
- {
- my $val = $Totals{$key};
- my $category = $val->[1];
- if (!defined $last_category or $last_category ne $category) {
- $last_category = $category;
- print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n";
- }
- my $x = lc $key;
- $x =~ s/[ ,'":\/()]+/_/g;
- print OUT "<tr><td class=\"SUMM_DESC\">";
- print OUT $val->[2];
- print OUT "</td><td>";
- print OUT $val->[0];
- print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n";
- }
-
- # Print out the table of errors.
-
-print OUT <<ENDTEXT;
-</table>
-<h2>Reports</h2>
-
-<table class="sortable" style="table-layout:automatic">
-<thead><tr>
- <td>Bug Group</td>
- <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind">&nbsp;&#x25BE;</span></td>
- <td>File</td>
- <td class="Q">Line</td>
- <td class="Q">Path Length</td>
- <td class="sorttable_nosort"></td>
- <!-- REPORTBUGCOL -->
-</tr></thead>
-<tbody>
-ENDTEXT
-
- my $prefix = GetPrefix();
- my $regex;
- my $InFileRegex;
- my $InFilePrefix = "File:</td><td>";
-
- if (defined $prefix) {
- $regex = qr/^\Q$prefix\E/is;
- $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is;
- }
-
- for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) {
- my $x = "$row->[1]:$row->[2]";
- $x = lc $x;
- $x =~ s/[ ,'":\/()]+/_/g;
-
- my $ReportFile = $row->[0];
-
- print OUT "<tr class=\"bt_$x\">";
- print OUT "<td class=\"DESC\">";
- print OUT $row->[1];
- print OUT "</td>";
- print OUT "<td class=\"DESC\">";
- print OUT $row->[2];
- print OUT "</td>";
-
- # Update the file prefix.
- my $fname = $row->[3];
-
- if (defined $regex) {
- $fname =~ s/$regex//;
- UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix)
- }
-
- print OUT "<td>";
- my @fname = split /\//,$fname;
- if ($#fname > 0) {
- while ($#fname >= 0) {
- my $x = shift @fname;
- print OUT $x;
- if ($#fname >= 0) {
- print OUT "<span class=\"W\"> </span>/";
- }
- }
- }
- else {
- print OUT $fname;
- }
- print OUT "</td>";
-
- # Print out the quantities.
- for my $j ( 4 .. 5 ) {
- print OUT "<td class=\"Q\">$row->[$j]</td>";
- }
-
- # Print the rest of the columns.
- for (my $j = 6; $j <= $#{$row}; ++$j) {
- print OUT "<td>$row->[$j]</td>"
- }
-
- # Emit the "View" link.
- print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>";
-
- # Emit REPORTBUG markers.
- print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n";
-
- # End the row.
- print OUT "</tr>\n";
- }
-
- print OUT "</tbody>\n</table>\n\n";
- }
-
- if ($Crashes) {
- # Read the crash directory for files.
- opendir(DIR, "$Dir/crashes");
- my @files = grep { /[.]info.txt$/ } readdir(DIR);
- closedir(DIR);
-
- if (scalar(@files)) {
- print OUT <<ENDTEXT;
-<h2>Analyzer Failures</h2>
-
-<p>The analyzer had problems processing the following files:</p>
-
-<table>
-<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>
-ENDTEXT
-
- foreach my $file (sort @files) {
- $file =~ /(.+).info.txt$/;
- # Get the preprocessed file.
- my $ppfile = $1;
- # Open the info file and get the name of the source file.
- open (INFO, "$Dir/crashes/$file") or
- die "Cannot open $Dir/crashes/$file\n";
- my $srcfile = <INFO>;
- chomp $srcfile;
- my $problem = <INFO>;
- chomp $problem;
- close (INFO);
- # Print the information in the table.
- my $prefix = GetPrefix();
- if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
- print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"crashes/$ppfile\">$ppfile</a></td><td><a href=\"crashes/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
- my $ppfile_clang = $ppfile;
- $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
- print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"crashes/$ppfile\" clangfile=\"crashes/$ppfile_clang\" stderr=\"crashes/$ppfile.stderr.txt\" info=\"crashes/$ppfile.info.txt\" -->\n";
- }
-
- print OUT <<ENDTEXT;
-</table>
-<p>Please consider submitting preprocessed files as <a href="http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs">bug reports</a>. <!-- REPORTCRASHES --> </p>
-ENDTEXT
- }
- }
-
- print OUT "</body></html>\n";
- close(OUT);
- CopyFiles($Dir);
-
- # Make sure $Dir and $BaseDir are world readable/executable.
- system("chmod", "755", $Dir);
- if (defined $BaseDir) { system("chmod", "755", $BaseDir); }
-
- my $Num = scalar(@Index);
- Diag("$Num bugs found.\n");
- if ($Num > 0 && -r "$Dir/index.html") {
- Diag("Run 'scan-view $Dir' to examine bug reports.\n");
- }
-
- DiagCrashes($Dir) if ($Crashes);
-
- return $Num;
-}
-
-##----------------------------------------------------------------------------##
-# RunBuildCommand - Run the build command.
-##----------------------------------------------------------------------------##
-
-sub AddIfNotPresent {
- my $Args = shift;
- my $Arg = shift;
- my $found = 0;
-
- foreach my $k (@$Args) {
- if ($k eq $Arg) {
- $found = 1;
- last;
- }
- }
-
- if ($found == 0) {
- push @$Args, $Arg;
- }
-}
-
-sub RunBuildCommand {
-
- my $Args = shift;
- my $IgnoreErrors = shift;
- my $Cmd = $Args->[0];
- my $CCAnalyzer = shift;
-
- # Get only the part of the command after the last '/'.
- if ($Cmd =~ /\/([^\/]+)$/) {
- $Cmd = $1;
- }
-
- if ($Cmd eq "gcc" or $Cmd eq "cc" or $Cmd eq "llvm-gcc"
- or $Cmd eq "ccc-analyzer") {
- shift @$Args;
- unshift @$Args, $CCAnalyzer;
- }
- elsif ($IgnoreErrors) {
- if ($Cmd eq "make" or $Cmd eq "gmake") {
- AddIfNotPresent($Args,"-k");
- AddIfNotPresent($Args,"-i");
- }
- elsif ($Cmd eq "xcodebuild") {
- AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
- }
- }
-
- if ($Cmd eq "xcodebuild") {
- # Disable distributed builds for xcodebuild.
- AddIfNotPresent($Args,"-nodistribute");
-
- # Disable PCH files until clang supports them.
- AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
-
- # When 'CC' is set, xcodebuild uses it to do all linking, even if we are
- # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
- # when linking such files.
- die if (!defined $CXX);
- my $LDPLUSPLUS = `which $CXX`;
- $LDPLUSPLUS =~ s/\015?\012//; # strip newlines
- $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS;
- }
-
- return (system(@$Args) >> 8);
-}
-
-##----------------------------------------------------------------------------##
-# DisplayHelp - Utility function to display all help options.
-##----------------------------------------------------------------------------##
-
-sub DisplayHelp {
-
-print <<ENDTEXT;
-USAGE: $Prog [options] <build command> [build options]
-
-ENDTEXT
-
- if (defined $BuildName) {
- print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n";
- }
-
-print <<ENDTEXT;
-OPTIONS:
-
- -o - Target directory for HTML report files. Subdirectories
- will be created as needed to represent separate "runs" of
- the analyzer. If this option is not specified, a directory
- is created in /tmp to store the reports.
-
- -h - Display this message.
- --help
-
- -k - Add a "keep on going" option to the specified build command.
- --keep-going This option currently supports make and xcodebuild.
- This is a convenience option; one can specify this
- behavior directly using build options.
-
- --html-title [title] - Specify the title used on generated HTML pages.
- --html-title=[title] If not specified, a default title will be used.
-
- --status-bugs - By default, the exit status of $Prog is the same as the
- executed build command. Specifying this option causes the
- exit status of $Prog to be 1 if it found potential bugs
- and 0 otherwise.
-
- --use-cc [compiler path] - By default, $Prog uses 'gcc' to compile and link
- --use-cc=[compiler path] your C and Objective-C code. Use this option
- to specify an alternate compiler.
-
- --use-c++ [compiler path] - By default, $Prog uses 'g++' to compile and link
- --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option
- to specify an alternate compiler.
-
- -v - Verbose output from $Prog and the analyzer.
- A second and third '-v' increases verbosity.
-
- -V - View analysis results in a web browser when the build
- --view completes.
-
-
-AVAILABLE ANALYSES (multiple analyses may be specified):
-
-ENDTEXT
-
- foreach my $Analysis (sort keys %AvailableAnalyses) {
- if (defined $AnalysesDefaultEnabled{$Analysis}) {
- print " (+)";
- }
- else {
- print " ";
- }
-
- print " $Analysis $AvailableAnalyses{$Analysis}\n";
- }
-
-print <<ENDTEXT
-
- NOTE: "(+)" indicates that an analysis is enabled by default unless one
- or more analysis options are specified
-
-BUILD OPTIONS
-
- You can specify any build option acceptable to the build command.
-
-EXAMPLE
-
- $Prog -o /tmp/myhtmldir make -j4
-
- The above example causes analysis reports to be deposited into
- a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option.
- A different subdirectory is created each time $Prog analyzes a project.
- The analyzer should support most parallel builds, but not distributed builds.
-
-ENDTEXT
-}
-
-##----------------------------------------------------------------------------##
-# HtmlEscape - HTML entity encode characters that are special in HTML
-##----------------------------------------------------------------------------##
-
-sub HtmlEscape {
- # copy argument to new variable so we don't clobber the original
- my $arg = shift || '';
- my $tmp = $arg;
-
- $tmp =~ s/([\<\>\'\"])/sprintf("&#%02x;", chr($1))/ge;
-
- return $tmp;
-}
-
-##----------------------------------------------------------------------------##
-# ShellEscape - backslash escape characters that are special to the shell
-##----------------------------------------------------------------------------##
-
-sub ShellEscape {
- # copy argument to new variable so we don't clobber the original
- my $arg = shift || '';
- my $tmp = $arg;
-
- $tmp =~ s/([\!\;\\\'\"\`\<\>\|\s\(\)\[\]\?\#\$\^\&\*\=])/\\$1/g;
-
- return $tmp;
-}
-
-##----------------------------------------------------------------------------##
-# Process command-line arguments.
-##----------------------------------------------------------------------------##
-
-my $HtmlDir; # Parent directory to store HTML files.
-my $IgnoreErrors = 0; # Ignore build errors.
-my $ViewResults = 0; # View results when the build terminates.
-my $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found
-my @AnalysesToRun;
-
-if (!@ARGV) {
- DisplayHelp();
- exit 1;
-}
-
-while (@ARGV) {
-
- # Scan for options we recognize.
-
- my $arg = $ARGV[0];
-
- if ($arg eq "-h" or $arg eq "--help") {
- DisplayHelp();
- exit 0;
- }
-
- if (defined $AvailableAnalyses{$arg}) {
- shift @ARGV;
- push @AnalysesToRun, $arg;
- next;
- }
-
- if ($arg eq "-o") {
- shift @ARGV;
-
- if (!@ARGV) {
- DieDiag("'-o' option requires a target directory name.\n");
- }
-
- $HtmlDir = shift @ARGV;
- next;
- }
-
- if ($arg =~ /^--html-title(=(.+))?$/) {
- shift @ARGV;
-
- if ($2 eq '') {
- if (!@ARGV) {
- DieDiag("'--html-title' option requires a string.\n");
- }
-
- $HtmlTitle = shift @ARGV;
- } else {
- $HtmlTitle = $2;
- }
-
- next;
- }
-
- if ($arg eq "-k" or $arg eq "--keep-going") {
- shift @ARGV;
- $IgnoreErrors = 1;
- next;
- }
-
- if ($arg =~ /^--use-cc(=(.+))?$/) {
- shift @ARGV;
- my $cc;
-
- if ($2 eq "") {
- if (!@ARGV) {
- DieDiag("'--use-cc' option requires a compiler executable name.\n");
- }
- $cc = shift @ARGV;
- }
- else {
- $cc = $2;
- }
-
- $ENV{"CCC_CC"} = $cc;
- next;
- }
-
- if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
- shift @ARGV;
-
- if ($2 eq "") {
- if (!@ARGV) {
- DieDiag("'--use-c++' option requires a compiler executable name.\n");
- }
- $CXX = shift @ARGV;
- }
- else {
- $CXX = $2;
- }
- next;
- }
-
- if ($arg eq "-v") {
- shift @ARGV;
- $Verbose++;
- next;
- }
-
- if ($arg eq "-V" or $arg eq "--view") {
- shift @ARGV;
- $ViewResults = 1;
- next;
- }
-
- if ($arg eq "--status-bugs") {
- shift @ARGV;
- $ExitStatusFoundBugs = 1;
- next;
- }
-
- DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
-
- last;
-}
-
-if (!@ARGV) {
- Diag("No build command specified.\n\n");
- DisplayHelp();
- exit 1;
-}
-
-$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV)));
-$HtmlTitle = "${CurrentDirSuffix} - scan-build results"
- unless (defined($HtmlTitle));
-
-# Determine the output directory for the HTML reports.
-my $BaseDir = $HtmlDir;
-$HtmlDir = GetHTMLRunDir($HtmlDir);
-
-# Set the appropriate environment variables.
-SetHtmlEnv(\@ARGV, $HtmlDir);
-
-my $Cmd = "$RealBin/ccc-analyzer";
-
-DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n")
- if (! -x $Cmd);
-
-if (! -x $ClangSB) {
- Diag("'clang' executable not found in '$RealBin'.\n");
- Diag("Using 'clang' from path.\n");
-}
-
-if (defined $CXX) {
- $ENV{'CXX'} = $CXX;
-}
-else {
- $CXX = 'g++'; # This variable is used by other parts of scan-build
- # that need to know a default C++ compiler to fall back to.
-}
-
-$ENV{'CC'} = $Cmd;
-$ENV{'CLANG'} = $Clang;
-
-if ($Verbose >= 2) {
- $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
-}
-
-if ($Verbose >= 3) {
- $ENV{'CCC_ANALYZER_LOG'} = 1;
-}
-
-if (scalar(@AnalysesToRun) == 0) {
- foreach my $key (keys %AnalysesDefaultEnabled) {
- push @AnalysesToRun,$key;
- }
-}
-
-$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun;
-
-# Run the build.
-my $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd);
-
-# Postprocess the HTML directory.
-my $NumBugs = Postprocess($HtmlDir, $BaseDir);
-
-if ($ViewResults and -r "$HtmlDir/index.html") {
- Diag "Analysis run complete.\n";
- Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n";
- my $ScanView = "$RealBin/scan-view";
- if (! -x $ScanView) { $ScanView = "scan-view"; }
- exec $ScanView, "$HtmlDir";
-}
-
-if ($ExitStatusFoundBugs) {
- exit 1 if ($NumBugs > 0);
- exit 0;
-}
-
-exit $ExitStatus;
-
diff --git a/clang/utils/scanview.css b/clang/utils/scanview.css
deleted file mode 100644
index a0406f37a038..000000000000
--- a/clang/utils/scanview.css
+++ /dev/null
@@ -1,62 +0,0 @@
-body { color:#000000; background-color:#ffffff }
-body { font-family: Helvetica, sans-serif; font-size:9pt }
-h1 { font-size: 14pt; }
-h2 { font-size: 12pt; }
-table { font-size:9pt }
-table { border-spacing: 0px; border: 1px solid black }
-th, table thead {
- background-color:#eee; color:#666666;
- font-weight: bold; cursor: default;
- text-align:center;
- font-weight: bold; font-family: Verdana;
- white-space:nowrap;
-}
-.W { font-size:0px }
-th, td { padding:5px; padding-left:8px; text-align:left }
-td.SUMM_DESC { padding-left:12px }
-td.DESC { white-space:pre }
-td.Q { text-align:right }
-td { text-align:left }
-tbody.scrollContent { overflow:auto }
-
-table.form_group {
- background-color: #ccc;
- border: 1px solid #333;
- padding: 2px;
-}
-
-table.form_inner_group {
- background-color: #ccc;
- border: 1px solid #333;
- padding: 0px;
-}
-
-table.form {
- background-color: #999;
- border: 1px solid #333;
- padding: 2px;
-}
-
-td.form_label {
- text-align: right;
- vertical-align: top;
-}
-/* For one line entires */
-td.form_clabel {
- text-align: right;
- vertical-align: center;
-}
-td.form_value {
- text-align: left;
- vertical-align: top;
-}
-td.form_submit {
- text-align: right;
- vertical-align: top;
-}
-
-h1.SubmitFail {
- color: #f00;
-}
-h1.SubmitOk {
-}
diff --git a/clang/utils/sorttable.js b/clang/utils/sorttable.js
deleted file mode 100644
index 4352d3be0a5f..000000000000
--- a/clang/utils/sorttable.js
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- SortTable
- version 2
- 7th April 2007
- Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
-
- Instructions:
- Download this file
- Add <script src="sorttable.js"></script> to your HTML
- Add class="sortable" to any table you'd like to make sortable
- Click on the headers to sort
-
- Thanks to many, many people for contributions and suggestions.
- Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
- This basically means: do what you want with it.
-*/
-
-
-var stIsIE = /*@cc_on!@*/false;
-
-sorttable = {
- init: function() {
- // quit if this function has already been called
- if (arguments.callee.done) return;
- // flag this function so we don't do the same thing twice
- arguments.callee.done = true;
- // kill the timer
- if (_timer) clearInterval(_timer);
-
- if (!document.createElement || !document.getElementsByTagName) return;
-
- sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-
- forEach(document.getElementsByTagName('table'), function(table) {
- if (table.className.search(/\bsortable\b/) != -1) {
- sorttable.makeSortable(table);
- }
- });
-
- },
-
- makeSortable: function(table) {
- if (table.getElementsByTagName('thead').length == 0) {
- // table doesn't have a tHead. Since it should have, create one and
- // put the first table row in it.
- the = document.createElement('thead');
- the.appendChild(table.rows[0]);
- table.insertBefore(the,table.firstChild);
- }
- // Safari doesn't support table.tHead, sigh
- if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-
- if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-
- // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
- // "total" rows, for example). This is B&R, since what you're supposed
- // to do is put them in a tfoot. So, if there are sortbottom rows,
- // for backwards compatibility, move them to tfoot (creating it if needed).
- sortbottomrows = [];
- for (var i=0; i<table.rows.length; i++) {
- if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
- sortbottomrows[sortbottomrows.length] = table.rows[i];
- }
- }
- if (sortbottomrows) {
- if (table.tFoot == null) {
- // table doesn't have a tfoot. Create one.
- tfo = document.createElement('tfoot');
- table.appendChild(tfo);
- }
- for (var i=0; i<sortbottomrows.length; i++) {
- tfo.appendChild(sortbottomrows[i]);
- }
- delete sortbottomrows;
- }
-
- // work through each column and calculate its type
- headrow = table.tHead.rows[0].cells;
- for (var i=0; i<headrow.length; i++) {
- // manually override the type with a sorttable_type attribute
- if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
- mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
- if (mtch) { override = mtch[1]; }
- if (mtch && typeof sorttable["sort_"+override] == 'function') {
- headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
- } else {
- headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
- }
- // make it clickable to sort
- headrow[i].sorttable_columnindex = i;
- headrow[i].sorttable_tbody = table.tBodies[0];
- dean_addEvent(headrow[i],"click", function(e) {
-
- if (this.className.search(/\bsorttable_sorted\b/) != -1) {
- // if we're already sorted by this column, just
- // reverse the table, which is quicker
- sorttable.reverse(this.sorttable_tbody);
- this.className = this.className.replace('sorttable_sorted',
- 'sorttable_sorted_reverse');
- this.removeChild(document.getElementById('sorttable_sortfwdind'));
- sortrevind = document.createElement('span');
- sortrevind.id = "sorttable_sortrevind";
- sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
- this.appendChild(sortrevind);
- return;
- }
- if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
- // if we're already sorted by this column in reverse, just
- // re-reverse the table, which is quicker
- sorttable.reverse(this.sorttable_tbody);
- this.className = this.className.replace('sorttable_sorted_reverse',
- 'sorttable_sorted');
- this.removeChild(document.getElementById('sorttable_sortrevind'));
- sortfwdind = document.createElement('span');
- sortfwdind.id = "sorttable_sortfwdind";
- sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
- this.appendChild(sortfwdind);
- return;
- }
-
- // remove sorttable_sorted classes
- theadrow = this.parentNode;
- forEach(theadrow.childNodes, function(cell) {
- if (cell.nodeType == 1) { // an element
- cell.className = cell.className.replace('sorttable_sorted_reverse','');
- cell.className = cell.className.replace('sorttable_sorted','');
- }
- });
- sortfwdind = document.getElementById('sorttable_sortfwdind');
- if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
- sortrevind = document.getElementById('sorttable_sortrevind');
- if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-
- this.className += ' sorttable_sorted';
- sortfwdind = document.createElement('span');
- sortfwdind.id = "sorttable_sortfwdind";
- sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
- this.appendChild(sortfwdind);
-
- // build an array to sort. This is a Schwartzian transform thing,
- // i.e., we "decorate" each row with the actual sort key,
- // sort based on the sort keys, and then put the rows back in order
- // which is a lot faster because you only do getInnerText once per row
- row_array = [];
- col = this.sorttable_columnindex;
- rows = this.sorttable_tbody.rows;
- for (var j=0; j<rows.length; j++) {
- row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
- }
- /* If you want a stable sort, uncomment the following line */
- sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
- /* and comment out this one */
- //row_array.sort(this.sorttable_sortfunction);
-
- tb = this.sorttable_tbody;
- for (var j=0; j<row_array.length; j++) {
- tb.appendChild(row_array[j][1]);
- }
-
- delete row_array;
- });
- }
- }
- },
-
- guessType: function(table, column) {
- // guess the type of a column based on its first non-blank row
- sortfn = sorttable.sort_alpha;
- for (var i=0; i<table.tBodies[0].rows.length; i++) {
- text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
- if (text != '') {
- if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
- return sorttable.sort_numeric;
- }
- // check for a date: dd/mm/yyyy or dd/mm/yy
- // can have / or . or - as separator
- // can be mm/dd as well
- possdate = text.match(sorttable.DATE_RE)
- if (possdate) {
- // looks like a date
- first = parseInt(possdate[1]);
- second = parseInt(possdate[2]);
- if (first > 12) {
- // definitely dd/mm
- return sorttable.sort_ddmm;
- } else if (second > 12) {
- return sorttable.sort_mmdd;
- } else {
- // looks like a date, but we can't tell which, so assume
- // that it's dd/mm (English imperialism!) and keep looking
- sortfn = sorttable.sort_ddmm;
- }
- }
- }
- }
- return sortfn;
- },
-
- getInnerText: function(node) {
- // gets the text we want to use for sorting for a cell.
- // strips leading and trailing whitespace.
- // this is *not* a generic getInnerText function; it's special to sorttable.
- // for example, you can override the cell text with a customkey attribute.
- // it also gets .value for <input> fields.
-
- hasInputs = (typeof node.getElementsByTagName == 'function') &&
- node.getElementsByTagName('input').length;
-
- if (node.getAttribute("sorttable_customkey") != null) {
- return node.getAttribute("sorttable_customkey");
- }
- else if (typeof node.textContent != 'undefined' && !hasInputs) {
- return node.textContent.replace(/^\s+|\s+$/g, '');
- }
- else if (typeof node.innerText != 'undefined' && !hasInputs) {
- return node.innerText.replace(/^\s+|\s+$/g, '');
- }
- else if (typeof node.text != 'undefined' && !hasInputs) {
- return node.text.replace(/^\s+|\s+$/g, '');
- }
- else {
- switch (node.nodeType) {
- case 3:
- if (node.nodeName.toLowerCase() == 'input') {
- return node.value.replace(/^\s+|\s+$/g, '');
- }
- case 4:
- return node.nodeValue.replace(/^\s+|\s+$/g, '');
- break;
- case 1:
- case 11:
- var innerText = '';
- for (var i = 0; i < node.childNodes.length; i++) {
- innerText += sorttable.getInnerText(node.childNodes[i]);
- }
- return innerText.replace(/^\s+|\s+$/g, '');
- break;
- default:
- return '';
- }
- }
- },
-
- reverse: function(tbody) {
- // reverse the rows in a tbody
- newrows = [];
- for (var i=0; i<tbody.rows.length; i++) {
- newrows[newrows.length] = tbody.rows[i];
- }
- for (var i=newrows.length-1; i>=0; i--) {
- tbody.appendChild(newrows[i]);
- }
- delete newrows;
- },
-
- /* sort functions
- each sort function takes two parameters, a and b
- you are comparing a[0] and b[0] */
- sort_numeric: function(a,b) {
- aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
- if (isNaN(aa)) aa = 0;
- bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
- if (isNaN(bb)) bb = 0;
- return aa-bb;
- },
- sort_alpha: function(a,b) {
- if (a[0]==b[0]) return 0;
- if (a[0]<b[0]) return -1;
- return 1;
- },
- sort_ddmm: function(a,b) {
- mtch = a[0].match(sorttable.DATE_RE);
- y = mtch[3]; m = mtch[2]; d = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt1 = y+m+d;
- mtch = b[0].match(sorttable.DATE_RE);
- y = mtch[3]; m = mtch[2]; d = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt2 = y+m+d;
- if (dt1==dt2) return 0;
- if (dt1<dt2) return -1;
- return 1;
- },
- sort_mmdd: function(a,b) {
- mtch = a[0].match(sorttable.DATE_RE);
- y = mtch[3]; d = mtch[2]; m = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt1 = y+m+d;
- mtch = b[0].match(sorttable.DATE_RE);
- y = mtch[3]; d = mtch[2]; m = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt2 = y+m+d;
- if (dt1==dt2) return 0;
- if (dt1<dt2) return -1;
- return 1;
- },
-
- shaker_sort: function(list, comp_func) {
- // A stable sort function to allow multi-level sorting of data
- // see: http://en.wikipedia.org/wiki/Cocktail_sort
- // thanks to Joseph Nahmias
- var b = 0;
- var t = list.length - 1;
- var swap = true;
-
- while(swap) {
- swap = false;
- for(var i = b; i < t; ++i) {
- if ( comp_func(list[i], list[i+1]) > 0 ) {
- var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
- swap = true;
- }
- } // for
- t--;
-
- if (!swap) break;
-
- for(var i = t; i > b; --i) {
- if ( comp_func(list[i], list[i-1]) < 0 ) {
- var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
- swap = true;
- }
- } // for
- b++;
-
- } // while(swap)
- }
-}
-
-/* ******************************************************************
- Supporting functions: bundled here to avoid depending on a library
- ****************************************************************** */
-
-// Dean Edwards/Matthias Miller/John Resig
-
-/* for Mozilla/Opera9 */
-if (document.addEventListener) {
- document.addEventListener("DOMContentLoaded", sorttable.init, false);
-}
-
-/* for Internet Explorer */
-/*@cc_on @*/
-/*@if (@_win32)
- document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
- var script = document.getElementById("__ie_onload");
- script.onreadystatechange = function() {
- if (this.readyState == "complete") {
- sorttable.init(); // call the onload handler
- }
- };
-/*@end @*/
-
-/* for Safari */
-if (/WebKit/i.test(navigator.userAgent)) { // sniff
- var _timer = setInterval(function() {
- if (/loaded|complete/.test(document.readyState)) {
- sorttable.init(); // call the onload handler
- }
- }, 10);
-}
-
-/* for other browsers */
-window.onload = sorttable.init;
-
-// written by Dean Edwards, 2005
-// with input from Tino Zijdel, Matthias Miller, Diego Perini
-
-// http://dean.edwards.name/weblog/2005/10/add-event/
-
-function dean_addEvent(element, type, handler) {
- if (element.addEventListener) {
- element.addEventListener(type, handler, false);
- } else {
- // assign each event handler a unique ID
- if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
- // create a hash table of event types for the element
- if (!element.events) element.events = {};
- // create a hash table of event handlers for each element/event pair
- var handlers = element.events[type];
- if (!handlers) {
- handlers = element.events[type] = {};
- // store the existing event handler (if there is one)
- if (element["on" + type]) {
- handlers[0] = element["on" + type];
- }
- }
- // store the event handler in the hash table
- handlers[handler.$$guid] = handler;
- // assign a global event handler to do all the work
- element["on" + type] = handleEvent;
- }
-};
-// a counter used to create unique IDs
-dean_addEvent.guid = 1;
-
-function removeEvent(element, type, handler) {
- if (element.removeEventListener) {
- element.removeEventListener(type, handler, false);
- } else {
- // delete the event handler from the hash table
- if (element.events && element.events[type]) {
- delete element.events[type][handler.$$guid];
- }
- }
-};
-
-function handleEvent(event) {
- var returnValue = true;
- // grab the event object (IE uses a global event object)
- event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
- // get a reference to the hash table of event handlers
- var handlers = this.events[event.type];
- // execute each event handler
- for (var i in handlers) {
- this.$$handleEvent = handlers[i];
- if (this.$$handleEvent(event) === false) {
- returnValue = false;
- }
- }
- return returnValue;
-};
-
-function fixEvent(event) {
- // add W3C standard event methods
- event.preventDefault = fixEvent.preventDefault;
- event.stopPropagation = fixEvent.stopPropagation;
- return event;
-};
-fixEvent.preventDefault = function() {
- this.returnValue = false;
-};
-fixEvent.stopPropagation = function() {
- this.cancelBubble = true;
-}
-
-// Dean's forEach: http://dean.edwards.name/base/forEach.js
-/*
- forEach, version 1.0
- Copyright 2006, Dean Edwards
- License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-// array-like enumeration
-if (!Array.forEach) { // mozilla already supports this
- Array.forEach = function(array, block, context) {
- for (var i = 0; i < array.length; i++) {
- block.call(context, array[i], i, array);
- }
- };
-}
-
-// generic enumeration
-Function.prototype.forEach = function(object, block, context) {
- for (var key in object) {
- if (typeof this.prototype[key] == "undefined") {
- block.call(context, object[key], key, object);
- }
- }
-};
-
-// character enumeration
-String.forEach = function(string, block, context) {
- Array.forEach(string.split(""), function(chr, index) {
- block.call(context, chr, index, string);
- });
-};
-
-// globally resolve forEach enumeration
-var forEach = function(object, block, context) {
- if (object) {
- var resolve = Object; // default
- if (object instanceof Function) {
- // functions have a "length" property
- resolve = Function;
- } else if (object.forEach instanceof Function) {
- // the object implements a custom forEach method so use that
- object.forEach(block, context);
- return;
- } else if (typeof object == "string") {
- // the object is a string
- resolve = String;
- } else if (typeof object.length == "number") {
- // the object is array-like
- resolve = Array;
- }
- resolve.forEach(object, block, context);
- }
-};
-
diff --git a/clang/utils/ubiviz b/clang/utils/ubiviz
deleted file mode 100755
index 1582797c63f9..000000000000
--- a/clang/utils/ubiviz
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This script reads visualization data emitted by the static analyzer for
-# display in Ubigraph.
-#
-##===----------------------------------------------------------------------===##
-
-import xmlrpclib
-import sys
-
-def Error(message):
- print >> sys.stderr, 'ubiviz: ' + message
- sys.exit(1)
-
-def StreamData(filename):
- file = open(filename)
- for ln in file:
- yield eval(ln)
- file.close()
-
-def Display(G, data):
- action = data[0]
- if action == 'vertex':
- vertex = data[1]
- G.new_vertex_w_id(vertex)
- for attribute in data[2:]:
- G.set_vertex_attribute(vertex, attribute[0], attribute[1])
- elif action == 'edge':
- src = data[1]
- dst = data[2]
- edge = G.new_edge(src,dst)
- for attribute in data[3:]:
- G.set_edge_attribute(edge, attribute[0], attribute[1])
- elif action == "vertex_style":
- style_id = data[1]
- parent_id = data[2]
- G.new_vertex_style_w_id(style_id, parent_id)
- for attribute in data[3:]:
- G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
- elif action == "vertex_style_attribute":
- style_id = data[1]
- for attribute in data[2:]:
- G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
- elif action == "change_vertex_style":
- vertex_id = data[1]
- style_id = data[2]
- G.change_vertex_style(vertex_id,style_id)
-
-def main(args):
- if len(args) == 0:
- Error('no input files')
-
- server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
- G = server.ubigraph
-
- for arg in args:
- G.clear()
- for x in StreamData(arg):
- Display(G,x)
-
- sys.exit(0)
-
-
-if __name__ == '__main__':
- main(sys.argv[1:])
-
- \ No newline at end of file
diff --git a/clang/win32/clangAST/clangAST.vcproj b/clang/win32/clangAST/clangAST.vcproj
deleted file mode 100644
index 225c36e5635d..000000000000
--- a/clang/win32/clangAST/clangAST.vcproj
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangAST"
- ProjectGUID="{5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}"
- RootNamespace="clangAST"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\AST\ASTConsumer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\ASTContext.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\Builtins.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\CFG.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\Decl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\DeclBase.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\DeclCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\DeclObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\DeclSerialization.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\Expr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\ExprConstant.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\ExprCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\ParentMap.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\Stmt.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\StmtDumper.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\StmtIterator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\StmtPrinter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\StmtSerialization.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\StmtViz.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\TranslationUnit.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\Type.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\TypeSerialization.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\AST\AST.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\ASTConsumer.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\ASTContext.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\Builtins.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\CFG.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\Decl.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\DeclCXX.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\DeclObjC.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\Expr.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\ExprCXX.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\ParentMap.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\PrettyPrinter.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\RecordLayout.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\Stmt.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\StmtGraphTraits.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\StmtIterator.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\StmtVisitor.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\Type.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangAnalysis/clangAnalysis.vcproj b/clang/win32/clangAnalysis/clangAnalysis.vcproj
deleted file mode 100644
index f0f6c6618dcf..000000000000
--- a/clang/win32/clangAnalysis/clangAnalysis.vcproj
+++ /dev/null
@@ -1,347 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangAnalysis"
- ProjectGUID="{6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}"
- RootNamespace="clangAnalysis"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Analysis\BasicConstraintManager.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\BasicObjCFoundationChecks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\BasicObjCFoundationChecks.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\BasicStore.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\BasicValueFactory.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\BugReporter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\CFRefCount.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\CheckDeadStores.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\CheckNSError.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\CheckObjCDealloc.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\CheckObjCInstMethSignature.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\CheckObjCUnusedIVars.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\Environment.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\ExplodedGraph.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRBlockCounter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRCoreEngine.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRExprEngine.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRExprEngineInternalChecks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRSimpleVals.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRSimpleVals.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRState.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRTransferFuncs.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\LiveVariables.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\MemRegion.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\PathDiagnostic.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\RValues.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\SymbolManager.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\UninitializedValues.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\Analysis\ExprDeclBitVector.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\LiveVariables.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\LocalCheckers.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\ProgramEdge.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\UninitializedValues.h"
- >
- </File>
- <Filter
- Name="Visitors"
- >
- <File
- RelativePath="..\..\include\clang\Analysis\Visitors\CFGRecStmtDeclVisitor.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\Visitors\CFGRecStmtVisitor.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\Visitors\CFGStmtVisitor.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\Visitors\CFGVarDeclVisitor.h"
- >
- </File>
- </Filter>
- <Filter
- Name="ADT"
- >
- <File
- RelativePath="..\..\include\clang\Analysis\ADT\PersistentMap.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Support"
- >
- <File
- RelativePath="..\..\include\clang\Analysis\Support\IntrusiveSPtr.h"
- >
- </File>
- </Filter>
- <Filter
- Name="FlowSensitive"
- >
- <File
- RelativePath="..\..\include\clang\Analysis\FlowSensitive\DataflowSolver.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Analysis\FlowSensitive\DataflowValues.h"
- >
- </File>
- </Filter>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangBasic/clangBasic.vcproj b/clang/win32/clangBasic/clangBasic.vcproj
deleted file mode 100644
index d836a6604c73..000000000000
--- a/clang/win32/clangBasic/clangBasic.vcproj
+++ /dev/null
@@ -1,236 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangBasic"
- ProjectGUID="{298B4876-6EF1-4E80-85D7-72F80693BBEB}"
- RootNamespace="Basic"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\clangBasic.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)\clangBasic.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\clangBasic.pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4355,4146,4800"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)\clangBasic.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Basic\Diagnostic.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\FileManager.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\IdentifierTable.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\LangOptions.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\SourceLocation.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\SourceManager.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\TargetInfo.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\Targets.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Basic\TokenKinds.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\Basic\Diagnostic.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\FileManager.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\IdentifierTable.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\LangOptions.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\SourceLocation.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\SourceManager.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\TargetInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Basic\TokenKinds.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangCodeGen/clangCodeGen.vcproj b/clang/win32/clangCodeGen/clangCodeGen.vcproj
deleted file mode 100644
index a819fd94d867..000000000000
--- a/clang/win32/clangCodeGen/clangCodeGen.vcproj
+++ /dev/null
@@ -1,271 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="clangCodeGen"
- ProjectGUID="{4CEC5897-D957-47E7-A6AE-2021D4F44A8F}"
- RootNamespace="clangCodeGen"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\CodeGen\CGBuiltin.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGCall.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGDebugInfo.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGDecl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGExpr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGExprAgg.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGExprComplex.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGExprConstant.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGExprScalar.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGObjCGNU.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGObjCMac.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGStmt.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CodeGenFunction.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CodeGenModule.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CodeGenTypes.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\ModuleBuilder.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\lib\CodeGen\CGCall.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGDebugInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGObjCRuntime.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CGValue.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CodeGenFunction.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CodeGenModule.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\CodeGen\CodeGenTypes.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\CodeGen\ModuleBuilder.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangDriver/clangDriver.vcproj b/clang/win32/clangDriver/clangDriver.vcproj
deleted file mode 100644
index b95f03136c9e..000000000000
--- a/clang/win32/clangDriver/clangDriver.vcproj
+++ /dev/null
@@ -1,256 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangDriver"
- ProjectGUID="{7E7DA455-C276-4B93-8D02-8F7E2F629BAF}"
- RootNamespace="clangDriver"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- ManagedExtensions="0"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4355,4146,4800"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\clang.exe"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(TargetDir)/clang.pdb"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4355,4146,4800"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\clang.exe"
- LinkIncremental="1"
- GenerateDebugInformation="true"
- ProgramDatabaseFile="$(TargetDir)/clang.pdb"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\Driver\AnalysisConsumer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\ASTConsumers.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\clang.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\DiagChecker.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\HTMLPrint.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\PrintParserCallbacks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\PrintPreprocessedOutput.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\RewriteBlocks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\RewriteMacros.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\RewriteObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\SerializationTest.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\Driver\AnalysisConsumer.h"
- >
- </File>
- <File
- RelativePath="..\..\Driver\ASTConsumers.h"
- >
- </File>
- <File
- RelativePath="..\..\Driver\clang.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangLex/clangLex.vcproj b/clang/win32/clangLex/clangLex.vcproj
deleted file mode 100644
index e8d3041e833b..000000000000
--- a/clang/win32/clangLex/clangLex.vcproj
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangLex"
- ProjectGUID="{030F6909-B2FA-4E53-BEA7-9A559CFC2F73}"
- RootNamespace="clangLex"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Lex\HeaderMap.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\HeaderSearch.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\Lexer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\LiteralSupport.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\MacroArgs.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\MacroInfo.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\PPCaching.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\PPDirectives.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\PPExpressions.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\PPLexerChange.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\PPMacroExpansion.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\Pragma.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\Preprocessor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\ScratchBuffer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Lex\TokenLexer.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\Lex\DirectoryLookup.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\HeaderSearch.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\Lexer.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\LiteralSupport.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\MacroExpander.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\MacroInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\MultipleIncludeOpt.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\PPCallbacks.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\Pragma.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\Preprocessor.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\ScratchBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Lex\Token.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangLibDriver/clangLibDriver.vcproj b/clang/win32/clangLibDriver/clangLibDriver.vcproj
deleted file mode 100644
index 316814d572bf..000000000000
--- a/clang/win32/clangLibDriver/clangLibDriver.vcproj
+++ /dev/null
@@ -1,193 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangLibDriver"
- ProjectGUID="{AECB78DF-C319-4D49-B2FD-F98F62EBBDF4}"
- RootNamespace="clangLibDriver"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Driver\HTMLDiagnostics.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Driver\InitHeaderSearch.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Driver\TextDiagnosticBuffer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Driver\TextDiagnosticPrinter.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\Driver\HTMLDiagnostics.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Driver\InitHeaderSearch.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Driver\TextDiagnosticBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Driver\TextDiagnosticPrinter.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangParse/clangParse.vcproj b/clang/win32/clangParse/clangParse.vcproj
deleted file mode 100644
index ba217cb6cf89..000000000000
--- a/clang/win32/clangParse/clangParse.vcproj
+++ /dev/null
@@ -1,243 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangParse"
- ProjectGUID="{05DF3074-11AF-491A-B078-83BD2EDC31F6}"
- RootNamespace="clangParse"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Parse\AttributeList.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\DeclSpec.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\MinimalAction.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseCXXInlineMethods.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseDecl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseDeclCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseExpr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseExprCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseInit.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseObjc.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParsePragma.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\Parser.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseStmt.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseTentative.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\Parse\Action.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Parse\AttributeList.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Parse\DeclSpec.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Parse\Parser.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Parse\Scope.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangRewrite/clangRewrite.vcproj b/clang/win32/clangRewrite/clangRewrite.vcproj
deleted file mode 100644
index 0573c6a1c04d..000000000000
--- a/clang/win32/clangRewrite/clangRewrite.vcproj
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangRewrite"
- ProjectGUID="{F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}"
- RootNamespace="clangRewrite"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Rewrite\DeltaTree.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Rewrite\HTMLRewrite.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Rewrite\Rewriter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Rewrite\RewriteRope.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\include\clang\Rewrite\Rewriter.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\Rewrite\RewriteRope.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/win32/clangSema/clangSema.vcproj b/clang/win32/clangSema/clangSema.vcproj
deleted file mode 100644
index 96a57466d0bf..000000000000
--- a/clang/win32/clangSema/clangSema.vcproj
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="clangSema"
- ProjectGUID="{4727E8B7-AA99-41C9-AB09-A8A862595DB7}"
- RootNamespace="clangSema"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- InheritedPropertySheets="..\..\..\..\win32\common.vsprops"
- CharacterSet="2"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\include;..\..\..\..\include;..\..\..\..\win32"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__STDC_LIMIT_MACROS"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- DisableSpecificWarnings="4146"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\lib\Sema\IdentifierResolver.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\ParseAST.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\Sema.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaChecking.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaDecl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaDeclAttr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaDeclCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaDeclObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaExpr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaExprCXX.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaExprObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaInit.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaStmt.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaType.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\lib\Sema\CXXFieldCollector.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\IdentifierResolver.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\Sema.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\SemaUtil.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/www/CheckerNotes.html b/clang/www/CheckerNotes.html
deleted file mode 100644
index 523048de7690..000000000000
--- a/clang/www/CheckerNotes.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-<title>Static Analysis</title>
-<meta http-equiv="REFRESH" content="0;url=http://clang.llvm.org/StaticAnalysis.html"></HEAD>
-<BODY>
-This page has relocated: <a href="http://clang.llvm.org/StaticAnalysis.html">http://clang.llvm.org/StaticAnalysis.html</a>.
-</BODY>
-</HTML>
diff --git a/clang/www/StaticAnalysis.html b/clang/www/StaticAnalysis.html
deleted file mode 100644
index 29df8b9cca63..000000000000
--- a/clang/www/StaticAnalysis.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <title>LLVM/Clang Static Analyzer</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<h1>LLVM/Clang Static Analyzer</h1>
-
-<p>The LLVM/Clang static analyzer is a standalone tool that find bugs in C and
-Objective-C programs. Currently the analyzer is invoked as a command-line tool.
-It is intended to run in tandem with a build of a project or code base.</p>
-
-<p>Here are some important points we ask you to consider when using the static
-analyzer:</p>
-
-<ul>
-
-<li><b>This tool is <b>very early</b> in development.</b> There are many planned
-enhancements to improve both the precision and scope of its analysis algorithms
-as well as the kinds bugs it will find.</li>
-
-<li><b>Static analysis can be much slower than compilation.</b> While the
-analyzer is being designed to be as fast and light-weight as possible, please do
-not expect it to be as fast as compiling a program (even with optimizations
-enabled). Some of the algorithms needed to find bugs require in the worst case
-exponential time. The analyzer runs in a reasonable amount of time by both
-bounding the amount of checking work it will do as well as using clever
-algorithms to reduce the amount of work it must do to find bugs.</li>
-
-<li><b>False positives.</b> Static analysis is not perfect. It can falsely flag
-bugs in a program where the code behaves correctly. Because some code checks
-require more analysis precision than others, the frequency of false positives
-can vary widely between different checks. Our eventual goal is to have the
-analyzer have a low false positive rate for most code on all checks.</li>
-</ul>
-
-<h3>Please tell us about False Positives</h3>
-
-<p>If you encounter a false positive, <b>please let us know</b> by <a
-href="StaticAnalysisUsage.html#filingbugs">filing a bug report</a>. False
-positives cannot be addressed unless we know about them.</p>
-
-<h3>Want more bugs?</h3>
-
-<p>If there are specific kinds of bugs you would like the tool to find,
-please feel free to file <a href="StaticAnalysisUsage.html#filingbugs">feature
-requests</a>.</p>
-
-<!-- Generated from: http://www.spiffycorners.com/index.php -->
-
-<style type="text/css">
-.spiffy{display:block}
-.spiffy *{
- display:block;
- height:1px;
- overflow:hidden;
- font-size:.01em;
- background:#EBF0FA}
-.spiffy1{
- margin-left:3px;
- margin-right:3px;
- padding-left:1px;
- padding-right:1px;
- border-left:1px solid #f6f8fc;
- border-right:1px solid #f6f8fc;
- background:#f0f3fb}
-.spiffy2{
- margin-left:1px;
- margin-right:1px;
- padding-right:1px;
- padding-left:1px;
- border-left:1px solid #fdfdfe;
- border-right:1px solid #fdfdfe;
- background:#eef2fa}
-.spiffy3{
- margin-left:1px;
- margin-right:1px;
- border-left:1px solid #eef2fa;
- border-right:1px solid #eef2fa;}
-.spiffy4{
- border-left:1px solid #f6f8fc;
- border-right:1px solid #f6f8fc}
-.spiffy5{
- border-left:1px solid #f0f3fb;
- border-right:1px solid #f0f3fb}
-.spiffyfg{
- background:#EBF0FA}
-
-.spiffyfg h2 {
- margin:0px; padding:10px;
-}
-</style>
-
-<style type="text/css">
- #left { float:left; }
- #left h2 { margin:1px; padding-top:0px; }
- #right { float:left; margin-left:50px; padding:0px ;}
- #right h2 { padding:0px; margin:0px; }
- #wrappedcontent { padding:15px;}
-</style>
-
-<div id="left">
- <h2>Using the Analyzer</h2>
- <ul>
- <li><a href="StaticAnalysisUsage.html#Obtaining">Obtaining the Analyzer</a></li>
- <li><a href="StaticAnalysisUsage.html#BasicUsage">Basic Usage</a></li>
- <li><a href="StaticAnalysisUsage.html#Output">Output of the Analyzer</a></li>
- <li><a href="StaticAnalysisUsage.html#RecommendedUsageGuidelines">Recommended Usage Guidelines</a></li>
- <li><a href="StaticAnalysisUsage.html#Debugging">Debugging the Analyzer</a></li>
- <li><a href="StaticAnalysisUsage.html#filingbugs">Filing Bugs and Feature Requests</a></li>
- </ul>
-</div>
-
-<div id="right">
- <b class="spiffy">
- <b class="spiffy1"><b></b></b>
- <b class="spiffy2"><b></b></b>
- <b class="spiffy3"></b>
- <b class="spiffy4"></b>
- <b class="spiffy5"></b></b>
-
- <div class="spiffyfg">
- <div id="wrappedcontent">
- <h2>Download</h2>
- <ul>
- <li>Mac OS X (Intel-only, 10.5+):
- <p>
- <!--#include virtual="latest_checker.html.incl"-->
- </p>
- </li>
- <li><a href="StaticAnalysisUsage.html#OtherUsage">Other Platforms</a> (Building from Source)</li>
- </div>
-
- </div>
-
- <b class="spiffy">
- <b class="spiffy5"></b>
- <b class="spiffy4"></b>
- <b class="spiffy3"></b>
- <b class="spiffy2"><b></b></b>
- <b class="spiffy1"><b></b></b></b>
-</div>
-
-
-</div>
-</body>
-</html>
-
diff --git a/clang/www/StaticAnalysisUsage.html b/clang/www/StaticAnalysisUsage.html
deleted file mode 100644
index daab89f724aa..000000000000
--- a/clang/www/StaticAnalysisUsage.html
+++ /dev/null
@@ -1,274 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <title>Information on using the Static Analyzer ("Clang Checker")</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
- <style>
- thead {
- background-color:#eee; color:#666666;
- font-weight: bold; cursor: default;
- text-align:center;
- border-top: 2px solid #000000;
- border-bottom: 2px solid #000000;
- font-weight: bold; font-family: Verdana
- }
- table { border: 1px #000000 solid }
- table { border-collapse: collapse; border-spacing: 0px }
- table { margin-left:20px; margin-top:20px; margin-bottom:20px }
- td { border-bottom: 1px #000000 dotted }
- td { padding:5px; padding-left:8px; padding-right:8px }
- td { text-align:left; font-size:9pt }
- td.View { padding-left: 10px }
- </style>
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<h1>Information on using the Static Analyzer</h1>
-
-<h2 id="Obtaining">Obtaining the Analyzer</h2>
-
-<p> Using the analyzer involves executing <tt>scan-build</tt> (see <a
-href="#BasicUsage">Basic Usage</a>). <tt>scan-build</tt> will first look for a
-<tt>clang</tt> executable in the same directory as <tt>scan-build</tt>, and then
-search your path.</p>
-
-<p>If one is using the analyzer directly from the Clang sources, it suffices to
-just directly execute <tt>scan-build</tt> in the <tt>utils</tt> directory. No
-other special installation is needed.</p>
-
-<h3>Packaged Builds (Mac OS X)</h3>
-
-<p>Semi-regular pre-built binaries of the analyzer are available on Mac OS X
-(10.5).</p>
-
-<p>The latest build is:
- <!--#include virtual="latest_checker.html.incl"-->
-</p>
-
-Packaged builds for other platforms may eventually be provided, but as the tool
-is in its early stages we are not actively promoting releases yet. If you wish
-to help contribute regular builds of the analyzer on other platforms, please
-email the <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">Clang
-Developers' mailing list</a>.</p>
-
-<p>Packaged builds of the analyzer expand to the following files:</p>
-
-<table id="package">
-<thead><tr><td>File</td><td>Purpose</td></tr></thead>
-<tr><td><tt><b>scan-build</b></tt></td><td>Script for running the analyzer over a project build. <b>This is the only file you care about.</b></td></tr>
-<tr><td><tt>ccc-analyzer</tt></td><td>GCC interceptor (called by scan-build)</td></tr>
-<tr><td><tt>clang</tt></td><td>Static Analyzer (called by ccc-analyzer)</td><tr>
-<tr><td><tt>sorttable.js</tt></td><td>JavaScript used for displaying error reports</td></tr>
-</table>
-
-<h3 id="OtherPlatforms">Other Platforms (Building the Analyzer from Source)</h3>
-
-<p>Packaged builds simply consist of a few files from the Clang source tree,
-meaning that <b>anyone</b> who can build Clang can use the static analyzer.
-Please see the <a href="get_started.html">Getting Started</a> page for more
-details on downloading and compiling Clang.</p>
-
-<p>All files used by the analyzer (and included in packaged builds; <a
-href="#package">see above</a>) other than a compiled <tt>clang</tt> executable
-are found in the <tt>utils</tt> subdirectory in the Clang tree.</p>
-
-<h2 id="BasicUsage">Basic Usage</h2>
-
-<p>The analyzer is executed from the command-line. To run the analyzer, you will
-use <tt>scan-build</tt> to analyze the source files compiled by <tt>gcc</tt>
-during a project build.</p>
-
-<p>For example, to analyze the files compiled under a build:</p>
-
-<pre>
- $ <b>scan-build</b> make
- $ <b>scan-build</b> xcodebuild
-</pre>
-
-<p> In the first case <tt>scan-build</tt> analyzes the code of a project built
-with <tt>make</tt>, and in the second case <tt>scan-build</tt> analyzes a project
-built using <tt>xcodebuild</tt>. In general, the format is: </p>
-
-<pre>
- $ <b>scan-build</b> <i>[scan-build options]</i> <b>&lt;command&gt;</b> <i>[command options]</i>
-</pre>
-
-<p> Operationally, <tt>scan-build</tt> literally runs <command> with all of the
-subsequent options passed to it. For example:</p>
-
-<pre>
- $ scan-build make <b>-j4</b>
-</pre>
-
-<p>In this example, <tt>scan-build</tt> makes no effort to interpret the options
-after the build command (in this case, <tt>make</tt>); it just passes them
-through. In general, <tt>scan-build</tt> should support parallel builds, but
-<b>not distributed builds</b>. Similarly, you can use <tt>scan-build</tt> to
-analyze specific files:
-
-<pre>
- $ scan-build gcc -c <b>t1.c t2.c</b>
-</pre>
-
-<p>
-This example causes the files <tt>t1.c</tt> and <tt>t2.c</tt> to be analyzed.
-</p>
-
-<h3>Other Options</h3>
-
-<p>
-As mentioned above, extra options can be passed to <tt>scan-build</tt>. These
-options prefix the build command. For example:</p>
-
-<pre>
- $ scan-build <b>-k -V</b> make
- $ scan-build <b>-k -V</b> xcodebuild
-</pre>
-
-<p>Here is a subset of useful options:</p>
-
-<table>
- <thead><tr><td>Option</td><td>Description</td></tr></thead>
-
- <tr><td><b>-o</b></td><td>Target directory for HTML report files. Subdirectories will be
- created as needed to represent separate "runs" of the analyzer. If this option
-is not specified, a directory is created in <tt>/tmp</tt> to store the
-reports.</td><tr>
-
- <tr><td><b>-h</b><br><i><nobr>(or no arguments)</nobr></i></td><td>Display all <tt>scan-build</tt> options.</td></tr>
-
- <tr><td><b>-k</b><br><nobr><b>--keep-going</b></nobr></td><td>Add a "keep on going" option to the
- specified build command. <p>This option currently supports <tt>make</tt> and
- <tt>xcodebuild</tt>.</p> <p>This is a convenience option; one can specify this
- behavior directly using build options.</p></td></tr>
-
- <tr><td><b>-v<b></td><td>Verbose output from scan-build and the analyzer. <b>A second and third
- "-v" increases verbosity</b>, and is useful for filing bug reports against the analyzer.</td></tr>
-
- <tr><td><b>-V</b></td><td>View analysis results in a web browser when the build command completes.</td></tr>
-</table>
-
-<h2 id="Output">Output of the Analyzer</h2>
-
-<p>
-The output of the analyzer is a set of HTML files, each one which represents a
-separate bug report. A single <tt>index.html</tt> file is generated for
-surveying all of the bugs. You can then just open <tt>index.html</tt> in a web
-browser to view the bug reports.
-</p>
-
-<p>
-Where the HTML files are generated is specified with a <b>-o</b> option to
-<tt>scan-build</tt>. If <b>-o</b> isn't specified, a directory in <tt>/tmp</tt>
-is created to store the files (<tt>scan-build</tt> will print a message telling
-you where they are). If you want to view the reports immediately after the build
-completes, pass <b>-V</b> to <tt>scan-build</tt>.
-</p>
-
-
-<h2 id="RecommendedUsageGuidelines">Recommended Usage Guidelines</h2>
-
-Here are a few recommendations with running the analyzer:
-
-<h3>Always Analyze a Project in its "Debug" Configuration</h3>
-
-<p>Most projects can be built in a "debug" mode that enables assertions.
-Assertions are picked up by the static analyzer to prune infeasible paths, which
-in some cases can greatly reduce the number of false positives (bogus error
-reports) emitted by the tool.</p>
-
-<h3>Pass -k to scan-build</h3>
-
-<p>While <tt>ccc-analyzer</tt> invokes <tt>gcc</tt> to compile code, any
-problems in correctly forwarding arguments to <tt>gcc</tt> may result in a build
-failure. Passing <b>-k</b> to <tt>scan-build</tt> potentially allows you to
-analyze other code in a project for which this problem doesn't occur.</p>
-
-<p> Also, it is useful to analyze a project even if not all of the source files
-are compilable. This is great when using <tt>scan-build</tt> as part of your
-compile-debug cycle.</p>
-
-<h3>Use Verbose Output when Debugging scan-build</h3>
-
-<p><tt>scan-build</tt> takes a <b>-v</b> option to emit verbose output about
-what it's doing; two <b>-v</b> options emit more information. Redirecting the
-output of <tt>scan-build</tt> to a text file (make sure to redirect standard
-error) is useful for filing bug reports against <tt>scan-build</tt> or the
-analyzer, as we can see the exact options (and files) passed to the analyzer.
-For more comprehensible logs, don't perform a parallel build.</p>
-
-<h2 id="Debugging">Debugging the Analyzer</h2>
-
-<p>This section provides information on debugging the analyzer, and troubleshooting
-it when you have problems analyzing a particular project.</p>
-
-<h3>How it Works</h3>
-
-<p>To analyze a project, <tt>scan-build</tt> simply sets the environment variable
-<tt>CC</tt> to the full path to <tt>ccc-analyzer</tt>. It also sets a few other
-environment variables to communicate to <tt>ccc-analyzer</tt> where to dump HTML
-report files.</p>
-
-<p>Some Makefiles (or equivalent project files) hardcode the compiler; for such
-projects simply overriding <tt>CC</tt> won't cause <tt>ccc-analyzer</tt> to be
-called. This will cause the compiled code <b>to not be analyzed.</b></p> If you
-find that your code isn't being analyzed, check to see if <tt>CC</tt> is
-hardcoded. If this is the case, you can hardcode it instead to the <b>full
-path</b> to <tt>ccc-analyzer</tt>.</p>
-
-<p>When applicable, you can also run <tt>./configure</tt> for a project through
-<tt>scan-build</tt> so that configure sets up the location of <tt>CC</tt> based
-on the environment passed in from <tt>scan-build</tt>:
-
-<pre>
- $ scan-build <b>./configure</b>
-</pre>
-
-<p><tt>scan-build</tt> has special knowledge about <tt>configure</tt>, so it in
-most cases will not actually analyze the configure tests run by
-<tt>configure</tt>.</p>
-
-<p>Under the hood, <tt>ccc-analyzer</tt> directly invokes <tt>gcc</tt> to
-compile the actual code in addition to running the analyzer (which occurs by it
-calling <tt>clang</tt>). <tt>ccc-analyzer</tt> tries to correctly forward all
-the arguments over to <tt>gcc</tt>, but this may not work perfectly (please
-report bugs of this kind).
-
-<h2 id="filingbugs">Filing Bugs and Feature Requests</h2>
-
-<p>We encourage users to file bug reports for any problems that they encounter.
-We also welcome feature requests. When filing a bug report, please do the
-following:</p>
-
-<ul>
-
-<li>Include the checker build (for prebuilt Mac OS X binaries) or the SVN
-revision number.</li>
-
-<li>Provide a self-encapsulated, reduced test case that exhibits the issue
- you are experiencing.</li>
-
-<li>Test cases don't tell us everything. Please briefly describe the problem you are seeing.</li>
-
-</ul>
-
-<h3>Outside Apple</h3>
-
-<p>Please <a href="http://llvm.org/bugs/enter_bug.cgi?product=clang">file
-bugs</a> in LLVM's Bugzilla database against the Clang <b>Static Analyzer</b>
-component.</p>
-
-<h3>Apple-internal Users</h3>
-
-<p>Please file bugs in Radar against the <b>llvm - checker</b> component.</p>
-
-</div>
-</body>
-</html>
-
diff --git a/clang/www/carbon-compile.png b/clang/www/carbon-compile.png
deleted file mode 100644
index e8516c7055bb..000000000000
--- a/clang/www/carbon-compile.png
+++ /dev/null
Binary files differ
diff --git a/clang/www/clang_video-05-25-2007.html b/clang/www/clang_video-05-25-2007.html
deleted file mode 100644
index eb04761a9317..000000000000
--- a/clang/www/clang_video-05-25-2007.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>2007 LLVM Developer's Meeting</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
- <!--#include virtual="menu.html.incl"-->
- <div id="content">
- <h1>2007 LLVM Developer's Meeting</h1>
- Discussion about Clang at the <a href="http://llvm.org/devmtg/2007-05/">2007 LLVM Developer's Meeting</a>.
- <h2>About:</h2>
- <p>In this video, Steve Naroff introduces the Clang project and talks about some of the goals and motivations for starting the project.
- <br><br>
- <p><b>Details:</b> New LLVM C Front-end - This talk describes a new from-scratch C frontend (which is aiming to support Objective C and C++ someday) for LLVM, built as a native part of the LLVM system and in the LLVM design style.
- <h2>The Presentation:</h2>
- <p>You can download a copy of the presentation in mov format. However, due to the picture quality, it is recommended that you also download the lecture slides for viewing while you watch the video.
- <ul>
- <li><a href="http://llvm.org/devmtg/2007-05/09-Naroff-CFE.mov">Video (mov file)</a>
- <li><a href="http://llvm.org/devmtg/2007-05/09-Naroff-CFE.pdf">Lecture slides (PDF)</a>
- </ul>
- </div>
-</body>
-</html> \ No newline at end of file
diff --git a/clang/www/clang_video-07-25-2007.html b/clang/www/clang_video-07-25-2007.html
deleted file mode 100644
index 53959ef36756..000000000000
--- a/clang/www/clang_video-07-25-2007.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>LLVM 2.0 and Beyond!</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
- <!--#include virtual="menu.html.incl"-->
- <div id="content">
- <h1>LLVM 2.0 and Beyond!</h1>
- A Google Techtalk by <a href="http://www.nondot.org/sabre/">Chris Lattner</a>
- <h2>About:</h2>
- <p>In this video, Chris Lattner talks about some of the features of Clang, especially in regards to performance.
- <br><br>
- <p><b>Details:</b> The LLVM 2.0 release brings a number of new features and capabilities to the LLVM toolset. This talk briefly describes those features, then moves on to talk about what is next: llvm 2.1, llvm-gcc 4.2, and puts a special emphasis on the 'clang' C front-end. This describes how the 'clang' preprocessor can be used to improve the scalability of distcc by up to 4.4x.
- <h2>The Presentation:</h2>
- <p>You can view the presentation through google video. In addition, the slides from the presentation are also available, if you wish to retain a copy.
- <ul>
- <li><a href="http://video.google.com/videoplay?docid=1921156852099786640">Google Tech Talk Video (19:00-)</a> (Note: the Clang lecture starts at 19 minutes into the video.)
- <li><a href="http://llvm.org/pubs/2007-07-25-LLVM-2.0-and-Beyond.pdf">LLVM 2.0 and Beyond! slides (PDF)</a>
- </ul>
- <h2>Publishing Information:</h2>
- "LLVM 2.0 and Beyond!", Chris Lattner,<br>
- <i>Google Tech Talk</i>, Mountain View, CA, July 2007.
- </div>
-</body>
-</html> \ No newline at end of file
diff --git a/clang/www/comparison.html b/clang/www/comparison.html
deleted file mode 100644
index 0a13ea8637bc..000000000000
--- a/clang/www/comparison.html
+++ /dev/null
@@ -1,196 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>Comparing clang to other open source compilers</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
- <!--#include virtual="menu.html.incl"-->
- <div id="content">
- <h1>Clang vs Other Open Source Compilers</h1>
-
- <p>Building an entirely new compiler front-end is a big task, and it isn't
- always clear to people why we decided to do this. Here we compare clang
- and its goals to other open source compiler front-ends that are
- available. We restrict the discussion to very specific objective points
- to avoid controversy where possible. Also, software is infinitely
- mutable, so we don't talk about little details that can be fixed with
- a reasonable amount of effort: we'll talk about issues that are
- difficult to fix for architectural or political reasons.</p>
-
- <p>The goal of this list is to describe how differences in goals lead to
- different strengths and weaknesses, not to make some compiler look bad.
- This will hopefully help you to evaluate whether using clang is a good
- idea for your personal goals. Because we don't know specifically what
- <em>you</em> want to do, we describe the features of these compilers in
- terms of <em>our</em> goals: if you are only interested in static
- analysis, you may not care that something lacks codegen support, for
- example.</p>
-
- <p>Please email cfe-dev if you think we should add another compiler to this
- list or if you think some characterization is unfair here.</p>
-
- <ul>
- <li><a href="#gcc">Clang vs GCC</a> (GNU Compiler Collection)</li>
- <li><a href="#elsa">Clang vs Elsa</a> (Elkhound-based C++ Parser)</li>
- <li><a href="#pcc">Clang vs PCC</a> (Portable C Compiler)</li>
- </ul>
-
-
- <!--=====================================================================-->
- <h2><a name="gcc">Clang vs GCC (GNU Compiler Collection)</a></h2>
- <!--=====================================================================-->
-
- <p>Pro's of GCC vs clang:</p>
-
- <ul>
- <li>GCC supports languages that clang does not aim to, such as Java, Ada,
- FORTRAN, etc.</li>
- <li>GCC front-ends are very mature and already support C/C++/ObjC and all
- the variants we are interested in. <a href="cxx_status.html">clang's
- support for C++</a> in particular is nowhere near what GCC supports.</li>
- <li>GCC's codegen is much more mature than clang's right now and supports
- more targets than LLVM.</li>
- <li>GCC is popular and widely adopted.</li>
- <li>GCC does not require a C++ compiler to build it.</li>
- </ul>
-
- <p>Pro's of clang vs GCC:</p>
-
- <ul>
- <li>The Clang ASTs and design are intended to be <a
- href="features.html#simplecode">easily understandable</a> by
- anyone who is familiar with the languages involved and who has a basic
- understanding of how a compiler works. GCC has a very old codebase
- which presents a steep learning curve to new developers.</li>
- <li>Clang is designed as an API from its inception, allowing it to be reused
- by source analysis tools, refactoring, IDEs (etc) as well as for code
- generation. GCC is built as a monolithic static compiler, which makes
- it extremely difficult to use as an API and integrate into other tools.
- Further, its historic design and <a
- href="http://gcc.gnu.org/ml/gcc/2007-11/msg00460.html">current</a>
- <a href="http://gcc.gnu.org/ml/gcc/2004-12/msg00888.html">policy</a>
- makes it difficult to decouple the front-end from the rest of the
- compiler. </li>
- <li>Various GCC design decisions make it very difficult to reuse: its build
- system is difficult to modify, you can't link multiple targets into one
- binary, you can't link multiple front-ends into one binary, it uses a
- custom garbage collector, uses global variables extensively, is not
- reentrant or multi-threadable, etc. Clang has none of these problems.
- </li>
- <li>For every token, clang tracks information about where it was written and
- where it was ultimately expanded into if it was involved in a macro.
- GCC does not track information about macro instantiations when parsing
- source code. This makes it very difficult for source rewriting tools
- (e.g. for refactoring) to work in the presence of (even simple)
- macros.</li>
- <li>Clang does not implicitly simplify code as it parses it like GCC does.
- Doing so causes many problems for source analysis tools: as one simple
- example, if you write "x-x" in your source code, the GCC AST will
- contain "0", with no mention of 'x'. This is extremely bad for a
- refactoring tool that wants to rename 'x'.</li>
- <li>Clang can serialize its AST out to disk and read it back into another
- program, which is useful for whole program analysis. GCC does not have
- this. GCC's PCH mechanism (which is just a dump of the compiler
- memory image) is related, but is architecturally only
- able to read the dump back into the exact same executable as the one
- that produced it (it is not a structured format).</li>
- <li>Clang is <a href="features.html#performance">much faster and uses far
- less memory</a> than GCC.</li>
- <li>Clang aims to provide extremely clear and concise diagnostics (error and
- warning messages), and includes support for <a
- href="features.html#expressivediags">expressive diagnostics</a>. GCC's
- warnings are acceptable, but are often confusing and it does not support
- expressive diagnostics. Clang also preserves typedefs in diagnostics
- consistently.</li>
- <li>GCC is licensed under the GPL license. clang uses a BSD license, which
- allows it to be used by projects that do not themselves want to be
- GPL.</li>
- <li>Clang inherits a number of features from its use of LLVM as a backend,
- including support for a bytecode representation for intermediate code,
- pluggable optimizers, link-time optimization support, Just-In-Time
- compilation, ability to link in multiple code generators, etc.</li>
- </ul>
-
- <!--=====================================================================-->
- <h2><a name="elsa">Clang vs Elsa (Elkhound-based C++ Parser)</a></h2>
- <!--=====================================================================-->
-
- <p>Pro's of Elsa vs clang:</p>
-
- <ul>
- <li>Elsa's support for C++ is far beyond what clang provides. If you need
- C++ support in the next year, Elsa is a great way to get it. That said,
- Elsa is missing important support for templates and other pieces: for
- example, it is not capable of compiling the GCC STL headers from any
- version newer than GCC 3.4.</li>
- <li>Elsa's parser and AST is designed to be easily extensible by adding
- grammar rules. Clang has a very simple and easily hackable parser,
- but requires you to write C++ code to do it.</li>
- </ul>
-
- <p>Pro's of clang vs Elsa:</p>
-
- <ul>
- <li>The Elsa community is extremely small and major development work seems
- to have ceased in 2005, though it continues to be used by other small
- projects
- (e.g. Oink). Clang has a vibrant community including developers that
- are paid to work on it full time. In practice this means that you can
- file bugs against Clang and they will often be fixed for you. If you
- use Elsa, you are (mostly) on your own for bug fixes and feature
- enhancements.</li>
- <li>Elsa is not built as a stack of reusable libraries like clang is. It is
- very difficult to use part of Elsa without the whole front-end. For
- example, you cannot use Elsa to parse C/ObjC code without building an
- AST. You can do this in Clang and it is much faster than building an
- AST.</li>
- <li>Elsa does not have an integrated preprocessor, which makes it extremely
- difficult to accurately map from a source location in the AST back to
- its original position before preprocessing. Like GCC, it does not keep
- track of macro expansions.</li>
- <li>Elsa is even slower and uses more memory than GCC, which itself requires
- far more space and time than clang.</li>
- <li>Elsa only does partial semantic analysis. It is intended to work on
- code that is already validated by GCC, so it does not do many semantic
- checks required by the languages it implements.</li>
- <li>Elsa does not support Objective-C.</li>
- <li>Elsa does not support native code generation.</li>
- </ul>
-
- <p>Note that there is a fork of Elsa known as "Pork". It addresses some of
- these shortcomings by loosely integrating a preprocessor. This allows it
- to map from a source location in the AST to the original position before
- preprocessing, providing it better support for static analysis and
- refactoring. Note that Pork is in stasis now too.</p>
-
-
- <!--=====================================================================-->
- <h2><a name="pcc">Clang vs PCC (Portable C Compiler)</a></h2>
- <!--=====================================================================-->
-
- <p>Pro's of PCC vs clang:</p>
-
- <ul>
- <li>The PCC source base is very small and builds quickly with just a C
- compiler.</li>
- </ul>
-
- <p>Pro's of clang vs PCC:</p>
-
- <ul>
- <li>PCC dates from the 1970's and has been dormant for most of that time.
- The clang + llvm communities are very active.</li>
- <li>PCC doesn't support C99, Objective-C, and doesn't aim to support
- C++.</li>
- <li>PCC's code generation is very limited compared to LLVM. It produces very
- inefficient code and does not support many important targets.</li>
- <li>Like Elsa, PCC's does not have an integrated preprocessor, making it
- extremely difficult to use it for source analysis tools.</li>
- </div>
-</body>
-</html>
diff --git a/clang/www/content.css b/clang/www/content.css
deleted file mode 100644
index 2fe5fd70c924..000000000000
--- a/clang/www/content.css
+++ /dev/null
@@ -1,23 +0,0 @@
-html, body {
- padding:0px;
- font-size:12px; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222;
- line-height:1.5;
-}
-
-h1, h2, h3, tt { color: #000 }
-
-h1 { padding-top:0px; margin-top:0px;}
-h2 { color:#333333; padding-top:0.5em; }
-h3 { padding-top: 0.5em; margin-bottom: -0.25em; color:#2d58b7}
-li { padding-bottom: 0.5em; }
-ul { padding-left:1.5em; }
-
-/* Slides */
-IMG.img_slide {
- display: block;
- margin-left: auto;
- margin-right: auto
-}
-
-/* Tables */
-tr { vertical-align:top } \ No newline at end of file
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
deleted file mode 100644
index 9e154aa0bf22..000000000000
--- a/clang/www/cxx_status.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>Clang - C++ Support</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
- <style type="text/css">
-</style>
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<!--*************************************************************************-->
-<h1>C++ Support in Clang</h1>
-<!--*************************************************************************-->
-
-<p>
-This page tracks the status of C++ support in Clang.<br>
-Currently most of the C++ features are missing; here you can find features that are at least partially supported in Clang. </p>
-
-<p>
-In this table, parser support means that the parser knows the grammar for
-the feature. "Sema" support means that we do type checking, report errors
-about misuses of the feature and build an AST. CodeGen support means that we
-actually produce LLVM code for the feature with the -emit-llvm option.
-</p>
-
-<table width="689" border="1" cellspacing="0">
- <tr>
- <td width="150"><h3>Feature</h3></td>
- <td width="172"><h3>Example</h3></td>
- <td width="345"><h3>Status</h3></td>
- </tr>
- <tr>
- <td>Bool type </td>
- <td>bool x; </td>
- <td>Full support.</td>
- </tr>
- <tr>
- <td>wchar_t type </td>
- <td>wchar_t x; </td>
- <td>Parser and Sema support in, partial Codegen support.</td>
- </tr>
- <tr>
- <td>Named Casts </td>
- <td>static_cast&lt;int&gt;(x)</td>
- <td>Partial Parser and Sema support, no codegen.</td>
- </tr>
- <tr>
- <td>References</td>
- <td>int &amp;x = ...;</td>
- <td>Parser and Sema support in, partial Codegen support.</td>
- </tr>
- <tr>
- <td>Default arguments </td>
- <td>void f(int x=0); </td>
- <td>Full support. </td>
- </tr>
- <tr>
- <td>Namespaces</td>
- <td>namespace A {<br/>
- &nbsp;&nbsp;&nbsp;int x;<br/>
- }</td>
- <td>Parser and Sema support in, no Codegen support.</td>
- </tr>
- <tr>
- <td>Class definitions</td>
- <td>class C {<br/>
- public:<br/>
- &nbsp;&nbsp;&nbsp;int getX() { return x; }<br/>
- private:<br/>
- &nbsp;&nbsp;&nbsp;int x;<br/>
- };</td>
- <td>Partial Parser and Sema support, no Codegen support.</td>
- </tr>
-</table>
-</div>
-</body>
-</html>
diff --git a/clang/www/demo/DemoInfo.html b/clang/www/demo/DemoInfo.html
deleted file mode 100644
index 54a5afa1d799..000000000000
--- a/clang/www/demo/DemoInfo.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-<html>
-<head>
-<title>
-Demo page information
-</title>
-</head>
-
-<body>
-
-<h1>Demo page information</h1>
-
-<p>Press "back" or <a href=".">click here</a> to return to the demo
-page.</p>
-
-<h2><a name="hints">Hints and Advice</a></h2>
-
-<ul>
-<li>The generated LLVM code will be easier to read if
-you use stdio (e.g., printf) than iostreams (e.g., std::cout).</li>
-
-<li>Unused inline functions and methods are not generated. Instead
-of '<tt>class foo { void bar() {}};</tt>',
-try writing '<tt>class foo { void bar(); }; void foo::bar() {}</tt>'.</li>
-
-<li>If you want to try out a file that uses non-standard header files, you should
- preprocess it (e.g., with the <tt>-save-temps</tt> or <tt>-E</tt> options to
- <tt>gcc</tt>) then upload the result.</li>
-
-</ul>
-
-
-<h2><a name="demangle">Demangle C++ names with C++ filt</a></h2>
-
-<p>
-Select this option if you want to run the output LLVM IR through "c++filt",
-which converts 'mangled' C++ names to their unmangled version.
-Note that LLVM code produced will not be lexically valid, but it will
-be easier to understand.
-</p>
-
-<h2><a name="lto">Run link-time optimizer</a></h2>
-
-<p>
-Select this option to run the LLVM link-time optimizer, which is designed to
-optimize across files in your application. Since the demo page doesn't allow
-you to upload multiple files at once, and does not link in any libraries, we
-configured the demo page optimizer to assume there are no calls
-coming in from outside the source file, allowing it to optimize more
-aggressively.</p>
-
-<p>Note that you have to define 'main' in your program for this
-to make much of a difference.
-</p>
-
-<h2><a name="stats">Show detailed pass statistics</a></h2>
-
-<p>
-Select this option to enable compilation timings and statistics from various
-optimizers.</p>
-
-
-<h2><a name="bcanalyzer">Analyze generated bytecode</a></h2>
-
-<p>
-Select this option to run the <a
-href="http://llvm.org/cmds/llvm-bcanalyzer.html">llvm-bcanalyzer</a> tool
-on the generated bytecode, which introspects into the format of the .bc file
-itself. </p>
-
-
-<h2><a name="llvm2cpp">Show C++ API code</a></h2>
-
-<p>
-Select this option to run the <a
-href="http://llvm.org/cmds/llvm2cpp.html">llvm2cpp</a> tool
-on the generated bytecode, which auto generates the C++ API calls that could
-be used to create the .bc file.
-</p>
-
-</body>
-</html>
-
diff --git a/clang/www/demo/cathead.png b/clang/www/demo/cathead.png
deleted file mode 100644
index 3bf1a45ec6f3..000000000000
--- a/clang/www/demo/cathead.png
+++ /dev/null
Binary files differ
diff --git a/clang/www/demo/index.cgi b/clang/www/demo/index.cgi
deleted file mode 100644
index b29efb60e9cc..000000000000
--- a/clang/www/demo/index.cgi
+++ /dev/null
@@ -1,461 +0,0 @@
-#!/usr/dcs/software/supported/bin/perl -w
-# LLVM Web Demo script
-#
-
-use strict;
-use CGI;
-use POSIX;
-use Mail::Send;
-
-$| = 1;
-
-my $ROOT = "/tmp/webcompile";
-#my $ROOT = "/home/vadve/lattner/webcompile";
-
-open( STDERR, ">&STDOUT" ) or die "can't redirect stderr to stdout";
-
-if ( !-d $ROOT ) { mkdir( $ROOT, 0777 ); }
-
-my $LOGFILE = "$ROOT/log.txt";
-my $FORM_URL = 'index.cgi';
-my $MAILADDR = 'sabre@nondot.org';
-my $CONTACT_ADDRESS = 'Questions or comments? Email the <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev mailing list</a>.';
-my $LOGO_IMAGE_URL = 'cathead.png';
-my $TIMEOUTAMOUNT = 20;
-$ENV{'LD_LIBRARY_PATH'} = '/home/vadve/shared/localtools/fc1/lib/';
-
-my @PREPENDPATHDIRS =
- (
- '/home/vadve/shared/llvm-gcc4.0-2.1/bin/',
- '/home/vadve/shared/llvm-2.1/Release/bin');
-
-my $defaultsrc = "#include <stdio.h>\n#include <stdlib.h>\n\n" .
- "int power(int X) {\n if (X == 0) return 1;\n" .
- " return X*power(X-1);\n}\n\n" .
- "int main(int argc, char **argv) {\n" .
- " printf(\"%d\\n\", power(atoi(argv[0])));\n}\n";
-
-sub getname {
- my ($extension) = @_;
- for ( my $count = 0 ; ; $count++ ) {
- my $name =
- sprintf( "$ROOT/_%d_%d%s", $$, $count, $extension );
- if ( !-f $name ) { return $name; }
- }
-}
-
-my $c;
-
-sub barf {
- print "<b>", @_, "</b>\n";
- print $c->end_html;
- system("rm -f $ROOT/locked");
- exit 1;
-}
-
-sub writeIntoFile {
- my $extension = shift @_;
- my $contents = join "", @_;
- my $name = getname($extension);
- local (*FILE);
- open( FILE, ">$name" ) or barf("Can't write to $name: $!");
- print FILE $contents;
- close FILE;
- return $name;
-}
-
-sub addlog {
- my ( $source, $pid, $result ) = @_;
- open( LOG, ">>$LOGFILE" );
- my $time = scalar localtime;
- my $remotehost = $ENV{'REMOTE_ADDR'};
- print LOG "[$time] [$remotehost]: $pid\n";
- print LOG "<<<\n$source\n>>>\nResult is: <<<\n$result\n>>>\n";
- close LOG;
-}
-
-sub dumpFile {
- my ( $header, $file ) = @_;
- my $result;
- open( FILE, "$file" ) or barf("Can't read $file: $!");
- while (<FILE>) {
- $result .= $_;
- }
- close FILE;
- my $UnhilightedResult = $result;
- my $HtmlResult =
- "<h3>$header</h3>\n<pre>\n" . $c->escapeHTML($result) . "\n</pre>\n";
- if (wantarray) {
- return ( $UnhilightedResult, $HtmlResult );
- }
- else {
- return $HtmlResult;
- }
-}
-
-sub syntaxHighlightLLVM {
- my ($input) = @_;
- $input =~ s@\b(void|i8|i1|i16|i32|i64|float|double|type|label|opaque)\b@<span class="llvm_type">$1</span>@g;
- $input =~ s@\b(add|sub|mul|div|rem|and|or|xor|setne|seteq|setlt|setgt|setle|setge|phi|tail|call|cast|to|shl|shr|vaarg|vanext|ret|br|switch|invoke|unwind|malloc|alloca|free|load|store|getelementptr|begin|end|true|false|declare|global|constant|const|internal|uninitialized|external|implementation|linkonce|weak|appending|null|to|except|not|target|endian|pointersize|big|little|volatile)\b@<span class="llvm_keyword">$1</span>@g;
-
- # Add links to the FAQ.
- $input =~ s@(_ZNSt8ios_base4Init[DC]1Ev)@<a href="../docs/FAQ.html#iosinit">$1</a>@g;
- $input =~ s@\bundef\b@<a href="../docs/FAQ.html#undef">undef</a>@g;
- return $input;
-}
-
-sub mailto {
- my ( $recipient, $body ) = @_;
- my $msg =
- new Mail::Send( Subject => "LLVM Demo Page Run", To => $recipient );
- my $fh = $msg->open();
- print $fh $body;
- $fh->close();
-}
-
-$c = new CGI;
-print $c->header;
-
-print <<EOF;
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Try out LLVM in your browser!</title>
- <style>
- \@import url("syntax.css");
- \@import url("http://llvm.org/llvm.css");
- </style>
-</head>
-<body leftmargin="10" marginwidth="10">
-
-<div class="www_sectiontitle">
- Try out LLVM in your browser!
-</div>
-
-<table border=0><tr><td>
-<img align=right width=100 height=111 src="$LOGO_IMAGE_URL">
-</td><td>
-EOF
-
-if ( -f "$ROOT/locked" ) {
- my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$locktime) =
- stat("$ROOT/locked");
- my $currtime = time();
- if ($locktime + 60 > $currtime) {
- print "This page is already in use by someone else at this ";
- print "time, try reloading in a second or two. Meow!</td></tr></table>'\n";
- exit 0;
- }
-}
-
-system("touch $ROOT/locked");
-
-print <<END;
-Bitter Melon the cat says, paste a C/C++ program in the text box or upload
-one from your computer, and you can see LLVM compile it, meow!!
-</td></tr></table><p>
-END
-
-print $c->start_multipart_form( 'POST', $FORM_URL );
-
-my $source = $c->param('source');
-
-
-# Start the user out with something valid if no code.
-$source = $defaultsrc if (!defined($source));
-
-print '<table border="0"><tr><td>';
-
-print "Type your source code in below: (<a href='DemoInfo.html#hints'>hints and
-advice</a>)<br>\n";
-
-print $c->textarea(
- -name => "source",
- -rows => 16,
- -columns => 60,
- -default => $source
-), "<br>";
-
-print "Or upload a file: ";
-print $c->filefield( -name => 'uploaded_file', -default => '' );
-
-print "<p />\n";
-
-
-print '<p></td><td valign=top>';
-
-print "<center><h3>General Options</h3></center>";
-
-print "Source language: ",
- $c->radio_group(
- -name => 'language',
- -values => [ 'C', 'C++' ],
- -default => 'C'
- ), "<p>";
-
-print $c->checkbox(
- -name => 'linkopt',
- -label => 'Run link-time optimizer',
- -checked => 'checked'
- ),' <a href="DemoInfo.html#lto">?</a><br>';
-
-print $c->checkbox(
- -name => 'showstats',
- -label => 'Show detailed pass statistics'
- ), ' <a href="DemoInfo.html#stats">?</a><br>';
-
-print $c->checkbox(
- -name => 'cxxdemangle',
- -label => 'Demangle C++ names'
- ),' <a href="DemoInfo.html#demangle">?</a><p>';
-
-
-print "<center><h3>Output Options</h3></center>";
-
-print $c->checkbox(
- -name => 'showbcanalysis',
- -label => 'Show detailed bytecode analysis'
- ),' <a href="DemoInfo.html#bcanalyzer">?</a><br>';
-
-print $c->checkbox(
- -name => 'showllvm2cpp',
- -label => 'Show LLVM C++ API code'
- ), ' <a href="DemoInfo.html#llvm2cpp">?</a>';
-
-print "</td></tr></table>";
-
-print "<center>", $c->submit(-value=> 'Compile Source Code'),
- "</center>\n", $c->endform;
-
-print "\n<p>If you have questions about the LLVM code generated by the
-front-end, please check the <a href='/docs/FAQ.html#cfe_code'>FAQ</a> and
-the demo page <a href='DemoInfo.html#hints'>hints section</a>.
-</p>\n";
-
-$ENV{'PATH'} = ( join ( ':', @PREPENDPATHDIRS ) ) . ":" . $ENV{'PATH'};
-
-sub sanitychecktools {
- my $sanitycheckfail = '';
-
- # insert tool-specific sanity checks here
- $sanitycheckfail .= ' llvm-dis'
- if `llvm-dis --help 2>&1` !~ /ll disassembler/;
-
- $sanitycheckfail .= ' llvm-gcc'
- if ( `llvm-gcc --version 2>&1` !~ /Free Software Foundation/ );
-
- $sanitycheckfail .= ' llvm-ld'
- if `llvm-ld --help 2>&1` !~ /llvm linker/;
-
- $sanitycheckfail .= ' llvm-bcanalyzer'
- if `llvm-bcanalyzer --help 2>&1` !~ /bcanalyzer/;
-
- barf(
-"<br/>The demo page is currently unavailable. [tools: ($sanitycheckfail ) failed sanity check]"
- )
- if $sanitycheckfail;
-}
-
-sanitychecktools();
-
-sub try_run {
- my ( $program, $commandline, $outputFile ) = @_;
- my $retcode = 0;
-
- eval {
- local $SIG{ALRM} = sub { die "timeout"; };
- alarm $TIMEOUTAMOUNT;
- $retcode = system($commandline);
- alarm 0;
- };
- if ( $@ and $@ =~ /timeout/ ) {
- barf("Program $program took too long, compile time limited for the web script, sorry!.\n");
- }
- if ( -s $outputFile ) {
- print scalar dumpFile( "Output from $program", $outputFile );
- }
- #print "<p>Finished dumping command output.</p>\n";
- if ( WIFEXITED($retcode) && WEXITSTATUS($retcode) != 0 ) {
- barf(
-"$program exited with an error. Please correct source and resubmit.<p>\n" .
-"Please note that this form only allows fully formed and correct source" .
-" files. It will not compile fragments of code.<p>"
- );
- }
- if ( WIFSIGNALED($retcode) != 0 ) {
- my $sig = WTERMSIG($retcode);
- barf(
- "Ouch, $program caught signal $sig. Sorry, better luck next time!\n"
- );
- }
-}
-
-my %suffixes = (
- 'Java' => '.java',
- 'JO99' => '.jo9',
- 'C' => '.c',
- 'C++' => '.cc',
- 'Stacker' => '.st',
- 'preprocessed C' => '.i',
- 'preprocessed C++' => '.ii'
-);
-my %languages = (
- '.jo9' => 'JO99',
- '.java' => 'Java',
- '.c' => 'C',
- '.i' => 'preprocessed C',
- '.ii' => 'preprocessed C++',
- '.cc' => 'C++',
- '.cpp' => 'C++',
- '.st' => 'Stacker'
-);
-
-my $uploaded_file_name = $c->param('uploaded_file');
-if ($uploaded_file_name) {
- if ($source) {
- barf(
-"You must choose between uploading a file and typing code in. You can't do both at the same time."
- );
- }
- $uploaded_file_name =~ s/^.*(\.[A-Za-z]+)$/$1/;
- my $language = $languages{$uploaded_file_name};
- $c->param( 'language', $language );
-
- print "<p>Processing uploaded file. It looks like $language.</p>\n";
- my $fh = $c->upload('uploaded_file');
- if ( !$fh ) {
- barf( "Error uploading file: " . $c->cgi_error );
- }
- while (<$fh>) {
- $source .= $_;
- }
- close $fh;
-}
-
-if ($c->param('source')) {
- print $c->hr;
- my $extension = $suffixes{ $c->param('language') };
- barf "Unknown language; can't compile\n" unless $extension;
-
- # Add a newline to the source here to avoid a warning from gcc.
- $source .= "\n";
-
- # Avoid security hole due to #including bad stuff.
- $source =~
-s@(\n)?#include.*[<"](.*\.\..*)[">].*\n@$1#error "invalid #include file $2 detected"\n@g;
-
- my $inputFile = writeIntoFile( $extension, $source );
- my $pid = $$;
-
- my $bytecodeFile = getname(".bc");
- my $outputFile = getname(".llvm-gcc.out");
- my $timerFile = getname(".llvm-gcc.time");
-
- my $stats = '';
- if ( $extension eq ".st" ) {
- $stats = "-stats -time-passes "
- if ( $c->param('showstats') );
- try_run( "llvm Stacker front-end (stkrc)",
- "stkrc $stats -o $bytecodeFile $inputFile > $outputFile 2>&1",
- $outputFile );
- } else {
- #$stats = "-Wa,--stats,--time-passes,--info-output-file=$timerFile"
- $stats = "-ftime-report"
- if ( $c->param('showstats') );
- try_run( "llvm C/C++ front-end (llvm-gcc)",
- "llvm-gcc -emit-llvm -W -Wall -O2 $stats -o $bytecodeFile -c $inputFile > $outputFile 2>&1",
- $outputFile );
- }
-
- if ( $c->param('showstats') && -s $timerFile ) {
- my ( $UnhilightedResult, $HtmlResult ) =
- dumpFile( "Statistics for front-end compilation", $timerFile );
- print "$HtmlResult\n";
- }
-
- if ( $c->param('linkopt') ) {
- my $stats = '';
- my $outputFile = getname(".gccld.out");
- my $timerFile = getname(".gccld.time");
- $stats = "--stats --time-passes --info-output-file=$timerFile"
- if ( $c->param('showstats') );
- my $tmpFile = getname(".bc");
- try_run(
- "optimizing linker (llvm-ld)",
-"llvm-ld $stats -o=$tmpFile $bytecodeFile > $outputFile 2>&1",
- $outputFile
- );
- system("mv $tmpFile.bc $bytecodeFile");
- system("rm $tmpFile");
-
- if ( $c->param('showstats') && -s $timerFile ) {
- my ( $UnhilightedResult, $HtmlResult ) =
- dumpFile( "Statistics for optimizing linker", $timerFile );
- print "$HtmlResult\n";
- }
- }
-
- print " Bytecode size is ", -s $bytecodeFile, " bytes.\n";
-
- my $disassemblyFile = getname(".ll");
- try_run( "llvm-dis",
- "llvm-dis -o=$disassemblyFile $bytecodeFile > $outputFile 2>&1",
- $outputFile );
-
- if ( $c->param('cxxdemangle') ) {
- print " Demangling disassembler output.\n";
- my $tmpFile = getname(".ll");
- system("c++filt < $disassemblyFile > $tmpFile 2>&1");
- system("mv $tmpFile $disassemblyFile");
- }
-
- my ( $UnhilightedResult, $HtmlResult );
- if ( -s $disassemblyFile ) {
- ( $UnhilightedResult, $HtmlResult ) =
- dumpFile( "Output from LLVM disassembler", $disassemblyFile );
- print syntaxHighlightLLVM($HtmlResult);
- }
- else {
- print "<p>Hmm, that's weird, llvm-dis didn't produce any output.</p>\n";
- }
-
- if ( $c->param('showbcanalysis') ) {
- my $analFile = getname(".bca");
- try_run( "llvm-bcanalyzer", "llvm-bcanalyzer $bytecodeFile > $analFile 2>&1",
- $analFile);
- }
- if ($c->param('showllvm2cpp') ) {
- my $l2cppFile = getname(".l2cpp");
- try_run("llvm2cpp","llvm2cpp $bytecodeFile -o $l2cppFile 2>&1",
- $l2cppFile);
- }
-
- # Get the source presented by the user to CGI, convert newline sequences to simple \n.
- my $actualsrc = $c->param('source');
- $actualsrc =~ s/\015\012/\n/go;
- # Don't log this or mail it if it is the default code.
- if ($actualsrc ne $defaultsrc) {
- addlog( $source, $pid, $UnhilightedResult );
-
- my ( $ip, $host, $lg, $lines );
- chomp( $lines = `wc -l < $inputFile` );
- $lg = $c->param('language');
- $ip = $c->remote_addr();
- chomp( $host = `host $ip` ) if $ip;
- mailto( $MAILADDR,
- "--- Query: ---\nFrom: ($ip) $host\nInput: $lines lines of $lg\n"
- . "C++ demangle = "
- . ( $c->param('cxxdemangle') ? 1 : 0 )
- . ", Link opt = "
- . ( $c->param('linkopt') ? 1 : 0 ) . "\n\n"
- . ", Show stats = "
- . ( $c->param('showstats') ? 1 : 0 ) . "\n\n"
- . "--- Source: ---\n$source\n"
- . "--- Result: ---\n$UnhilightedResult\n" );
- }
- unlink( $inputFile, $bytecodeFile, $outputFile, $disassemblyFile );
-}
-
-print $c->hr, "<address>$CONTACT_ADDRESS</address>", $c->end_html;
-system("rm $ROOT/locked");
-exit 0;
diff --git a/clang/www/demo/syntax.css b/clang/www/demo/syntax.css
deleted file mode 100644
index 90daf5fcbd1f..000000000000
--- a/clang/www/demo/syntax.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/* LLVM syntax highlighting for the Web */
-
-.llvm_type { font-style: oblique; color: green }
-.llvm_keyword { font-weight: bold; color: blue }
diff --git a/clang/www/demo/what is this directory.txt b/clang/www/demo/what is this directory.txt
deleted file mode 100644
index 47d5d4ed2db9..000000000000
--- a/clang/www/demo/what is this directory.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is for the LLVM+Clang browser based demo.
-It is supposed to work like the LLVM+GCC demo here: http://llvm.org/demo/ but for the BSD licensed Clang instead.
-
-Perhaps it could also be used for getting crash information and details on errors.... I'm not sure if this would require some major changes or not to report this info. Maybe also adding ways that people can use it to test for errors and a way to report such errors would also be good.
-
-Status:
-Anyways, right now, these file a basically just a copy of the LLVM+GCC demo (no changes have been made). The files don't even work right in this location on the server. As such, someone will need to edit the file or rewrite it.
-
-If nobody in the LLVM community has the skills, one suggestion would be to post a request on a friendly Perl forum and see if anybody might be interested in taking on the challenge.
-
-Alternatively, you could try a PHP, Python, Ruby, or Lisp mailing list and see if there are any takers who would be interested (and willing to do a rewrite to their language of choice).
-
---
-BTW, once this feature was working, my intention was to link to it from the index.html page in the section entitled:
-Try Clang \ No newline at end of file
diff --git a/clang/www/distclang_status.html b/clang/www/distclang_status.html
deleted file mode 100644
index f8675ce7ad16..000000000000
--- a/clang/www/distclang_status.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>Clang - Distributed Compilation Support</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
- <style type="text/css">
-</style>
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<!--*************************************************************************-->
-<h1>Distributed Compilation Support in Clang</h1>
-<!--*************************************************************************-->
-
-<p>
-This page tracks the status of Distributed Compilation support in Clang.<br>
-Currently some basic features are working but the code is under heavy
-development. </p>
-
-
-</div>
-</body>
-</html>
diff --git a/clang/www/feature-compile1.png b/clang/www/feature-compile1.png
deleted file mode 100644
index cec7c4851492..000000000000
--- a/clang/www/feature-compile1.png
+++ /dev/null
Binary files differ
diff --git a/clang/www/feature-compile2.png b/clang/www/feature-compile2.png
deleted file mode 100644
index 0eb93001ffca..000000000000
--- a/clang/www/feature-compile2.png
+++ /dev/null
Binary files differ
diff --git a/clang/www/feature-diagnostics1.png b/clang/www/feature-diagnostics1.png
deleted file mode 100644
index 00b0a0d71927..000000000000
--- a/clang/www/feature-diagnostics1.png
+++ /dev/null
Binary files differ
diff --git a/clang/www/feature-memory1.png b/clang/www/feature-memory1.png
deleted file mode 100644
index 29368aa83820..000000000000
--- a/clang/www/feature-memory1.png
+++ /dev/null
Binary files differ
diff --git a/clang/www/features.html b/clang/www/features.html
deleted file mode 100644
index 7a491406c1e3..000000000000
--- a/clang/www/features.html
+++ /dev/null
@@ -1,420 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>Clang - Features and Goals</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
- <style type="text/css">
-</style>
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<!--*************************************************************************-->
-<h1>Clang - Features and Goals</h1>
-<!--*************************************************************************-->
-
-<p>
-This page describes the <a href="index.html#goals">features and goals</a> of
-Clang in more detail and gives a more broad explanation about what we mean.
-These features are:
-</p>
-
-<p>End-User Features:</p>
-
-<ul>
-<li><a href="#performance">Fast compiles and low memory use</a></li>
-<li><a href="#expressivediags">Expressive diagnostics</a></li>
-<li><a href="#gcccompat">GCC compatibility</a></li>
-</ul>
-
-<p>Utility and Applications:</p>
-
-<ul>
-<li><a href="#libraryarch">Library based architecture</a></li>
-<li><a href="#diverseclients">Support diverse clients</a></li>
-<li><a href="#ideintegration">Integration with IDEs</a></li>
-<li><a href="#license">Use the LLVM 'BSD' License</a></li>
-</ul>
-
-<p>Internal Design and Implementation:</p>
-
-<ul>
-<li><a href="#real">A real-world, production quality compiler</a></li>
-<li><a href="#simplecode">A simple and hackable code base</a></li>
-<li><a href="#unifiedparser">A single unified parser for C, Objective C, C++,
- and Objective C++</a></li>
-<li><a href="#conformance">Conformance with C/C++/ObjC and their
- variants</a></li>
-</ul>
-
-<!--*************************************************************************-->
-<h2><a name="enduser">End-User Features</a></h2>
-<!--*************************************************************************-->
-
-
-<!--=======================================================================-->
-<h3><a name="performance">Fast compiles and Low Memory Use</a></h3>
-<!--=======================================================================-->
-
-<p>A major focus of our work on clang is to make it fast, light and scalable.
-The library-based architecture of clang makes it straight-forward to time and
-profile the cost of each layer of the stack, and the driver has a number of
-options for performance analysis.</p>
-
-<p>While there is still much that can be done, we find that the clang front-end
-is significantly quicker than gcc and uses less memory For example, when
-compiling "Carbon.h" on Mac OS/X, we see that clang is 2.5x faster than GCC:</p>
-
-<img class="img_slide" src="feature-compile1.png" width="400" height="300" />
-
-<p>Carbon.h is a monster: it transitively includes 558 files, 12.3M of code,
-declares 10000 functions, has 2000 struct definitions, 8000 fields, 20000 enum
-constants, etc (see slide 25+ of the <a href="clang_video-07-25-2007.html">clang
-talk</a> for more information). It is also #include'd into almost every C file
-in a GUI app on the Mac, so its compile time is very important.</p>
-
-<p>From the slide above, you can see that we can measure the time to preprocess
-the file independently from the time to parse it, and independently from the
-time to build the ASTs for the code. GCC doesn't provide a way to measure the
-parser without AST building (it only provides -fsyntax-only). In our
-measurements, we find that clang's preprocessor is consistently 40% faster than
-GCCs, and the parser + AST builder is ~4x faster than GCC's. If you have
-sources that do not depend as heavily on the preprocessor (or if you
-use Precompiled Headers) you may see a much bigger speedup from clang.
-</p>
-
-<p>Compile time performance is important, but when using clang as an API, often
-memory use is even moreso: the less memory the code takes the more code you can
-fit into memory at a time (useful for whole program analysis tools, for
-example).</p>
-
-<img class="img_slide" src="feature-memory1.png" width="400" height="300" />
-
-<p>Here we see a huge advantage of clang: its ASTs take <b>5x less memory</b>
-than GCC's syntax trees, despite the fact that clang's ASTs capture far more
-source-level information than GCC's trees do. This feat is accomplished through
-the use of carefully designed APIs and efficient representations.</p>
-
-<p>In addition to being efficient when pitted head-to-head against GCC in batch
-mode, clang is built with a <a href="#libraryarch">library based
-architecture</a> that makes it relatively easy to adapt it and build new tools
-with it. This means that it is often possible to apply out-of-the-box thinking
-and novel techniques to improve compilation in various ways.</p>
-
-<img class="img_slide" src="feature-compile2.png" width="400" height="300" />
-
-<p>This slide shows how the clang preprocessor can be used to make "distcc"
-parallelization <b>3x</b> more scalable than when using the GCC preprocessor.
-"distcc" quickly bottlenecks on the preprocessor running on the central driver
-machine, so a fast preprocessor is very useful. Comparing the first two bars
-of each group shows how a ~40% faster preprocessor can reduce preprocessing time
-of these large C++ apps by about 40% (shocking!).</p>
-
-<p>The third bar on the slide is the interesting part: it shows how trivial
-caching of file system accesses across invocations of the preprocessor allows
-clang to reduce time spent in the kernel by 10x, making distcc over 3x more
-scalable. This is obviously just one simple hack, doing more interesting things
-(like caching tokens across preprocessed files) would yield another substantial
-speedup.</p>
-
-<p>The clean framework-based design of clang means that many things are possible
-that would be very difficult in other systems, for example incremental
-compilation, multithreading, intelligent caching, etc. We are only starting
-to tap the full potential of the clang design.</p>
-
-
-<!--=======================================================================-->
-<h3><a name="expressivediags">Expressive Diagnostics</a></h3>
-<!--=======================================================================-->
-
-<p>Clang is designed to efficiently capture range information for expressions
-and statements, which allows it to emit very useful and detailed diagnostic
-information (e.g. warnings and errors) when a problem is detected.</p>
-
-<p>For example, this slide compares the diagnostics emitted by clang (top) to
-the diagnostics emitted by GCC (middle) for a simple example:</p>
-
-<img class="img_slide" src="feature-diagnostics1.png" width="400" height="300"/>
-
-<p>As you can see, clang goes beyond tracking just column number information: it
-is able to highlight the subexpressions involved in a problem, making it much
-easier to understand the source of the problem in many cases. For example, in
-the first problem, it tells you <em>why</em> the operand is invalid (it
-requires a pointer) and what type it really is.</p>
-
-<p>In the second error, you can see how clang uses column number information to
-identify exactly which "+" out of the four on that line is causing the problem.
-Further, it highlights the subexpressions involved, which can be very useful
-when a complex subexpression that relies on tricky precedence rules.</p>
-
-<p>The example doesn't show it, but clang works very hard to retain typedef
-information, ensuring that diagnostics print the user types, not the fully
-expanded (and often huge) types. This is clearly important for C++ code (tell
-me about "<tt>std::string</tt>", not about "<tt>std::basic_string&lt;char,
-std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;</tt>"!), but it is
-also very useful in C code in some cases as well (e.g. "<tt>__m128"</tt> vs
-"<tt>float __attribute__((__vector_size__(16)))</tt>").</p>
-
-<!--=======================================================================-->
-<h3><a name="gcccompat">GCC Compatibility</a></h3>
-<!--=======================================================================-->
-
-<p>GCC is currently the defacto-standard open source compiler today, and it
-routinely compiles a huge volume of code. GCC supports a huge number of
-extensions and features (many of which are undocumented) and a lot of
-code and header files depend on these features in order to build.</p>
-
-<p>While it would be nice to be able to ignore these extensions and focus on
-implementing the language standards to the letter, pragmatics force us to
-support the GCC extensions that see the most use. Many users just want their
-code to compile, they don't care to argue about whether it is pedantically C99
-or not.</p>
-
-<p>As mentioned above, all
-extensions are explicitly recognized as such and marked with extension
-diagnostics, which can be mapped to warnings, errors, or just ignored.
-</p>
-
-
-<!--*************************************************************************-->
-<h2><a name="applications">Utility and Applications</a></h2>
-<!--*************************************************************************-->
-
-<!--=======================================================================-->
-<h3><a name="libraryarch">Library Based Architecture</a></h3>
-<!--=======================================================================-->
-
-<p>A major design concept for clang is its use of a library-based
-architecture. In this design, various parts of the front-end can be cleanly
-divided into separate libraries which can then be mixed up for different needs
-and uses. In addition, the library-based approach encourages good interfaces
-and makes it easier for new developers to get involved (because they only need
-to understand small pieces of the big picture).</p>
-
-<blockquote>
-"The world needs better compiler tools, tools which are built as libraries.
-This design point allows reuse of the tools in new and novel ways. However,
-building the tools as libraries isn't enough: they must have clean APIs, be as
-decoupled from each other as possible, and be easy to modify/extend. This
-requires clean layering, decent design, and keeping the libraries independent of
-any specific client."</blockquote>
-
-<p>
-Currently, clang is divided into the following libraries and tool:
-</p>
-
-<ul>
-<li><b>libsupport</b> - Basic support library, from LLVM.</li>
-<li><b>libsystem</b> - System abstraction library, from LLVM.</li>
-<li><b>libbasic</b> - Diagnostics, SourceLocations, SourceBuffer abstraction,
- file system caching for input source files.</li>
-<li><b>libast</b> - Provides classes to represent the C AST, the C type system,
- builtin functions, and various helpers for analyzing and manipulating the
- AST (visitors, pretty printers, etc).</li>
-<li><b>liblex</b> - Lexing and preprocessing, identifier hash table, pragma
- handling, tokens, and macro expansion.</li>
-<li><b>libparse</b> - Parsing. This library invokes coarse-grained 'Actions'
- provided by the client (e.g. libsema builds ASTs) but knows nothing about
- ASTs or other client-specific data structures.</li>
-<li><b>libsema</b> - Semantic Analysis. This provides a set of parser actions
- to build a standardized AST for programs.</li>
-<li><b>libcodegen</b> - Lower the AST to LLVM IR for optimization &amp; code
- generation.</li>
-<li><b>librewrite</b> - Editing of text buffers (important for code rewriting
- transformation, like refactoring).</li>
-<li><b>libanalysis</b> - Static analysis support.</li>
-<li><b>clang</b> - A driver program, client of the libraries at various
- levels.</li>
-</ul>
-
-<p>As an example of the power of this library based design.... If you wanted to
-build a preprocessor, you would take the Basic and Lexer libraries. If you want
-an indexer, you would take the previous two and add the Parser library and
-some actions for indexing. If you want a refactoring, static analysis, or
-source-to-source compiler tool, you would then add the AST building and
-semantic analyzer libraries.</p>
-
-<p>For more information about the low-level implementation details of the
-various clang libraries, please see the <a href="docs/InternalsManual.html">
-clang Internals Manual</a>.</p>
-
-<!--=======================================================================-->
-<h3><a name="diverseclients">Support Diverse Clients</a></h3>
-<!--=======================================================================-->
-
-<p>Clang is designed and built with many grand plans for how we can use it. The
-driving force is the fact that we use C and C++ daily, and have to suffer due to
-a lack of good tools available for it. We believe that the C and C++ tools
-ecosystem has been significantly limited by how difficult it is to parse and
-represent the source code for these languages, and we aim to rectify this
-problem in clang.</p>
-
-<p>The problem with this goal is that different clients have very different
-requirements. Consider code generation, for example: a simple front-end that
-parses for code generation must analyze the code for validity and emit code
-in some intermediate form to pass off to a optimizer or backend. Because
-validity analysis and code generation can largely be done on the fly, there is
-not hard requirement that the front-end actually build up a full AST for all
-the expressions and statements in the code. TCC and GCC are examples of
-compilers that either build no real AST (in the former case) or build a stripped
-down and simplified AST (in the later case) because they focus primarily on
-codegen.</p>
-
-<p>On the opposite side of the spectrum, some clients (like refactoring) want
-highly detailed information about the original source code and want a complete
-AST to describe it with. Refactoring wants to have information about macro
-expansions, the location of every paren expression '(((x)))' vs 'x', full
-position information, and much more. Further, refactoring wants to look
-<em>across the whole program</em> to ensure that it is making transformations
-that are safe. Making this efficient and getting this right requires a
-significant amount of engineering and algorithmic work that simply are
-unnecessary for a simple static compiler.</p>
-
-<p>The beauty of the clang approach is that it does not restrict how you use it.
-In particular, it is possible to use the clang preprocessor and parser to build
-an extremely quick and light-weight on-the-fly code generator (similar to TCC)
-that does not build an AST at all. As an intermediate step, clang supports
-using the current AST generation and semantic analysis code and having a code
-generation client free the AST for each function after code generation. Finally,
-clang provides support for building and retaining fully-fledged ASTs, and even
-supports writing them out to disk.</p>
-
-<p>Designing the libraries with clean and simple APIs allows these high-level
-policy decisions to be determined in the client, instead of forcing "one true
-way" in the implementation of any of these libraries. Getting this right is
-hard, and we don't always get it right the first time, but we fix any problems
-when we realize we made a mistake.</p>
-
-<!--=======================================================================-->
-<h3><a name="ideintegration">Integration with IDEs</h3>
-<!--=======================================================================-->
-
-<p>
-We believe that Integrated Development Environments (IDE's) are a great way
-to pull together various pieces of the development puzzle, and aim to make clang
-work well in such an environment. The chief advantage of an IDE is that they
-typically have visibility across your entire project and are long-lived
-processes, whereas stand-alone compiler tools are typically invoked on each
-individual file in the project, and thus have limited scope.</p>
-
-<p>There are many implications of this difference, but a significant one has to
-do with efficiency and caching: sharing an address space across different files
-in a project, means that you can use intelligent caching and other techniques to
-dramatically reduce analysis/compilation time.</p>
-
-<p>A further difference between IDEs and batch compiler is that they often
-impose very different requirements on the front-end: they depend on high
-performance in order to provide a "snappy" experience, and thus really want
-techniques like "incremental compilation", "fuzzy parsing", etc. Finally, IDEs
-often have very different requirements than code generation, often requiring
-information that a codegen-only frontend can throw away. Clang is
-specifically designed and built to capture this information.
-</p>
-
-
-<!--=======================================================================-->
-<h3><a name="license">Use the LLVM 'BSD' License</a></h3>
-<!--=======================================================================-->
-
-<p>We actively indend for clang (and a LLVM as a whole) to be used for
-commercial projects, and the BSD license is the simplest way to allow this. We
-feel that the license encourages contributors to pick up the source and work
-with it, and believe that those individuals and organizations will contribute
-back their work if they do not want to have to maintain a fork forever (which is
-time consuming and expensive when merges are involved). Further, nobody makes
-money on compilers these days, but many people need them to get bigger goals
-accomplished: it makes sense for everyone to work together.</p>
-
-<p>For more information about the LLVM/clang license, please see the <a
-href="http://llvm.org/docs/DeveloperPolicy.html#license">LLVM License
-Description</a> for more information.</p>
-
-
-
-<!--*************************************************************************-->
-<h2><a name="design">Internal Design and Implementation</a></h2>
-<!--*************************************************************************-->
-
-<!--=======================================================================-->
-<h3><a name="real">A real-world, production quality compiler</a></h3>
-<!--=======================================================================-->
-
-<p>
-Clang is designed and built by experienced compiler developers who
-are increasingly frustrated with the problems that <a
-href="comparison.html">existing open source compilers</a> have. Clang is
-carefully and thoughtfully designed and built to provide the foundation of a
-whole new generation of C/C++/Objective C development tools, and we intend for
-it to be production quality.</p>
-
-<p>Being a production quality compiler means many things: it means being high
-performance, being solid and (relatively) bug free, and it means eventually
-being used and depended on by a broad range of people. While we are still in
-the early development stages, we strongly believe that this will become a
-reality.</p>
-
-<!--=======================================================================-->
-<h3><a name="simplecode">A simple and hackable code base</a></h3>
-<!--=======================================================================-->
-
-<p>Our goal is to make it possible for anyone with a basic understanding
-of compilers and working knowledge of the C/C++/ObjC languages to understand and
-extend the clang source base. A large part of this falls out of our decision to
-make the AST mirror the languages as closely as possible: you have your friendly
-if statement, for statement, parenthesis expression, structs, unions, etc, all
-represented in a simple and explicit way.</p>
-
-<p>In addition to a simple design, we work to make the source base approachable
-by commenting it well, including citations of the language standards where
-appropriate, and designing the code for simplicity. Beyond that, clang offers
-a set of AST dumpers, printers, and visualizers that make it easy to put code in
-and see how it is represented.</p>
-
-<!--=======================================================================-->
-<h3><a name="unifiedparser">A single unified parser for C, Objective C, C++,
-and Objective C++</a></h3>
-<!--=======================================================================-->
-
-<p>Clang is the "C Language Family Front-end", which means we intend to support
-the most popular members of the C family. We are convinced that the right
-parsing technology for this class of languages is a hand-built recursive-descent
-parser. Because it is plain C++ code, recursive descent makes it very easy for
-new developers to understand the code, it easily supports ad-hoc rules and other
-strange hacks required by C/C++, and makes it straight-forward to implement
-excellent diagnostics and error recovery.</p>
-
-<p>We believe that implementing C/C++/ObjC in a single unified parser makes the
-end result easier to maintain and evolve than maintaining a separate C and C++
-parser which must be bugfixed and maintained independently of each other.</p>
-
-<!--=======================================================================-->
-<h3><a name="conformance">Conformance with C/C++/ObjC and their
- variants</a></h3>
-<!--=======================================================================-->
-
-<p>When you start work on implementing a language, you find out that there is a
-huge gap between how the language works and how most people understand it to
-work. This gap is the difference between a normal programmer and a (scary?
-super-natural?) "language lawyer", who knows the ins and outs of the language
-and can grok standardese with ease.</p>
-
-<p>In practice, being conformant with the languages means that we aim to support
-the full language, including the dark and dusty corners (like trigraphs,
-preprocessor arcana, C99 VLAs, etc). Where we support extensions above and
-beyond what the standard officially allows, we make an effort to explicitly call
-this out in the code and emit warnings about it (which are disabled by default,
-but can optionally be mapped to either warnings or errors), allowing you to use
-clang in "strict" mode if you desire.</p>
-
-<p>We also intend to support "dialects" of these languages, such as C89, K&amp;R
-C, C++'03, Objective-C 2, etc.</p>
-
-</div>
-</body>
-</html>
diff --git a/clang/www/get_involved.html b/clang/www/get_involved.html
deleted file mode 100644
index 8d0c68511304..000000000000
--- a/clang/www/get_involved.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>Clang - Get Involved</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<h1>Getting Involved with the Clang Project</h1>
-
-<p>Once you have <a href="get_started.html">checked out and built</a> clang and
-played around with it, you might be wondering what you can do to make it better
-and contribute to its development. Alternatively, maybe you just want to follow
-the development of the project to see it progress.
-</p>
-
-<h2>Follow what's going on</h2>
-
-<p>Clang is a subproject of the <a href="http://llvm.org">LLVM Project</a>, but
-has its own mailing lists because the communities have people with different
-interests. The two clang lists are:</p>
-
-<ul>
-<li><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits
-</a> - This list is for patch submission/discussion.</li>
-
-<li><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a> -
-This list is for everything else clang related (questions and answers, bug
-reports, etc).</li>
-
-</ul>
-
-<p>If you are interested in clang only, these two lists should be all
-you need. If you are interested in the LLVM optimizer and code generator,
-please consider signing up for <a
-href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">llvmdev</a> and <a
-href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">llvm-commits</a>
-as well.</p>
-
-
-<p>The best way to talk with other developers on the project is through the <a
-href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev mailing
-list</a>. The clang mailing list is a very friendly place and we welcome
-newcomers. In addition to the cfe-dev list, a significant amount of design
-discussion takes place on the <a
-href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits mailing
-list</a>. All of these lists have archives, so you can browse through previous
-discussions or follow the list development on the web if you prefer.</p>
-
-
-<h2>Open Projects</h2>
-
-<p>Here are a few tasks that are available for newcomers to work on, depending
-on what your interests are. This list is provided to generate ideas, it is not
-intended to be comprehensive. Please ask on cfe-dev for more specifics or to
-verify that one of these isn't already completed. :)</p>
-
-<ul>
-<li><b>Compile your favorite C/ObjC project with "clang -fsyntax-only"</b>:
-the clang type checker and verifier is quite close to complete (but not bug
-free!) for C and Objective C. We appreciate all reports of code that is
-rejected by the front-end, and if you notice invalid code that is not rejected
-by clang, that is also very important to us. For make-based projects,
-the <a href="get_started.html#ccc"><code>ccc</code></a> script in clang's
-<tt>utils</tt> folder might help to get you started.</li>
-
-<li><b>Compile your favorite C project with "clang -emit-llvm"</b>:
-The clang to LLVM converter is getting more mature, so you may be able to
-compile it. If not, please let us know. Again,
-<a href="get_started.html#ccc"><code>ccc</code></a> might help you. Once it
-compiles it should run. If not, that's a bug :)</li>
-
-<li><b>Work on code generation for Objective C</b>: -emit-llvm support for
-Objective C is basically nonexistent at the time of this writing, this is a
-nice open project that can be tackled incrementally (one language feature at a
-time).</li>
-
-<li><b>Debug Info Generation</b>: -emit-llvm doesn't currently support emission
-of <a href="http://llvm.org/docs/SourceLevelDebugging.html">LLVM debug info</a>
-(which the code generator turns into DWARF). Adding this should be
-straight-forward if you follow the example of what llvm-gcc generates.</li>
-
-<li><b>Continue work on C++ support</b>: Implementing all of C++ is a very big
-job, but there are lots of little pieces that can be picked off and implemented.
-See the <a href="cxx_status.html">C++ status report page</a> to find out what is
-missing and what is already at least partially supported.</li>
-
-<li><b>Improve target support</b>: The current target interfaces are heavily
-stubbed out and need to be implemented fully. See the FIXME's in TargetInfo.
-Additionally, the actual target implementations (instances of TargetInfoImpl)
-also need to be completed. This includes defining builtin macros for linux
-targets and other stuff like that.</li>
-
-<li><b>Implement 'builtin' headers</b>: GCC provides a bunch of builtin headers,
-such as stdbool.h, iso646.h, float.h, limits.h, etc. It also provides a bunch
-of target-specific headers like altivec.h and xmmintrin.h. clang will
-eventually need to provide its own copies of these (and there is a <a href=
-"http://lists.cs.uiuc.edu/pipermail/cfe-dev/2007-December/000560.html">lot of
-improvement</a> that can be made to the GCC ones!) that are clean-room
-implemented to avoid GPL taint.</li>
-
-<li><b>Implement a clang 'libgcc'</b>: As with the headers, clang (or a another
-related subproject of llvm) will need to implement the features that libgcc
-provides. libgcc provides a bunch of routines the code generator uses for
-"fallback" when the chip doesn't support some operation (e.g. 64-bit divide on
-a 32-bit chip). It also provides software floating point support and many other
-things. I don't think that there is a specific licensing reason to reimplement
-libgcc, but there is a lot of room for improvement in it in many
-dimensions.</li>
-
-<li><b>Implement an tool to generate code documentation</b>: Clang's
-library-based design allows it to be used by a variety of tools that reason
-about source code. One great application of Clang would be to build an
-auto-documentation system like doxygen that generates code documentation from
-source code. The advantage of using Clang for such a tool is that the tool would
-use the same preprocessor/parser/ASTs as the compiler itself, giving it a very
-rich understanding of the code.</li>
-
-<li><b>Use clang libraries to implement better versions of existing tools</b>:
-Clang is built as a set of libraries, which means that it is possible to
-implement capabilities similar to other source language tools, improving them
-in various ways. Two examples are <a href="http://distcc.samba.org/">distcc</a>
-and the <a href="http://delta.tigris.org/">delta testcase reduction tool</a>.
-The former can be improved to scale better and be more efficient. The later
-could also be faster and more efficient at reducing C-family programs if built
-on the clang preprocessor.</li>
-
-<li><b>Use clang libraries to extend Ragel with a JIT</b>: <a
-href="http://research.cs.queensu.ca/~thurston/ragel/">Ragel</a> is a state
-machine compiler that lets you embed C code into state machines and generate
-C code. It would be relatively easy to turn this into a JIT compiler using
-LLVM.</li>
-
-<li><b>Self-testing using clang</b>: There are several neat ways to
-improve the quality of clang by self-testing. Some examples:
-<ul>
- <li>Improve the reliability of AST printing and serialization by
- ensuring that the AST produced by clang on an input doesn't change
- when it is reparsed or unserialized.
-
- <li>Improve parser reliability and error generation by automatically
- or randomly changing the input checking that clang doesn't crash and
- that it doesn't generate excessive errors for small input
- changes. Manipulating the input at both the text and token levels is
- likely to produce interesting test cases.
-</ul>
-</li>
-
-</ul>
-
-<p>If you hit a bug with clang, it is very useful for us if you reduce the code
-that demonstrates the problem down to something small. There are many ways to
-do this; ask on cfe-dev for advice.</p>
-
-</div>
-</body>
-</html>
diff --git a/clang/www/get_started.html b/clang/www/get_started.html
deleted file mode 100644
index a975eaf17ca6..000000000000
--- a/clang/www/get_started.html
+++ /dev/null
@@ -1,231 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>Clang - Getting Started</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
-
-<!--#include virtual="menu.html.incl"-->
-
-<div id="content">
-
-<h1>Getting Started: Building and Running Clang</h1>
-
-
-<p>This page gives you the shortest path to checking out clang and demos a few
-options. This should get you up and running with the minimum of muss and fuss.
-If you like what you see, please consider <a href="get_involved.html">getting
-involved</a> with the clang community.</p>
-
-
-<h2>A word of warning</h2>
-
-<p>While this work aims to provide a fully functional C/C++/ObjC front-end, it
-is <em>still early work</em> and is under heavy development. In particular,
-there is no real C++ support yet (this is obviously a big project), and C/ObjC
-support is still missing some features. Some of the more notable missing pieces
-of C support are:</p>
-
-<ol>
- <li>The semantic analyzer does not produce all of the warnings and errors it
- should.</li>
- <li>The LLVM code generator is still missing important features. clang is not
- ready to be used as a general purpose C code generator yet, but if you
- hit problems and report them to cfe-dev, we'll fix them :).</li>
- <li>We don't consider the API to be stable yet, and reserve the right to
- change fundamental things.</li>
-</ol>
-
-<p>Our plan is to continue chipping away at these issues until C works really
-well, but we'd love help from other interested contributors. We expect C to be
-in good shape by mid to late 2008.</p>
-
-<h2 id="build">Building clang / working with the code</h2>
-
-<p>If you would like to check out and build the project, the current scheme
-is:</p>
-
-<ol>
- <li><a href="http://www.llvm.org/docs/GettingStarted.html#checkout">Checkout
- and build LLVM</a> from SVN head:</li>
-
- <ul>
- <li><tt>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
- <li><tt>cd llvm</tt></li>
- <li><tt>./configure; make</tt></li>
- </ul>
- <li>Checkout clang:</li>
- <ul>
- <li>From within the <tt>llvm</tt> directory (where you
- built llvm):</li>
- <li><tt>cd tools</tt>
- <li><tt>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
-
- </ul>
- <li>Non-mac users: Paths to system header files are currently hard coded
- into clang; as a result, if clang can't find your system headers,
- please follow these instructions:</li>
-
- <ul>
- <li>'<tt>touch empty.c; gcc -v empty.c -fsyntax-only</tt>' to get the
- path.</li>
- <li>Look for the comment "FIXME: temporary hack:
- hard-coded paths" in <tt>clang/lib/Driver/InitHeaderSearch.cpp</tt> and
- change the lines below to include that path.</li>
- </ul>
-
- <li>Build clang:</li>
- <ul>
- <li><tt>cd clang</tt> (assuming that you are in <tt>llvm/tools</tt>)</li>
- <li><tt>make</tt> (this will give you a debug build)</li>
- </ul>
-
- <li>Try it out (assuming you add llvm/Debug/bin to your path):</li>
- <ul>
- <li><tt>clang --help</tt></li>
- <li><tt>clang file.c -fsyntax-only</tt> (check for correctness)</li>
- <li><tt>clang file.c -ast-dump</tt> (internal debug dump of ast)</li>
- <li><tt>clang file.c -ast-view</tt> (<a
- href="http://llvm.org/docs/ProgrammersManual.html#ViewGraph">set up graphviz
- and rebuild llvm first</a>)</li>
- <li><tt>clang file.c -emit-llvm</tt> (print out unoptimized llvm code)</li>
- <li><tt>clang file.c -emit-llvm -o - | llvm-as | opt -std-compile-opts |
- llvm-dis</tt> (print out optimized llvm code)</li>
- <li><tt>clang file.c -emit-llvm -o - | llvm-as | opt -std-compile-opts | llc
- &gt; file.s</tt> (output native machine code)</li>
- </ul>
-</ol>
-
-<p>Note that the C front-end uses LLVM, but does not depend on
- llvm-gcc. If you encounter problems with building clang, make
- sure you have the latest SVN version of LLVM. LLVM contains
- support libraries for clang that will be updated as well as
- development on clang progresses.</p>
-
-<h3>Building clang while building llvm:</h3>
- <p>Since you've checked out clang into the llvm source tree you can
- build them all at once with a simple Makefile change. This moves
- Step 1 above to Step 4.</p>
- <ul>
- <li><tt>cd llvm/tools</tt></li>
- <li>then edit <tt>Makefile</tt> to have a clang target in <tt>PARALLEL_DIRS</tt>
- just like <tt>llvm-config</tt></li>
- <li>then just build llvm normally as above and clang will build at
- the same time</li>
- <li><em>Note:</em> you can update your toplevel project and all (possibly unrelated)
- projects inside it with <tt><b>make update</b></tt>. This will run
- <tt>svn update</tt> on all subdirectories related to subversion.</li>
- </ul>
-
-<h2>Examples of using clang</h2>
-
-<p>The clang driver takes a lot of GCC compatible options, which you can see
-with 'clang --help'. Here are a few examples:</p>
-<!-- Thanks to
- http://shiflett.org/blog/2006/oct/formatting-and-highlighting-php-code-listings
-Site suggested using pre in CSS, but doesn't work in IE, so went for the <pre>
-tag. -->
-
-<pre class="code">
-$ <b>cat ~/t.c</b>
-typedef float V __attribute__((vector_size(16)));
-V foo(V a, V b) { return a+b*a; }
-</pre>
-
-
-<h3>Preprocessing:</h3>
-
-<pre class="code">
-$ <b>clang ~/t.c -E</b>
-# 1 "/Users/sabre/t.c" 1
-
-typedef float V __attribute__((vector_size(16)));
-
-V foo(V a, V b) { return a+b*a; }
-</pre>
-
-
-<h3>Type checking:</h3>
-
-<pre class="code">
-$ <b>clang -fsyntax-only ~/t.c</b>
-</pre>
-
-
-<h3>GCC options:</h3>
-
-<pre class="code">
-$ <b>clang -fsyntax-only ~/t.c -pedantic</b>
-/Users/sabre/t.c:2:17: warning: extension used
-typedef float V __attribute__((vector_size(16)));
- ^
-1 diagnostic generated.
-</pre>
-
-
-<h3>Pretty printing from the AST:</h3>
-
-<pre class="code">
-$ <b>clang ~/t.c -ast-print</b>
-typedef float V __attribute__(( vector_size(16) ));
-V foo(V a, V b) {
- return a + b * a;
-}
-</pre>
-
-
-<h3>Code generation with LLVM:</h3>
-
-<pre class="code">
-$ <b>clang ~/t.c -emit-llvm -o - | llvm-as | opt -std-compile-opts | llvm-dis</b>
-define &lt;4 x float&gt; @foo(&lt;4 x float&gt; %a, &lt;4 x float&gt; %b) {
-entry:
- %mul = mul &lt;4 x float&gt; %b, %a
- %add = add &lt;4 x float&gt; %mul, %a
- ret &lt;4 x float&gt; %add
-}
-$ <b>clang ~/t.c -emit-llvm -o - | llvm-as | opt -std-compile-opts | llc -march=ppc32 -mcpu=g5</b>
-..
-_foo:
- vmaddfp v2, v3, v2, v2
- blr
-$ <b>clang ~/t.c -emit-llvm -o - | llvm-as | opt -std-compile-opts | llc -march=x86 -mcpu=yonah</b>
-..
-_foo:
- mulps %xmm0, %xmm1
- addps %xmm0, %xmm1
- movaps %xmm1, %xmm0
- ret
-</pre>
-
-<a name="ccc"><h3>GCC "Emulation" Driver</h3></a>
-
-<p>While the <tt>clang</tt> executable is a compiler driver that can perform
-code generation, program analysis, and other actions, it is not designed to be a
-drop-in replacement for GCC's <tt>cc</tt>. There is interest in developing such
-a driver for clang, but in the interim the clang source tree includes a Python
-script <tt>ccc</tt> in the <tt>utils</tt> subdirectory that provides some of
-this functionality (the script is intended to be used where GCC's <tt>cc</tt>
-could be used). It is currently a work in progress, and eventually will likely
-be replaced by a more complete driver.</p>
-
-<p>Example use:</p>
-
-<pre class="code">
-$ <b>ccc t.c</b>
-clang -emit-llvm-bc -o t.o -U__GNUC__ t.c
-llvm-ld -native -o a.out t.o
-$ <b>ls</b>
-a.out a.out.bc t.c t.o
-</pre>
-
-
-
-
-</div>
-</body>
-</html>
diff --git a/clang/www/index.html b/clang/www/index.html
deleted file mode 100644
index a0408e0cea53..000000000000
--- a/clang/www/index.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
-<html>
-<head>
- <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <title>"clang" C Language Family Frontend for LLVM</title>
- <link type="text/css" rel="stylesheet" href="menu.css" />
- <link type="text/css" rel="stylesheet" href="content.css" />
-</head>
-<body>
-<!--#include virtual="menu.html.incl"-->
-<div id="content">
- <!--*********************************************************************-->
- <h1>clang: a C language family frontend for LLVM</h1>
- <!--*********************************************************************-->
-
- <p>The goal of the Clang project is to create a new C, C++, Objective C and
- Objective C++ front-end for the <a href="http://www.llvm.org/">LLVM</a>
- compiler. You can <a href="get_started.html">get and build</a> the source
- today.</p>
-
- <!--=====================================================================-->
- <h2 id="goals">Features and Goals</h2>
- <!--=====================================================================-->
-
- <p>Some of the goals for the project include the following:</p>
-
- <p><b><a href="features.html#enduser">End-User Features</a></b>:</p>
-
- <ul>
- <li>Fast compiles and low memory use</li>
- <li>Expressive diagnostics</li>
- <li>GCC compatibility</li>
- </ul>
-
- <p><b><a href="features.html#applications">Utility and
- Applications</a></b>:</p>
-
- <ul>
- <li>Modular library based architecture</li>
- <li>Support diverse clients (refactoring, static analysis, code generation,
- etc)</li>
- <li>Allow tight integration with IDEs</li>
- <li>Use the LLVM 'BSD' License</li>
- </ul>
-
- <p><b><a href="features.html#design">Internal Design and
- Implementation</a></b>:</p>
-
- <ul>
- <li>A real-world, production quality compiler</li>
- <li>A simple and hackable code base</li>
- <li>A single unified parser for C, Objective C, C++, and Objective C++</li>
- <li>Conformance with C/C++/ObjC and their variants</li>
- </ul>
-
- <p>Of course this is only a rough outline of the goals and features of
- Clang. To get a true sense of what it is all about, see the <a
- href="features.html">Features</a> section, which breaks
- each of these down and explains them in more detail.</p>
-
-
- <!--=====================================================================-->
- <h2>Why?</h2>
- <!--=====================================================================-->
-
- <p>The development of a new front-end was started out of a need -- a need
- for a compiler that allows better diagnostics, better integration with
- IDEs, a license that is compatible with commercial products, and a
- nimble compiler that is easy to develop and maintain. All of these were
- motivations for starting work on a new front-end that could
- meet these needs.</p>
-
- <p>A good (but quite dated) introduction to Clang can be found in the
- following video lectures:</p>
-
- <ul>
- <li><a href="clang_video-05-25-2007.html">Clang Introduction</a>
- (May 2007)</li>
- <li><a href="clang_video-07-25-2007.html">Features and Performance of
- Clang</a> (July 2007)</li>
- </ul>
-
- <p>For a more detailed comparison between Clang and other compilers, please
- see the <a href="comparison.html">clang comparison page</a>.</p>
-
- <!--=====================================================================-->
- <h2>Current Status</h2>
- <!--=====================================================================-->
-
- <p>Clang is still in early development stages. If you are looking for
- source analysis or source-to-source transformation tools, clang is probably
- a great solution for you. If you want to use it as a drop in C compiler, it
- is not yet ready.</p>
-
- <p>Clang currently has pretty good parsing and semantic analysis support for
- C and Objective-C right now, and bugs are usually quickly fixed once
- reported. <a href="cxx_status.html">C++ support</a> is still very early,
- and we don't expect to have respectable C++ support for another 2 years
- or so.</p>
-
- <!--=====================================================================-->
- <h2>Get it and get involved!</h2>
- <!--=====================================================================-->
-
- <p>Start by <a href="get_started.html">getting the code, building it, and
- playing with it</a>. This will show you the sorts of things we can do
- today and will let you have the "clang experience" first hand: hopefully
- it will "resonate" with you. :)</p>
-
- <p>Once you've done that, please consider <a href="get_involved.html">getting
- involved in the clang community</a>. The clang developers include numerous
- volunteer contributors with a variety of backgrounds. If you're
- interested in
- following the development of clang, signing up for a mailing list is a good
- way to learn about how the project works.</p>
-</div>
-</body>
-</html>
diff --git a/clang/www/latest_checker.html.incl b/clang/www/latest_checker.html.incl
deleted file mode 100644
index d0b2d6d3b14e..000000000000
--- a/clang/www/latest_checker.html.incl
+++ /dev/null
@@ -1 +0,0 @@
-<b><a href="http://keeda.stanford.edu/~kremenek/checker/checker-108.tar.bz2">checker-108.tar.bz2</a></b> (built October 6, 2008)
diff --git a/clang/www/menu.css b/clang/www/menu.css
deleted file mode 100644
index ba1a6d3a5c62..000000000000
--- a/clang/www/menu.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/***************/
-/* page layout */
-/***************/
-
-[id=menu] {
- position:fixed;
- width:25ex;
-}
-[id=content] {
- /* ***** EDIT THIS VALUE IF CONTENT OVERLAPS MENU ***** */
- position:absolute;
- left:29ex;
- padding-right:4ex;
-}
-
-/**************/
-/* menu style */
-/**************/
-
-#menu .submenu {
- padding-top:1em;
- display:block;
-}
-
-#menu label {
- display:block;
- font-weight: bold;
- text-align: center;
- background-color: rgb(192,192,192);
-}
-#menu a {
- padding:0 .2em;
- display:block;
- text-align: center;
- background-color: rgb(235,235,235);
-}
-#menu a:visited {
- color:rgb(100,50,100);
-} \ No newline at end of file
diff --git a/clang/www/menu.html.incl b/clang/www/menu.html.incl
deleted file mode 100644
index 3fff393fb229..000000000000
--- a/clang/www/menu.html.incl
+++ /dev/null
@@ -1,38 +0,0 @@
-<div id="menu">
- <div>
- <a href="http://llvm.org/">LLVM Home</a>
- </div>
-
- <div class="submenu">
- <label>Clang Info</label>
- <a href="/index.html">About</a>
- <a href="/features.html">Features</a>
- <a href="/comparison.html">Comparisons</a>
- <a href="/get_started.html">Get&nbsp;Started</a>
- <a href="/get_involved.html">Get&nbsp;Involved</a>
- <a href="/cxx_status.html">C++ Status</a>
- <a href="/docs/InternalsManual.html">Clang&nbsp;Internals</a>
- </div>
-
- <div class="submenu">
- <label>Clang Tools</label>
- <a href="/StaticAnalysis.html">Automatic Bug-Finding</a>
- </div>
-
- <div class="submenu">
- <label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
- <a href="http://llvm.org/bugs/">Bug Reports</a>
- <a href="http://llvm.org/svn/llvm-project/cfe/trunk/">Browse Source</a>
- <a href="http://clang.llvm.org/doxygen/">doxygen</a>
- <a href="http://keeda.stanford.edu/~ddunbar/clang/references.html">Spec. References</a>
- <a href="http://keeda.stanford.edu/~ddunbar/clang/coverage/">Testing Coverage</a>
- </div>
-
- <div class="submenu">
- <label>Events</label>
- <a href="http://llvm.org/devmtg/">August 1, 2008 - LLVM/Clang Developer Meeting</a>
- </div>
-
-</div>