summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanya Lattner <tonic@nondot.org>2008-05-10 04:05:12 +0000
committerTanya Lattner <tonic@nondot.org>2008-05-10 04:05:12 +0000
commit468bddb269a2d8be00409726b7728fba098fcea1 (patch)
tree60d94b41ff5a051d0b0b3027f0038a45980592e7
parent9c4d685165953f0271123089518f32c013d344a0 (diff)
downloadllvm-468bddb269a2d8be00409726b7728fba098fcea1.tar.gz
Creating 2.3 release branch.
llvm-svn: 50932
-rw-r--r--clang/Driver/ASTConsumers.cpp990
-rw-r--r--clang/Driver/ASTConsumers.h80
-rw-r--r--clang/Driver/DiagChecker.cpp239
-rw-r--r--clang/Driver/HTMLDiagnostics.cpp399
-rw-r--r--clang/Driver/HTMLDiagnostics.h31
-rw-r--r--clang/Driver/HTMLPrint.cpp93
-rw-r--r--clang/Driver/Makefile13
-rw-r--r--clang/Driver/PrintParserCallbacks.cpp57
-rw-r--r--clang/Driver/PrintPreprocessedOutput.cpp685
-rw-r--r--clang/Driver/RewriteMacros.cpp184
-rw-r--r--clang/Driver/RewriteObjC.cpp3031
-rw-r--r--clang/Driver/SerializationTest.cpp197
-rw-r--r--clang/Driver/TextDiagnosticBuffer.cpp41
-rw-r--r--clang/Driver/TextDiagnosticBuffer.h53
-rw-r--r--clang/Driver/TextDiagnosticPrinter.cpp209
-rw-r--r--clang/Driver/TextDiagnosticPrinter.h52
-rw-r--r--clang/Driver/TextDiagnostics.cpp53
-rw-r--r--clang/Driver/TextDiagnostics.h50
-rw-r--r--clang/Driver/clang.cpp1490
-rw-r--r--clang/Driver/clang.h49
-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.pbxproj1212
-rw-r--r--clang/docs/InternalsManual.html610
-rw-r--r--clang/docs/index.html4
-rw-r--r--clang/include/clang/AST/AST.h25
-rw-r--r--clang/include/clang/AST/ASTConsumer.h60
-rw-r--r--clang/include/clang/AST/ASTContext.h376
-rw-r--r--clang/include/clang/AST/Attr.h234
-rw-r--r--clang/include/clang/AST/Builtins.def114
-rw-r--r--clang/include/clang/AST/Builtins.h89
-rw-r--r--clang/include/clang/AST/CFG.h407
-rw-r--r--clang/include/clang/AST/Decl.h847
-rw-r--r--clang/include/clang/AST/DeclBase.h345
-rw-r--r--clang/include/clang/AST/DeclObjC.h1193
-rw-r--r--clang/include/clang/AST/Expr.h1609
-rw-r--r--clang/include/clang/AST/ExprCXX.h173
-rw-r--r--clang/include/clang/AST/PPCBuiltins.def24
-rw-r--r--clang/include/clang/AST/PrettyPrinter.h31
-rw-r--r--clang/include/clang/AST/RecordLayout.h57
-rw-r--r--clang/include/clang/AST/Stmt.h1070
-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.def113
-rw-r--r--clang/include/clang/AST/StmtVisitor.h173
-rw-r--r--clang/include/clang/AST/TargetBuiltins.h37
-rw-r--r--clang/include/clang/AST/TranslationUnit.h92
-rw-r--r--clang/include/clang/AST/Type.h1262
-rw-r--r--clang/include/clang/AST/X86Builtins.def422
-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.h316
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/DataflowValues.h172
-rw-r--r--clang/include/clang/Analysis/LocalCheckers.h42
-rw-r--r--clang/include/clang/Analysis/PathDiagnostic.h207
-rw-r--r--clang/include/clang/Analysis/PathSensitive/AnnotatedPath.h67
-rw-r--r--clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h84
-rw-r--r--clang/include/clang/Analysis/PathSensitive/BugReporter.h161
-rw-r--r--clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h516
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRAuditor.h38
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRBlockCounter.h50
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h634
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRExprEngine.h654
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h41
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h119
-rw-r--r--clang/include/clang/Analysis/PathSensitive/GRWorkList.h74
-rw-r--r--clang/include/clang/Analysis/PathSensitive/RValues.h507
-rw-r--r--clang/include/clang/Analysis/PathSensitive/SymbolManager.h257
-rw-r--r--clang/include/clang/Analysis/PathSensitive/ValueState.h260
-rw-r--r--clang/include/clang/Analysis/ProgramPoint.h185
-rw-r--r--clang/include/clang/Analysis/Support/ExprDeclBitVector.h276
-rw-r--r--clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h88
-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.h198
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def1057
-rw-r--r--clang/include/clang/Basic/FileManager.h125
-rw-r--r--clang/include/clang/Basic/IdentifierTable.h329
-rw-r--r--clang/include/clang/Basic/LangOptions.h75
-rw-r--r--clang/include/clang/Basic/SourceLocation.h265
-rw-r--r--clang/include/clang/Basic/SourceManager.h471
-rw-r--r--clang/include/clang/Basic/TargetInfo.h222
-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.h31
-rw-r--r--clang/include/clang/Lex/DirectoryLookup.h135
-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.h164
-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.h82
-rw-r--r--clang/include/clang/Lex/Preprocessor.h543
-rw-r--r--clang/include/clang/Lex/ScratchBuffer.h50
-rw-r--r--clang/include/clang/Lex/Token.h158
-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.h813
-rw-r--r--clang/include/clang/Parse/AttributeList.h103
-rw-r--r--clang/include/clang/Parse/DeclSpec.h683
-rw-r--r--clang/include/clang/Parse/Parser.h496
-rw-r--r--clang/include/clang/Parse/Scope.h149
-rw-r--r--clang/include/clang/Rewrite/DeltaTree.h48
-rw-r--r--clang/include/clang/Rewrite/HTMLRewrite.h88
-rw-r--r--clang/include/clang/Rewrite/RewriteRope.h227
-rw-r--r--clang/include/clang/Rewrite/Rewriter.h219
-rw-r--r--clang/include/clang/Sema/ParseAST.h27
-rw-r--r--clang/lib/AST/ASTConsumer.cpp28
-rw-r--r--clang/lib/AST/ASTContext.cpp1753
-rw-r--r--clang/lib/AST/Builtins.cpp195
-rw-r--r--clang/lib/AST/CFG.cpp1634
-rw-r--r--clang/lib/AST/Decl.cpp574
-rw-r--r--clang/lib/AST/DeclObjC.cpp589
-rw-r--r--clang/lib/AST/DeclSerialization.cpp513
-rw-r--r--clang/lib/AST/Expr.cpp1421
-rw-r--r--clang/lib/AST/ExprCXX.cpp55
-rw-r--r--clang/lib/AST/Makefile22
-rw-r--r--clang/lib/AST/Stmt.cpp293
-rw-r--r--clang/lib/AST/StmtDumper.cpp490
-rw-r--r--clang/lib/AST/StmtIterator.cpp118
-rw-r--r--clang/lib/AST/StmtPrinter.cpp869
-rw-r--r--clang/lib/AST/StmtSerialization.cpp1082
-rw-r--r--clang/lib/AST/StmtViz.cpp59
-rw-r--r--clang/lib/AST/TranslationUnit.cpp245
-rw-r--r--clang/lib/AST/Type.cpp1022
-rw-r--r--clang/lib/AST/TypeSerialization.cpp293
-rw-r--r--clang/lib/Analysis/BasicObjCFoundationChecks.cpp290
-rw-r--r--clang/lib/Analysis/BasicObjCFoundationChecks.h39
-rw-r--r--clang/lib/Analysis/BasicValueFactory.cpp249
-rw-r--r--clang/lib/Analysis/BugReporter.cpp524
-rw-r--r--clang/lib/Analysis/CFRefCount.cpp2139
-rw-r--r--clang/lib/Analysis/DeadStores.cpp206
-rw-r--r--clang/lib/Analysis/ExplodedGraph.cpp259
-rw-r--r--clang/lib/Analysis/GRBlockCounter.cpp54
-rw-r--r--clang/lib/Analysis/GRCoreEngine.cpp464
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp2622
-rw-r--r--clang/lib/Analysis/GRSimpleVals.cpp712
-rw-r--r--clang/lib/Analysis/GRSimpleVals.h87
-rw-r--r--clang/lib/Analysis/GRTransferFuncs.cpp39
-rw-r--r--clang/lib/Analysis/LiveVariables.cpp323
-rw-r--r--clang/lib/Analysis/Makefile22
-rw-r--r--clang/lib/Analysis/PathDiagnostic.cpp74
-rw-r--r--clang/lib/Analysis/ProgramPoint.cpp64
-rw-r--r--clang/lib/Analysis/RValues.cpp432
-rw-r--r--clang/lib/Analysis/SymbolManager.cpp124
-rw-r--r--clang/lib/Analysis/UninitializedValues.cpp283
-rw-r--r--clang/lib/Analysis/ValueState.cpp565
-rw-r--r--clang/lib/Basic/Diagnostic.cpp241
-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.cpp94
-rw-r--r--clang/lib/Basic/SourceManager.cpp514
-rw-r--r--clang/lib/Basic/TargetInfo.cpp217
-rw-r--r--clang/lib/Basic/Targets.cpp933
-rw-r--r--clang/lib/Basic/TokenKinds.cpp29
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp830
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp171
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h84
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp192
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp673
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp430
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp532
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp633
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp1183
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp27
-rw-r--r--clang/lib/CodeGen/CGObjCEtoile.cpp244
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp185
-rw-r--r--clang/lib/CodeGen/CGObjCRuntime.h68
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp801
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp273
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h505
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp670
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h143
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp665
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.h179
-rw-r--r--clang/lib/CodeGen/Makefile23
-rw-r--r--clang/lib/CodeGen/ModuleBuilder.cpp113
-rw-r--r--clang/lib/Headers/Makefile39
-rw-r--r--clang/lib/Headers/mmintrin.devel.h377
-rw-r--r--clang/lib/Headers/stdbool.h38
-rw-r--r--clang/lib/Lex/HeaderMap.cpp241
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp425
-rw-r--r--clang/lib/Lex/Lexer.cpp1662
-rw-r--r--clang/lib/Lex/LiteralSupport.cpp729
-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/PPDirectives.cpp1153
-rw-r--r--clang/lib/Lex/PPExpressions.cpp713
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp401
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp530
-rw-r--r--clang/lib/Lex/Pragma.cpp386
-rw-r--r--clang/lib/Lex/Preprocessor.cpp577
-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.cpp101
-rw-r--r--clang/lib/Parse/DeclSpec.cpp288
-rw-r--r--clang/lib/Parse/Makefile22
-rw-r--r--clang/lib/Parse/MinimalAction.cpp136
-rw-r--r--clang/lib/Parse/ParseDecl.cpp1529
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp359
-rw-r--r--clang/lib/Parse/ParseExpr.cpp1047
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp105
-rw-r--r--clang/lib/Parse/ParseInit.cpp241
-rw-r--r--clang/lib/Parse/ParseObjc.cpp1588
-rw-r--r--clang/lib/Parse/ParseStmt.cpp1159
-rw-r--r--clang/lib/Parse/Parser.cpp667
-rw-r--r--clang/lib/Rewrite/DeltaTree.cpp485
-rw-r--r--clang/lib/Rewrite/HTMLRewrite.cpp480
-rw-r--r--clang/lib/Rewrite/Makefile22
-rw-r--r--clang/lib/Rewrite/RewriteRope.cpp785
-rw-r--r--clang/lib/Rewrite/Rewriter.cpp176
-rw-r--r--clang/lib/Sema/IdentifierResolver.cpp191
-rw-r--r--clang/lib/Sema/IdentifierResolver.h370
-rw-r--r--clang/lib/Sema/Makefile23
-rw-r--r--clang/lib/Sema/ParseAST.cpp69
-rw-r--r--clang/lib/Sema/Sema.cpp226
-rw-r--r--clang/lib/Sema/Sema.h930
-rw-r--r--clang/lib/Sema/SemaChecking.cpp802
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2624
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp384
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp1179
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2341
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp51
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp465
-rw-r--r--clang/lib/Sema/SemaInit.cpp309
-rw-r--r--clang/lib/Sema/SemaStmt.cpp820
-rw-r--r--clang/lib/Sema/SemaType.cpp579
-rw-r--r--clang/lib/Sema/SemaUtil.h35
-rw-r--r--clang/test/Analysis-Apple/CFDate.m109
-rw-r--r--clang/test/Analysis-Apple/CFDateGC.m17
-rw-r--r--clang/test/Analysis-Apple/CFString.c30
-rw-r--r--clang/test/Analysis-Apple/NSString.m45
-rw-r--r--clang/test/Analysis-Apple/NoReturn.m36
-rw-r--r--clang/test/Analysis-Apple/uninit-msg-expr.m20
-rw-r--r--clang/test/Analysis/conditional-op-missing-lhs.c26
-rw-r--r--clang/test/Analysis/dead-stores.c45
-rw-r--r--clang/test/Analysis/exercise-ps.c10
-rw-r--r--clang/test/Analysis/null-deref-ps.c58
-rw-r--r--clang/test/Analysis/stack-addr-ps.c21
-rw-r--r--clang/test/Analysis/uninit-vals-ps.c35
-rw-r--r--clang/test/Analysis/uninit-vals.c44
-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/OpaqueStruct.c12
-rw-r--r--clang/test/CodeGen/address-space.c9
-rw-r--r--clang/test/CodeGen/array.c14
-rw-r--r--clang/test/CodeGen/atomic.c35
-rw-r--r--clang/test/CodeGen/attributes.c26
-rw-r--r--clang/test/CodeGen/bitfield-init.c4
-rw-r--r--clang/test/CodeGen/bitfield.c32
-rw-r--r--clang/test/CodeGen/boolassign.c6
-rw-r--r--clang/test/CodeGen/cast.c6
-rw-r--r--clang/test/CodeGen/cfstring.c6
-rw-r--r--clang/test/CodeGen/complex.c53
-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.c27
-rw-r--r--clang/test/CodeGen/const-init.c13
-rw-r--r--clang/test/CodeGen/cxx-default-arg.cpp25
-rw-r--r--clang/test/CodeGen/dostmt.c62
-rw-r--r--clang/test/CodeGen/enum.c18
-rw-r--r--clang/test/CodeGen/exprs.c36
-rw-r--r--clang/test/CodeGen/extern-block-var.c6
-rw-r--r--clang/test/CodeGen/func-return-member.c23
-rw-r--r--clang/test/CodeGen/functions.c11
-rw-r--r--clang/test/CodeGen/global-with-initialiser.c25
-rw-r--r--clang/test/CodeGen/globalinit.c52
-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/mandel.c73
-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-to-int.c6
-rw-r--r--clang/test/CodeGen/shared-string-literals.c9
-rw-r--r--clang/test/CodeGen/statements.c13
-rw-r--r--clang/test/CodeGen/staticinit.c20
-rw-r--r--clang/test/CodeGen/string-literal.c5
-rw-r--r--clang/test/CodeGen/struct-x86-darwin.c27
-rw-r--r--clang/test/CodeGen/struct.c147
-rw-r--r--clang/test/CodeGen/switch.c76
-rw-r--r--clang/test/CodeGen/trunc-array-initializer.c3
-rw-r--r--clang/test/CodeGen/typedef.c8
-rw-r--r--clang/test/CodeGen/types.c34
-rw-r--r--clang/test/CodeGen/union.c33
-rw-r--r--clang/test/CodeGen/vector.c7
-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/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.c5
-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.cpp15
-rw-r--r--clang/test/Lexer/escape_newline.c7
-rw-r--r--clang/test/Lexer/number.c4
-rw-r--r--clang/test/Lexer/pragma-mark.c11
-rw-r--r--clang/test/Lexer/unknown-char.c2
-rw-r--r--clang/test/Makefile40
-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.c10
-rw-r--r--clang/test/Parser/attributes.c6
-rw-r--r--clang/test/Parser/bad-control.c9
-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.cpp31
-rw-r--r--clang/test/Parser/cxx-reference.cpp17
-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.m25
-rw-r--r--clang/test/Parser/objc-init.m17
-rw-r--r--clang/test/Parser/objc-messaging-1.m14
-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.m3
-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/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/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/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/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/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/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/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.m16
-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-protocol-type-1.m24
-rw-r--r--clang/test/Rewriter/rewrite-try-catch.m23
-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/DoubleMethod.m19
-rw-r--r--clang/test/Sema/address-constant.c10
-rw-r--r--clang/test/Sema/address_spaces.c19
-rw-r--r--clang/test/Sema/alias-test-1.m31
-rw-r--r--clang/test/Sema/alias-test-2.m16
-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/argument-checking.m25
-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.c210
-rw-r--r--clang/test/Sema/asm.c27
-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/attributes.c25
-rw-r--r--clang/test/Sema/builtins.c41
-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/category-1.m38
-rw-r--r--clang/test/Sema/check-dup-decl-methods-1.m38
-rw-r--r--clang/test/Sema/check-dup-objc-decls-1.m28
-rw-r--r--clang/test/Sema/check-increment.c10
-rw-r--r--clang/test/Sema/class-conforming-protocol-1.m21
-rw-r--r--clang/test/Sema/class-def-test-1.m26
-rw-r--r--clang/test/Sema/class-impl-1.m33
-rw-r--r--clang/test/Sema/class-names.cpp50
-rw-r--r--clang/test/Sema/class-proto-1.m36
-rw-r--r--clang/test/Sema/cocoa.m5
-rw-r--r--clang/test/Sema/compare.c17
-rw-r--r--clang/test/Sema/complex-int.c43
-rw-r--r--clang/test/Sema/compound-literal.c24
-rw-r--r--clang/test/Sema/conditional-expr.c38
-rw-r--r--clang/test/Sema/conditional.c4
-rw-r--r--clang/test/Sema/conflicting-ivar-test-1.m86
-rw-r--r--clang/test/Sema/cxx-namespace.cpp53
-rw-r--r--clang/test/Sema/cxx-references.cpp28
-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/default1.cpp17
-rw-r--r--clang/test/Sema/default2.cpp38
-rw-r--r--clang/test/Sema/deref.c43
-rw-r--r--clang/test/Sema/enhanced-proto-2.m21
-rw-r--r--clang/test/Sema/enum.c30
-rw-r--r--clang/test/Sema/expr-address-of.c33
-rw-r--r--clang/test/Sema/exprs.c11
-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.c74
-rw-r--r--clang/test/Sema/forward-class-1.m24
-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/id_builtin.m10
-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/incompatible-protocol-qualified-types.m40
-rw-r--r--clang/test/Sema/incomplete-decl.c19
-rw-r--r--clang/test/Sema/inherit.cpp25
-rw-r--r--clang/test/Sema/init.c32
-rw-r--r--clang/test/Sema/invalid-decl.c8
-rw-r--r--clang/test/Sema/invalid-objc-decls-1.m29
-rw-r--r--clang/test/Sema/invalid-struct-init.c26
-rw-r--r--clang/test/Sema/ivar-sem-check-1.m19
-rw-r--r--clang/test/Sema/member-reference.c9
-rw-r--r--clang/test/Sema/merge-decls.c19
-rw-r--r--clang/test/Sema/message.m63
-rw-r--r--clang/test/Sema/method-def-1.m10
-rw-r--r--clang/test/Sema/method-def-2.m19
-rw-r--r--clang/test/Sema/method-encoding-2.m12
-rw-r--r--clang/test/Sema/method-not-defined.m13
-rw-r--r--clang/test/Sema/method-undef-category-warn-1.m32
-rw-r--r--clang/test/Sema/method-undefined-warn-1.m42
-rw-r--r--clang/test/Sema/missing-method-context.m4
-rw-r--r--clang/test/Sema/missing-string-interface.m7
-rw-r--r--clang/test/Sema/ms-fuzzy-asm.c9
-rw-r--r--clang/test/Sema/objc-bad-receiver-1.m9
-rw-r--r--clang/test/Sema/objc-comptypes-1.m89
-rw-r--r--clang/test/Sema/objc-comptypes-2.m37
-rw-r--r--clang/test/Sema/objc-comptypes-3.m64
-rw-r--r--clang/test/Sema/objc-comptypes-4.m25
-rw-r--r--clang/test/Sema/objc-comptypes-5.m44
-rw-r--r--clang/test/Sema/objc-comptypes-6.m16
-rw-r--r--clang/test/Sema/objc-comptypes-7.m70
-rw-r--r--clang/test/Sema/objc-comptypes-8.m12
-rw-r--r--clang/test/Sema/objc-ivar-lookup.m18
-rw-r--r--clang/test/Sema/objc-legacy-implementation-1.m11
-rw-r--r--clang/test/Sema/objc-property-1.m39
-rw-r--r--clang/test/Sema/objc-property-2.m63
-rw-r--r--clang/test/Sema/objc-property-3.m14
-rw-r--r--clang/test/Sema/objc-property-4.m30
-rw-r--r--clang/test/Sema/objc-property-5.m31
-rw-r--r--clang/test/Sema/objc-string.m11
-rw-r--r--clang/test/Sema/objc-unused.m18
-rw-r--r--clang/test/Sema/offsetof.c36
-rw-r--r--clang/test/Sema/predef.c12
-rw-r--r--clang/test/Sema/predefined-function.c40
-rw-r--r--clang/test/Sema/protocol-expr-1.m15
-rw-r--r--clang/test/Sema/protocol-expr-neg-1.m19
-rw-r--r--clang/test/Sema/protocol-id-test-1.m16
-rw-r--r--clang/test/Sema/protocol-id-test-2.m14
-rw-r--r--clang/test/Sema/protocol-id-test-3.m94
-rw-r--r--clang/test/Sema/protocol-test-1.m20
-rw-r--r--clang/test/Sema/protocol-test-2.m31
-rw-r--r--clang/test/Sema/recover-goto.c4
-rw-r--r--clang/test/Sema/redefinition.c5
-rw-r--r--clang/test/Sema/return-stack-addr.cpp113
-rw-r--r--clang/test/Sema/selector-1.m14
-rw-r--r--clang/test/Sema/selector-overload.m47
-rw-r--r--clang/test/Sema/self-comparison.c25
-rw-r--r--clang/test/Sema/shift.c6
-rw-r--r--clang/test/Sema/static-init.c3
-rw-r--r--clang/test/Sema/static-ivar-ref-1.m16
-rw-r--r--clang/test/Sema/stmt_exprs.c12
-rw-r--r--clang/test/Sema/struct-compat.c17
-rw-r--r--clang/test/Sema/struct-packed-align.c71
-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.c24
-rw-r--r--clang/test/Sema/typecheck-binop.c20
-rw-r--r--clang/test/Sema/typedef-prototype.c8
-rw-r--r--clang/test/Sema/typedef-retain.c26
-rw-r--r--clang/test/Sema/typedef-variable-type.c3
-rw-r--r--clang/test/Sema/undef-protocol-methods-1.m42
-rw-r--r--clang/test/Sema/undef-superclass-1.m26
-rw-r--r--clang/test/Sema/undefined-protocol-type-1.m9
-rw-r--r--clang/test/Sema/unused-expr.c37
-rw-r--r--clang/test/Sema/usual-float.c12
-rw-r--r--clang/test/Sema/va-method-1.m17
-rw-r--r--clang/test/Sema/varargs.c26
-rw-r--r--clang/test/Sema/vector-assign.c39
-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.c7
-rw-r--r--clang/test/Sema/void_arg.c25
-rw-r--r--clang/test/Serialization/complex.c48
-rw-r--r--clang/test/Serialization/stmt_exprs.c12
-rwxr-xr-xclang/test/TestRunner.sh89
-rwxr-xr-xclang/utils/ccc213
-rwxr-xr-xclang/utils/ccc-analyzer266
-rwxr-xr-xclang/utils/scan-build677
-rw-r--r--clang/utils/sorttable.js493
-rw-r--r--clang/win32/clangAST/clangAST.vcproj301
-rw-r--r--clang/win32/clangAnalysis/clangAnalysis.vcproj305
-rw-r--r--clang/win32/clangBasic/clangBasic.vcproj234
-rw-r--r--clang/win32/clangCodeGen/clangCodeGen.vcproj241
-rw-r--r--clang/win32/clangDriver/clangDriver.vcproj270
-rw-r--r--clang/win32/clangLex/clangLex.vcproj269
-rw-r--r--clang/win32/clangParse/clangParse.vcproj229
-rw-r--r--clang/win32/clangRewrite/clangRewrite.vcproj185
-rw-r--r--clang/win32/clangSema/clangSema.vcproj221
-rw-r--r--clang/www/CheckerNotes.html242
-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.html195
-rw-r--r--clang/www/content.css10
-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/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.html130
-rw-r--r--clang/www/get_started.html231
-rw-r--r--clang/www/index.html119
-rw-r--r--clang/www/menu.css36
-rw-r--r--clang/www/menu.html.incl23
686 files changed, 0 insertions, 108415 deletions
diff --git a/clang/Driver/ASTConsumers.cpp b/clang/Driver/ASTConsumers.cpp
deleted file mode 100644
index 3276228e6068..000000000000
--- a/clang/Driver/ASTConsumers.cpp
+++ /dev/null
@@ -1,990 +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 "HTMLDiagnostics.h"
-#include "clang/AST/TranslationUnit.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/CFG.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/Timer.h"
-#include "llvm/ADT/OwningPtr.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-/// DeclPrinter - Utility class for printing top-level decls.
-
-namespace {
- class DeclPrinter {
- public:
- std::ostream& Out;
-
- DeclPrinter(std::ostream* out) : Out(out ? *out : *llvm::cerr.stream()) {}
- DeclPrinter() : Out(*llvm::cerr.stream()) {}
-
- 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
-
-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 (isa<ObjCClassDecl>(D)) {
- Out << "@class [printing todo]\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() << ") ";
- // FIXME: just print original selector name!
- Out << OMD->getSelector().getName();
-
- for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i) {
- ParmVarDecl *PDecl = OMD->getParamDecl(i);
- // FIXME: selector is missing here!
- Out << " :(" << PDecl->getType().getAsString() << ") " << PDecl->getName();
- }
-}
-
-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?
- int count = OID->getNumIntfRefProtocols();
-
- if (count > 0) {
- ObjCProtocolDecl **refProtocols = OID->getReferencedProtocols();
- for (int i = 0; i < count; i++)
- Out << (i == 0 ? '<' : ',') << refProtocols[i]->getName();
- }
-
- if (count > 0)
- Out << ">\n";
- else
- 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::OBJC_PR_IMPL_SYNTHSIZE)
- 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(std::ostream* o = NULL) : DeclPrinter(o) {}
-
- virtual void HandleTopLevelDecl(Decl *D) {
- PrintDecl(D);
- }
- };
-}
-
-ASTConsumer *clang::CreateASTPrinter(std::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";
- } else if (isa<ObjCImplementationDecl>(D)) {
- Out << "Read objc 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(); }
-
-
-//===----------------------------------------------------------------------===//
-// CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit
-// the CFGs for all function definitions.
-
-namespace {
-
-class CFGVisitor : public ASTConsumer {
- std::string FName;
-public:
- CFGVisitor(const std::string& fname) : FName(fname) {}
- CFGVisitor() : FName("") {}
-
- // CFG Visitor interface to be implemented by subclass.
- virtual void VisitCFG(CFG& C, Decl& CD) = 0;
- virtual bool printFuncDeclStart() { return true; }
-
- virtual void HandleTopLevelDecl(Decl *D);
-};
-
-} // end anonymous namespace
-
-void CFGVisitor::HandleTopLevelDecl(Decl *D) {
-
- CFG *C = NULL;
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-
- if (!FD->getBody())
- return;
-
- if (FName.size() > 0 && FName != FD->getIdentifier()->getName())
- return;
-
- if (printFuncDeclStart()) {
- DeclPrinter().PrintFunctionDeclStart(FD);
- llvm::cerr << '\n';
- }
-
- C = CFG::buildCFG(FD->getBody());
- }
- else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
-
- if (!MD->getBody())
- return;
-
- if (FName.size() > 0 && FName != MD->getSelector().getName())
- return;
-
- if (printFuncDeclStart()) {
- DeclPrinter().PrintObjCMethodDecl(MD);
- llvm::cerr << '\n';
- }
-
- C = CFG::buildCFG(MD->getBody());
- }
-
- if (C) {
- VisitCFG(*C, *D);
- delete C;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// DumpCFGs - Dump CFGs to stderr or visualize with Graphviz
-
-namespace {
- class CFGDumper : public CFGVisitor {
- const bool UseGraphviz;
- public:
- CFGDumper(bool use_graphviz, const std::string& fname)
- : CFGVisitor(fname), UseGraphviz(use_graphviz) {}
-
- virtual void VisitCFG(CFG& C, Decl&) {
- if (UseGraphviz)
- C.viewCFG();
- else
- C.dump();
- }
- };
-} // end anonymous namespace
-
-ASTConsumer *clang::CreateCFGDumper(bool ViewGraphs, const std::string& FName) {
- return new CFGDumper(ViewGraphs, FName);
-}
-
-//===----------------------------------------------------------------------===//
-// AnalyzeLiveVariables - perform live variable analysis and dump results
-
-namespace {
- class LivenessVisitor : public CFGVisitor {
- SourceManager *SM;
- public:
- LivenessVisitor(const std::string& fname) : CFGVisitor(fname) {}
-
- virtual void Initialize(ASTContext &Context) {
- SM = &Context.getSourceManager();
- }
-
- virtual void VisitCFG(CFG& C, Decl& CD) {
- LiveVariables L(C);
- L.runOnCFG(C);
- L.dumpBlockLiveness(*SM);
- }
- };
-} // end anonymous namespace
-
-ASTConsumer *clang::CreateLiveVarAnalyzer(const std::string& fname) {
- return new LivenessVisitor(fname);
-}
-
-//===----------------------------------------------------------------------===//
-// DeadStores - run checker to locate dead stores in a function
-
-namespace {
- class DeadStoreVisitor : public CFGVisitor {
- Diagnostic &Diags;
- ASTContext *Ctx;
- public:
- DeadStoreVisitor(Diagnostic &diags) : Diags(diags) {}
- virtual void Initialize(ASTContext &Context) {
- Ctx = &Context;
- }
-
- virtual void VisitCFG(CFG& C, Decl& CD) {
- CheckDeadStores(C, *Ctx, Diags);
- }
-
- virtual bool printFuncDeclStart() { return false; }
- };
-} // end anonymous namespace
-
-ASTConsumer *clang::CreateDeadStoreChecker(Diagnostic &Diags) {
- return new DeadStoreVisitor(Diags);
-}
-
-//===----------------------------------------------------------------------===//
-// Unitialized Values - run checker to flag potential uses of uninitalized
-// variables.
-
-namespace {
- class UninitValsVisitor : public CFGVisitor {
- Diagnostic &Diags;
- ASTContext *Ctx;
- public:
- UninitValsVisitor(Diagnostic &diags) : Diags(diags) {}
- virtual void Initialize(ASTContext &Context) {
- Ctx = &Context;
- }
-
- virtual void VisitCFG(CFG& C, Decl&) {
- CheckUninitializedValues(C, *Ctx, Diags);
- }
-
- virtual bool printFuncDeclStart() { return false; }
- };
-} // end anonymous namespace
-
-ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
- return new UninitValsVisitor(Diags);
-}
-
-//===----------------------------------------------------------------------===//
-// CheckerConsumer - Generic Driver for running intra-procedural path-sensitive
-// analyses.
-
-namespace {
-
-class CheckerConsumer : public CFGVisitor {
-protected:
- Diagnostic &Diags;
- ASTContext* Ctx;
- Preprocessor* PP;
- PreprocessorFactory* PPF;
- const std::string& HTMLDir;
- bool Visualize;
- bool TrimGraph;
- llvm::OwningPtr<PathDiagnosticClient> PD;
- bool AnalyzeAll;
-public:
- CheckerConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf,
- const std::string& fname,
- const std::string& htmldir,
- bool visualize, bool trim, bool analyzeAll)
- : CFGVisitor(fname), Diags(diags), PP(pp), PPF(ppf), HTMLDir(htmldir),
- Visualize(visualize), TrimGraph(trim), AnalyzeAll(analyzeAll) {}
-
- virtual void Initialize(ASTContext &Context) { Ctx = &Context; }
- virtual void VisitCFG(CFG& C, Decl&);
- virtual bool printFuncDeclStart() { return false; }
-
- virtual const char* getCheckerName() = 0;
- virtual void getTransferFunctions(std::vector<GRTransferFuncs*>& TFs) = 0;
-};
-} // end anonymous namespace
-
-void CheckerConsumer::VisitCFG(CFG& C, Decl& CD) {
-
- if (Diags.hasErrorOccurred())
- return;
-
- SourceLocation Loc = CD.getLocation();
-
- if (!Loc.isFileID())
- return;
-
- if (!AnalyzeAll && !Ctx->getSourceManager().isFromMainFile(Loc))
- return;
-
- // Lazily create the diagnostic client.
-
- if (!HTMLDir.empty() && PD.get() == NULL)
- PD.reset(CreateHTMLDiagnosticClient(HTMLDir, PP, PPF));
-
-
- if (!Visualize) {
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(&CD)) {
- llvm::cerr << "ANALYZE: "
- << Ctx->getSourceManager().getSourceName(FD->getLocation())
- << ' '
- << FD->getIdentifier()->getName()
- << '\n';
- }
- else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(&CD)) {
- llvm::cerr << "ANALYZE (ObjC Method): "
- << Ctx->getSourceManager().getSourceName(MD->getLocation())
- << " '"
- << MD->getSelector().getName() << "'\n";
- }
- }
- else
- llvm::cerr << '\n';
-
- std::vector<GRTransferFuncs*> TFs;
- getTransferFunctions(TFs);
-
- while (!TFs.empty()) {
-
- // Construct the analysis engine.
- GRExprEngine Eng(C, CD, *Ctx);
-
- // Set base transfer functions.
- llvm::OwningPtr<GRTransferFuncs> TF(TFs.back());
- TFs.pop_back();
-
- Eng.setTransferFunctions(TF.get());
-
- // Execute the worklist algorithm.
- Eng.ExecuteWorkList();
-
- // Display warnings.
- Eng.EmitWarnings(Diags, PD.get());
-
- #ifndef NDEBUG
- if (Visualize) Eng.ViewGraph(TrimGraph);
- #endif
- }
-}
-
-//===----------------------------------------------------------------------===//
-// GRSimpleVals - Perform intra-procedural, path-sensitive constant propagation.
-
-namespace {
-class GRSimpleValsVisitor : public CheckerConsumer {
-public:
- GRSimpleValsVisitor(Diagnostic &diags, Preprocessor* pp,
- PreprocessorFactory* ppf,
- const std::string& fname, const std::string& htmldir,
- bool visualize, bool trim, bool analyzeAll)
- : CheckerConsumer(diags, pp, ppf, fname, htmldir, visualize,
- trim, analyzeAll) {}
-
- virtual const char* getCheckerName() { return "GRSimpleVals"; }
-
- virtual void getTransferFunctions(std::vector<GRTransferFuncs*>& TFs) {
- return TFs.push_back(MakeGRSimpleValsTF());
- }
-};
-} // end anonymous namespace
-
-ASTConsumer* clang::CreateGRSimpleVals(Diagnostic &Diags,
- Preprocessor* PP,
- PreprocessorFactory* PPF,
- const std::string& FunctionName,
- const std::string& HTMLDir,
- bool Visualize, bool TrimGraph,
- bool AnalyzeAll) {
-
- return new GRSimpleValsVisitor(Diags, PP, PPF, FunctionName, HTMLDir,
- Visualize, TrimGraph, AnalyzeAll);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Core Foundation Reference Counting Checker
-
-namespace {
-class CFRefCountCheckerVisitor : public CheckerConsumer {
- const LangOptions& LangOpts;
-public:
- CFRefCountCheckerVisitor(Diagnostic &diags, Preprocessor* pp,
- PreprocessorFactory* ppf,
- const LangOptions& lopts,
- const std::string& fname,
- const std::string& htmldir,
- bool visualize, bool trim, bool analyzeAll)
- : CheckerConsumer(diags, pp, ppf, fname, htmldir, visualize,
- trim, analyzeAll), LangOpts(lopts) {}
-
- virtual const char* getCheckerName() { return "CFRefCountChecker"; }
-
- virtual void getTransferFunctions(std::vector<GRTransferFuncs*>& TFs) {
- switch (LangOpts.getGCMode()) {
- case LangOptions::NonGC:
- TFs.push_back(MakeCFRefCountTF(*Ctx, false, true, LangOpts));
- break;
-
- case LangOptions::GCOnly:
- TFs.push_back(MakeCFRefCountTF(*Ctx, true, true, LangOpts));
- break;
-
- case LangOptions::HybridGC:
- TFs.push_back(MakeCFRefCountTF(*Ctx, false, true, LangOpts));
- TFs.push_back(MakeCFRefCountTF(*Ctx, true, false, LangOpts));
- break;
- }
- }
-};
-} // end anonymous namespace
-
-ASTConsumer* clang::CreateCFRefChecker(Diagnostic &Diags,
- Preprocessor* PP,
- PreprocessorFactory* PPF,
- const LangOptions& LangOpts,
- const std::string& FunctionName,
- const std::string& HTMLDir,
- bool Visualize, bool TrimGraph,
- bool AnalyzeAll) {
-
- return new CFRefCountCheckerVisitor(Diags, PP, PPF, LangOpts, FunctionName,
- HTMLDir, Visualize, TrimGraph,
- AnalyzeAll);
-}
-
-//===----------------------------------------------------------------------===//
-// AST Serializer
-
-namespace {
-
-class ASTSerializer : public ASTConsumer {
-protected:
- Diagnostic &Diags;
- const LangOptions& lang;
- TranslationUnit* TU;
-
-public:
- ASTSerializer(Diagnostic& diags, const LangOptions& LO)
- : Diags(diags), lang(LO), TU(0) {}
-
- virtual ~ASTSerializer() { delete TU; }
-
- virtual void Initialize(ASTContext &Context) {
- if (!TU) TU = new TranslationUnit(Context, lang);
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- if (Diags.hasErrorOccurred())
- return;
-
- if (TU) TU->AddTopLevelDecl(D);
- }
-};
-
-class SingleFileSerializer : public ASTSerializer {
- const llvm::sys::Path FName;
-public:
- SingleFileSerializer(const llvm::sys::Path& F, Diagnostic &diags,
- const LangOptions &LO)
- : ASTSerializer(diags,LO), FName(F) {}
-
- ~SingleFileSerializer() {
- EmitASTBitcodeFile(TU, FName);
- }
-};
-
-class BuildSerializer : public ASTSerializer {
- llvm::sys::Path EmitDir;
-public:
- BuildSerializer(const llvm::sys::Path& dir, Diagnostic &diags,
- const LangOptions &LO)
- : ASTSerializer(diags,LO), EmitDir(dir) {}
-
- ~BuildSerializer() {
-
- if (!TU)
- 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,
- const LangOptions &Features) {
-
- 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, Features);
- }
-
- // 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, Features);
-}
diff --git a/clang/Driver/ASTConsumers.h b/clang/Driver/ASTConsumers.h
deleted file mode 100644
index 7037ade1ddff..000000000000
--- a/clang/Driver/ASTConsumers.h
+++ /dev/null
@@ -1,80 +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 <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(std::ostream* OS = NULL);
-
-ASTConsumer *CreateASTDumper();
-
-ASTConsumer *CreateASTViewer();
-
-ASTConsumer *CreateCFGDumper(bool ViewGraphs, const std::string& FName);
-
-ASTConsumer *CreateLiveVarAnalyzer(const std::string& fname);
-
-ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
-
-ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
-
-ASTConsumer *CreateGRSimpleVals(Diagnostic &Diags,
- Preprocessor* PP, PreprocessorFactory* PPF,
- const std::string& Function,
- const std::string& HTMLDir, bool Visualize,
- bool TrimGraph, bool AnalyzeAll);
-
-ASTConsumer *CreateCFRefChecker(Diagnostic &Diags,
- Preprocessor* PP, PreprocessorFactory* PPF,
- const LangOptions& LangOpts,
- const std::string& Function,
- const std::string& HTMLDir, bool Visualize,
- bool TrimGraph, bool AnalyzeAll);
-
-ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
- const std::string& OutFile,
- Diagnostic &Diags,
- const LangOptions &LOpts);
-
-ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D,
- Preprocessor *PP, PreprocessorFactory* PPF);
-
-ASTConsumer *CreateSerializationTest(Diagnostic &Diags,
- FileManager& FMgr,
- const LangOptions &LOpts);
-
-ASTConsumer *CreateASTSerializer(const std::string& InFile,
- const std::string& EmitDir,
- Diagnostic &Diags,
- const LangOptions &LOpts);
-
-} // end clang namespace
-
-#endif
diff --git a/clang/Driver/DiagChecker.cpp b/clang/Driver/DiagChecker.cpp
deleted file mode 100644
index c06026764033..000000000000
--- a/clang/Driver/DiagChecker.cpp
+++ /dev/null
@@ -1,239 +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 "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";
-
-/// 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) {
- // 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);
- }
- } 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 TextDiagnosticBuffer &Diags =
- static_cast<const TextDiagnosticBuffer&>(PP.getDiagnostics().getClient());
- 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:");
-
- 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);
-
- // Gather the set of expected diagnostics.
- DiagList ExpectedErrors, ExpectedWarnings;
- FindExpectedDiags(PP, ExpectedErrors, ExpectedWarnings);
-
- // Check that the expected diagnostics occurred.
- return CheckResults(PP, ExpectedErrors, ExpectedWarnings);
-}
diff --git a/clang/Driver/HTMLDiagnostics.cpp b/clang/Driver/HTMLDiagnostics.cpp
deleted file mode 100644
index 760ef25379dc..000000000000
--- a/clang/Driver/HTMLDiagnostics.cpp
+++ /dev/null
@@ -1,399 +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 "HTMLDiagnostics.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Analysis/PathDiagnostic.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/System/Path.h"
-#include <fstream>
-#include <sstream>
-
-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, const PathDiagnosticPiece& P,
- unsigned num, unsigned max);
-
- void HighlightRange(Rewriter& R, 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;
-
- // Create a new rewriter to generate HTML.
- SourceManager& SMgr = D.begin()->getLocation().getManager();
- 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, *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::ostringstream os;
-
- os << "<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<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::ostringstream os;
- os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- {
- std::ostringstream os;
- os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- {
- std::ostringstream os;
- os << "\n<!-- BUGLINE " << D.back()->getLocation().getLogicalLineNumber()
- << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- {
- std::ostringstream os;
- os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
- }
-
- // Add CSS, header, and footer.
-
- html::AddHeaderFooterInternalBuiltinCSS(R, FileID);
-
- // 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,
- 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 (!SM.isFromMainFile(LPos.getLocation()))
- 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.
-
- std::ostringstream os;
-
- 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 (max > 1)
- os << "<span class=\"PathIndex\">[" << num << "]</span> ";
-
- os << html::EscapeText(P.getString()) << "</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, *I);
-}
-
-void HTMLDiagnostics::HighlightRange(Rewriter& R, 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.isFromMainFile(LogicalStart) ||
- !SM.isFromMainFile(LogicalEnd))
- 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/Driver/HTMLDiagnostics.h b/clang/Driver/HTMLDiagnostics.h
deleted file mode 100644
index be72c49fd2eb..000000000000
--- a/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/Driver/HTMLPrint.cpp b/clang/Driver/HTMLPrint.cpp
deleted file mode 100644
index e6e6ab7edf76..000000000000
--- a/clang/Driver/HTMLPrint.cpp
+++ /dev/null
@@ -1,93 +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/Rewrite/Rewriter.h"
-#include "clang/Rewrite/HTMLRewrite.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.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();
- html::AddLineNumbers(R, FileID);
- html::AddHeaderFooterInternalBuiltinCSS(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);
- 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 66031d6fdd65..000000000000
--- a/clang/Driver/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-LEVEL = ../../..
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../include
-CXXFLAGS = -fno-rtti
-
-TOOLNAME = clang
-USEDLIBS = clangCodeGen.a clangAnalysis.a clangRewrite.a clangSEMA.a \
- clangAST.a clangParse.a clangLex.a clangBasic.a \
- LLVMCore.a LLVMSupport.a LLVMSystem.a \
- LLVMBitWriter.a LLVMBitReader.a LLVMCodeGen.a LLVMTarget.a
-
-
-
-include $(LEVEL)/Makefile.common
diff --git a/clang/Driver/PrintParserCallbacks.cpp b/clang/Driver/PrintParserCallbacks.cpp
deleted file mode 100644
index 9c67f83aa13f..000000000000
--- a/clang/Driver/PrintParserCallbacks.cpp
+++ /dev/null
@@ -1,57 +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) {}
-
- /// 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 << "ActOnDeclarator ";
- 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 << "ActOnPopScope\n";
-
- // Pass up to EmptyActions so that the symbol table is maintained right.
- MinimalAction::ActOnPopScope(Loc, S);
- }
- };
-}
-
-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 105e99e9c481..000000000000
--- a/clang/Driver/PrintPreprocessedOutput.cpp
+++ /dev/null
@@ -1,685 +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 <cstdio>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Simple buffered I/O
-//===----------------------------------------------------------------------===//
-//
-// Empirically, iostream is over 30% slower than stdio for this workload, and
-// stdio itself isn't very well suited. The problem with stdio is use of
-// putchar_unlocked. We have many newline characters that need to be emitted,
-// but stdio needs to do extra checks to handle line buffering mode. These
-// extra checks make putchar_unlocked fall off its inlined code path, hitting
-// slow system code. In practice, using 'write' directly makes 'clang -E -P'
-// about 10% faster than using the stdio path on darwin.
-
-#if defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
-#include <unistd.h>
-#include <fcntl.h>
-#else
-#define USE_STDIO 1
-#endif
-
-static std::string OutputFilename;
-#ifdef USE_STDIO
-static FILE *OutputFILE;
-#else
-static int OutputFD;
-static char *OutBufStart = 0, *OutBufEnd, *OutBufCur;
-#endif
-
-/// InitOutputBuffer - Initialize our output buffer.
-///
-static void InitOutputBuffer(const std::string& Output) {
-#ifdef USE_STDIO
- if (!Output.size() || Output == "-")
- OutputFILE = stdout;
- else {
- OutputFilename = Output;
- OutputFILE = fopen(Output.c_str(), "w+");
-
- if (OutputFILE == 0) {
- fprintf(stderr, "Error opening output file '%s'.\n", Output.c_str());
- exit(1);
- }
-
- }
-
- assert(OutputFILE && "failed to open output file");
-#else
- OutBufStart = new char[64*1024];
- OutBufEnd = OutBufStart+64*1024;
- OutBufCur = OutBufStart;
-
- if (!Output.size() || Output == "-")
- OutputFD = STDOUT_FILENO;
- else {
- OutputFilename = Output;
- OutputFD = open(Output.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
- if (OutputFD < 0) {
- fprintf(stderr, "Error opening output file '%s'.\n", Output.c_str());
- exit(1);
- }
- }
-#endif
-}
-
-#ifndef USE_STDIO
-/// FlushBuffer - Write the accumulated bytes to the output stream.
-///
-static void FlushBuffer() {
- write(OutputFD, OutBufStart, OutBufCur-OutBufStart);
- OutBufCur = OutBufStart;
-}
-#endif
-
-/// CleanupOutputBuffer - Finish up output.
-///
-static void CleanupOutputBuffer(bool ErrorOccurred) {
-#ifdef USE_STDIO
- if (OutputFILE != stdout)
- fclose(OutputFILE);
-#else
- FlushBuffer();
- delete [] OutBufStart;
- if (OutputFD != STDOUT_FILENO)
- close(OutputFD);
-#endif
-
- // If an error occurred, remove the output file.
- if (ErrorOccurred && !OutputFilename.empty())
- llvm::sys::Path(OutputFilename).eraseFromDisk();
-}
-
-static void OutputChar(char c) {
-#if defined(_MSC_VER)
- putc(c, OutputFILE);
-#elif defined(USE_STDIO)
- putc_unlocked(c, OutputFILE);
-#else
- if (OutBufCur >= OutBufEnd)
- FlushBuffer();
- *OutBufCur++ = c;
-#endif
-}
-
-static void OutputString(const char *Ptr, unsigned Size) {
-#ifdef USE_STDIO
- fwrite(Ptr, Size, 1, OutputFILE);
-#else
- if (OutBufCur+Size >= OutBufEnd)
- FlushBuffer();
-
- switch (Size) {
- default:
- memcpy(OutBufCur, Ptr, Size);
- break;
- case 3:
- OutBufCur[2] = Ptr[2];
- case 2:
- OutBufCur[1] = Ptr[1];
- case 1:
- OutBufCur[0] = Ptr[0];
- case 0:
- break;
- }
- OutBufCur += Size;
-#endif
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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;
- unsigned CurLine;
- bool EmittedTokensOnThisLine;
- DirectoryLookup::DirType FileType;
- llvm::SmallString<512> CurFilename;
-public:
- PrintPPOutputPPCallbacks(Preprocessor &pp) : PP(pp) {
- CurLine = 0;
- CurFilename += "<uninit>";
- EmittedTokensOnThisLine = false;
- FileType = DirectoryLookup::NormalHeaderDir;
- }
-
- void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
- bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
-
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- DirectoryLookup::DirType 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);
-};
-} // end anonymous namespace
-
-/// UToStr - Do itoa on the specified number, in-place in the specified buffer.
-/// endptr points to the end of the buffer.
-static char *UToStr(unsigned N, char *EndPtr) {
- // Null terminate the buffer.
- *--EndPtr = '\0';
- if (N == 0) // Zero is a special case.
- *--EndPtr = '0';
- while (N) {
- *--EndPtr = '0' + char(N % 10);
- N /= 10;
- }
- return EndPtr;
-}
-
-
-/// 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) {
- if (DisableLineMarkers) {
- unsigned LineNo = PP.getSourceManager().getLogicalLineNumber(Loc);
- if (LineNo == CurLine) return false;
-
- CurLine = LineNo;
-
- if (!EmittedTokensOnThisLine)
- return true;
-
- OutputChar('\n');
- EmittedTokensOnThisLine = false;
- return true;
- }
-
- unsigned LineNo = PP.getSourceManager().getLogicalLineNumber(Loc);
-
- // 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)
- OutputChar('\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";
- OutputString(NewLines, LineNo-CurLine);
- }
- CurLine = LineNo;
- } else {
- if (EmittedTokensOnThisLine) {
- OutputChar('\n');
- EmittedTokensOnThisLine = false;
- }
-
- CurLine = LineNo;
-
- OutputChar('#');
- OutputChar(' ');
- char NumberBuffer[20];
- const char *NumStr = UToStr(LineNo, NumberBuffer+20);
- OutputString(NumStr, (NumberBuffer+20)-NumStr-1);
- OutputChar(' ');
- OutputChar('"');
- OutputString(&CurFilename[0], CurFilename.size());
- OutputChar('"');
-
- if (FileType == DirectoryLookup::SystemHeaderDir)
- OutputString(" 3", 2);
- else if (FileType == DirectoryLookup::ExternCSystemHeaderDir)
- OutputString(" 3 4", 4);
- OutputChar('\n');
- }
- 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,
- DirectoryLookup::DirType FileType) {
- // 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 = FileType;
-
- if (EmittedTokensOnThisLine) {
- OutputChar('\n');
- EmittedTokensOnThisLine = false;
- }
-
- OutputChar('#');
- OutputChar(' ');
-
- char NumberBuffer[20];
- const char *NumStr = UToStr(CurLine, NumberBuffer+20);
- OutputString(NumStr, (NumberBuffer+20)-NumStr-1);
- OutputChar(' ');
- OutputChar('"');
- OutputString(&CurFilename[0], CurFilename.size());
- OutputChar('"');
-
- switch (Reason) {
- case PPCallbacks::EnterFile:
- OutputString(" 1", 2);
- break;
- case PPCallbacks::ExitFile:
- OutputString(" 2", 2);
- break;
- case PPCallbacks::SystemHeaderPragma: break;
- case PPCallbacks::RenameFile: break;
- }
-
- if (FileType == DirectoryLookup::SystemHeaderDir)
- OutputString(" 3", 2);
- else if (FileType == DirectoryLookup::ExternCSystemHeaderDir)
- OutputString(" 3 4", 4);
-
- OutputChar('\n');
-}
-
-/// HandleIdent - Handle #ident directives when read by the preprocessor.
-///
-void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
- MoveToLine(Loc);
-
- OutputString("#ident ", strlen("#ident "));
- OutputString(&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))
- OutputChar(' ');
-
- // Otherwise, indent the appropriate number of spaces.
- for (; ColNo > 1; --ColNo)
- OutputChar(' ');
-
- 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());
- OutputString(Prefix, strlen(Prefix));
-
- // Read and print all of the pragma tokens.
- while (PragmaTok.isNot(tok::eom)) {
- if (PragmaTok.hasLeadingSpace())
- OutputChar(' ');
- std::string TokSpell = PP.getSpelling(PragmaTok);
- OutputString(&TokSpell[0], TokSpell.size());
- PP.LexUnexpandedToken(PragmaTok);
- }
- OutputChar('\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);
-
- InitOutputBuffer(OutFile);
- InitAvoidConcatTokenInfo();
-
- Token Tok, PrevTok;
- char Buffer[256];
- PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(PP);
- 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))) {
- OutputChar(' ');
- }
-
- if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
- const char *Str = II->getName();
- unsigned Len = Tok.needsCleaning() ? strlen(Str) : Tok.getLength();
- OutputString(Str, Len);
- } else if (Tok.getLength() < 256) {
- const char *TokPtr = Buffer;
- unsigned Len = PP.getSpelling(Tok, TokPtr);
- OutputString(TokPtr, Len);
- } else {
- std::string S = PP.getSpelling(Tok);
- OutputString(&S[0], S.size());
- }
- Callbacks->SetEmittedTokensOnThisLine();
-
- if (Tok.is(tok::eof)) break;
-
- PrevTok = Tok;
- PP.Lex(Tok);
- }
- OutputChar('\n');
-
- CleanupOutputBuffer(PP.getDiagnostics().hasErrorOccurred());
-}
-
diff --git a/clang/Driver/RewriteMacros.cpp b/clang/Driver/RewriteMacros.cpp
deleted file mode 100644
index b61a13c9bb52..000000000000
--- a/clang/Driver/RewriteMacros.cpp
+++ /dev/null
@@ -1,184 +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/System/Path.h"
-#include <fstream>
-using namespace clang;
-
-/// isSameToken - Return true if the two specified tokens start have the same
-/// content.
-static bool isSameToken(Token &RawTok, Token &PPTok) {
- if (PPTok.getKind() == RawTok.getKind())
- return true;
-
- if (PPTok.getIdentifierInfo() &&
- PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
- return true;
-
- return false;
-}
-
-static void GetNextRawTok(Lexer &RawLex, Token &RawTok, Preprocessor &PP) {
- RawLex.LexRawToken(RawTok);
-
- // If we have an identifier with no identifier info for our raw token, look
- // up the indentifier info.
- if (RawTok.is(tok::identifier) && !RawTok.getIdentifierInfo())
- RawTok.setIdentifierInfo(PP.LookUpIdentifierInfo(RawTok));
-}
-
-/// 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());
-
- const SourceManager &SourceMgr = PP.getSourceManager();
- std::pair<const char*, const char*> File =
- SourceMgr.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);
- Token RawTok;
- GetNextRawTok(RawLex, RawTok, PP);
-
- // 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 bug 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 input file, but we don't want to treat them as such... just ignore
- // them.
- if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
- GetNextRawTok(RawLex, RawTok, PP);
- while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
- GetNextRawTok(RawLex, RawTok, PP);
- 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)) {
- GetNextRawTok(RawLex, RawTok, PP);
- 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.
- RB.InsertTextAfter(RawOffs, "/*", 2);
- unsigned EndPos;
-
- // Switch on comment lexing. If we get a comment, we don't want to
- // include it as part of our run of tokens, because we don't want to
- // nest /* */ comments.
- RawLex.SetCommentRetentionState(true);
-
- do {
- EndPos = RawOffs+RawTok.getLength();
-
- GetNextRawTok(RawLex, RawTok, PP);
- RawOffs = SM.getFullFilePos(RawTok.getLocation());
-
- if (RawTok.is(tok::comment)) {
- RawLex.SetCommentRetentionState(false);
- // Skip past the comment.
- GetNextRawTok(RawLex, RawTok, PP);
- break;
- }
-
- } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
- (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));
-
- RawLex.SetCommentRetentionState(false);
-
- 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.
- std::ostream *OutFile;
- if (OutFileName == "-") {
- OutFile = llvm::cout.stream();
- } else if (!OutFileName.empty()) {
- OutFile = new std::ofstream(OutFileName.c_str(),
- std::ios_base::binary|std::ios_base::out);
- } else if (InFileName == "-") {
- OutFile = llvm::cout.stream();
- } else {
- llvm::sys::Path Path(InFileName);
- Path.eraseSuffix();
- Path.appendSuffix("cpp");
- OutFile = new std::ofstream(Path.toString().c_str(),
- std::ios_base::binary|std::ios_base::out);
- }
-
- // 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");
- }
-}
diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp
deleted file mode 100644
index cf715d0cdcde..000000000000
--- a/clang/Driver/RewriteObjC.cpp
+++ /dev/null
@@ -1,3031 +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/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/Support/MemoryBuffer.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/System/Path.h"
-#include <sstream>
-#include <fstream>
-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:
- void Initialize(ASTContext &context);
-
-
- // 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();
-
- 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);
- bool needToScanForQualifiers(QualType T);
- ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
- QualType getSuperStructType();
- QualType getConstantStringStructType();
-
- // Expression Rewriting.
- Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
- Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
- Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
- 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(ObjCProtocolDecl **Protocols,
- int NumProtocols,
- 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";
- Preamble += "__OBJC_RW_EXTERN Protocol *objc_getProtocol(const char *);\n";
- if (LangOpts.Microsoft)
- Preamble += "#undef __OBJC_RW_EXTERN\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 += "#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 += "extern int __CFConstantStringClassReference[];\n";
- Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
- Preamble += "#endif\n";
- if (LangOpts.Microsoft)
- 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.
-}
-
-RewriteObjC::~RewriteObjC() {
- // Get the top-level buffer that this corresponds to.
-
- // Rewrite tabs if we care.
- //RewriteTabs();
-
- if (Diags.hasErrorOccurred())
- return;
-
- // Create the output file.
-
- std::ostream *OutFile;
- if (OutFileName == "-") {
- OutFile = llvm::cout.stream();
- } else if (!OutFileName.empty()) {
- OutFile = new std::ofstream(OutFileName.c_str(),
- std::ios_base::binary|std::ios_base::out);
- } else if (InFileName == "-") {
- OutFile = llvm::cout.stream();
- } else {
- llvm::sys::Path Path(InFileName);
- Path.eraseSuffix();
- Path.appendSuffix("cpp");
- OutFile = new std::ofstream(Path.toString().c_str(),
- std::ios_base::binary|std::ios_base::out);
- }
-
- 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;
-}
-
-//===----------------------------------------------------------------------===//
-// 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) {
- ResultStr += "\nstatic ";
- if (OMD->getResultType()->isObjCQualifiedIdType())
- ResultStr += "id";
- 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 += ") ";
-
-}
-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) {
- 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, Decl::Struct, TUDecl,
- SourceLocation(), II, 0);
- assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
- QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
- CastExpr *castExpr = new CastExpr(castT, IV->getBase(), SourceLocation());
- // Don't forget the parens to enforce the proper binding.
- ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), 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;
- } else {
- 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, Decl::Struct, TUDecl,
- SourceLocation(), II, 0);
- assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
- QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
- CastExpr *castExpr = new CastExpr(castT, IV->getBase(), SourceLocation());
- // Don't forget the parens to enforce the proper binding.
- ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), 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);
- }
-
- SourceLocation OrigStmtEnd = S->getLocEnd();
-
- // 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);
-
- 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, OrigStmtEnd);
- if (BreakStmt *StmtBreakStmt =
- dyn_cast<BreakStmt>(S))
- return RewriteBreakStmt(StmtBreakStmt);
- if (ContinueStmt *StmtContinueStmt =
- dyn_cast<ContinueStmt>(S))
- return RewriteContinueStmt(StmtContinueStmt);
-
- 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::ostringstream Buf;
- 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;
- QualType ElementType = cast<ValueDecl>(DS->getDecl())->getType();
- elementTypeAsString = ElementType.getAsString();
- buf += elementTypeAsString;
- buf += " ";
- elementName = DS->getDecl()->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.
- SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(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";
- ReplaceText(startLoc, 13, buf.c_str(), buf.size());
- SourceLocation endLoc = S->getSynchExpr()->getLocEnd();
- const char *endBuf = SM->getCharacterData(endLoc);
- endBuf++;
- const char *rparenBuf = strchr(endBuf, ')');
- SourceLocation rparenLoc = startLoc.getFileLocWithOffset(rparenBuf-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 @try block");
- SourceLocation lastCurlyLoc = startLoc;
- buf = "}\nelse {\n";
- buf += " _rethrow = objc_exception_extract(&_stack);\n";
- buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- // FIXME: This must be objc_sync_exit(syncExpr);
- buf += " objc_sync_exit();\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;
-
- 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());
-
- bool sawIdTypedCatch = false;
- Stmt *lastCatchBody = 0;
- ObjCAtCatchStmt *catchList = S->getCatchStmts();
- 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->getDecl())->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");
- bodyLoc = bodyLoc.getFileLocWithOffset(1);
- buf = " } } /* @catch end */\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();
- }
- // 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";
- ReplaceText(startLoc, 6, 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 == Context->getObjCIdType())
- return true;
-
- 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(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 != 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 {
- while (*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, Decl::Struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("objc_super"), 0);
- 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, Decl::Struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("objc_super"), 0);
- 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_";
- 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::ostringstream prettyBuf;
- 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 CastExpr(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;
-
- CastExpr *CE = dyn_cast<CastExpr>(recExpr);
- if (!CE) return 0;
-
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr());
- if (!DRE) return 0;
-
- ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl());
- if (!PVD) return 0;
-
- if (strcmp(PVD->getName(), "self") != 0)
- return 0;
-
- // is this id<P1..> type?
- if (CE->getType()->isObjCQualifiedIdType())
- return 0;
- const PointerType *PT = CE->getType()->getAsPointerType();
- if (!PT) return 0;
-
- ObjCInterfaceType *IT = dyn_cast<ObjCInterfaceType>(PT->getPointeeType());
- if (!IT) return 0;
-
- if (IT->getDecl() != CurMethodDecl->getClassInterface()->getSuperClass())
- return 0;
-
- return IT->getDecl();
-}
-
-// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
-QualType RewriteObjC::getSuperStructType() {
- if (!SuperStructDecl) {
- SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("objc_super"), 0);
- 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(FieldDecls, 4);
- }
- return Context->getTagDeclType(SuperStructDecl);
-}
-
-QualType RewriteObjC::getConstantStringStructType() {
- if (!ConstantStringDecl) {
- ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct, TUDecl,
- SourceLocation(),
- &Context->Idents.get("__NSConstantStringImpl"), 0);
- 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(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.getCanonicalType()->isStructureType()
- || resultType.getCanonicalType()->isUnionType())
- MsgSendStretFlavor = MsgSendStretFunctionDecl;
- else if (resultType.getCanonicalType()->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.
- 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 CastExpr(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 CastExpr(Context->getObjCIdType(),
- recExpr, 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 CastExpr(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 (CastExpr *CE = dyn_cast<CastExpr>(recExpr))
- recExpr = CE->getSubExpr();
- recExpr = new CastExpr(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 CastExpr(ICE->getType()->isObjCQualifiedIdType()
- ? Context->getObjCIdType()
- : ICE->getType(), userExpr, SourceLocation());
- }
- // Make id<P...> cast into an 'id' cast.
- else if (CastExpr *CE = dyn_cast<CastExpr>(userExpr)) {
- if (CE->getType()->isObjCQualifiedIdType()) {
- while ((CE = dyn_cast<CastExpr>(userExpr)))
- userExpr = CE->getSubExpr();
- userExpr = new CastExpr(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 CastExpr(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 CastExpr(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 CastExpr(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 CastExpr(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;
-
-}
-
-/// 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");
-
- // 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(ObjCProtocolDecl **Protocols,
- int NumProtocols,
- const char *prefix,
- const char *ClassName,
- std::string &Result) {
- static bool objc_protocol_methods = false;
- if (NumProtocols > 0) {
- for (int i = 0; i < NumProtocols; 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(NumProtocols);
- Result += "];\n} _OBJC_";
- Result += prefix;
- Result += "_PROTOCOLS_";
- Result += ClassName;
- Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
- "{\n\t0, ";
- Result += utostr(NumProtocols);
- Result += "\n";
-
- Result += "\t,{&_OBJC_PROTOCOL_";
- Result += Protocols[0]->getName();
- Result += " \n";
-
- for (int i = 1; i < NumProtocols; i++) {
- ObjCProtocolDecl *PDecl = Protocols[i];
- Result += "\t ,&_OBJC_PROTOCOL_";
- Result += PDecl->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(),
- CDecl->getNumReferencedProtocols(),
- "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->getNumReferencedProtocols() > 0) {
- 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) {
- 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(),
- CDecl->getNumIntfRefProtocols(),
- "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->getNumIntfRefProtocols() > 0) {
- 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->getNumIntfRefProtocols() > 0) {
- 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 += "#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 6e9309dc28ba..000000000000
--- a/clang/Driver/SerializationTest.cpp
+++ /dev/null
@@ -1,197 +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.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 {
- llvm::OwningPtr<TranslationUnit> TU;
- Diagnostic &Diags;
- FileManager &FMgr;
- const LangOptions& lopts;
-public:
- SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts)
- : Diags(d), FMgr(fmgr), lopts(LOpts) {}
-
- ~SerializationTest();
-
- virtual void Initialize(ASTContext& context) {
- if (!TU) TU.reset(new TranslationUnit(context, lopts));
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- TU->AddTopLevelDecl(D);
- }
-
-private:
- bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
- bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
-};
-
-} // end anonymous namespace
-
-ASTConsumer*
-clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr,
- const LangOptions &LOpts) {
-
- return new SerializationTest(Diags,FMgr,LOpts);
-}
-
-
-bool SerializationTest::Serialize(llvm::sys::Path& Filename,
- llvm::sys::Path& FNameDeclPrint) {
- {
- // Pretty-print the decls to a temp file.
- std::ofstream DeclPP(FNameDeclPrint.c_str());
- assert (DeclPP && "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::ofstream DeclPP(FNameDeclPrint.c_str());
- assert (DeclPP && "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);
- }
- };
-}
-
-SerializationTest::~SerializationTest() {
-
- 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);
- 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/TextDiagnosticBuffer.cpp b/clang/Driver/TextDiagnosticBuffer.cpp
deleted file mode 100644
index aa6fbe9ab5e3..000000000000
--- a/clang/Driver/TextDiagnosticBuffer.cpp
+++ /dev/null
@@ -1,41 +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 "TextDiagnosticBuffer.h"
-#include "clang/Basic/SourceManager.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::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/Driver/TextDiagnosticBuffer.h b/clang/Driver/TextDiagnosticBuffer.h
deleted file mode 100644
index e0230cf70884..000000000000
--- a/clang/Driver/TextDiagnosticBuffer.h
+++ /dev/null
@@ -1,53 +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 "TextDiagnostics.h"
-#include <vector>
-
-namespace clang {
-
-class Preprocessor;
-class SourceManager;
-
-class TextDiagnosticBuffer : public TextDiagnostics {
-public:
- typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
- typedef DiagList::iterator iterator;
- typedef DiagList::const_iterator const_iterator;
-private:
- DiagList Errors, Warnings;
-public:
- TextDiagnosticBuffer() {}
-
- 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(); }
-
- 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/Driver/TextDiagnosticPrinter.cpp b/clang/Driver/TextDiagnosticPrinter.cpp
deleted file mode 100644
index 5d06ebea2d14..000000000000
--- a/clang/Driver/TextDiagnosticPrinter.cpp
+++ /dev/null
@@ -1,209 +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 "TextDiagnosticPrinter.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Lexer.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <string>
-using namespace clang;
-
-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"));
-
-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 &CaratLine,
- const std::string &SourceLine) {
- assert(CaratLine.size() == SourceLine.size() &&
- "Expect a correspondence between source and carat 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 = CaratLine.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 = CaratLine.size();
- }
- }
-
- // Pick the last non-whitespace column.
- while (EndColNo-1 &&
- (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
- --EndColNo;
-
- // Fill the range with ~'s.
- assert(StartColNo <= EndColNo && "Invalid range!");
- for (unsigned i = StartColNo; i != EndColNo; ++i)
- CaratLine[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 && !NoShowColumn)
- 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 (!NoCaretDiagnostics && 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 carat that is filled with spaces that is the same
- // length as the line of source code.
- std::string CaratLine(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,
- CaratLine, SourceLine);
-
- // Next, insert the carat itself.
- if (ColNo-1 < CaratLine.size())
- CaratLine[ColNo-1] = '^';
- else
- CaratLine.push_back('^');
-
- // Scan the source line, looking for tabs. If we find any, manually expand
- // them to 8 characters and update the CaratLine 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 CaratLine.
- CaratLine.insert(i+1, NumSpaces, CaratLine[i] == '~' ? '~' : ' ');
- }
-
- // Finally, remove any blank spaces from the end of CaratLine.
- while (CaratLine[CaratLine.size()-1] == ' ')
- CaratLine.erase(CaratLine.end()-1);
-
- // Emit what we have computed.
- OS << SourceLine << "\n";
- OS << CaratLine << "\n";
- }
-}
diff --git a/clang/Driver/TextDiagnosticPrinter.h b/clang/Driver/TextDiagnosticPrinter.h
deleted file mode 100644
index 633f29edbefe..000000000000
--- a/clang/Driver/TextDiagnosticPrinter.h
+++ /dev/null
@@ -1,52 +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 "TextDiagnostics.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/Support/Streams.h"
-
-namespace clang {
-class SourceManager;
-
-class TextDiagnosticPrinter : public TextDiagnostics {
- FullSourceLoc LastWarningLoc;
- FullSourceLoc LastLoc;
- llvm::OStream OS;
-public:
- TextDiagnosticPrinter(llvm::OStream &os = llvm::cerr) : OS(os) {}
-
- void PrintIncludeStack(FullSourceLoc Pos);
-
- void HighlightRange(const SourceRange &R,
- SourceManager& SrcMgr,
- unsigned LineNo, unsigned FileID,
- std::string &CaratLine,
- 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/Driver/TextDiagnostics.cpp b/clang/Driver/TextDiagnostics.cpp
deleted file mode 100644
index 7a78e9478331..000000000000
--- a/clang/Driver/TextDiagnostics.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//===--- TextDiagnostics.cpp - Text Diagnostics Parent Class --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the parent class for all text diagnostics.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TextDiagnostics.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/HeaderSearch.h"
-using namespace clang;
-
-TextDiagnostics:: ~TextDiagnostics() {}
-
-std::string TextDiagnostics::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;
-}
-
-bool TextDiagnostics::isInSystemHeader(FullSourceLoc Pos) const {
- if (!Pos.isValid()) return false;
-
- if (const FileEntry *F = Pos.getFileEntryForLoc()) {
- DirectoryLookup::DirType DirInfo = TheHeaderSearch->getFileDirFlavor(F);
- if (DirInfo == DirectoryLookup::SystemHeaderDir ||
- DirInfo == DirectoryLookup::ExternCSystemHeaderDir)
- return true;
- }
-
- return false;
-}
diff --git a/clang/Driver/TextDiagnostics.h b/clang/Driver/TextDiagnostics.h
deleted file mode 100644
index 9b8d9fb27db9..000000000000
--- a/clang/Driver/TextDiagnostics.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===--- TextDiagnostics.h - Text Diagnostics Checkers ----------*- 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 parent class for all text diagnostics.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TEXT_DIAGNOSTICS_H_
-#define TEXT_DIAGNOSTICS_H_
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
-class SourceManager;
-class HeaderSearch;
-class Preprocessor;
-
-class TextDiagnostics : public DiagnosticClient {
- HeaderSearch *TheHeaderSearch;
-protected:
- std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
- diag::kind ID,
- const std::string *Strs,
- unsigned NumStrs);
-public:
- TextDiagnostics() {}
- virtual ~TextDiagnostics();
-
- void setHeaderSearch(HeaderSearch &HS) { TheHeaderSearch = &HS; }
-
- virtual bool isInSystemHeader(FullSourceLoc Pos) const;
-
- 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 namspace clang
-
-#endif
diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
deleted file mode 100644
index 1071659016bd..000000000000
--- a/clang/Driver/clang.cpp
+++ /dev/null
@@ -1,1490 +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 "TextDiagnosticBuffer.h"
-#include "TextDiagnosticPrinter.h"
-#include "HTMLDiagnostics.h"
-#include "clang/Analysis/PathDiagnostic.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/Module.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Signals.h"
-#include "llvm/Config/config.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/System/Path.h"
-#include <memory>
-#include <fstream>
-#include <algorithm>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Global options.
-//===----------------------------------------------------------------------===//
-
-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.
- 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.
- ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
- ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
- AnalysisLiveVariables, // Print results of live-variable analysis.
- AnalysisGRSimpleVals, // Perform graph-reachability constant prop.
- AnalysisGRSimpleValsView, // Visualize results of path-sens. analysis.
- CheckerCFRef, // Run the Core Foundation Ref. Count Checker.
- WarnDeadStores, // Run DeadStores checker on parsed ASTs.
- WarnDeadStoresCheck, // Check diagnostics for "DeadStores".
- WarnUninitVals, // Run UnitializedVariables checker.
- 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.
-};
-
-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(ParseCFGDump, "dump-cfg",
- "Run parser, then build and print CFGs"),
- clEnumValN(ParseCFGView, "view-cfg",
- "Run parser, then build and view CFGs with Graphviz"),
- clEnumValN(AnalysisLiveVariables, "dump-live-variables",
- "Print results of live variable analysis"),
- clEnumValN(WarnDeadStores, "warn-dead-stores",
- "Flag warnings of stores to dead variables"),
- clEnumValN(WarnUninitVals, "warn-uninit-values",
- "Flag warnings of uses of unitialized variables"),
- clEnumValN(AnalysisGRSimpleVals, "checker-simple",
- "Perform path-sensitive constant propagation"),
- clEnumValN(CheckerCFRef, "checker-cfref",
- "Run the Core Foundation reference count checker"),
- 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"),
- 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"));
-
-//===----------------------------------------------------------------------===//
-// Analyzer Options
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<bool>
-VisualizeEG("visualize-egraph",
- llvm::cl::desc("Display static analysis Exploded Graph"));
-
-static llvm::cl::opt<bool>
-AnalyzeAll("checker-opt-analyze-headers",
- llvm::cl::desc("Force the static analyzer to analyze "
- "functions defined in header files"));
-
-//===----------------------------------------------------------------------===//
-// 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_gnu89, 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: add:
-// -ansi
-// -trigraphs
-// -fdollars-in-identifiers
-// -fpascal-strings
-static void InitializeLanguageStandard(LangOptions &Options, LangKind LK) {
- 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 (LangStd == lang_c89 || LangStd == lang_c94 || LangStd == lang_gnu89)
- Options.ImplicitInt = 1;
- else
- Options.ImplicitInt = 0;
- Options.Trigraphs = 1; // -trigraphs or -ansi
- Options.DollarIdents = 1; // FIXME: Really a target property.
- Options.PascalStrings = PascalStrings;
- Options.Microsoft = MSExtensions;
- Options.WritableStrings = WritableStrings;
- Options.LaxVectorConversions = LaxVectorConversions;
-}
-
-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>
-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>
-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"
- "Warn about use of implicitly defined functions");
-
-/// InitializeDiagnostics - Initialize the diagnostic object, based on the
-/// current command line option settings.
-static void InitializeDiagnostics(Diagnostic &Diags) {
- Diags.setWarningsAsErrors(WarningsAsErrors);
- Diags.setWarnOnExtensions(WarnOnExtensions);
- Diags.setErrorOnExtensions(ErrorOnExtensions);
-
- // 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 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;
-
- // 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())
- return Triple;
-
- // 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);
- }
-
- return Arch + std::string(Triple.begin()+FirstDashIdx, Triple.end());
-}
-
-//===----------------------------------------------------------------------===//
-// 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.
-enum IncludeDirGroup {
- Quoted = 0,
- Angled,
- System,
- After
-};
-
-static std::vector<DirectoryLookup> IncludeGroup[4];
-
-/// AddPath - Add the specified path to the specified group list.
-///
-static void AddPath(const std::string &Path, IncludeDirGroup Group,
- bool isCXXAware, bool isUserSupplied,
- bool isFramework, HeaderSearch &HS) {
- assert(!Path.empty() && "can't handle empty path here");
- FileManager &FM = HS.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.
- DirectoryLookup::DirType Type;
- if (Group == Quoted || Group == Angled)
- Type = DirectoryLookup::NormalHeaderDir;
- else if (isCXXAware)
- Type = DirectoryLookup::SystemHeaderDir;
- else
- Type = DirectoryLookup::ExternCSystemHeaderDir;
-
-
- // 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 = HS.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());
-}
-
-/// RemoveDuplicates - If there are duplicate directory entries in the specified
-/// search list, remove the later (dead) ones.
-static void RemoveDuplicates(std::vector<DirectoryLookup> &SearchList) {
- 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) {
- 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 (Verbose)
- fprintf(stderr, "ignoring duplicate directory \"%s\"\n",
- SearchList[i].getDir()->getName());
- } 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.
- SearchList.erase(SearchList.begin()+i);
- --i;
- }
-}
-
-// AddEnvVarPaths - Add a list of paths from an environment variable to a
-// header search list.
-//
-static void AddEnvVarPaths(const char *Name, HeaderSearch &Headers) {
- const char* at = getenv(Name);
- if (!at)
- return;
-
- const char* delim = strchr(at, llvm::sys::PathSeparator);
- while (delim != 0) {
- if (delim-at == 0)
- AddPath(".", Angled, false, true, false, Headers);
- else
- AddPath(std::string(at, std::string::size_type(delim-at)), Angled, false,
- true, false, Headers);
- at = delim + 1;
- delim = strchr(at, llvm::sys::PathSeparator);
- }
- if (*at == 0)
- AddPath(".", Angled, false, true, false, Headers);
- else
- AddPath(at, Angled, false, true, false, Headers);
-}
-
-/// InitializeIncludePaths - Process the -I options and set them in the
-/// HeaderSearch object.
-static void InitializeIncludePaths(const char *Argv0, HeaderSearch &Headers,
- FileManager &FM, const LangOptions &Lang) {
- // Handle -F... options.
- for (unsigned i = 0, e = F_dirs.size(); i != e; ++i)
- AddPath(F_dirs[i], Angled, false, true, true, Headers);
-
- // Handle -I... options.
- for (unsigned i = 0, e = I_dirs.size(); i != e; ++i)
- AddPath(I_dirs[i], Angled, false, true, false, Headers);
-
- // Handle -idirafter... options.
- for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i)
- AddPath(idirafter_dirs[i], After, false, true, false, Headers);
-
- // Handle -iquote... options.
- for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i)
- AddPath(iquote_dirs[i], Quoted, false, true, false, Headers);
-
- // Handle -isystem... options.
- for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i)
- AddPath(isystem_dirs[i], System, false, true, false, Headers);
-
- // 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))) {
- AddPath(Prefix+iwithprefix_vals[iwithprefix_idx],
- System, false, false, false, Headers);
- ++iwithprefix_idx;
- iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size();
- } else {
- AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx],
- Angled, false, false, false, Headers);
- ++iwithprefixbefore_idx;
- iwithprefixbefore_done =
- iwithprefixbefore_idx == iwithprefixbefore_vals.size();
- }
- }
- }
-
- AddEnvVarPaths("CPATH", Headers);
- if (Lang.CPlusPlus && Lang.ObjC1)
- AddEnvVarPaths("OBJCPLUS_INCLUDE_PATH", Headers);
- else if (Lang.CPlusPlus)
- AddEnvVarPaths("CPLUS_INCLUDE_PATH", Headers);
- else if (Lang.ObjC1)
- AddEnvVarPaths("OBJC_INCLUDE_PATH", Headers);
- else
- AddEnvVarPaths("C_INCLUDE_PATH", Headers);
-
- // 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
- AddPath(MainExecutablePath.c_str(), System, false, false, false, Headers);
- }
-
- // FIXME: temporary hack: hard-coded paths.
- // FIXME: get these from the target?
- if (!nostdinc) {
- if (Lang.CPlusPlus) {
- AddPath("/usr/include/c++/4.0.0", System, true, false, false, Headers);
- AddPath("/usr/include/c++/4.0.0/i686-apple-darwin8", System, true, false,
- false, Headers);
- AddPath("/usr/include/c++/4.0.0/backward", System, true, false, false,
- Headers);
-
- // Ubuntu 7.10 - Gutsy Gibbon
- AddPath("/usr/include/c++/4.1.3", System, true, false, false, Headers);
- AddPath("/usr/include/c++/4.1.3/i486-linux-gnu", System, true, false,
- false, Headers);
- AddPath("/usr/include/c++/4.1.3/backward", System, true, false, false,
- Headers);
-
- // Fedora 8
- AddPath("/usr/include/c++/4.1.2", System, true, false, false, Headers);
- AddPath("/usr/include/c++/4.1.2/i386-redhat-linux", System, true, false,
- false, Headers);
- AddPath("/usr/include/c++/4.1.2/backward", System, true, false, false,
- Headers);
- }
-
- AddPath("/usr/local/include", System, false, false, false, Headers);
- // leopard
- AddPath("/usr/lib/gcc/i686-apple-darwin9/4.0.1/include", System,
- false, false, false, Headers);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin9/4.0.1/include",
- System, false, false, false, Headers);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin9/"
- "4.0.1/../../../../powerpc-apple-darwin0/include",
- System, false, false, false, Headers);
-
- // tiger
- AddPath("/usr/lib/gcc/i686-apple-darwin8/4.0.1/include", System,
- false, false, false, Headers);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include",
- System, false, false, false, Headers);
- AddPath("/usr/lib/gcc/powerpc-apple-darwin8/"
- "4.0.1/../../../../powerpc-apple-darwin8/include",
- System, false, false, false, Headers);
-
- // Ubuntu 7.10 - Gutsy Gibbon
- AddPath("/usr/lib/gcc/i486-linux-gnu/4.1.3/include", System,
- false, false, false, Headers);
-
- // Fedora 8
- AddPath("/usr/lib/gcc/i386-redhat-linux/4.1.2/include", System,
- false, false, false, Headers);
-
- //Debian testing/lenny x86
- AddPath("/usr/lib/gcc/i486-linux-gnu/4.2.3/include", System,
- false, false, false, Headers);
-
- //Debian testing/lenny amd64
- AddPath("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include", System,
- false, false, false, Headers);
-
- AddPath("/usr/include", System, false, false, false, Headers);
- AddPath("/System/Library/Frameworks", System, true, false, true, Headers);
- AddPath("/Library/Frameworks", System, true, false, true, Headers);
- }
-
- // Now that we have collected all of the include paths, merge them all
- // together and tell the preprocessor about them.
-
- // 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);
- RemoveDuplicates(IncludeGroup[Quoted]);
-
- // 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");
- }
-}
-
-//===----------------------------------------------------------------------===//
-// 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,
- llvm::Module *&DestModule) {
- 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 ParseCFGDump:
- case ParseCFGView:
- return CreateCFGDumper(ProgAction == ParseCFGView,
- AnalyzeSpecificFunction);
-
- case AnalysisLiveVariables:
- return CreateLiveVarAnalyzer(AnalyzeSpecificFunction);
-
- case WarnDeadStores:
- return CreateDeadStoreChecker(Diag);
-
- case WarnUninitVals:
- return CreateUnitValsChecker(Diag);
-
- case AnalysisGRSimpleVals:
- return CreateGRSimpleVals(Diag, PP, PPF, AnalyzeSpecificFunction,
- OutputFile, VisualizeEG, TrimGraph, AnalyzeAll);
-
- case CheckerCFRef:
- return CreateCFRefChecker(Diag, PP, PPF, LangOpts,
- AnalyzeSpecificFunction,
- OutputFile, VisualizeEG, TrimGraph, AnalyzeAll);
-
- case TestSerialization:
- return CreateSerializationTest(Diag, FileMgr, LangOpts);
-
- case EmitLLVM:
- case EmitBC:
- DestModule = new llvm::Module(InFile);
- return CreateLLVMCodeGen(Diag, LangOpts, DestModule, GenerateDebugInfo);
-
- case SerializeAST:
- // FIXME: Allow user to tailor where the file is written.
- return CreateASTSerializer(InFile, OutputFile, Diag, LangOpts);
-
- case RewriteObjC:
- return CreateCodeRewriterTest(InFile, OutputFile, Diag, LangOpts);
- }
-}
-
-/// ProcessInputFile - Process a single input file with the specified state.
-///
-static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
- const std::string &InFile) {
-
- ASTConsumer* Consumer = NULL;
- bool ClearSourceMgr = false;
- llvm::Module *CodeGenModule = 0;
-
- switch (ProgAction) {
- default:
- Consumer = CreateASTConsumer(InFile, PP.getDiagnostics(),
- PP.getFileManager(), PP.getLangOptions(), &PP,
- &PPF, CodeGenModule);
-
- if (!Consumer) {
- fprintf(stderr, "Unexpected program action!\n");
- 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 = new ASTConsumer();
- break;
-
- case RewriteMacros:
- RewriteMacrosInInput(PP, InFile, OutputFile);
- ClearSourceMgr = true;
- break;
- }
-
- if (Consumer) {
- if (VerifyDiagnostics)
- exit(CheckASTConsumer(PP, Consumer));
-
- // This deletes Consumer.
- ParseAST(PP, Consumer, Stats);
- }
-
- // If running the code generator, finish up now.
- if (CodeGenModule) {
- 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 (ProgAction == EmitLLVM)
- Path.appendSuffix("ll");
- else if (ProgAction == EmitBC)
- Path.appendSuffix("bc");
- else
- assert(0 && "Unknown action");
- Out = new std::ofstream(Path.toString().c_str(),
- std::ios_base::binary|std::ios_base::out);
- }
-
- if (ProgAction == EmitLLVM) {
- CodeGenModule->print(*Out);
- } else {
- assert(ProgAction == EmitBC);
- llvm::WriteBitcodeToFile(CodeGenModule, *Out);
- }
-
- if (Out != llvm::cout.stream())
- delete Out;
- delete CodeGenModule;
- }
-
- 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::Module *DestModule;
- llvm::OwningPtr<ASTConsumer>
- Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(), 0, 0,
- DestModule));
-
- 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.
- std::auto_ptr<DiagnosticClient> DiagClient;
- TextDiagnostics* TextDiagClient = NULL;
-
- if (!HTMLDiag.empty()) {
-
- // FIXME: The HTMLDiagnosticClient uses the Preprocessor for
- // (optional) syntax highlighting, but we don't have a preprocessor yet.
- // Fix this dependency later.
- DiagClient.reset(CreateHTMLDiagnosticClient(HTMLDiag, 0, 0));
- }
- else { // Use Text diagnostics.
- if (!VerifyDiagnostics) {
- // Print diagnostics to stderr by default.
- TextDiagClient = new TextDiagnosticPrinter();
- } 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;
- }
- }
-
- assert (TextDiagClient);
- DiagClient.reset(TextDiagClient);
- }
-
- // Configure our handling of diagnostics.
- Diagnostic Diags(*DiagClient);
- 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();
- 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);
- }
-
- for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
- const std::string &InFile = InputFilenames[i];
-
- if (isSerializedFile(InFile))
- ProcessSerializedFile(InFile,Diags,FileMgr);
- else {
- /// Create a SourceManager object. This tracks and owns all the file
- /// buffers allocated to a translation unit.
- SourceManager SourceMgr;
-
- // Initialize language options, inferring file types from input filenames.
- LangOptions LangInfo;
- InitializeBaseLanguage();
- LangKind LK = GetLanguage(InFile);
- InitializeLangOptions(LangInfo, LK);
- InitializeLanguageStandard(LangInfo, LK);
- InitializeGCMode(LangInfo);
-
- // Process the -I options and set them in the HeaderInfo.
- HeaderSearch HeaderInfo(FileMgr);
- if (TextDiagClient) TextDiagClient->setHeaderSearch(HeaderInfo);
- InitializeIncludePaths(argv[0], HeaderInfo, FileMgr, LangInfo);
-
- // Set up the preprocessor with these options.
- DriverPreprocessorFactory PPFactory(InFile, Diags, LangInfo, *Target,
- SourceMgr, HeaderInfo);
-
- llvm::OwningPtr<Preprocessor> PP(PPFactory.CreatePreprocessor());
-
- if (!PP)
- continue;
-
- ProcessInputFile(*PP, PPFactory, InFile);
- HeaderInfo.ClearFileInfo();
-
- if (Stats)
- SourceMgr.PrintStats();
- }
- }
-
- delete Target;
-
- unsigned NumDiagnostics = Diags.getNumDiagnostics();
-
- if (NumDiagnostics)
- fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
- (NumDiagnostics == 1 ? "" : "s"));
-
- if (Stats) {
- FileMgr.PrintStats();
- fprintf(stderr, "\n");
- }
-
- return Diags.getNumErrors() != 0;
-}
diff --git a/clang/Driver/clang.h b/clang/Driver/clang.h
deleted file mode 100644
index 69434b705350..000000000000
--- a/clang/Driver/clang.h
+++ /dev/null
@@ -1,49 +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);
-
-
-} // 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 6d20df81284a..000000000000
--- a/clang/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-LEVEL = ../..
-DIRS := lib Driver
-
-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 a64fa6fc990f..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 64.9% 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 0895baa29083..000000000000
--- a/clang/clang.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1212 +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 */; };
- 1A376A2D0D4AED9B002A1C52 /* CGExprConstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.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 */; };
- 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 */; };
- 356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */; };
- 35707EFE0CD0F5CC000B2204 /* SourceLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35707EFD0CD0F5CC000B2204 /* SourceLocation.cpp */; };
- 3574BC2B0D9B531D00DF491A /* HTMLDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3574BC2A0D9B531D00DF491A /* HTMLDiagnostics.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 */; };
- 3593790A0DA48ABA0043B19C /* BugReporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 359379090DA48ABA0043B19C /* BugReporter.cpp */; };
- 35A3E7020DD3874400757F74 /* CGDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */; };
- 35A8FCF90D9B4B2A001C2F97 /* PathDiagnostic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.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 */; };
- 35EF67700DAD1D2C00B19414 /* SemaDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */; };
- 35EFEFB60DB67ED60020783D /* GRTransferFuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */; };
- 35F8D0D60D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.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 */; };
- 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 */; };
- 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 */; };
- DE4121330D7F1C1C0080F80A /* ValueState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121250D7F1C1C0080F80A /* ValueState.cpp */; };
- DE4121340D7F1C1C0080F80A /* DeadStores.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121260D7F1C1C0080F80A /* DeadStores.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 */; };
- DE41213F0D7F1C1C0080F80A /* ProgramPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4121320D7F1C1C0080F80A /* ProgramPoint.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 */; };
- DEB0AEB90C2087A700718A22 /* TextDiagnostics.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEB0AEB80C2087A700718A22 /* TextDiagnostics.h */; };
- DEB0AEBB0C2087AB00718A22 /* TextDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB0AEBA0C2087AB00718A22 /* TextDiagnostics.cpp */; };
- 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 */; };
- DECAB0950DA684C500E13CCB /* CGObjCEtoile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECAB0940DA684C500E13CCB /* CGObjCEtoile.cpp */; };
- 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 */; };
- DEEBCBE30C33702C00A9FE82 /* TextDiagnosticBuffer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEEBCBE20C33702C00A9FE82 /* TextDiagnosticBuffer.h */; };
- DEEBCBE50C33703100A9FE82 /* TextDiagnosticBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEEBCBE40C33703100A9FE82 /* TextDiagnosticBuffer.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 */; };
- F0226FD20C18084500141F42 /* TextDiagnosticPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F0226FD00C18084500141F42 /* TextDiagnosticPrinter.cpp */; };
- F0226FD30C18084500141F42 /* TextDiagnosticPrinter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F0226FD10C18084500141F42 /* TextDiagnosticPrinter.h */; };
-/* 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 */,
- F0226FD30C18084500141F42 /* TextDiagnosticPrinter.h in CopyFiles */,
- DEEBBD440C19C5D200A9FE82 /* TODO.txt in CopyFiles */,
- 84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */,
- DEB0AEB90C2087A700718A22 /* TextDiagnostics.h in CopyFiles */,
- DEEBC3BA0C2363B800A9FE82 /* CodeGenTypes.h in CopyFiles */,
- DEEBCBE30C33702C00A9FE82 /* TextDiagnosticBuffer.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>"; };
- 1A376A2C0D4AED9B002A1C52 /* CGExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprConstant.cpp; path = lib/CodeGen/CGExprConstant.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjC.cpp; path = lib/CodeGen/CGObjC.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = lib/CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; };
- 3513185F0CD14468006B66F7 /* DeclSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclSerialization.cpp; path = lib/AST/DeclSerialization.cpp; sourceTree = "<group>"; };
- 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = lib/AST/ExprCXX.cpp; sourceTree = "<group>"; };
- 3527124F0DAFE54700C76352 /* IdentifierResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IdentifierResolver.h; path = lib/Sema/IdentifierResolver.h; sourceTree = "<group>"; };
- 352712500DAFE54700C76352 /* IdentifierResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IdentifierResolver.cpp; path = lib/Sema/IdentifierResolver.cpp; sourceTree = "<group>"; };
- 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>"; };
- 3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.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>"; };
- 3574BC290D9B531D00DF491A /* HTMLDiagnostics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLDiagnostics.h; path = Driver/HTMLDiagnostics.h; sourceTree = "<group>"; };
- 3574BC2A0D9B531D00DF491A /* HTMLDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLDiagnostics.cpp; path = Driver/HTMLDiagnostics.cpp; sourceTree = "<group>"; };
- 3574BF280D9B7CC000DF491A /* AnnotatedPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnnotatedPath.h; path = clang/Analysis/PathSensitive/AnnotatedPath.h; 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; lastKnownFileType = sourcecode.cpp.cpp; name = StmtSerialization.cpp; path = lib/AST/StmtSerialization.cpp; sourceTree = "<group>"; };
- 35839B0A0CDF845F006ED061 /* TypeSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSerialization.cpp; path = lib/AST/TypeSerialization.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = StmtIterator.cpp; path = lib/AST/StmtIterator.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>"; };
- 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaUtil.h; path = lib/Sema/SemaUtil.h; sourceTree = "<group>"; };
- 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGDebugInfo.cpp; path = lib/CodeGen/CGDebugInfo.cpp; sourceTree = "<group>"; };
- 35A3E7010DD3874400757F74 /* CGDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGDebugInfo.h; path = lib/CodeGen/CGDebugInfo.h; sourceTree = "<group>"; };
- 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>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = TranslationUnit.cpp; path = lib/AST/TranslationUnit.cpp; sourceTree = "<group>"; };
- 35BB2D7E0D19954000944DB5 /* ASTConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumer.cpp; path = lib/AST/ASTConsumer.cpp; sourceTree = "<group>"; };
- 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumer.h; path = clang/AST/ASTConsumer.h; sourceTree = "<group>"; };
- 35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtViz.cpp; path = lib/AST/StmtViz.cpp; sourceTree = "<group>"; };
- 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>"; };
- 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclCXX.cpp; path = lib/Sema/SemaDeclCXX.cpp; sourceTree = "<group>"; };
- 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GRTransferFuncs.cpp; path = lib/Analysis/GRTransferFuncs.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>"; };
- 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; };
- 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; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = Expr.cpp; path = lib/AST/Expr.cpp; sourceTree = "<group>"; };
- DE1732FF0B068B700080B521 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ASTContext.cpp; path = lib/AST/ASTContext.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = lib/CodeGen/CGExprComplex.cpp; sourceTree = "<group>"; };
- DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = lib/CodeGen/CGExprScalar.cpp; sourceTree = "<group>"; };
- DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDeclCXX.cpp; path = lib/Parse/ParseDeclCXX.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = Stmt.cpp; path = lib/AST/Stmt.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = StmtPrinter.cpp; path = lib/AST/StmtPrinter.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.c.h; name = CGObjCRuntime.h; path = lib/CodeGen/CGObjCRuntime.h; sourceTree = "<group>"; };
- DE38CD4F0D794D0100A273B6 /* CGObjCGNU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCGNU.cpp; path = lib/CodeGen/CGObjCGNU.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = DeclObjC.cpp; path = lib/AST/DeclObjC.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.c.h; path = IdentifierTable.h; sourceTree = "<group>"; };
- 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>"; };
- DE41211C0D7F1BBE0080F80A /* ValueState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueState.h; path = clang/Analysis/PathSensitive/ValueState.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>"; };
- DE4121250D7F1C1C0080F80A /* ValueState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueState.cpp; path = lib/Analysis/ValueState.cpp; sourceTree = "<group>"; };
- DE4121260D7F1C1C0080F80A /* DeadStores.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeadStores.cpp; path = lib/Analysis/DeadStores.cpp; 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>"; };
- DE41212D0D7F1C1C0080F80A /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LiveVariables.cpp; path = lib/Analysis/LiveVariables.cpp; 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>"; };
- DE4121320D7F1C1C0080F80A /* ProgramPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProgramPoint.cpp; path = lib/Analysis/ProgramPoint.cpp; sourceTree = "<group>"; };
- DE4264FB0C113592005A861D /* CGDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGDecl.cpp; path = lib/CodeGen/CGDecl.cpp; sourceTree = "<group>"; };
- DE46BF270AE0A82D00CC047C /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetInfo.h; sourceTree = "<group>"; };
- DE4772F90C10EAE5002239E8 /* CGStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGStmt.cpp; path = lib/CodeGen/CGStmt.cpp; sourceTree = "<group>"; };
- DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExpr.cpp; path = lib/CodeGen/CGExpr.cpp; sourceTree = "<group>"; };
- DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprObjC.cpp; path = lib/Sema/SemaExprObjC.cpp; sourceTree = "<group>"; };
- 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>"; };
- DE67E70A0C020EC500F66BC5 /* SemaType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaType.cpp; path = lib/Sema/SemaType.cpp; sourceTree = "<group>"; };
- DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaStmt.cpp; path = lib/Sema/SemaStmt.cpp; sourceTree = "<group>"; };
- DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprCXX.cpp; path = lib/Sema/SemaExprCXX.cpp; sourceTree = "<group>"; };
- DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExpr.cpp; path = lib/Sema/SemaExpr.cpp; sourceTree = "<group>"; };
- DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDecl.cpp; path = lib/Sema/SemaDecl.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- DE67E7140C020EDF00F66BC5 /* Sema.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Sema.h; path = lib/Sema/Sema.h; sourceTree = "<group>"; };
- DE67E7160C020EE400F66BC5 /* Sema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Sema.cpp; path = lib/Sema/Sema.cpp; sourceTree = "<group>"; };
- DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseAST.cpp; path = lib/Sema/ParseAST.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclObjC.cpp; path = lib/Sema/SemaDeclObjC.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = Type.cpp; path = lib/AST/Type.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleBuilder.cpp; path = lib/CodeGen/ModuleBuilder.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.c.h; name = CodeGenModule.h; path = lib/CodeGen/CodeGenModule.h; sourceTree = "<group>"; };
- DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenModule.cpp; path = lib/CodeGen/CodeGenModule.cpp; sourceTree = "<group>"; };
- DE928B800C0A615B00231DA4 /* CodeGenFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CodeGenFunction.h; path = lib/CodeGen/CodeGenFunction.h; sourceTree = "<group>"; };
- DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenFunction.cpp; path = lib/CodeGen/CodeGenFunction.cpp; sourceTree = "<group>"; };
- 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>"; };
- DEB0AEB80C2087A700718A22 /* TextDiagnostics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextDiagnostics.h; path = Driver/TextDiagnostics.h; sourceTree = "<group>"; };
- DEB0AEBA0C2087AB00718A22 /* TextDiagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnostics.cpp; path = Driver/TextDiagnostics.cpp; sourceTree = "<group>"; };
- DEC63B190C7B940200DBF169 /* CFG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CFG.cpp; path = lib/AST/CFG.cpp; sourceTree = "<group>"; };
- 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>"; };
- DECAB0940DA684C500E13CCB /* CGObjCEtoile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGObjCEtoile.cpp; path = lib/CodeGen/CGObjCEtoile.cpp; 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 = 8; 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; lastKnownFileType = sourcecode.cpp.cpp; name = Builtins.cpp; path = lib/AST/Builtins.cpp; sourceTree = "<group>"; };
- DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = "<group>"; };
- DED7D7320A524295003AD0FB /* DiagnosticKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DiagnosticKinds.def; sourceTree = "<group>"; };
- DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = "<group>"; };
- DED7D7350A524295003AD0FB /* SourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SourceLocation.h; sourceTree = "<group>"; };
- DED7D7360A524295003AD0FB /* SourceManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SourceManager.h; sourceTree = "<group>"; };
- DED7D7370A524295003AD0FB /* TokenKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = TokenKinds.def; sourceTree = "<group>"; };
- DED7D7380A524295003AD0FB /* TokenKinds.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TokenKinds.h; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.c.h; name = CodeGenTypes.h; path = lib/CodeGen/CodeGenTypes.h; sourceTree = "<group>"; };
- DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenTypes.cpp; path = lib/CodeGen/CodeGenTypes.cpp; sourceTree = "<group>"; };
- DEEBCBE20C33702C00A9FE82 /* TextDiagnosticBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextDiagnosticBuffer.h; path = Driver/TextDiagnosticBuffer.h; sourceTree = "<group>"; };
- DEEBCBE40C33703100A9FE82 /* TextDiagnosticBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnosticBuffer.cpp; path = Driver/TextDiagnosticBuffer.cpp; sourceTree = "<group>"; };
- 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; lastKnownFileType = sourcecode.cpp.cpp; name = StmtDumper.cpp; path = lib/AST/StmtDumper.cpp; sourceTree = "<group>"; };
- DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprAgg.cpp; path = lib/CodeGen/CGExprAgg.cpp; sourceTree = "<group>"; };
- DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaChecking.cpp; path = lib/Sema/SemaChecking.cpp; sourceTree = "<group>"; };
- 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>"; };
- F0226FD00C18084500141F42 /* TextDiagnosticPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TextDiagnosticPrinter.cpp; path = Driver/TextDiagnosticPrinter.cpp; sourceTree = "<group>"; };
- F0226FD10C18084500141F42 /* TextDiagnosticPrinter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextDiagnosticPrinter.h; path = Driver/TextDiagnosticPrinter.h; 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 */,
- );
- name = Source;
- sourceTree = "<group>";
- };
- 1AB674ADFE9D54B511CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 8DD76F6C0486A84900D96B5E /* clang */,
- );
- name = Products;
- 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 = (
- 35EFEFB50DB67ED60020783D /* GRTransferFuncs.cpp */,
- 359379090DA48ABA0043B19C /* BugReporter.cpp */,
- 356B89760D9BFDC100CBEBE9 /* BasicObjCFoundationChecks.h */,
- 35F8D0D50D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp */,
- 35A8FCF80D9B4B29001C2F97 /* PathDiagnostic.cpp */,
- 35D55B240D81D8C60092E734 /* BasicValueFactory.cpp */,
- 35D55B250D81D8C60092E734 /* CFRefCount.cpp */,
- 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */,
- DE4121250D7F1C1C0080F80A /* ValueState.cpp */,
- DE4121260D7F1C1C0080F80A /* DeadStores.cpp */,
- DE4121270D7F1C1C0080F80A /* SymbolManager.cpp */,
- DE4121280D7F1C1C0080F80A /* ExplodedGraph.cpp */,
- DE4121290D7F1C1C0080F80A /* UninitializedValues.cpp */,
- DE41212A0D7F1C1C0080F80A /* GRCoreEngine.cpp */,
- DE41212C0D7F1C1C0080F80A /* GRSimpleVals.h */,
- DE41212D0D7F1C1C0080F80A /* LiveVariables.cpp */,
- DE41212E0D7F1C1C0080F80A /* RValues.cpp */,
- DE41212F0D7F1C1C0080F80A /* GRSimpleVals.cpp */,
- DE4121300D7F1C1C0080F80A /* GRBlockCounter.cpp */,
- DE4121310D7F1C1C0080F80A /* GRExprEngine.cpp */,
- DE4121320D7F1C1C0080F80A /* ProgramPoint.cpp */,
- );
- name = Analysis;
- 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 = (
- 84D9A88B0C1A581300AC7ABC /* AttributeList.h */,
- DE06E8130A8FF9330050E87E /* Action.h */,
- DE17336F0B068DC60080B521 /* DeclSpec.h */,
- DE1F22020A7D852A00FBF588 /* Parser.h */,
- DE06BECA0A854E4B0050E87E /* Scope.h */,
- );
- name = Parse;
- sourceTree = "<group>";
- };
- DE1F22600A7D8C9B00FBF588 /* Parse */ = {
- isa = PBXGroup;
- children = (
- 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */,
- DE17336D0B068DC20080B521 /* DeclSpec.cpp */,
- DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */,
- DE06D42F0A8BB52D0050E87E /* Parser.cpp */,
- DE34600E0AFDCCCE00DBC861 /* ParseDecl.cpp */,
- DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */,
- DE3460120AFDCCDA00DBC861 /* ParseExpr.cpp */,
- DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */,
- DE3460040AFDCC6500DBC861 /* ParseInit.cpp */,
- DE345FFF0AFDCC1900DBC861 /* ParseObjc.cpp */,
- DE34600A0AFDCCBF00DBC861 /* ParseStmt.cpp */,
- );
- name = Parse;
- sourceTree = "<group>";
- };
- DE4121130D7F1B980080F80A /* PathSensitive */ = {
- isa = PBXGroup;
- children = (
- 359378FF0DA486490043B19C /* BugReporter.h */,
- 35F8D0CA0D9B7E8200D91C5E /* GRSimpleAPICheck.h */,
- 35F8D0CB0D9B7E8200D91C5E /* GRAuditor.h */,
- 3574BF280D9B7CC000DF491A /* AnnotatedPath.h */,
- 35D55B290D81D8E50092E734 /* BasicValueFactory.h */,
- DE41211B0D7F1BBE0080F80A /* RValues.h */,
- DE41211C0D7F1BBE0080F80A /* ValueState.h */,
- DE41211D0D7F1BBE0080F80A /* GRWorkList.h */,
- DE41211E0D7F1BBE0080F80A /* SymbolManager.h */,
- DE41211F0D7F1BBE0080F80A /* GRBlockCounter.h */,
- DE4121200D7F1BBE0080F80A /* ExplodedGraph.h */,
- DE4121210D7F1BBE0080F80A /* GRExprEngine.h */,
- DE4121220D7F1BBE0080F80A /* GRTransferFuncs.h */,
- DE4121230D7F1BBE0080F80A /* GRCoreEngine.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 */,
- 35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */,
- DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */,
- DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */,
- DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */,
- DE47999B0D2EBE1A00706D2D /* SemaExprObjC.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 = (
- 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */,
- 35A3E7010DD3874400757F74 /* CGDebugInfo.h */,
- DE928B800C0A615B00231DA4 /* CodeGenFunction.h */,
- DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */,
- DE928B7C0C0A615100231DA4 /* CodeGenModule.h */,
- DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */,
- DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */,
- DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */,
- 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */,
- 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 */,
- DECAB0940DA684C500E13CCB /* CGObjCEtoile.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 */,
- DE3985780CB8ADC800223765 /* ASTConsumers.h */,
- DE39857A0CB8ADCB00223765 /* ASTConsumers.cpp */,
- DE38CF150D8C9DE000A273B6 /* DiagChecker.cpp */,
- DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */,
- DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */,
- 352981080CC58344008B5E84 /* SerializationTest.cpp */,
- 3574BC290D9B531D00DF491A /* HTMLDiagnostics.h */,
- 3574BC2A0D9B531D00DF491A /* HTMLDiagnostics.cpp */,
- 72D16C210D9975EA00E6DA4A /* HTMLPrint.cpp */,
- 035611E10DB40C8100D2EF2A /* RewriteObjC.cpp */,
- DEA0EBD90DD2D3C8007A02A9 /* RewriteMacros.cpp */,
- DEB0AEBA0C2087AB00718A22 /* TextDiagnostics.cpp */,
- DEB0AEB80C2087A700718A22 /* TextDiagnostics.h */,
- F0226FD00C18084500141F42 /* TextDiagnosticPrinter.cpp */,
- F0226FD10C18084500141F42 /* TextDiagnosticPrinter.h */,
- DEEBCBE40C33703100A9FE82 /* TextDiagnosticBuffer.cpp */,
- DEEBCBE20C33702C00A9FE82 /* TextDiagnosticBuffer.h */,
- );
- name = Driver;
- sourceTree = "<group>";
- };
- DEC8D98B0A9433BC00353FCA /* AST */ = {
- isa = PBXGroup;
- children = (
- DEC8D9A30A94346E00353FCA /* AST.h */,
- 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */,
- DE75ED280B044DC90020CF81 /* ASTContext.h */,
- 1A72BEAC0D641E9400B085E9 /* Attr.h */,
- DED676D00B6C786700AAD4A3 /* Builtins.def */,
- DED676F90B6C797B00AAD4A3 /* Builtins.h */,
- DEC63B1B0C7B940600DBF169 /* CFG.h */,
- DEC8D9900A9433CD00353FCA /* Decl.h */,
- 035611470DA6A45C00D2EF2A /* DeclBase.h */,
- 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */,
- DE0FCA620A95859D00248FD5 /* Expr.h */,
- 1A30A9E80B93A4C800201A91 /* ExprCXX.h */,
- 1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */,
- 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 */,
- 1A68BC130D0CADDD001A28C8 /* X86Builtins.def */,
- );
- name = AST;
- sourceTree = "<group>";
- };
- DEC8D9920A9433F400353FCA /* AST */ = {
- isa = PBXGroup;
- children = (
- 35BB2D7E0D19954000944DB5 /* ASTConsumer.cpp */,
- DE1732FF0B068B700080B521 /* ASTContext.cpp */,
- DED677C80B6C854100AAD4A3 /* Builtins.cpp */,
- DEC63B190C7B940200DBF169 /* CFG.cpp */,
- DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
- DE38CF260D8C9E6C00A273B6 /* DeclObjC.cpp */,
- 3513185F0CD14468006B66F7 /* DeclSerialization.cpp */,
- DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
- 35260CA40C7F75C000D66CE9 /* ExprCXX.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 */,
- );
- 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 = (
- 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 */,
- F0226FD20C18084500141F42 /* TextDiagnosticPrinter.cpp in Sources */,
- 84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */,
- DEB0AEBB0C2087AB00718A22 /* TextDiagnostics.cpp in Sources */,
- DEEBC3BC0C2363BC00A9FE82 /* CodeGenTypes.cpp in Sources */,
- DEEBCBE50C33703100A9FE82 /* TextDiagnosticBuffer.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 */,
- DE4121330D7F1C1C0080F80A /* ValueState.cpp in Sources */,
- DE4121340D7F1C1C0080F80A /* DeadStores.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 */,
- DE41213F0D7F1C1C0080F80A /* ProgramPoint.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 */,
- 3574BC2B0D9B531D00DF491A /* HTMLDiagnostics.cpp in Sources */,
- 35F8D0D60D9B82CD00D91C5E /* BasicObjCFoundationChecks.cpp in Sources */,
- 3593790A0DA48ABA0043B19C /* BugReporter.cpp in Sources */,
- DECAB0950DA684C500E13CCB /* CGObjCEtoile.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 */,
- );
- 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",
- "-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";
- PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
- PRODUCT_NAME = clang;
- };
- name = Release;
- };
- 1DEB923608733DC60010E9CD /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- ../../include,
- include,
- );
- LIBRARY_SEARCH_PATHS = ../../Debug/lib;
- OTHER_LDFLAGS = (
- "-lLLVMSupport",
- "-lLLVMSystem",
- "-lLLVMCore",
- "-lLLVMBitReader",
- "-lLLVMBitWriter",
- "-lLLVMTarget",
- );
- 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 = (
- "-lLLVMSupport",
- "-lLLVMSystem",
- "-lLLVMCore",
- "-lLLVMBitReader",
- "-lLLVMBitWriter",
- "-lLLVMTarget",
- );
- 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 78fb9b1d9ce2..000000000000
--- a/clang/docs/InternalsManual.html
+++ /dev/null
@@ -1,610 +0,0 @@
-<title>"clang" CFE Internals Manual</title>
-
-<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>
--->
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/AST.h b/clang/include/clang/AST/AST.h
deleted file mode 100644
index 70d7b42279f9..000000000000
--- a/clang/include/clang/AST/AST.h
+++ /dev/null
@@ -1,25 +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/DeclObjC.h"
-#include "clang/AST/Expr.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 bfaa141573ee..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 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) {}
-
- /// HandleTopLevelDecl - Handle the specified top-level declaration. This is
- /// called by HandleTopLevelDeclaration to process every top-level Decl*.
- virtual void HandleTopLevelDecl(Decl *D) {}
-
-
- /// HandleTopLevelDeclaration - Handle the specified top-level declaration.
- /// This is called only for Decl* that are the head of a chain of
- /// Decl's (in the case that the Decl* is a ScopedDecl*). Subclasses
- /// can override its behavior; by default it calls HandleTopLevelDecl
- /// for every Decl* in a decl chain.
- virtual void HandleTopLevelDeclaration(Decl *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) {}
-
- /// 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 dfe117053cf4..000000000000
--- a/clang/include/clang/AST/ASTContext.h
+++ /dev/null
@@ -1,376 +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/AST/Builtins.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include "llvm/Support/Allocator.h"
-#include <vector>
-
-namespace clang {
- class TargetInfo;
- class IdentifierTable;
-
-/// 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<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::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;
-
- TranslationUnitDecl *TUDecl;
-
- SourceManager &SourceMgr;
- llvm::MallocAllocator Allocator;
-public:
- TargetInfo &Target;
- IdentifierTable &Idents;
- SelectorTable &Selectors;
-
- SourceManager& getSourceManager() { return SourceMgr; }
- llvm::MallocAllocator &getAllocator() { return Allocator; }
-
- 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 SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy;
- QualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
- QualType UnsignedLongLongTy;
- QualType FloatTy, DoubleTy, LongDoubleTy;
- QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- QualType VoidPtrTy;
-
- ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents,
- SelectorTable &sels, unsigned size_reserve=0 ) :
- CFConstantStringTypeDecl(0), SourceMgr(SM), Target(t),
- Idents(idents), Selectors(sels) {
-
- if (size_reserve > 0) Types.reserve(size_reserve);
- InitBuiltinTypes();
- BuiltinInfo.InitializeBuiltins(idents, Target);
- TUDecl = TranslationUnitDecl::Create(*this);
- }
-
- ~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);
-
- /// 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, QualType *ArgArray,
- unsigned NumArgs, bool isVariadic);
-
- /// getTypeDeclType - Return the unique reference to the type for
- /// the specified type declaration.
- QualType getTypeDeclType(TypeDecl *Decl);
-
- /// 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(QualType idType,
- 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;
-
- /// 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;
- }
-
- // 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(ObjCMethodDecl *Decl, std::string &S);
-
- /// getObjCEncodingTypeSize returns size of type for objective-c encoding
- /// purpose.
- int getObjCEncodingTypeSize(QualType t);
-
- // This setter/getter repreents the ObjC 'id' type. It is setup lazily, by
- // Sema.
- void setObjCIdType(TypedefDecl *Decl);
- QualType getObjCIdType() const { return ObjCIdType; }
-
- void setObjCSelType(TypedefDecl *Decl);
- QualType getObjCSelType() const { return ObjCSelType; }
-
- void setObjCProtoType(QualType QT);
- QualType getObjCProtoType() const { return ObjCProtoType; }
-
- void setObjCClassType(TypedefDecl *Decl);
- QualType getObjCClassType() const { return ObjCClassType; }
-
- void setBuiltinVaListType(QualType T);
- QualType getBuiltinVaListType() const { return BuiltinVaListType; }
-
- //===--------------------------------------------------------------------===//
- // Type Sizing and Analysis
- //===--------------------------------------------------------------------===//
-
- /// 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);
-
- //===--------------------------------------------------------------------===//
- // 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);
-
- /// 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 pointerTypesAreCompatible(QualType, QualType); // C99 6.7.5.1p2
- bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6
- bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
-
- 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;
- }
-
- //===--------------------------------------------------------------------===//
- // 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);
-};
-
-} // 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 abdcfb4b0504..000000000000
--- a/clang/include/clang/AST/Attr.h
+++ /dev/null
@@ -1,234 +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 "llvm/GlobalValue.h"
-#include <cassert>
-#include <string>
-
-namespace clang {
-
-/// Attr - This represents one attribute.
-class Attr {
-public:
- enum Kind {
- Aligned,
- Packed,
- Annotate,
- NoReturn,
- Deprecated,
- Weak,
- DLLImport,
- DLLExport,
- NoThrow,
- Format,
- Visibility,
- FastCall,
- StdCall,
- TransparentUnion
- };
-
-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 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 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 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 {
- llvm::GlobalValue::VisibilityTypes VisibilityType;
-public:
- VisibilityAttr(llvm::GlobalValue::VisibilityTypes v) : Attr(Visibility),
- VisibilityType(v) {}
-
- llvm::GlobalValue::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; }
-};
-
-} // 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 33380baadb0a..000000000000
--- a/clang/include/clang/AST/Builtins.def
+++ /dev/null
@@ -1,114 +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.
-
-// Standard libc/libm functions:
-BUILTIN(__builtin_inf , "d" , "nc")
-BUILTIN(__builtin_inff , "f" , "nc")
-BUILTIN(__builtin_infl , "Ld" , "nc")
-BUILTIN(__builtin_abs , "ii" , "ncF")
-BUILTIN(__builtin_fabs , "dd" , "ncF")
-BUILTIN(__builtin_fabsf, "ff" , "ncF")
-BUILTIN(__builtin_fabsl, "LdLd", "ncF")
-BUILTIN(__builtin_huge_val, "d", "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)
-
-// 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_memcpy, "v*v*vC*z", "n")
-BUILTIN(__builtin_expect, "iii" , "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 d645de593f46..000000000000
--- a/clang/include/clang/AST/Builtins.h
+++ /dev/null
@@ -1,89 +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_inf).
- bool isLibFunction(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'F') != 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 162240ab1f79..000000000000
--- a/clang/include/clang/AST/CFG.h
+++ /dev/null
@@ -1,407 +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 <list>
-#include <vector>
-#include <iosfwd>
-#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();
- }
-
- 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(std::ostream& OS, const CFG* cfg) const;
- void printTerminator(std::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(std::ostream& OS) const;
- void dump() const;
-
- //===--------------------------------------------------------------------===//
- // Internal: constructors and data.
- //===--------------------------------------------------------------------===//
-
- CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
- BlkExprMap(NULL), BlkEdgeSet(NULL), Allocator(NULL) {};
-
- ~CFG();
-
-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;
-
- /// BlkEdgeSet - An opaque pointer to prevent inclusion of FoldingSet.h.
- /// The set contains std::pair<CFGBlock*,CFGBlock*> objects that have
- /// stable references for use by the 'BlockEdge' class. This set is intended
- /// to be sparse, as it only contains edges whether both the source
- /// and destination block have multiple successors/predecessors.
- void* BlkEdgeSet;
-
- /// Alloc - An internal allocator used for BlkEdgeSet.
- void* Allocator;
-
- friend class BlockEdge;
-
- /// getBlockEdgeImpl - Utility method used by the class BlockEdge. The CFG
- /// stores a set of interned std::pair<CFGBlock*,CFGBlock*> that can
- /// be used by BlockEdge to refer to edges that cannot be represented
- /// by a single pointer.
- const std::pair<CFGBlock*,CFGBlock*>* getBlockEdgeImpl(const CFGBlock* B1,
- const CFGBlock* B2);
-
-};
-} // 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 ea9ab0cc0dac..000000000000
--- a/clang/include/clang/AST/Decl.h
+++ /dev/null
@@ -1,847 +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 interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECL_H
-#define LLVM_CLANG_AST_DECL_H
-
-#include "clang/AST/DeclBase.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);
-};
-
-/// 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);
-
- 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:
- Expr *Init;
- // FIXME: This can be packed into the bitfields in Decl.
- unsigned SClass : 3;
-
- friend class StmtIteratorBase;
-protected:
- VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T,
- StorageClass SC, ScopedDecl *PrevDecl)
- : ValueDecl(DK, DC, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
-public:
- static VarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, StorageClass S, ScopedDecl *PrevDecl);
-
- StorageClass getStorageClass() const { return (StorageClass)SClass; }
-
- const Expr *getInit() const { return Init; }
- Expr *getInit() { return Init; }
- void setInit(Expr *I) { Init = I; }
-
- /// 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()))
- 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);
-};
-
-/// 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.
-
- /// DeclChain - Linked list of declarations that are defined inside this
- /// function.
- ScopedDecl *DeclChain;
-
- // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
- unsigned SClass : 2;
- bool IsInline : 1;
- bool IsImplicit : 1;
-
- /// 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;
-
- FunctionDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S, bool isInline, ScopedDecl *PrevDecl)
- : ValueDecl(Function, DC, L, Id, T, PrevDecl),
- DeclContext(Function),
- ParamInfo(0), Body(0), DeclChain(0), SClass(S),
- IsInline(isInline), IsImplicit(0), PreviousDeclaration(0) {}
-
- virtual ~FunctionDecl();
-public:
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S = None, bool isInline = false,
- ScopedDecl *PrevDecl = 0);
-
- /// 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;
- 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; }
-
- ScopedDecl *getDeclChain() const { return DeclChain; }
- void setDeclChain(ScopedDecl *D) { DeclChain = D; }
-
- /// getPreviousDeclaration - Return the previous declaration of this
- /// function.
- const FunctionDecl *getPreviousDeclaration() const {
- return PreviousDeclaration;
- }
-
- // 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() { 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;
- 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 cast<FunctionType>(getType())->getResultType();
- }
- StorageClass getStorageClass() const { return StorageClass(SClass); }
- bool isInline() const { return IsInline; }
-
- /// AddRedeclaration - Adds the function declaration FD as a
- /// redeclaration of this function.
- void AddRedeclaration(FunctionDecl *FD);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == Function; }
- 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);
- friend void Decl::Destroy(ASTContext& C) const;
-};
-
-
-/// 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; }
- QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
-
- 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 {
- Expr *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(E), Val(V) {}
- ~EnumConstantDecl() {}
-public:
-
- static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *E,
- const llvm::APSInt &V, ScopedDecl *PrevDecl);
-
- const Expr *getInitExpr() const { return Init; }
- Expr *getInitExpr() { return Init; }
- const llvm::APSInt &getInitVal() const { return Val; }
-
- void setInitExpr(Expr *E) { Init = 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);
- friend void Decl::Destroy(ASTContext& C) const;
-};
-
-
-/// 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:
- // 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) {}
- ~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);
- friend void Decl::Destroy(ASTContext& C) const;
-};
-
-
-/// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl : public TypeDecl {
- /// 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;
- }
-
- const char *getKindName() const {
- switch (getKind()) {
- default: assert(0 && "Unknown TagDecl!");
- case Struct: return "struct";
- case Union: return "union";
- case Class: return "class";
- case Enum: return "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 {
- /// ElementList - this is a linked list of EnumConstantDecl's which are linked
- /// together through their getNextDeclarator pointers.
- EnumConstantDecl *ElementList;
-
- /// 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) {
- ElementList = 0;
- IntegerType = QualType();
- }
-public:
- static EnumDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ScopedDecl *PrevDecl);
-
- /// 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!");
- ElementList = 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 ElementList; }
- const EnumConstantDecl *getEnumConstantList() const { return ElementList; }
-
- 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.
-
- RecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- ScopedDecl *PrevDecl) : TagDecl(DK, DC, L, Id, PrevDecl) {
- HasFlexibleArrayMember = false;
- assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
- Members = 0;
- NumMembers = -1;
- }
-public:
-
- static RecordDecl *Create(ASTContext &C, Kind DK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ScopedDecl *PrevDecl);
-
- bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
- void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
-
- /// 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]; }
-
- /// 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(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 f8ef8d41de60..000000000000
--- a/clang/include/clang/AST/DeclBase.h
+++ /dev/null
@@ -1,345 +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 FunctionDecl;
-class ObjCMethodDecl;
-class EnumDecl;
-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.
-
- // Decl
- TranslationUnit,
- // NamedDecl
- Field,
- ObjCIvar,
- ObjCCategory,
- ObjCCategoryImpl,
- ObjCImplementation,
- ObjCProtocol,
- ObjCProperty,
- // ScopedDecl
- Namespace,
- // TypeDecl
- Typedef,
- // TagDecl
- Enum,
- // RecordDecl
- Struct,
- Union,
- Class,
- // ValueDecl
- EnumConstant,
- Function,
- Var,
- ParmVar,
- ObjCInterface,
- ObjCCompatibleAlias,
- ObjCMethod,
- 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 = ObjCIvar,
- ScopedFirst = Namespace, ScopedLast = ParmVar,
- TypeFirst = Typedef, TypeLast = Class,
- TagFirst = Enum , TagLast = Class,
- RecordFirst = Struct , RecordLast = Class,
- ValueFirst = EnumConstant , ValueLast = ParmVar,
- 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:
- 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);
-
- 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 Typedef:
- case Function:
- case Var:
- case ParmVar:
- case EnumConstant:
- case ObjCInterface:
- case ObjCCompatibleAlias:
- return IDNS_Ordinary;
- case Struct:
- case Union:
- case Class:
- case Enum:
- return IDNS_Tag;
- case Namespace:
- return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary);
- }
- }
- // 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.
- void Destroy(ASTContext& C) const;
-
-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
-/// ObjCMethodDecl
-/// EnumDecl
-/// ObjCInterfaceDecl
-///
-class DeclContext {
- /// DeclKind - This indicates which class this is.
- Decl::Kind DeclKind : 8;
-
- // 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::Function:
- return static_cast<FunctionDecl*>(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));
- case Decl::Enum:
- return static_cast<EnumDecl*>(const_cast<From*>(D));
- default:
- assert(false && "a decl that inherits DeclContext isn't handled");
- return 0;
- }
- }
-
-protected:
- DeclContext(Decl::Kind K) : DeclKind(K) {}
-
-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::ObjCMethod:
- return true;
- default:
- return false;
- }
- }
-
- /// 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::Function:
- case Decl::ObjCMethod:
- case Decl::ObjCInterface:
- case Decl::Enum:
- return true;
- default:
- 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 ObjCMethodDecl *D) { return true; }
- static bool classof(const EnumDecl *D) { return true; }
- static bool classof(const ObjCInterfaceDecl *D) { return true; }
-};
-
-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/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
deleted file mode 100644
index 1255c179256f..000000000000
--- a/clang/include/clang/AST/DeclObjC.h
+++ /dev/null
@@ -1,1193 +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;
-
-/// 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.
- AttributeList *MethodAttrs;
-
- 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;
- ParmVarDecl *SelfDecl;
-
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T,
- Decl *contextDecl,
- AttributeList *M = 0, 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),
- MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {}
- ~ObjCMethodDecl();
-public:
-
- static ObjCMethodDecl *Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc, Selector SelInfo,
- QualType T, Decl *contextDecl,
- AttributeList *M = 0, 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; }
-
- 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);
-
- AttributeList *getMethodAttrs() const {return MethodAttrs;}
- 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);
- }
- Stmt *getBody() { return Body; }
- const Stmt *getBody() const { return Body; }
- void setBody(Stmt *B) { Body = B; }
-
- const ParmVarDecl *getSelfDecl() const { return SelfDecl; }
- ParmVarDecl *getSelfDecl() { return SelfDecl; }
- void setSelfDecl(ParmVarDecl *PVD) { SelfDecl = PVD; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
- static bool classof(const ObjCMethodDecl *D) { return true; }
-
- friend void Decl::Destroy(ASTContext& C) const;
-};
-
-/// 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
- ObjCProtocolDecl **ReferencedProtocols; // Null if none
- unsigned NumReferencedProtocols; // 0 if none
-
- /// 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,
- unsigned numRefProtos,
- IdentifierInfo *Id, SourceLocation CLoc,
- bool FD, bool isInternal)
- : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
- TypeForDecl(0), SuperClass(0),
- ReferencedProtocols(0), NumReferencedProtocols(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) {
- AllocIntfRefProtocols(numRefProtos);
- }
-public:
-
- static ObjCInterfaceDecl *Create(ASTContext &C,
- SourceLocation atLoc,
- unsigned numRefProtos,
- IdentifierInfo *Id,
- SourceLocation ClassLoc = SourceLocation(),
- bool ForwardDecl = false,
- bool isInternal = false);
-
- // This is necessary when converting a forward declaration to a definition.
- void AllocIntfRefProtocols(unsigned numRefProtos) {
- if (numRefProtos) {
- ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
- memset(ReferencedProtocols, '\0',
- numRefProtos*sizeof(ObjCProtocolDecl*));
- NumReferencedProtocols = numRefProtos;
- }
- }
-
- ObjCProtocolDecl **getReferencedProtocols() const {
- return ReferencedProtocols;
- }
- unsigned getNumIntfRefProtocols() const { return NumReferencedProtocols; }
-
- ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
- ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
- ObjCIvarDecl *FindIvarDeclaration(IdentifierInfo *IvarId) const;
-
- typedef ObjCProtocolDecl * const * protocol_iterator;
- protocol_iterator protocol_begin() const { return ReferencedProtocols; }
- protocol_iterator protocol_end() const {
- return ReferencedProtocols+NumReferencedProtocols;
- }
-
- 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; }
-
- 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;
- }
-
- 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; }
-
- void setIntfRefProtocols(unsigned idx, ObjCProtocolDecl *OID) {
- assert((idx < NumReferencedProtocols) && "index out of range");
- ReferencedProtocols[idx] = OID;
- }
-
- 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 *&clsDeclared);
-
- // Get the local instance method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(Selector Sel) {
- 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) {
- 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 defaultToPrivate; // same as C++.
-/// @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 {
- ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
- : FieldDecl(ObjCIvar, L, Id, T) {}
-public:
- static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T);
-
- enum AccessControl {
- None, Private, Protected, Public, Package
- };
- void setAccessControl(AccessControl ac) { DeclAccess = ac; }
- AccessControl getAccessControl() const { return 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;
-};
-
-
-/// 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
- ObjCProtocolDecl **ReferencedProtocols; // Null if none
- unsigned NumReferencedProtocols; // 0 if none
-
- /// 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, unsigned numRefProtos, IdentifierInfo *Id)
- : NamedDecl(ObjCProtocol, L, Id),
- ReferencedProtocols(0), NumReferencedProtocols(0),
- InstanceMethods(0), NumInstanceMethods(0),
- ClassMethods(0), NumClassMethods(0),
- PropertyDecl(0), NumPropertyDecl(0),
- isForwardProtoDecl(true) {
- AllocReferencedProtocols(numRefProtos);
- }
-public:
- static ObjCProtocolDecl *Create(ASTContext &C, SourceLocation L,
- unsigned numRefProtos, IdentifierInfo *Id);
-
- void AllocReferencedProtocols(unsigned numRefProtos) {
- if (numRefProtos) {
- ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
- memset(ReferencedProtocols, '\0',
- numRefProtos*sizeof(ObjCProtocolDecl*));
- NumReferencedProtocols = numRefProtos;
- }
- }
- void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
- ObjCMethodDecl **clsMethods, unsigned numClsMembers,
- SourceLocation AtEndLoc);
-
- void setReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
- assert((idx < NumReferencedProtocols) && "index out of range");
- ReferencedProtocols[idx] = OID;
- }
-
- ObjCProtocolDecl** getReferencedProtocols() const {
- return ReferencedProtocols;
- }
- unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
- typedef ObjCProtocolDecl * const * protocol_iterator;
- protocol_iterator protocol_begin() const { return ReferencedProtocols; }
- protocol_iterator protocol_end() const {
- return ReferencedProtocols+NumReferencedProtocols;
- }
-
- unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
- unsigned getNumClassMethods() const { return NumClassMethods; }
-
- unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
-
- ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
- ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
-
- void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
-
- 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) {
- 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) {
- 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;
- }
-public:
- 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; }
-
- 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;
- }
- }
-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];
- }
-
- 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.
- ObjCProtocolDecl **ReferencedProtocols; // Null if none
- unsigned NumReferencedProtocols; // 0 if none
-
- /// 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), ReferencedProtocols(0), NumReferencedProtocols(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; }
-
- void setReferencedProtocolList(ObjCProtocolDecl **List, unsigned NumRPs);
-
- void setCatReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
- assert((idx < NumReferencedProtocols) && "index out of range");
- ReferencedProtocols[idx] = OID;
- }
-
- ObjCProtocolDecl **getReferencedProtocols() const {
- return ReferencedProtocols;
- }
- unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
- 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);
-
- 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) {
- 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) {
- 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);
-
- // Get the class method definition for this implementation.
- ObjCMethodDecl *getClassMethod(Selector Sel);
-
- 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);
-
- // Get the class method definition for this implementation.
- ObjCMethodDecl *getClassMethod(Selector Sel);
-
- 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 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; }
- QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
-
- PropertyAttributeKind getPropertyAttributes() const {
- return PropertyAttributeKind(PropertyAttributes);
- }
- void setPropertyAttributes(PropertyAttributeKind PRVal) {
- PropertyAttributes |= PRVal;
- }
-
- 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 PropertyImplKind {
- OBJC_PR_IMPL_None,
- OBJC_PR_IMPL_SYNTHSIZE,
- OBJC_PR_IMPL_DYNAMIC
- };
-private:
- SourceLocation AtLoc; // location of @synthesize or @dynamic
- /// Property declaration being implemented
- ObjCPropertyDecl *PropertyDecl;
- PropertyImplKind PropertyImplementation;
- /// Null for @dynamic. Required for @synthesize.
- ObjCIvarDecl *PropertyIvarDecl;
-public:
- ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- PropertyImplKind propertyKind,
- ObjCIvarDecl *ivarDecl)
- : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(property),
- PropertyImplementation(propertyKind), PropertyIvarDecl(ivarDecl){}
-
- static ObjCPropertyImplDecl *Create(ASTContext &C, SourceLocation atLoc,
- SourceLocation L,
- ObjCPropertyDecl *property,
- PropertyImplKind propertyKind,
- ObjCIvarDecl *ivarDecl);
-
- void setPropertyDecl(ObjCPropertyDecl *property) { PropertyDecl = property; }
- ObjCPropertyDecl *getPropertyDecl() const { return PropertyDecl; }
-
- void setImplKind (PropertyImplKind propImplKind)
- { PropertyImplementation = propImplKind; }
- PropertyImplKind getPropertyImplementation() const
- { return PropertyImplementation; }
-
- void setPropertyIvarDecl(ObjCIvarDecl *ivarDecl)
- { PropertyIvarDecl = ivarDecl; }
- ObjCIvarDecl *getPropertyIvarDecl() { 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 05238f906234..000000000000
--- a/clang/include/clang/AST/Expr.h
+++ /dev/null
@@ -1,1609 +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 "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/APFloat.h"
-#include <vector>
-
-class llvm::Constant;
-
-namespace clang {
- class IdentifierInfo;
- class Selector;
- class Decl;
- class ASTContext;
-
-/// 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() 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
- };
- isModifiableLvalueResult isModifiableLvalue() const;
-
- bool isNullPointerConstant(ASTContext &Ctx) const;
-
- /// 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(32);
- return isIntegerConstantExpr(X, Ctx, Loc);
- }
- /// isConstantExpr - Return true if this expression is a valid constant expr.
- bool isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) 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));
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Primary Expressions.
-//===----------------------------------------------------------------------===//
-
-/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
-/// enum, etc.
-class DeclRefExpr : public Expr {
- ValueDecl *D;
- SourceLocation Loc;
-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; }
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass;
- }
- 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 pre-defined identifier such as __func__.
-class PreDefinedExpr : public Expr {
-public:
- enum IdentType {
- Func,
- Function,
- PrettyFunction
- };
-
-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;
-public:
- // type should be IntTy
- CharacterLiteral(unsigned value, QualType type, SourceLocation l)
- : Expr(CharacterLiteralClass, type), Value(value), Loc(l) {
- }
- SourceLocation getLoc() const { return Loc; }
-
- 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; }
-
- /// getValueAsDouble - This returns the value as an inaccurate double. Note
- /// that this may cause loss of precision, but is useful for debugging dumps
- /// etc.
- double getValueAsDouble() const {
- // FIXME: We need something for long double here.
- if (cast<BuiltinType>(getType())->getKind() == BuiltinType::Float)
- return Value.convertToFloat();
- else
- return Value.convertToDouble();
- }
-
- 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 {
- Expr *Val;
-public:
- ImaginaryLiteral(Expr *val, QualType Ty)
- : Expr(ImaginaryLiteralClass, Ty), Val(val) {}
-
- const Expr *getSubExpr() const { return Val; }
- Expr *getSubExpr() { return 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;
- Expr *Val;
-public:
- ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
- : Expr(ParenExprClass, val->getType()), L(l), R(r), Val(val) {}
-
- const Expr *getSubExpr() const { return Val; }
- Expr *getSubExpr() { return 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:
- Expr *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 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);
-
- 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) {}
-
- 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 };
- Expr* 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 SubExprs[LHS]; }
- const Expr *getLHS() const { return SubExprs[LHS]; }
-
- Expr *getRHS() { return SubExprs[RHS]; }
- const Expr *getRHS() const { return SubExprs[RHS]; }
-
- Expr *getBase() {
- return (getRHS()->getType()->isIntegerType()) ? getLHS() : getRHS();
- }
-
- const Expr *getBase() const {
- return (getRHS()->getType()->isIntegerType()) ? getLHS() : getRHS();
- }
-
- Expr *getIdx() {
- return (getRHS()->getType()->isIntegerType()) ? getRHS() : getLHS();
- }
-
- const Expr *getIdx() const {
- return (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 };
- Expr **SubExprs;
- unsigned NumArgs;
- SourceLocation RParenLoc;
-
- // This version of the ctor is for deserialization.
- CallExpr(Expr** 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 SubExprs[FN]; }
- Expr *getCallee() { return 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 SubExprs[Arg+ARGS_START];
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return 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 Expr **arg_iterator;
- typedef Expr * const *arg_const_iterator;
- arg_iterator arg_begin() { return SubExprs+ARGS_START; }
- arg_iterator arg_end() { return SubExprs+ARGS_START+getNumArgs(); }
- arg_const_iterator arg_begin() const { return SubExprs+ARGS_START; }
- arg_const_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; }
-
- bool isBuiltinClassifyType(llvm::APSInt &Result) const;
-
- /// isBuiltinConstantExpr - Return true if this built-in call is constant.
- bool isBuiltinConstantExpr() 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 {
- Expr *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 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);
-};
-
-/// 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 {
- Expr *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 Base; }
- Expr *getBase() { return 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).
- llvm::Constant *getEncodedElementAccess() const;
-
- /// 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);
-
- 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();
-};
-
-/// 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;
- Expr *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 Init; }
- Expr *getInitializer() { return 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);
-};
-
-/// 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 Expr {
- Expr *Op;
-public:
- ImplicitCastExpr(QualType ty, Expr *op) :
- Expr(ImplicitCastExprClass, ty), Op(op) {}
-
- Expr *getSubExpr() { return Op; }
- const Expr *getSubExpr() const { return Op; }
-
- virtual SourceRange getSourceRange() const { return Op->getSourceRange(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImplicitCastExprClass;
- }
- static bool classof(const ImplicitCastExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static ImplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
-};
-
-/// CastExpr - [C99 6.5.4] Cast Operators.
-///
-class CastExpr : public Expr {
- Expr *Op;
- SourceLocation Loc; // the location of the left paren
-public:
- CastExpr(QualType ty, Expr *op, SourceLocation l) :
- Expr(CastExprClass, ty), Op(op), Loc(l) {}
-
- SourceLocation getLParenLoc() const { return Loc; }
-
- Expr *getSubExpr() const { return Op; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CastExprClass;
- }
- static bool classof(const CastExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- virtual void EmitImpl(llvm::Serializer& S) const;
- static CastExpr* 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 };
- Expr* 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 SubExprs[LHS]; }
- Expr *getRHS() const { return 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; }
- bool isRelationalOp() const { return Opc >= LT && Opc <= GE; }
- bool isEqualityOp() const { return Opc == EQ || Opc == NE; }
- bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; }
- 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 };
- Expr* 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 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 SubExprs[LHS] ? SubExprs[COND] : SubExprs[LHS];
- }
-
- // 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 SubExprs[RHS]; }
-
- Expr *getLHS() const { return SubExprs[LHS]; }
- Expr *getRHS() const { return 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 {
- CompoundStmt *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 SubStmt; }
- const CompoundStmt *getSubStmt() const { return 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();
-};
-
-/// 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 };
- Expr* 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 SubExprs[COND]; }
- Expr *getLHS() const { return SubExprs[LHS]; }
- Expr *getRHS() const { return 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.
- Expr **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 Expr*[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 Expr * const *arg_const_iterator;
- arg_const_iterator arg_begin() const { return SubExprs+1; }
-
- /// getNumArgs - Return the number of arguments to pass to the candidate
- /// functions.
- unsigned getNumArgs(ASTContext &Ctx) const {
- llvm::APSInt constEval(32);
- (void) SubExprs[0]->isIntegerConstantExpr(constEval, Ctx);
- return constEval.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) {
- assert((Index < NumExprs) && "Arg access out of range!");
- return SubExprs[Index];
- }
-
- /// getFn - Return the matching candidate function for this OverloadExpr.
- Expr *getFn() const { return 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 {
- Expr *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 Val; }
- Expr *getSubExpr() { return 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<Expr *> 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 InitExprs[Init];
- }
-
- Expr* getInit(unsigned Init) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return 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()) {}
-};
-
-/// 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;
- Expr *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 SourceRange(Loc); }
- const Expr *getBase() const { return Base; }
- Expr *getBase() { return 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);
-};
-
-class ObjCMessageExpr : public Expr {
- enum { RECEIVER=0, ARGS_START=1 };
-
- Expr **SubExprs;
-
- 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;
-
- // constructor used during deserialization
- ObjCMessageExpr(Selector selInfo, QualType retType,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType), NumArgs(nargs), SelName(selInfo),
- MethodProto(NULL), LBracloc(LBrac), RBracloc(RBrac) {}
-
-public:
- // constructor for class messages.
- // FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(IdentifierInfo *clsName, 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 instance methods. For
- /// instance methods, use getClassName.
- Expr *getReceiver() {
- uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- return x & 0x1 ? NULL : (Expr*) x;
- }
- 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; }
-
- /// getClassName - For instance methods, this returns the invoked class,
- /// and returns NULL otherwise. For regular methods, use getReceiver.
- IdentifierInfo *getClassName() {
- uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- return x & 0x1 ? (IdentifierInfo*) (x & ~0x1) : NULL;
- }
- const IdentifierInfo *getClassName() const {
- return const_cast<ObjCMessageExpr*>(this)->getClassName();
- }
-
- /// 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 SubExprs[Arg+ARGS_START];
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return 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 Expr** arg_iterator;
- typedef const Expr* const* const_arg_iterator;
-
- arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
- arg_iterator arg_end() { return arg_begin() + NumArgs; }
- const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
- const_arg_iterator arg_end() const { return arg_begin() + 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/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
deleted file mode 100644
index 98bfbe945bb4..000000000000
--- a/clang/include/clang/AST/ExprCXX.h
+++ /dev/null
@@ -1,173 +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"
-
-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;
- Expr *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 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 {
- Expr *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 Op; }
- Expr *getSubExpr() { return 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);
- };
-} // 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/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h
deleted file mode 100644
index 9de8331e7fc4..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 <iosfwd>
-
-namespace clang {
-
-class Stmt;
-
-class PrinterHelper {
-public:
- virtual ~PrinterHelper();
- virtual bool handledStmt(Stmt* E, std::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 10c10c9a2c29..000000000000
--- a/clang/include/clang/AST/RecordLayout.h
+++ /dev/null
@@ -1,57 +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. These objects are managed by ASTContext.
-class ASTRecordLayout {
- uint64_t Size; // Size of record in bits.
- unsigned Alignment; // Alignment of record in bits.
- uint64_t *FieldOffsets;
- friend class ASTContext;
-
- ASTRecordLayout() {}
- ~ASTRecordLayout() {
- delete [] FieldOffsets;
- }
-
- void SetLayout(uint64_t size, unsigned alignment, uint64_t *fieldOffsets) {
- Size = size; Alignment = alignment;
- FieldOffsets = fieldOffsets;
- }
-
- 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 {
- 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 5875d008b37d..000000000000
--- a/clang/include/clang/AST/Stmt.h
+++ /dev/null
@@ -1,1070 +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 "clang/Basic/SourceLocation.h"
-#include "clang/AST/StmtIterator.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator"
-#include "llvm/Bitcode/SerializationFwd.h"
-#include <iosfwd>
-#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;
-public:
- Stmt(StmtClass SC) : sClass(SC) {
- if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
- }
- virtual ~Stmt() {}
-
- 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(std::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 {
- ScopedDecl *TheDecl;
- SourceLocation StartLoc, EndLoc;
-public:
- DeclStmt(ScopedDecl *D, SourceLocation startLoc, SourceLocation endLoc)
- : Stmt(DeclStmtClass), TheDecl(D), StartLoc(startLoc), EndLoc(endLoc) {}
-
- const ScopedDecl *getDecl() const { return TheDecl; }
- ScopedDecl *getDecl() { 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
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
- 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 {
- Expr *Target;
- // FIXME: Add location information (e.g. SourceLocation objects).
- // When doing so, update the serialization routines.
-public:
- IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
-
- Expr *getTarget() { return Target; }
- const Expr *getTarget() const { return Target; }
-
- 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 {
- Expr *RetExpr;
- SourceLocation RetLoc;
-public:
- ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
- RetExpr(E), RetLoc(RL) {}
-
- const Expr *getRetValue() const { return RetExpr; }
- Expr *getRetValue() { return RetExpr; }
-
- 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 d40e61e53a3f..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"
-#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 0df573b57bdb..000000000000
--- a/clang/include/clang/AST/StmtNodes.def
+++ /dev/null
@@ -1,113 +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 , Expr)
-STMT(50, CompoundLiteralExpr , Expr)
-STMT(51, ExtVectorElementExpr , Expr)
-STMT(52, InitListExpr , Expr)
-STMT(53, 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)
-
-// 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)
-
-// Clang Extensions.
-STMT(76, OverloadExpr , Expr)
-
-LAST_EXPR(76)
-
-#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 86b566b9a35e..000000000000
--- a/clang/include/clang/AST/StmtVisitor.h
+++ /dev/null
@@ -1,173 +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"
-
-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 d0f78444c383..000000000000
--- a/clang/include/clang/AST/TargetBuiltins.h
+++ /dev/null
@@ -1,37 +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"
-
-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 6aa3a40b87cb..000000000000
--- a/clang/include/clang/AST/TranslationUnit.h
+++ /dev/null
@@ -1,92 +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/Basic/LangOptions.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 {
- LangOptions LangOpts;
- ASTContext* Context;
- std::vector<Decl*> TopLevelDecls;
- bool OwnsMetaData;
-
- // The default ctor is only invoked during deserialization.
- explicit TranslationUnit() : Context(NULL), OwnsMetaData(true) {}
-
-public:
- explicit TranslationUnit(ASTContext& Ctx, const LangOptions& lopt)
- : LangOpts(lopt), Context(&Ctx), OwnsMetaData(false) {}
-
- ~TranslationUnit();
-
- const LangOptions& getLangOpts() const { return LangOpts; }
- 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 LangOpts; }
-
- 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);
-
-/// ReadASTBitcodeFile - Reconsitute a translation unit from a bitcode file.
-TranslationUnit* ReadASTBitcodeFile(const llvm::sys::Path& Filename,
- 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 8781ff309e2c..000000000000
--- a/clang/include/clang/AST/Type.h
+++ /dev/null
@@ -1,1262 +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 EnumDecl;
- class FieldDecl;
- class ObjCInterfaceDecl;
- class ObjCProtocolDecl;
- class ObjCMethodDecl;
- class Expr;
- class SourceLocation;
- class PointerLikeType;
- class PointerType;
- class ReferenceType;
- class VectorType;
- class ArrayType;
- class ConstantArrayType;
- class VariableArrayType;
- class IncompleteArrayType;
- class RecordType;
- class ComplexType;
- class TagType;
- class FunctionType;
- 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;
- }
-
- 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;
- }
-
- /// addConst/addVolatile/addRestrict - add the specified type qual to this
- /// QualType.
- void addConst() { ThePtr |= Const; }
- void addVolatile() { ThePtr |= Volatile; }
- void addRestrict() { ThePtr |= Restrict; }
-
- QualType getQualifiedType(unsigned TQs) const {
- return QualType(getTypePtr(), TQs);
- }
-
- 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 = 0) const;
-
-//private:
- /// getCanonicalType - Return the canonical version of this type, with the
- /// appropriate type qualifiers on it.
- inline QualType getCanonicalType() const;
-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);
-
-private:
- void ReadBackpatch(llvm::Deserializer& D);
- friend class FieldDecl;
-};
-
-} // 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.
- };
-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();
- 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;
-
- /// isIncompleteArrayType (C99 6.2.5p22) - Return true for variable array
- /// types that don't have any expression ("[]").
- bool isIncompleteArrayType() 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 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 isReferenceType() const;
- bool isFunctionPointerType() const;
- bool isArrayType() 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 PointerLikeType *getAsPointerLikeType() const; // Pointer or Reference.
- const PointerType *getAsPointerType() const;
- const ReferenceType *getAsReferenceType() const;
- const ArrayType *getAsArrayType() const;
- const ConstantArrayType *getAsConstantArrayType() const;
- const VariableArrayType *getAsVariableArrayType() const;
- const IncompleteArrayType *getAsIncompleteArrayType() const;
- const RecordType *getAsRecordType() const;
- const RecordType *getAsStructureType() const;
- const RecordType *getAsUnionType() 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;
-
-
- /// 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 returns "T*" as "T*", (not as "int*"), because the pointer is
- /// concrete.
- const Type *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;
-private:
- QualType getCanonicalTypeInternal() const { return CanonicalType; }
- friend class QualType;
-public:
- 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.
- 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.
-///
-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;
-};
-
-/// 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; }
-
- QualType getBaseType() const {
- const ArrayType *AT;
- QualType ElmtType = getElementType();
- // If we have a multi-dimensional array, navigate to the base type.
- while ((AT = ElmtType->getAsArrayType()))
- ElmtType = AT->getElementType();
- return ElmtType;
- }
- 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:
- llvm::APInt getSize() const { return Size; }
- int getMaximumElements() const {
- QualType ElmtType = getElementType();
- int maxElements = static_cast<int>(getSize().getZExtValue());
-
- const ConstantArrayType *CAT;
- // If we have a multi-dimensional array, include it's elements.
- while ((CAT = ElmtType->getAsConstantArrayType())) {
- ElmtType = CAT->getElementType();
- maxElements *= static_cast<int>(CAT->getSize().getZExtValue());
- }
- return maxElements;
- }
- 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.
- Expr *SizeExpr;
-
- VariableArrayType(QualType et, QualType can, Expr *e,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(VariableArray, et, can, sm, tq), SizeExpr(e) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- const Expr *getSizeExpr() const { return SizeExpr; }
- Expr *getSizeExpr() { return 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, 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.
-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;
-
-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 {
- 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; }
-};
-
-/// 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; }
-};
-
-
-
-
-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; }
-
- 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*, 8> Protocols;
-
- ObjCQualifiedInterfaceType(ObjCInterfaceDecl *D,
- ObjCProtocolDecl **Protos, unsigned NumP) :
- ObjCInterfaceType(ObjCQualifiedInterface, D),
- 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();
- }
-
- 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,
- const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCQualifiedInterface;
- }
- static bool classof(const ObjCQualifiedInterfaceType *) { return true; }
-};
-
-/// 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(QualType can, ObjCProtocolDecl **Protos, unsigned NumP)
- : Type(ObjCQualifiedId, can),
- 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.
-
-/// getCanonicalType - Return the canonical version of this type, with the
-/// appropriate type qualifiers on it.
-inline QualType QualType::getCanonicalType() const {
- QualType CanType = getTypePtr()->getCanonicalTypeInternal();
- return QualType(CanType.getTypePtr(),
- getCVRQualifiers() | CanType.getCVRQualifiers());
-}
-
-/// 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 {
- if (const ArrayType *AT = dyn_cast<ArrayType>(getCanonicalType()))
- return AT->getBaseType().getAddressSpace();
- if (const RecordType *RT = dyn_cast<RecordType>(getCanonicalType()))
- return RT->getAddressSpace();
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(getCanonicalType()))
- return ASQT->getAddressSpace();
- return 0;
-}
-
-inline bool Type::isFunctionType() const {
- return isa<FunctionType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType.getUnqualifiedType());
-}
-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::isRecordType() const {
- return isa<RecordType>(CanonicalType.getUnqualifiedType());
-}
-inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType);
-}
-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);
-}
-inline bool Type::isObjCQualifiedInterfaceType() const {
- return isa<ObjCQualifiedInterfaceType>(CanonicalType);
-}
-inline bool Type::isObjCQualifiedIdType() const {
- return isa<ObjCQualifiedIdType>(CanonicalType);
-}
-} // 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 90dcac5a3ff3..000000000000
--- a/clang/include/clang/AST/X86Builtins.def
+++ /dev/null
@@ -1,422 +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.
-
-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, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpltps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpleps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpgtps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpgeps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpunordps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpneqps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnltps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnleps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngtps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngeps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpordps, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpeqss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpltss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpless, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpunordss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpneqss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnltss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpnless, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngtss, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpngess, "V4fV4fV4f", "")
-BUILTIN(__builtin_ia32_cmpordss, "V4fV4fV4f", "")
-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, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmplepd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpgtpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpgepd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpunordpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpneqpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnltpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnlepd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpngtpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpngepd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpordpd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpeqsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpltsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmplesd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpunordsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "")
-BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "")
-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", "")
-BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "")
-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, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfcmpge, "V2fV2fV2f", "")
-BUILTIN(__builtin_ia32_pfcmpgt, "V2fV2fV2f", "")
-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, "V2dd*C", "")
-BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "")
-BUILTIN(__builtin_ia32_loadhpd, "V2dV2dd*C", "")
-BUILTIN(__builtin_ia32_loadlpd, "V2dV2dd*C", "")
-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, "vv*C", "")
-BUILTIN(__builtin_ia32_lfence, "v", "")
-BUILTIN(__builtin_ia32_mfence, "v", "")
-BUILTIN(__builtin_ia32_loaddqu, "V16cc*C", "")
-BUILTIN(__builtin_ia32_storedqu, "vc*CV16c", "")
-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, "V2LLiV2LLii", "")
-BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLii", "")
-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, "v", "")
-BUILTIN(__builtin_ia32_vec_ext_v4hi, "v", "")
-BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "")
-BUILTIN(__builtin_ia32_vec_set_v8hi, "v", "")
-BUILTIN(__builtin_ia32_vec_set_v4hi, "v", "")
-
-// Apple local SSE builtins? These are probably not needed eventually, but are
-// in the apple-gcc xmmintrin.h file (rdar://4099020).
-BUILTIN(__builtin_ia32_movqv4si, "V4iV4i", "")
-BUILTIN(__builtin_ia32_loadlv4si, "V4iV2i*", "")
-BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
-
-
-#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 b7cb1f8a0628..000000000000
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ /dev/null
@@ -1,316 +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(CFG& cfg, const CFGBlock* B, const CFGBlock* Prev) {
- return BlockEdge(cfg,Prev,B);
- }
-
- static BlockEdge NextEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Next) {
- return BlockEdge(cfg,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(CFG& cfg, const CFGBlock* B, const CFGBlock* Prev) {
- return BlockEdge(cfg,B,Prev);
- }
-
- static BlockEdge NextEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Next) {
- return BlockEdge(cfg,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) {
- EnqueueFirstBlock(cfg,AnalysisDirTag());
-
- while (!WorkList.isEmpty()) {
- const CFGBlock* B = WorkList.dequeue();
- ProcessMerge(cfg,B);
- ProcessBlock(B, recordStmtValues, AnalysisDirTag());
- UpdateEdges(cfg,B,TF.getVal());
- }
- }
-
- void EnqueueFirstBlock(const CFG& cfg, dataflow::forward_analysis_tag) {
- WorkList.enqueue(&cfg.getEntry());
- }
-
- void EnqueueFirstBlock(const CFG& cfg, dataflow::backward_analysis_tag) {
- WorkList.enqueue(&cfg.getExit());
- }
-
- 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(cfg,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(cfg,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 530bf90e7e4e..000000000000
--- a/clang/include/clang/Analysis/LocalCheckers.h
+++ /dev/null
@@ -1,42 +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;
-
-void CheckDeadStores(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags);
-
-void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
- bool FullUninitTaint=false);
-
-GRTransferFuncs* MakeGRSimpleValsTF();
-GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
- bool StandardWarnings,
- const LangOptions& lopts);
-BugType* MakeDeadStoresChecker();
-
-} // 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 89ca18c61ead..000000000000
--- a/clang/include/clang/Analysis/PathDiagnostic.h
+++ /dev/null
@@ -1,207 +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));
- }
-
- const SourceRange* ranges_begin() const {
- return ranges.empty() ? NULL : &ranges[0];
- }
-
- const SourceRange* 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::vector<std::string> OtherDesc;
-
-public:
- PathDiagnostic() : Size(0) {}
-
- PathDiagnostic(const char* desc) : Size(0), Desc(desc) {}
-
- PathDiagnostic(const std::string& desc) : Size(0), Desc(desc) {}
-
- ~PathDiagnostic();
-
- const std::string& getDescription() const { return Desc; }
-
- 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/AnnotatedPath.h b/clang/include/clang/Analysis/PathSensitive/AnnotatedPath.h
deleted file mode 100644
index 3873bd45d290..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/AnnotatedPath.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//=-- AnnotatedPath.h - An annotated list 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 AnnotatedPath, which represents a collection of
-// annotated ExplodedNodes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANNOTPATH
-#define LLVM_CLANG_ANALYSIS_ANNOTPATH
-
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include <string>
-#include <list>
-
-namespace clang {
-
- class Expr;
-
-template <typename STATE>
-class AnnotatedNode {
- ExplodedNode<STATE> *Node;
- std::string annotation;
- Expr* E;
-
-public:
- AnnotatedNode(ExplodedNode<STATE>* N, const std::string& annot,
- Expr* e = NULL)
- : Node(N), annotation(annot), E(e) {}
-
- ExplodedNode<STATE>* getNode() const { return Node; }
-
- const std::string& getString() const { return annotation; }
-
- Expr* getExpr() const { return E; }
-};
-
-
-template <typename STATE>
-class AnnotatedPath {
- typedef std::list<AnnotatedNode<STATE> > impl;
- impl path;
-public:
- AnnotatedPath() {}
-
- void push_back(ExplodedNode<STATE>* N, const std::string& s, Expr* E = NULL) {
- path.push_back(AnnotatedNode<STATE>(N, s, E));
- }
-
- typedef typename impl::iterator iterator;
-
- iterator begin() { return path.begin(); }
- iterator end() { return path.end(); }
-
- AnnotatedNode<STATE>& back() { return path.back(); }
- const AnnotatedNode<STATE>& back() const { return path.back(); }
-};
-
-} // 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 c3729ed53e2a..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h
+++ /dev/null
@@ -1,84 +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);
-};
-
-} // 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 7aefb1c57c32..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h
+++ /dev/null
@@ -1,161 +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 ValueState.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
-#define LLVM_CLANG_ANALYSIS_BUGREPORTER
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Analysis/PathSensitive/ValueState.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include <vector>
-
-namespace clang {
-
-class PathDiagnostic;
-class PathDiagnosticPiece;
-class PathDiagnosticClient;
-class ASTContext;
-class Diagnostic;
-class BugReporter;
-class GRExprEngine;
-class ValueState;
-class Stmt;
-class BugReport;
-
-class BugType {
-public:
- BugType() {}
- virtual ~BugType();
-
- virtual const char* getName() const = 0;
- virtual const char* getDescription() const { return getName(); }
-
- 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<ValueState>*>& Nodes) {}
-
- virtual bool isCached(BugReport& R) = 0;
-};
-
-class BugTypeCacheLocation : public BugType {
- llvm::SmallPtrSet<void*,10> CachedErrors;
-public:
- BugTypeCacheLocation() {}
- virtual ~BugTypeCacheLocation() {}
- virtual bool isCached(BugReport& R);
-};
-
-
-class BugReport {
- BugType& Desc;
- ExplodedNode<ValueState> *EndNode;
- SourceRange R;
-public:
- BugReport(BugType& D, ExplodedNode<ValueState> *n) : Desc(D), EndNode(n) {}
- virtual ~BugReport();
-
- const BugType& getBugType() const { return Desc; }
- BugType& getBugType() { return Desc; }
-
- ExplodedNode<ValueState>* 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 std::pair<const char**,const char**> getExtraDescriptiveText() {
- return getBugType().getExtraDescriptiveText();
- }
-
- virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
- ExplodedNode<ValueState>* N);
-
- virtual FullSourceLoc getLocation(SourceManager& Mgr);
-
- virtual void getRanges(BugReporter& BR,const SourceRange*& beg,
- const SourceRange*& end);
-
- virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
- ExplodedNode<ValueState>* PrevN,
- ExplodedGraph<ValueState>& G,
- BugReporter& BR);
-};
-
-class RangedBugReport : public BugReport {
- std::vector<SourceRange> Ranges;
-public:
- RangedBugReport(BugType& D, ExplodedNode<ValueState> *n)
- : BugReport(D, n) {}
-
- virtual ~RangedBugReport();
-
- 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 BugReporter {
- Diagnostic& Diag;
- PathDiagnosticClient* PD;
- ASTContext& Ctx;
- GRExprEngine& Eng;
-
-public:
- BugReporter(Diagnostic& diag, PathDiagnosticClient* pd,
- ASTContext& ctx, GRExprEngine& eng)
- : Diag(diag), PD(pd), Ctx(ctx), Eng(eng) {}
-
- ~BugReporter();
-
- Diagnostic& getDiagnostic() { return Diag; }
-
- PathDiagnosticClient* getDiagnosticClient() { return PD; }
-
- ASTContext& getContext() { return Ctx; }
-
- SourceManager& getSourceManager() { return Ctx.getSourceManager(); }
-
- ExplodedGraph<ValueState>& getGraph();
-
- GRExprEngine& getEngine() { return Eng; }
-
- CFG& getCFG() { return getGraph().getCFG(); }
-
- void EmitWarning(BugReport& R);
-
- void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
-};
-
-} // 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 39a064d4c609..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h
+++ /dev/null
@@ -1,516 +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. Normally this value
- /// is immutable, but we anticipate there will be times when algorithms
- /// that directly manipulate the analysis graph will need to change it.
- 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, 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) {
- assert (!V->isSink());
- Preds.addNode(V);
- V->Succs.addNode(this);
- }
-
-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(); }
-};
-
-
-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, StateTy* St)
- : ExplodedNodeImpl(loc, St) {}
-
- /// getState - Returns the state associated with the node.
- inline StateTy* getState() const {
- return static_cast<StateTy*>(State);
- }
-
- // Profiling (for FoldingSet).
-
- static inline void Profile(llvm::FoldingSetNodeID& ID,
- const ProgramPoint& Loc,
- 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, 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,
- void* State, bool* IsNew) {
-
- return getNode(L, static_cast<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, 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 29fb3bc18624..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRAuditor.h
+++ /dev/null
@@ -1,38 +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;
-
- virtual ~GRAuditor() {}
- virtual bool Audit(NodeTy* N) = 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 aa8ca231b0f3..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ /dev/null
@@ -1,634 +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;
-
- typedef llvm::DenseMap<Stmt*,Stmt*> ParentMapTy;
-
- /// G - The simulation graph. Each node is a (location,state) pair.
- llvm::OwningPtr<ExplodedGraphImpl> G;
-
- /// ParentMap - A lazily populated map from a Stmt* to its parent Stmt*.
- void* ParentMap;
-
- /// CurrentBlkExpr - The current Block-level expression being processed.
- /// This is used when lazily populating ParentMap.
- Stmt* CurrentBlkExpr;
-
- /// 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, void* State,
- ExplodedNodeImpl* Pred = NULL);
-
- /// 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 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, 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, void* State,
- ExplodedNodeImpl* Pred,
- bool isLoad = false);
-
- inline ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State,
- bool isLoad = false) {
- ExplodedNodeImpl* N = getLastNode();
- assert (N && "Predecessor of new node is infeasible.");
- return generateNodeImpl(S, State, N, isLoad);
- }
-
- Stmt* getStmt() const { return B[Idx]; }
-
- CFGBlock* getBlock() const { return &B; }
-};
-
-
-template<typename STATE>
-class GRStmtNodeBuilder {
- typedef STATE StateTy;
- typedef ExplodedNode<StateTy> NodeTy;
-
- GRStmtNodeBuilderImpl& NB;
- StateTy* CleanedState;
-
- GRAuditor<StateTy> **CallExprAuditBeg, **CallExprAuditEnd;
- GRAuditor<StateTy> **ObjCMsgExprAuditBeg, **ObjCMsgExprAuditEnd;
-
-public:
- GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb),
- CallExprAuditBeg(0), CallExprAuditEnd(0),
- ObjCMsgExprAuditBeg(0), ObjCMsgExprAuditEnd(0),
- BuildSinks(false), HasGeneratedNode(false) {
-
- CleanedState = getLastNode()->getState();
- }
-
- void setObjCMsgExprAuditors(GRAuditor<StateTy> **B,
- GRAuditor<StateTy> **E) {
- ObjCMsgExprAuditBeg = B;
- ObjCMsgExprAuditEnd = E;
- }
-
- void setCallExprAuditors(GRAuditor<StateTy> **B,
- GRAuditor<StateTy> **E) {
- CallExprAuditBeg = B;
- CallExprAuditEnd = E;
- }
-
- NodeTy* getLastNode() const {
- return static_cast<NodeTy*>(NB.getLastNode());
- }
-
- NodeTy* generateNode(Stmt* S, StateTy* St, NodeTy* Pred, bool isLoad = false){
- HasGeneratedNode = true;
- return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, Pred, isLoad));
- }
-
- NodeTy* generateNode(Stmt* S, StateTy* St, bool isLoad = false) {
- HasGeneratedNode = true;
- return static_cast<NodeTy*>(NB.generateNodeImpl(S, St, isLoad));
- }
-
- GRBlockCounter getBlockCounter() const {
- return NB.getBlockCounter();
- }
-
- unsigned getCurrentBlockCount() const {
- return NB.getCurrentBlockCount();
- }
-
- StateTy* GetState(NodeTy* Pred) const {
- if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
- return CleanedState;
- else
- return Pred->getState();
- }
-
- void SetCleanedState(StateTy* St) {
- CleanedState = St;
- }
-
- NodeTy* MakeNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
- NodeTy* Pred, StateTy* St) {
-
- StateTy* PredState = GetState(Pred);
-
- GRAuditor<StateTy> **AB = NULL, **AE = NULL;
-
- switch (S->getStmtClass()) {
- default: break;
- case Stmt::CallExprClass:
- AB = CallExprAuditBeg;
- AE = CallExprAuditEnd;
- break;
- case Stmt::ObjCMessageExprClass:
- AB = ObjCMsgExprAuditBeg;
- AE = ObjCMsgExprAuditEnd;
- break;
- }
-
- // If the state hasn't changed, don't generate a new node.
- if (!BuildSinks && St == PredState && AB == NULL) {
- Dst.Add(Pred);
- return NULL;
- }
-
- NodeTy* N = generateNode(S, St, Pred);
-
- if (N) {
- if (BuildSinks)
- N->markAsSink();
- else {
- for ( ; AB != AE; ++AB)
- if ((*AB)->Audit(N))
- N->markAsSink();
-
- Dst.Add(N);
- }
- }
-
- return N;
- }
-
- bool BuildSinks;
- bool HasGeneratedNode;
-};
-
-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(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());
- }
-
- StateTy* getState() const {
- return getPredecessor()->getState();
- }
-
- inline NodeTy* generateNode(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);
- }
-
- inline 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, void* State,
- bool isSink);
-
- inline Expr* getTarget() const { return E; }
- inline 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;
-
- inline iterator begin() { return NB.begin(); }
- inline iterator end() { return NB.end(); }
-
- inline Expr* getTarget() const { return NB.getTarget(); }
-
- inline NodeTy* generateNode(const iterator& I, StateTy* St, bool isSink=false){
- return static_cast<NodeTy*>(NB.generateNodeImpl(I, St, isSink));
- }
-
- inline StateTy* getState() const {
- return static_cast<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, void* State);
- ExplodedNodeImpl* generateDefaultCaseNodeImpl(void* State, bool isSink);
-
- inline Expr* getCondition() const { return Condition; }
- inline 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;
-
- inline iterator begin() { return NB.begin(); }
- inline iterator end() { return NB.end(); }
-
- inline Expr* getCondition() const { return NB.getCondition(); }
-
- inline NodeTy* generateCaseStmtNode(const iterator& I, StateTy* St) {
- return static_cast<NodeTy*>(NB.generateCaseStmtNodeImpl(I, St));
- }
-
- inline NodeTy* generateDefaultCaseNode(StateTy* St, bool isSink = false) {
- return static_cast<NodeTy*>(NB.generateDefaultCaseNodeImpl(St, isSink));
- }
-
- inline StateTy* getState() const {
- return static_cast<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(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();
- }
-
- StateTy* getState() const {
- return getPredecessor()->getState();
- }
-
- NodeTy* MakeNode(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 ExplodedGraph<StateTy> GraphTy;
- typedef typename GraphTy::NodeTy NodeTy;
-
-protected:
- SubEngineTy& SubEngine;
-
- virtual 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.ProcessStmt(S, Builder);
- }
-
- virtual bool ProcessBlockEntrance(CFGBlock* Blk, void* State,
- GRBlockCounter BC) {
- return SubEngine.ProcessBlockEntrance(Blk, static_cast<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 fb8af773c1bf..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ /dev/null
@@ -1,654 +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/ValueState.h"
-#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/AST/Type.h"
-
-namespace clang {
-
- class BugType;
- class PathDiagnosticClient;
- class Diagnostic;
-
-class GRExprEngine {
-
-public:
- typedef ValueState 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 ValueStateManager::RemoveDeadBindings.
- ValueStateManager::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.
- ValueStateManager StateMgr;
-
- /// ValueMgr - Object that manages the data for all created RVals.
- BasicValueFactory& BasicVals;
-
- /// TF - Object that represents a bundle of transfer functions
- /// for manipulating and creating RVals.
- GRTransferFuncs* TF;
-
- /// 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).
- ValueState* CleanedState;
-
- /// CurrentStmt - The current block-level statement.
- Stmt* CurrentStmt;
-
- // Obj-C Class Identifiers.
- IdentifierInfo* NSExceptionII;
-
- // Obj-C Selectors.
- Selector* NSExceptionInstanceRaiseSelectors;
- Selector RaiseSel;
-
- typedef llvm::SmallVector<GRSimpleAPICheck*,2> SimpleChecksTy;
-
- SimpleChecksTy CallChecks;
- SimpleChecksTy MsgExprChecks;
-
-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);
- ~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(); }
-
- /// 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.
- ValueState* 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(); }
-
- void Register(BugType* B) {
- BugTypes.push_back(B);
- }
-
- void EmitWarnings(Diagnostic& Diag, PathDiagnosticClient* PD);
-
- 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(); }
-
- 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();
- }
-
- typedef SimpleChecksTy::iterator simple_checks_iterator;
-
- simple_checks_iterator call_auditors_begin() { return CallChecks.begin(); }
- simple_checks_iterator call_auditors_end() { return CallChecks.end(); }
-
- simple_checks_iterator msgexpr_auditors_begin() {
- return MsgExprChecks.begin();
- }
- simple_checks_iterator msgexpr_auditors_end() {
- return MsgExprChecks.end();
- }
-
- void AddCallCheck(GRSimpleAPICheck* A);
-
- void AddObjCMessageExprCheck(GRSimpleAPICheck* A);
-
- /// 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, ValueState* 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) {
- TF->EvalEndPath(*this, builder);
- }
-
- ValueStateManager& getStateManager() { return StateMgr; }
- const ValueStateManager& getStateManger() const { return StateMgr; }
-
- BasicValueFactory& getBasicVals() { return BasicVals; }
- const BasicValueFactory& getBasicVals() const { return BasicVals; }
-
- SymbolManager& getSymbolManager() { return SymMgr; }
- const SymbolManager& getSymbolManager() const { return SymMgr; }
-
-protected:
-
- ValueState* GetState(NodeTy* N) {
- return N == EntryNode ? CleanedState : N->getState();
- }
-
-public:
-
- // FIXME: Maybe make these accesible only within the StmtBuilder?
-
- ValueState* SetRVal(ValueState* St, Expr* Ex, RVal V);
-
- ValueState* SetRVal(ValueState* St, const Expr* Ex, RVal V) {
- return SetRVal(St, const_cast<Expr*>(Ex), V);
- }
-
-protected:
-
- ValueState* SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V) {
- return StateMgr.SetRVal(St, Ex, V, true, false);
- }
-
- ValueState* SetRVal(ValueState* St, LVal LV, RVal V) {
- return StateMgr.SetRVal(St, LV, V);
- }
-
- RVal GetRVal(ValueState* St, Expr* Ex) {
- return StateMgr.GetRVal(St, Ex);
- }
-
- RVal GetRVal(ValueState* St, const Expr* Ex) {
- return GetRVal(St, const_cast<Expr*>(Ex));
- }
-
- RVal GetBlkExprRVal(ValueState* St, Expr* Ex) {
- return StateMgr.GetBlkExprRVal(St, Ex);
- }
-
- RVal GetRVal(ValueState* St, LVal LV, QualType T = QualType()) {
- return StateMgr.GetRVal(St, LV, T);
- }
-
- inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
- return NonLVal::MakeVal(BasicVals, X, Ex->getType());
- }
-
- /// Assume - Create new state by assuming that a given expression
- /// is true or false.
- ValueState* Assume(ValueState* St, RVal Cond, bool Assumption,
- bool& isFeasible) {
-
- if (Cond.isUnknown()) {
- isFeasible = true;
- return St;
- }
-
- if (isa<LVal>(Cond))
- return Assume(St, cast<LVal>(Cond), Assumption, isFeasible);
- else
- return Assume(St, cast<NonLVal>(Cond), Assumption, isFeasible);
- }
-
- ValueState* Assume(ValueState* St, LVal Cond, bool Assumption,
- bool& isFeasible);
-
- ValueState* AssumeAux(ValueState* St, LVal Cond, bool Assumption,
- bool& isFeasible);
-
- ValueState* Assume(ValueState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible);
-
- ValueState* AssumeAux(ValueState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible);
-
- ValueState* AssumeSymNE(ValueState* St, SymbolID sym, const llvm::APSInt& V,
- bool& isFeasible);
-
- ValueState* AssumeSymEQ(ValueState* St, SymbolID sym, const llvm::APSInt& V,
- bool& isFeasible);
-
- ValueState* AssumeSymInt(ValueState* St, bool Assumption,
- const SymIntConstraint& C, bool& isFeasible);
-
- NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, ValueState* St) {
- assert (Builder && "GRStmtNodeBuilder not present.");
- return Builder->MakeNode(Dst, S, Pred, St);
- }
-
- /// 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);
-
- void VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
- 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, ValueState* St, NodeTy* Pred, RVal Denom);
-
- RVal EvalCast(RVal X, QualType CastT) {
- if (X.isUnknownOrUndef())
- return X;
-
- if (isa<LVal>(X))
- return TF->EvalCast(*this, cast<LVal>(X), CastT);
- else
- return TF->EvalCast(*this, cast<NonLVal>(X), CastT);
- }
-
- RVal EvalMinus(UnaryOperator* U, RVal X) {
- return X.isValid() ? TF->EvalMinus(*this, U, cast<NonLVal>(X)) : X;
- }
-
- RVal EvalComplement(RVal X) {
- return X.isValid() ? TF->EvalComplement(*this, cast<NonLVal>(X)) : X;
- }
-
- RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, RVal R) {
- return R.isValid() ? TF->EvalBinOp(*this, Op, L, cast<NonLVal>(R)) : R;
- }
-
- RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, NonLVal R) {
- return R.isValid() ? TF->EvalBinOp(*this, Op, L, R) : 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 TF->EvalBinOp(*this, Op, cast<LVal>(L), cast<LVal>(R));
- else
- return TF->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 TF->EvalBinOp(*this, Op, cast<LVal>(R), cast<NonLVal>(L));
- }
- else
- return TF->EvalBinOp(*this, Op, cast<NonLVal>(L), cast<NonLVal>(R));
- }
-
- void EvalCall(NodeSet& Dst, CallExpr* CE, RVal L, NodeTy* Pred) {
- assert (Builder && "GRStmtNodeBuilder must be defined.");
- TF->EvalCall(Dst, *this, *Builder, CE, L, Pred);
- }
-
- void EvalObjCMessageExpr(NodeSet& Dst, ObjCMessageExpr* ME, NodeTy* Pred) {
- assert (Builder && "GRStmtNodeBuilder must be defined.");
- TF->EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
- }
-
- void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* 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,
- ValueState* St, RVal location, bool CheckOnly = false);
-
- ValueState* EvalLocation(Expr* Ex, NodeTy* Pred,
- ValueState* St, RVal location, bool isLoad = false);
-
- void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred);
-
- ValueState* MarkBranch(ValueState* 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 782ddcfffeac..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"
-
-namespace clang {
-
-class ValueState;
-class Diagnostic;
-class BugReporter;
-class ASTContext;
-class GRExprEngine;
-class PathDiagnosticClient;
-template <typename T> class ExplodedGraph;
-
-
-class GRSimpleAPICheck : public GRAuditor<ValueState> {
-public:
- GRSimpleAPICheck() {}
- virtual ~GRSimpleAPICheck() {}
- virtual void EmitWarnings(BugReporter& BR) = 0;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
deleted file mode 100644
index 3dd296941376..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ /dev/null
@@ -1,119 +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/ValueState.h"
-
-namespace clang {
-
- class GRExprEngine;
-
-class GRTransferFuncs {
-public:
- GRTransferFuncs() {}
- virtual ~GRTransferFuncs() {}
-
- virtual ValueState::CheckerStatePrinter* getCheckerStatePrinter() {
- return NULL;
- }
-
- 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 RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R) = 0;
-
- 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<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<ValueState>* Pred) {}
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<ValueState>* 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<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* E, ExplodedNode<ValueState>* Pred,
- ValueState* St, RVal TargetLV, RVal Val);
-
-
- // End-of-path and dead symbol notification.
-
- virtual void EvalEndPath(GRExprEngine& Engine,
- GREndPathNodeBuilder<ValueState>& Builder) {}
-
-
- virtual void EvalDeadSymbols(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ExplodedNode<ValueState>* Pred,
- Stmt* S,
- ValueState* St,
- const ValueStateManager::DeadSymbolsTy& Dead) {}
-
- // Return statements.
-
- virtual void EvalReturn(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ReturnStmt* S,
- ExplodedNode<ValueState>* Pred) {}
-
- // Assumptions.
-
- virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* 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 401e35042e73..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/RValues.h b/clang/include/clang/Analysis/PathSensitive/RValues.h
deleted file mode 100644
index 5a010dd0dc80..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/RValues.h
+++ /dev/null
@@ -1,507 +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 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;
- }
-
- 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(BasicValueFactory& BasicVals, 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();
- }
-};
-
-//==------------------------------------------------------------------------==//
-// 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, DeclValKind, 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 DeclVal : public LVal {
-public:
- DeclVal(const VarDecl* vd) : LVal(DeclValKind, vd) {}
-
- VarDecl* getDecl() const {
- return static_cast<VarDecl*>(Data);
- }
-
- inline bool operator==(const DeclVal& R) const {
- return getDecl() == R.getDecl();
- }
-
- inline bool operator!=(const DeclVal& R) const {
- return getDecl() != R.getDecl();
- }
-
- // Implement isa<T> support.
- static inline bool classof(const RVal* V) {
- return V->getBaseKind() == LValKind &&
- V->getSubKind() == DeclValKind;
- }
-
- static inline bool classof(const LVal* V) {
- return V->getSubKind() == DeclValKind;
- }
-};
-
-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/SymbolManager.h b/clang/include/clang/Analysis/PathSensitive/SymbolManager.h
deleted file mode 100644
index d0473c6a8eeb..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ /dev/null
@@ -1,257 +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;
- unsigned Count;
-
-public:
- SymbolConjured(SymbolID Sym, Expr* exp, unsigned count)
- : SymbolData(ConjuredKind, Sym), E(exp), Count(count) {}
-
- Expr* getExpr() const { return E; }
- unsigned getCount() const { return Count; }
-
- static void Profile(llvm::FoldingSetNodeID& profile,
- Expr* E, unsigned Count) {
-
- profile.AddInteger((unsigned) ConjuredKind);
- profile.AddPointer(E);
- profile.AddInteger(Count);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, E, 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, unsigned 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/PathSensitive/ValueState.h b/clang/include/clang/Analysis/PathSensitive/ValueState.h
deleted file mode 100644
index a4133085a87a..000000000000
--- a/clang/include/clang/Analysis/PathSensitive/ValueState.h
+++ /dev/null
@@ -1,260 +0,0 @@
-//== ValueState*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 ValueState*
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
-#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
-
-// FIXME: Reduce the number of includes.
-
-#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/SmallPtrSet.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 {
-
-//===----------------------------------------------------------------------===//
-// ValueState- An ImmutableMap type Stmt*/Decl*/Symbols to RVals.
-//===----------------------------------------------------------------------===//
-
-/// ValueState - 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 ValueState : public llvm::FoldingSetNode {
-public:
-
- // Typedefs.
-
- typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
- typedef llvm::ImmutableMap<Expr*,RVal> ExprBindingsTy;
- typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
- typedef llvm::ImmutableMap<SymbolID,IntSetTy> ConstNotEqTy;
- typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
-
-private:
-
- void operator=(const ValueState& R) const;
-
- // FIXME: Make these private.
-
-public:
- ExprBindingsTy SubExprBindings;
- ExprBindingsTy BlockExprBindings;
- VarBindingsTy VarBindings;
- ConstNotEqTy ConstNotEq;
- ConstEqTy ConstEq;
- void* CheckerState;
-
-public:
-
- /// This ctor is used when creating the first ValueState object.
- ValueState(ExprBindingsTy EB, VarBindingsTy VB,
- ConstNotEqTy CNE, ConstEqTy CE)
- : SubExprBindings(EB),
- BlockExprBindings(EB),
- VarBindings(VB),
- ConstNotEq(CNE),
- ConstEq(CE),
- CheckerState(NULL) {}
-
- /// Copy ctor - We must explicitly define this or else the "Next" ptr
- /// in FoldingSetNode will also get copied.
- ValueState(const ValueState& RHS)
- : llvm::FoldingSetNode(),
- SubExprBindings(RHS.SubExprBindings),
- BlockExprBindings(RHS.BlockExprBindings),
- VarBindings(RHS.VarBindings),
- ConstNotEq(RHS.ConstNotEq),
- ConstEq(RHS.ConstEq),
- CheckerState(RHS.CheckerState) {}
-
- /// Profile - Profile the contents of a ValueState object for use
- /// in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID& ID, const ValueState* V) {
- V->SubExprBindings.Profile(ID);
- V->BlockExprBindings.Profile(ID);
- V->VarBindings.Profile(ID);
- V->ConstNotEq.Profile(ID);
- V->ConstEq.Profile(ID);
- ID.AddPointer(V->CheckerState);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- // Queries.
-
- bool isNotEqual(SymbolID sym, const llvm::APSInt& V) const;
- const llvm::APSInt* getSymVal(SymbolID sym) const;
-
- // Iterators.
-
- typedef VarBindingsTy::iterator vb_iterator;
- vb_iterator vb_begin() const { return VarBindings.begin(); }
- vb_iterator vb_end() const { return VarBindings.end(); }
-
- typedef ExprBindingsTy::iterator seb_iterator;
- seb_iterator seb_begin() const { return SubExprBindings.begin(); }
- seb_iterator seb_end() const { return SubExprBindings.end(); }
-
- typedef ExprBindingsTy::iterator beb_iterator;
- beb_iterator beb_begin() const { return BlockExprBindings.begin(); }
- beb_iterator beb_end() const { return BlockExprBindings.end(); }
-
- typedef ConstNotEqTy::iterator cne_iterator;
- cne_iterator cne_begin() const { return ConstNotEq.begin(); }
- cne_iterator cne_end() const { return ConstNotEq.end(); }
-
- typedef ConstEqTy::iterator ce_iterator;
- ce_iterator ce_begin() const { return ConstEq.begin(); }
- ce_iterator ce_end() const { return ConstEq.end(); }
-
- class CheckerStatePrinter {
- public:
- virtual ~CheckerStatePrinter() {}
- virtual void PrintCheckerState(std::ostream& Out, void* State,
- const char* nl, const char* sep) = 0;
- };
-
- void print(std::ostream& Out, CheckerStatePrinter* P = NULL,
- const char* nl = "\n", const char* sep = "") const;
-
- void printStdErr(CheckerStatePrinter* P = NULL) const;
-
- void printDOT(std::ostream& Out, CheckerStatePrinter*P = NULL) const;
-};
-
-template<> struct GRTrait<ValueState*> {
- static inline void* toPtr(ValueState* St) { return (void*) St; }
- static inline ValueState* toState(void* P) { return (ValueState*) P; }
- static inline void Profile(llvm::FoldingSetNodeID& profile, ValueState* St) {
- // At this point states have already been uniqued. Just
- // add the pointer.
- profile.AddPointer(St);
- }
-};
-
-
-class ValueStateManager {
-private:
- ValueState::IntSetTy::Factory ISetFactory;
- ValueState::ExprBindingsTy::Factory EXFactory;
- ValueState::VarBindingsTy::Factory VBFactory;
- ValueState::ConstNotEqTy::Factory CNEFactory;
- ValueState::ConstEqTy::Factory CEFactory;
-
- /// StateSet - FoldingSet containing all the states created for analyzing
- /// a particular function. This is used to unique states.
- llvm::FoldingSet<ValueState> 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;
-
-private:
-
- ValueState::ExprBindingsTy Remove(ValueState::ExprBindingsTy B, Expr* E) {
- return EXFactory.Remove(B, E);
- }
-
- ValueState::VarBindingsTy Remove(ValueState::VarBindingsTy B, VarDecl* V) {
- return VBFactory.Remove(B, V);
- }
-
- inline ValueState::ExprBindingsTy Remove(const ValueState& V, Expr* E) {
- return Remove(V.BlockExprBindings, E);
- }
-
- inline ValueState::VarBindingsTy Remove(const ValueState& V, VarDecl* D) {
- return Remove(V.VarBindings, D);
- }
-
- ValueState* BindVar(ValueState* St, VarDecl* D, RVal V);
- ValueState* UnbindVar(ValueState* St, VarDecl* D);
-
-public:
- ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& alloc)
- : ISetFactory(alloc),
- EXFactory(alloc),
- VBFactory(alloc),
- CNEFactory(alloc),
- CEFactory(alloc),
- BasicVals(Ctx, alloc),
- SymMgr(alloc),
- Alloc(alloc) {}
-
- ValueState* getInitialState();
-
- BasicValueFactory& getBasicValueFactory() { return BasicVals; }
- SymbolManager& getSymbolManager() { return SymMgr; }
-
- typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
-
- ValueState* RemoveDeadBindings(ValueState* St, Stmt* Loc,
- const LiveVariables& Liveness,
- DeadSymbolsTy& DeadSymbols);
-
- ValueState* RemoveSubExprBindings(ValueState* St) {
- ValueState NewSt = *St;
- NewSt.SubExprBindings = EXFactory.GetEmptyMap();
- return getPersistentState(NewSt);
- }
-
- ValueState* SetRVal(ValueState* St, Expr* E, RVal V, bool isBlkExpr,
- bool Invalidate);
-
- ValueState* SetRVal(ValueState* St, LVal LV, RVal V);
-
- RVal GetRVal(ValueState* St, Expr* E);
- RVal GetRVal(ValueState* St, LVal LV, QualType T = QualType());
-
- RVal GetBlkExprRVal(ValueState* St, Expr* Ex);
-
- void BindVar(ValueState& StImpl, VarDecl* D, RVal V);
-
- void Unbind(ValueState& StImpl, LVal LV);
-
- ValueState* getPersistentState(ValueState& Impl);
-
- ValueState* AddEQ(ValueState* St, SymbolID sym, const llvm::APSInt& V);
- ValueState* AddNE(ValueState* St, SymbolID sym, const llvm::APSInt& V);
-};
-
-} // 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 efd16b416df7..000000000000
--- a/clang/include/clang/Analysis/ProgramPoint.h
+++ /dev/null
@@ -1,185 +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 { BlockEntranceKind=0, PostStmtKind=1, PostLoadKind=2,
- BlockExitKind=3, BlockEdgeSrcKind=4, BlockEdgeDstKind=5,
- BlockEdgeAuxKind=6 };
-protected:
- uintptr_t Data;
-
- ProgramPoint(const void* Ptr, Kind k) {
- setRawData(Ptr, k);
- }
-
- ProgramPoint() : Data(0) {}
-
- void setRawData(const void* Ptr, Kind k) {
- assert ((reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) & 0x7) == 0
- && "Address must have at least an 8-byte alignment.");
-
- Data = reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) | k;
- }
-
-public:
- unsigned getKind() const { return Data & 0x7; }
- void* getRawPtr() const { return reinterpret_cast<void*>(Data & ~0x7); }
- void* getRawData() const { return reinterpret_cast<void*>(Data); }
-
- 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; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger(getKind());
- ID.AddPointer(getRawPtr());
- }
-};
-
-class BlockEntrance : public ProgramPoint {
-public:
- BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {}
-
- CFGBlock* getBlock() const {
- return reinterpret_cast<CFGBlock*>(getRawPtr());
- }
-
- 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*>(getRawPtr());
- }
-
- 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*) getRawPtr(); }
-
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
- return k == PostStmtKind || k == PostLoadKind;
- }
-};
-
-class PostLoad : public PostStmt {
-public:
- PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {}
-
- static bool classof(const ProgramPoint* Location) {
- return Location->getKind() == PostLoadKind;
- }
-};
-
-class BlockEdge : public ProgramPoint {
- typedef std::pair<CFGBlock*,CFGBlock*> BPair;
-public:
- BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2);
-
- /// This ctor forces the BlockEdge to be constructed using an explicitly
- /// allocated pair object that is stored in the CFG. This is usually
- /// used to construct edges representing jumps using computed gotos.
- BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2, bool)
- : ProgramPoint(cfg.getBlockEdgeImpl(B1, B2), BlockEdgeAuxKind) {}
-
-
- CFGBlock* getSrc() const;
- CFGBlock* getDst() const;
-
- static bool classof(const ProgramPoint* Location) {
- unsigned k = Location->getKind();
- return k >= BlockEdgeSrcKind && k <= BlockEdgeAuxKind;
- }
-};
-
-
-
-} // 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 DenseMapInfo<void*>::getHashValue(Loc.getRawData());
- }
-
- 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 5796fb39a7fd..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:
- Idx(unsigned i) : I(i) {}
- explicit 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 fab14c38daae..000000000000
--- a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
+++ /dev/null
@@ -1,88 +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 (ScopedDecl* D = DS->getDecl(); D != NULL; D = D->getNextDeclarator()) {
- 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(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(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 4307955b2cf7..000000000000
--- a/clang/include/clang/Basic/Diagnostic.h
+++ /dev/null
@@ -1,198 +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 WarningsAsErrors; // Treat warnings like errors:
- bool WarnOnExtensions; // Enables warnings for gcc extensions: -pedantic.
- bool ErrorOnExtensions; // Error on extensions: -pedantic-errors.
- 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);
- ~Diagnostic();
-
- //===--------------------------------------------------------------------===//
- // Diagnostic characterization methods, used by a client to customize how
- //
-
- DiagnosticClient &getClient() { return Client; };
-
- const DiagnosticClient &getClient() const { return Client; };
-
- /// 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; }
-
- /// 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 {
-public:
- virtual ~DiagnosticClient();
-
- /// isInSystemHeader - If the client can tell that this is a system header,
- /// return true.
- virtual bool isInSystemHeader(FullSourceLoc Pos) const { return false; }
-
- /// 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 38322cbbc761..000000000000
--- a/clang/include/clang/Basic/DiagnosticKinds.def
+++ /dev/null
@@ -1,1057 +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.
-// 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_invalid_receiver_to_message, ERROR,
- "invalid receiver to message expression")
-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_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_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(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_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 statment 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', referenced by '%1'")
-DIAG(err_duplicate_protocol_def, ERROR,
- "duplicate protocol declaration of '%0'")
-DIAG(err_undef_interface, ERROR,
- "cannot find interface declaration for '%0'")
-DIAG(err_dup_category_def, ERROR,
- "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(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_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'")
-
-//===----------------------------------------------------------------------===//
-// Semantic Analysis
-//===----------------------------------------------------------------------===//
-
-// 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(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")
-
-// Attributes
-DIAG(err_attribute_wrong_number_arguments, ERROR,
- "attribute requires %0 argument(s)")
-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_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_string, ERROR,
- "format argument not a string type")
-DIAG(err_format_attribute_not_NSString, ERROR,
- "format argument is not an NSString")
-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_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_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'")
-
-// 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_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(err_typecheck_illegal_vla, ERROR,
- "variable length array declared outside of any function")
-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 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_illegal_initializer, ERROR,
- "illegal initializer (only variables can be initialized)")
-
-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")
-
-// 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(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_structUnion, ERROR,
- "member reference is not to a structure or union")
-DIAG(err_typecheck_member_reference_arrow, ERROR,
- "member reference 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")
-
-// 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, EXTENSION,
- "incompatible pointer to integer conversion %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_int_pointer, EXTENSION,
- "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, EXTENSION,
- "incompatible pointer types %2 '%1', expected '%0'")
-DIAG(ext_typecheck_convert_discards_qualifiers, EXTENSION,
- "%2 '%1' discards qualifiers, 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_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_call_too_many_args, ERROR,
- "too many arguments to function")
-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(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(warn_unused_expr, WARNING,
- "expression result unused")
-DIAG(err_pascal_string_too_long, ERROR,
- "Pascal string is too long")
-DIAG(err_invalid_lvalue_in_asm_output, ERROR,
- "invalid lvalue in asm output")
-DIAG(err_invalid_output_constraint_in_asm, ERROR,
- "invalid output constraint in asm")
-DIAG(err_invalid_input_constraint_in_asm, ERROR,
- "invalid input constraint in asm")
-DIAG(err_invalid_type_in_asm_input, ERROR,
- "invalid type '%0' in asm input")
-DIAG(err_unknown_register_name_in_asm, 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")
-
-// 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: stores to variables that are no longer live (dead stores)
-DIAG(warn_dead_store, WARNING, "value stored to variable is never used")
-
-// CHECK: use of uninitialized values
-DIAG(warn_uninit_val, WARNING, "use of uninitialized variable")
-
-// 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")
-
-#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 024ff14456e4..000000000000
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ /dev/null
@@ -1,329 +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.
-
-/// 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 : 9; // 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.
- // 6 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 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 589153f47ecc..000000000000
--- a/clang/include/clang/Basic/LangOptions.h
+++ /dev/null
@@ -1,75 +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;
-
-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 = 0;
- }
-
- 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 6bc45057d54d..000000000000
--- a/clang/include/clang/Basic/SourceLocation.h
+++ /dev/null
@@ -1,265 +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();
- FullSourceLoc getIncludeLoc();
-
- unsigned getLineNumber() const;
- unsigned getColumnNumber() const;
-
- unsigned getLogicalLineNumber() const;
- unsigned getLogicalColumnNumber() const;
-
- const char *getCharacterData() const;
-
- const llvm::MemoryBuffer* getBuffer() const;
-
- const char* getSourceName() const;
- const FileEntry* getFileEntryForLoc() 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;
- }
-};
-
-} // 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 700dcd31acc4..000000000000
--- a/clang/include/clang/Basic/SourceManager.h
+++ /dev/null
@@ -1,471 +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 - Private classes that are part of the SourceManager implementation.
-///
-namespace SrcMgr {
- /// 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;
-
- /// 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) {
- FileIDInfo X;
- X.IncludeLoc = IL;
- X.ChunkNo = CN;
- X.Content = Con;
- return X;
- }
-
- SourceLocation getIncludeLoc() const { return IncludeLoc; }
- unsigned getChunkNo() const { return ChunkNo; }
- const ContentCache* getContentCache() const { return Content; }
-
- /// 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() {
- 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){
- const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
- if (IR == 0) return 0; // Error opening file?
- return createFileID(IR, IncludePos);
- }
-
- /// 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);
- 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());
- }
-
- /// 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);
-
- return std::pair<unsigned,unsigned>(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();
- }
-
- /// 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 class 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);
-
- /// 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 36fbb0d1c237..000000000000
--- a/clang/include/clang/Basic/TargetInfo.h
+++ /dev/null
@@ -1,222 +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 DoubleWidth, DoubleAlign;
- unsigned char LongWidth, LongAlign;
- unsigned char LongLongWidth, LongLongAlign;
-
- 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);
- }
- virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
- return PointerWidth;
- }
- virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
- return PointerAlign;
- }
-
- /// 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 32; } // FIXME
- unsigned getFloatAlign() const { return 32; } // FIXME
- 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 64; } // FIXME
- unsigned getLongDoubleAlign() const { return 64; } // FIXME
- 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;
- }
-
- ///===---- 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 {
- // FIXME !
- // Hard code darwin-x86 for now.
- return "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";
- }
-
- struct GCCRegAlias {
- const char * const Aliases[5];
- const char * const Register;
- };
-
- virtual bool useGlobalsForAutomaticVariables() const {return false;}
-
-protected:
- 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 b6ec1cf142df..000000000000
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ /dev/null
@@ -1,31 +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
-
-namespace llvm {
- class Module;
-}
-
-namespace clang {
- class Diagnostic;
- struct LangOptions;
- class ASTConsumer;
-
- ASTConsumer *CreateLLVMCodeGen(Diagnostic &Diags, const LangOptions &Features,
- llvm::Module *&DestModule,
- bool GenerateDebugInfo);
-}
-
-#endif
diff --git a/clang/include/clang/Lex/DirectoryLookup.h b/clang/include/clang/Lex/DirectoryLookup.h
deleted file mode 100644
index eb9bf5dbbb20..000000000000
--- a/clang/include/clang/Lex/DirectoryLookup.h
+++ /dev/null
@@ -1,135 +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
-
-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 DirType {
- NormalHeaderDir,
- SystemHeaderDir,
- ExternCSystemHeaderDir
- };
-
- 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;
-
- // NOTE: VC++ treats enums as signed, avoid using the DirType enum
- /// DirCharacteristic - The type of directory this is, one of the DirType enum
- /// values.
- 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, DirType 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, DirType 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.
- DirType getDirCharacteristic() const { return DirType(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 3c43213be6f9..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;
-
- // NOTE: VC++ treats enums as signed, avoid using DirectoryLookup::DirType
- /// 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.
- 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(DirectoryLookup::NormalHeaderDir),
- 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.
- DirectoryLookup::DirType getFileDirFlavor(const FileEntry *File) {
- return DirectoryLookup::DirType(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 fiel as a system header, e.g.
- /// due to #pragma GCC system_header.
- void MarkFileSystemHeader(const FileEntry *File) {
- getFileInfo(File).DirInfo = DirectoryLookup::SystemHeaderDir;
- }
-
- /// 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 80861ba3659e..000000000000
--- a/clang/include/clang/Lex/LiteralSupport.h
+++ /dev/null
@@ -1,164 +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());
-
- /// 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 ccaf5a7123a6..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,
- DirectoryLookup::DirType 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 20c5c5872eb6..000000000000
--- a/clang/include/clang/Lex/Pragma.h
+++ /dev/null
@@ -1,82 +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);
- }
-
- 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 2617f2838bc3..000000000000
--- a/clang/include/clang/Lex/Preprocessor.h
+++ /dev/null
@@ -1,543 +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.
-
- /// 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];
-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);
-
- /// 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);
-
- /// 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();
-
- /// 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
- CurTokenLexer->Lex(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'.
- ///
- /// NOTE: is a relatively expensive method, so it should not be used in common
- /// code paths if possible!
- ///
- Token LookAhead(unsigned N);
-
- /// 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);
-
- //===--------------------------------------------------------------------===//
- /// 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 d5bfd9cdf59c..000000000000
--- a/clang/include/clang/Lex/Token.h
+++ /dev/null
@@ -1,158 +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;
- }
-
- /// isNamedIdentifier - Return true if this token is a ppidentifier with the
- /// specified name. For example, tok.isNamedIdentifier("this").
- bool isNamedIdentifier(const char *Name) const;
-
- /// 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 17899d41d7e3..000000000000
--- a/clang/include/clang/Parse/Action.h
+++ /dev/null
@@ -1,813 +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/Basic/TokenKinds.h"
-#include "clang/Parse/AccessSpecifier.h"
-
-namespace clang {
- // Semantic.
- class DeclSpec;
- class ObjCDeclSpec;
- class Declarator;
- class AttributeList;
- class 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 EmptyAction
-/// 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 DeclTy *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
- /// 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) {
- 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;
- }
-
- /// 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;
- }
-
- /// 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 ActOnDeclarator(FnBodyScope, D, 0);
- }
-
- 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;
- }
-
- //===--------------------------------------------------------------------===//
- // 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;
- }
-
- 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) {}
-
- 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;
- }
-
- //===------------------------- C++ Declarations -------------------------===//
- /// ActOnParamDefaultArgument - Parse default argument for function parameter
- virtual void ActOnParamDefaultArgument(DeclTy *param,
- SourceLocation EqualLoc,
- ExprTy *defarg) {
- }
-
- //===------------------------- 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;
- }
-
- /// 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;
- }
-
- //===---------------------------- C++ Classes ---------------------------===//
- /// ActOnBaseSpecifier - Parsed a base specifier
- virtual void ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- DeclTy *basetype, SourceLocation BaseLoc) {
- }
-
- //===----------------------- 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 AtInterafceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- IdentifierInfo **ProtocolNames,
- unsigned NumProtocols,
- 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 AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName,
- SourceLocation ProtocolLoc,
- IdentifierInfo **ProtoRefNames,
- unsigned NumProtoRefs,
- SourceLocation EndProtoLoc) {
- 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,
- IdentifierInfo **ProtoRefNames,
- 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,
- IdentifierInfo **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(SourceLocation TypeLoc,
- IdentifierInfo **ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVector<DeclTy *, 8> &
- Protocols) {
- }
-
- //===----------------------- 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;
- }
-};
-
-/// 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 DeclTy *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,
- IdentifierInfo **ProtocolNames, unsigned NumProtocols,
- 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 645367924196..000000000000
--- a/clang/include/clang/Parse/AttributeList.h
+++ /dev/null
@@ -1,103 +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_aligned,
- AT_annotate,
- AT_deprecated,
- AT_dllimport,
- AT_dllexport,
- AT_ext_vector_type,
- AT_fastcall,
- AT_format,
- AT_malloc,
- 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,
- 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];
- }
-};
-
-} // 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 369aca480de2..000000000000
--- a/clang/include/clang/Parse/DeclSpec.h
+++ /dev/null
@@ -1,683 +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/Basic/Diagnostic.h"
-#include "clang/Parse/Action.h"
-#include "clang/Parse/AttributeList.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- struct LangOptions;
- 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_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.
- void *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>".
- llvm::SmallVector<Action::DeclTy *, 8> *ProtocolQualifiers;
-
- // 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);
-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) {
- }
- ~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,
- void *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; }
- AttributeList *getAttributes() const { 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;
- }
-
- llvm::SmallVector<Action::DeclTy *, 8> *getProtocolQualifiers() const {
- return ProtocolQualifiers;
- }
- void setProtocolQualifiers(llvm::SmallVector<Action::DeclTy *, 8> *protos) {
- ProtocolQualifiers = protos;
- }
- unsigned getNumProtocolQualifiers() const {
- return ProtocolQualifiers ? ProtocolQualifiers->size() : 0;
- }
- /// 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) {
- D.Report(FullSourceLoc(Loc,SrcMgr), DiagID);
- }
-
- void Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr,
- unsigned DiagID, const std::string &info) {
- D.Report(FullSourceLoc(Loc,SrcMgr), DiagID, &info, 1);
- }
-};
-
-/// 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); }
-
- const 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
- } 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;
- }
- };
-
- union {
- PointerTypeInfo Ptr;
- ReferenceTypeInfo Ref;
- ArrayTypeInfo Arr;
- FunctionTypeInfo Fun;
- };
-
-
- /// 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;
- }
-};
-
-
-/// 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 {
- 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.
- };
-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;
-
- // attributes.
- AttributeList *AttrList;
-public:
- Declarator(DeclSpec &ds, TheContext C)
- : DS(ds), Identifier(0), Context(C), InvalidType(false), AttrList(0) {
- }
-
- ~Declarator() {
- clear();
- }
-
- /// getDeclSpec - Return the declaration-specifier that this declarator was
- /// declared with.
- DeclSpec &getDeclSpec() const { return 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::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;
- }
-
- /// 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;
- }
-
- /// 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;
- }
- AttributeList *getAttributes() const { return AttrList; }
-
- void setInvalidType(bool flag) { InvalidType = flag; }
- bool getInvalidType() const { return InvalidType; }
-};
-
-/// 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 84fe49a76721..000000000000
--- a/clang/include/clang/Parse/Parser.h
+++ /dev/null
@@ -1,496 +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"
-
-namespace clang {
- class DeclSpec;
- class ObjCDeclSpec;
- class Declarator;
- class FieldDeclarator;
- class AttributeList;
- 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];
-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);
-
- /// Finalize - Shut down the parser.
- ///
- void Finalize();
-
-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 will 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.
- ///
- /// NOTE: is a relatively expensive method, so it should not be used in common
- /// code paths if possible!
- ///
- Token GetLookAheadToken(unsigned N) {
- if (N == 0 || Tok.is(tok::eof)) return Tok;
- return PP.LookAhead(N-1);
- }
-
-
- /// 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.
-
- void Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg = std::string());
- void Diag(const Token &Tok, unsigned DiagID,
- const std::string &M = std::string()) {
- 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;
-
- //===--------------------------------------------------------------------===//
- // 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<IdentifierInfo*> &,
- SourceLocation &endProtoLoc);
- void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
- tok::ObjCKeywordKind contextKey);
- DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
-
- 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();
-
- IdentifierInfo *ObjCForCollectionInKW;
- 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 ParseExpressionWithLeadingIdentifier(const Token &Tok);
- ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
- ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
-
- ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
- ExprResult ParseCastExpression(bool isUnaryExpression);
- ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
- ExprResult ParseSizeofAlignofExpression();
- ExprResult ParseBuiltinPrimaryExpression();
-
- /// 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++ 15: C++ Throw Expression
- ExprResult ParseThrowExpression();
-
- //===--------------------------------------------------------------------===//
- // C++ 2.13.5: C++ Boolean Literals
- ExprResult ParseCXXBoolLiteral();
-
- //===--------------------------------------------------------------------===//
- // C99 6.7.8: Initialization.
- ExprResult ParseInitializer();
- ExprResult ParseInitializerWithPotentialDesignator();
-
- //===--------------------------------------------------------------------===//
- // Objective-C Expressions
-
- bool isTokObjCMessageIdentifierReceiver() const {
- if (!Tok.is(tok::identifier))
- return false;
-
- if (Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
- return true;
-
- return Tok.isNamedIdentifier("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);
-
- //===--------------------------------------------------------------------===//
- // C99 6.8: Statements and Blocks.
-
- StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
- StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
- StmtResult ParseIdentifierStatement(bool OnlyStatement);
- 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);
-
- bool ParseTag(DeclTy *&Decl, unsigned TagType, SourceLocation StartLoc);
- 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;
-
- 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);
-
- //===--------------------------------------------------------------------===//
- // 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 5db9b2dd76c3..000000000000
--- a/clang/include/clang/Parse/Scope.h
+++ /dev/null
@@ -1,149 +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
- };
-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;
-
- /// 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; }
-
- /// 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.
- const Scope *getContinueParent() const { return ContinueParent; }
- Scope *getContinueParent() { return ContinueParent; }
-
- /// getBreakParent - Return the closest scope that a break statement
- /// would be affected by.
- const Scope *getBreakParent() const { return BreakParent; }
- Scope *getBreakParent() { return BreakParent; }
-
-
- 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;
- }
-
- /// 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;
- } else {
- FnParent = BreakParent = ContinueParent = 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;
-
- 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 1ebbade1613b..000000000000
--- a/clang/include/clang/Rewrite/HTMLRewrite.h
+++ /dev/null
@@ -1,88 +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 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);
-
- /// 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 963c0715d905..000000000000
--- a/clang/include/clang/Rewrite/RewriteRope.h
+++ /dev/null
@@ -1,227 +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"
-#include <cstring>
-
-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) {}
-
- const 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) {
- if (Start == End) return;
- Chunks.insert(Offset, MakeRopeString(Start, End));
- }
-
- void erase(unsigned Offset, unsigned NumBytes) {
- 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 6176cfb2dd5c..000000000000
--- a/clang/include/clang/Rewrite/Rewriter.h
+++ /dev/null
@@ -1,219 +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;
-
- /// 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 61ce30d9f4ee..000000000000
--- a/clang/include/clang/Sema/ParseAST.h
+++ /dev/null
@@ -1,27 +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 b3d12710927a..000000000000
--- a/clang/lib/AST/ASTConsumer.cpp
+++ /dev/null
@@ -1,28 +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"
-using namespace clang;
-
-ASTConsumer::~ASTConsumer() {}
-
-void ASTConsumer::HandleTopLevelDeclaration(Decl* d) {
- if (ScopedDecl* sd = dyn_cast<ScopedDecl>(d))
- while (sd) {
- HandleTopLevelDecl(sd);
- sd = sd->getNextDeclarator();
- }
- else
- HandleTopLevelDecl(d);
-}
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
deleted file mode 100644
index 8fd088a305f1..000000000000
--- a/clang/lib/AST/ASTContext.cpp
+++ /dev/null
@@ -1,1753 +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/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/SmallVector.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() {
- // Deallocate all the types.
- while (!Types.empty()) {
- if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(Types.back())) {
- // Destroy the object, but don't call delete. These are malloc'd.
- FT->~FunctionTypeProto();
- free(FT);
- } else {
- delete Types.back();
- }
- Types.pop_back();
- }
-}
-
-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;
- 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;
-
- 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<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()->getKind()) {
- default: assert(0 && "Unknown tagged type!");
- case Decl::Struct: ++NumTagStruct; break;
- case Decl::Union: ++NumTagUnion; break;
- case Decl::Class: ++NumTagClass; break;
- case Decl::Enum: ++NumTagEnum; break;
- }
- } else if (isa<ObjCInterfaceType>(T))
- ++NumObjCInterfaces;
- else if (isa<ObjCQualifiedInterfaceType>(T))
- ++NumObjCQualifiedInterfaces;
- else if (isa<ObjCQualifiedIdType>(T))
- ++NumObjCQualifiedIds;
- 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 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, "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)));
-}
-
-
-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);
-
- // 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
-//===----------------------------------------------------------------------===//
-
-/// 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: Vector alignment is not the alignment of its elements.
- Align = EltInfo.second;
- 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::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::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::Tagged: {
- 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);
-}
-
-/// 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) {
- assert(D->isDefinition() && "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;
-
- uint64_t *FieldOffsets = new uint64_t[D->getNumMembers()];
- uint64_t RecordSize = 0;
- unsigned RecordAlign = 8; // Default alignment = 1 byte = 8 bits.
-
- if (D->getKind() != Decl::Union) {
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- RecordAlign = std::max(RecordAlign, AA->getAlignment());
-
- bool StructIsPacked = D->getAttr<PackedAttr>();
-
- // 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);
- bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
- uint64_t FieldSize;
- unsigned FieldAlign;
-
- if (const Expr *BitWidthExpr = FD->getBitWidth()) {
- llvm::APSInt I(32);
- bool BitWidthIsICE =
- BitWidthExpr->isIntegerConstantExpr(I, *this);
- assert (BitWidthIsICE && "Invalid BitField size expression");
- FieldSize = I.getZExtValue();
-
- std::pair<uint64_t, unsigned> TypeInfo = getTypeInfo(FD->getType());
- uint64_t TypeSize = TypeInfo.first;
-
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = AA->getAlignment();
- else if (FieldIsPacked)
- FieldAlign = 8;
- else {
- // FIXME: This is X86 specific, use 32-bit alignment for long long.
- if (FD->getType()->isIntegerType() && TypeInfo.second > 32)
- FieldAlign = 32;
- else
- FieldAlign = TypeInfo.second;
- }
-
- // Check if we need to add padding to give the field the correct
- // alignment.
- if (RecordSize % FieldAlign + FieldSize > TypeSize)
- RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
-
- } else {
- if (FD->getType()->isIncompleteType()) {
- // This must be 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.
-
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = AA->getAlignment();
- else if (FieldIsPacked)
- FieldAlign = 8;
- else {
- const ArrayType* ATy = FD->getType()->getAsArrayType();
- FieldAlign = getTypeAlign(ATy->getElementType());
- }
- FieldSize = 0;
- } else {
- std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
- FieldSize = FieldInfo.first;
-
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = AA->getAlignment();
- else if (FieldIsPacked)
- FieldAlign = 8;
- else
- FieldAlign = FieldInfo.second;
- }
-
- // Round up the current record size to the field's alignment boundary.
- RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
- }
-
- // Place this field at the current location.
- FieldOffsets[i] = RecordSize;
-
- // Reserve space for this field.
- RecordSize += FieldSize;
-
- // Remember max struct/class alignment.
- RecordAlign = std::max(RecordAlign, FieldAlign);
- }
-
- // Finally, round the size of the total struct up to the alignment of the
- // struct itself.
- RecordSize = (RecordSize+RecordAlign-1) & ~(RecordAlign-1);
- } else {
- // Union layout just puts each member at the start of the record.
- for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
- const FieldDecl *FD = D->getMember(i);
- std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
- uint64_t FieldSize = FieldInfo.first;
- unsigned FieldAlign = FieldInfo.second;
-
- // FIXME: This is X86 specific, use 32-bit alignment for long long.
- if (FD->getType()->isIntegerType() && FieldAlign > 32)
- FieldAlign = 32;
-
- // Round up the current record size to the field's alignment boundary.
- RecordSize = std::max(RecordSize, FieldSize);
-
- // Place this field at the start of the record.
- FieldOffsets[i] = 0;
-
- // Remember max struct/class alignment.
- RecordAlign = std::max(RecordAlign, FieldAlign);
- }
- }
-
- NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets);
- 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);
-}
-
-/// 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, 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) {
- 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);
- else if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Decl)) {
- Decl->TypeForDecl = new RecordType(Record);
- Types.push_back(Decl->TypeForDecl);
- return QualType(Decl->TypeForDecl, 0);
- } else if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Decl)) {
- Decl->TypeForDecl = new EnumType(Enum);
- Types.push_back(Decl->TypeForDecl);
- return QualType(Decl->TypeForDecl, 0);
- } else
- assert(false && "TypeDecl without a type?");
-}
-
-/// 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(QualType idType,
- 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;
- QualType Canonical;
- if (!idType->isCanonical()) {
- Canonical = getObjCQualifiedIdType(getCanonicalType(idType),
- Protocols, NumProtocols);
- ObjCQualifiedIdType *NewQT =
- ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewQT == 0 && "Shouldn't be in the map!");
- }
-
- ObjCQualifiedIdType *QType =
- new ObjCQualifiedIdType(Canonical, 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 {
- // On Darwin, wchar_t is defined as a "int".
- // FIXME: should derive from "Target".
- return IntTy;
-}
-
-/// 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();
- return QualType(CanType.getTypePtr(),
- T.getCVRQualifiers() | CanType.getCVRQualifiers());
-}
-
-
-/// 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) {
- // Handle the common case where typedefs are not involved directly.
- QualType EltTy;
- unsigned ArrayQuals = 0;
- unsigned PointerQuals = 0;
- if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
- // Since T "isa" an array type, it could not have had an address space
- // qualifier, just CVR qualifiers. The properly qualified element pointer
- // gets the union of the CVR qualifiers from the element and the array, and
- // keeps any address space qualifier on the element type if present.
- EltTy = AT->getElementType();
- ArrayQuals = Ty.getCVRQualifiers();
- PointerQuals = AT->getIndexTypeQualifier();
- } else {
- // Otherwise, we have an ASQualType or a typedef, etc. Make sure we don't
- // lose qualifiers when dealing with typedefs. Example:
- // typedef int arr[10];
- // void test2() {
- // const arr b;
- // b[4] = 1;
- // }
- //
- // The decayed type of b is "const int*" even though the element type of the
- // array is "int".
- QualType CanTy = getCanonicalType(Ty);
- const ArrayType *PrettyArrayType = Ty->getAsArrayType();
- assert(PrettyArrayType && "Not an array type!");
-
- // Get the element type with 'getAsArrayType' so that we don't lose any
- // typedefs in the element type of the array.
- EltTy = PrettyArrayType->getElementType();
-
- // If the array was address-space qualifier, make sure to ASQual the element
- // type. We can just grab the address space from the canonical type.
- if (unsigned AS = CanTy.getAddressSpace())
- EltTy = getASQualType(EltTy, AS);
-
- // To properly handle [multiple levels of] typedefs, typeof's etc, we take
- // the CVR qualifiers directly from the canonical type, which is guaranteed
- // to have the full set unioned together.
- ArrayQuals = CanTy.getCVRQualifiers();
- PointerQuals = PrettyArrayType->getIndexTypeQualifier();
- }
-
- // 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."
- EltTy = EltTy.getQualifiedType(ArrayQuals | EltTy.getCVRQualifiers());
-
- QualType PtrTy = getPointerType(EltTy);
-
- // int x[restrict 4] -> int *restrict
- PtrTy = PtrTy.getQualifiedType(PointerQuals);
-
- return PtrTy;
-}
-
-/// 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, Decl::Struct, TUDecl, SourceLocation(),
- &Idents.get("NSConstantString"), 0);
- 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(FieldDecls, 4);
- }
-
- return getTagDeclType(CFConstantStringTypeDecl);
-}
-
-// 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(ObjCMethodDecl *Decl,
- std::string& S)
-{
- // 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);
- }
-}
-
-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 = T->getAsArrayType()) {
- 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();
- 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) {
- 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
- 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)
-{
- assert(ObjCIdType.isNull() && "'id' type already set!");
-
- 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)
-{
- assert(ObjCSelType.isNull() && "'SEL' type already set!");
-
- 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)
-{
- assert(ObjCProtoType.isNull() && "'Protocol' type already set!");
- ObjCProtoType = QT;
-}
-
-void ASTContext::setObjCClassType(TypedefDecl *TD)
-{
- assert(ObjCClassType.isNull() && "'Class' type already set!");
-
- 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 Compatibility Testing
-//===----------------------------------------------------------------------===//
-
-/// C99 6.2.7p1: If both are complete types, then the following additional
-/// requirements apply.
-/// FIXME (handle compatibility across source files).
-static bool areCompatTagTypes(TagType *LHS, TagType *RHS,
- const ASTContext &C) {
- // "Class" and "id" are compatible built-in structure types.
- if (C.isObjCIdType(QualType(LHS, 0)) && C.isObjCClassType(QualType(RHS, 0)) ||
- C.isObjCClassType(QualType(LHS, 0)) && C.isObjCIdType(QualType(RHS, 0)))
- return true;
-
- // Within a translation unit a tag type is only compatible with itself. Self
- // equality is already handled by the time we get here.
- assert(LHS != RHS && "Self equality not handled!");
- return false;
-}
-
-bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
- // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be
- // identically qualified and both shall be pointers to compatible types.
- if (lhs.getCVRQualifiers() != rhs.getCVRQualifiers() ||
- lhs.getAddressSpace() != rhs.getAddressSpace())
- return false;
-
- QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
- QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
-
- return typesAreCompatible(ltype, rtype);
-}
-
-bool ASTContext::functionTypesAreCompatible(QualType lhs, QualType rhs) {
- const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
- const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
- const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
- const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
-
- // first check the return types (common between C99 and K&R).
- if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
- return false;
-
- if (lproto && rproto) { // two C99 style function prototypes
- unsigned lproto_nargs = lproto->getNumArgs();
- unsigned rproto_nargs = rproto->getNumArgs();
-
- if (lproto_nargs != rproto_nargs)
- return false;
-
- // both prototypes have the same number of arguments.
- if ((lproto->isVariadic() && !rproto->isVariadic()) ||
- (rproto->isVariadic() && !lproto->isVariadic()))
- return false;
-
- // The use of ellipsis agree...now check the argument types.
- for (unsigned i = 0; i < lproto_nargs; i++)
- // C99 6.7.5.3p15: ...and each parameter declared with qualified type
- // is taken as having the unqualified version of it's declared type.
- if (!typesAreCompatible(lproto->getArgType(i).getUnqualifiedType(),
- rproto->getArgType(i).getUnqualifiedType()))
- return false;
- return true;
- }
-
- if (!lproto && !rproto) // two K&R style function decls, nothing to do.
- return true;
-
- // we have a mixture of K&R style with C99 prototypes
- const FunctionTypeProto *proto = lproto ? lproto : rproto;
- if (proto->isVariadic())
- return false;
-
- // FIXME: Each parameter type T in the prototype must be compatible with the
- // type resulting from applying the usual argument conversions to T.
- return true;
-}
-
-// C99 6.7.5.2p6
-static bool areCompatArrayTypes(ArrayType *LHS, ArrayType *RHS, ASTContext &C) {
- // Constant arrays must be the same size to be compatible.
- if (const ConstantArrayType* LCAT = dyn_cast<ConstantArrayType>(LHS))
- if (const ConstantArrayType* RCAT = dyn_cast<ConstantArrayType>(RHS))
- if (RCAT->getSize() != LCAT->getSize())
- return false;
-
- // Compatible arrays must have compatible element types
- return C.typesAreCompatible(LHS->getElementType(), RHS->getElementType());
-}
-
-/// 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();
-}
-
-/// areCompatObjCInterfaces - 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.
-///
-static bool areCompatObjCInterfaces(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_NC, QualType RHS_NC) {
- QualType LHS = LHS_NC.getCanonicalType();
- QualType RHS = RHS_NC.getCanonicalType();
-
- // 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.
- if (ReferenceType *RT = dyn_cast<ReferenceType>(LHS))
- LHS = RT->getPointeeType();
- if (ReferenceType *RT = dyn_cast<ReferenceType>(RHS))
- RHS = RT->getPointeeType();
-
- // If two types are identical, they are compatible.
- if (LHS == RHS)
- return true;
-
- // If qualifiers differ, the types are different.
- unsigned LHSAS = LHS.getAddressSpace(), RHSAS = RHS.getAddressSpace();
- if (LHS.getCVRQualifiers() != RHS.getCVRQualifiers() || LHSAS != RHSAS)
- return false;
-
- // Strip off ASQual's if present.
- if (LHSAS) {
- LHS = LHS.getUnqualifiedType();
- RHS = RHS.getUnqualifiedType();
- }
-
- Type::TypeClass LHSClass = LHS->getTypeClass();
- Type::TypeClass RHSClass = RHS->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 interface types.
- if (isa<ObjCInterfaceType>(LHS))
- return isObjCIdType(RHS);
- if (isa<ObjCInterfaceType>(RHS))
- return isObjCIdType(LHS);
-
- // C99 6.7.2.2p4: Each enumerated type shall be compatible with char,
- // a signed integer type, or an unsigned integer type.
- if (LHS->isEnumeralType() && RHS->isIntegralType()) {
- EnumDecl* EDecl = cast<EnumType>(LHS)->getDecl();
- return EDecl->getIntegerType() == RHS;
- }
- if (RHS->isEnumeralType() && LHS->isIntegralType()) {
- EnumDecl* EDecl = cast<EnumType>(RHS)->getDecl();
- return EDecl->getIntegerType() == LHS;
- }
-
- return false;
- }
-
- // The canonical type classes match.
- switch (LHSClass) {
- case Type::ASQual:
- case Type::FunctionProto:
- case Type::VariableArray:
- case Type::IncompleteArray:
- case Type::Reference:
- case Type::ObjCQualifiedInterface:
- assert(0 && "Canonicalized away above");
- case Type::Pointer:
- return pointerTypesAreCompatible(LHS, RHS);
- case Type::ConstantArray:
- return areCompatArrayTypes(cast<ArrayType>(LHS), cast<ArrayType>(RHS),
- *this);
- case Type::FunctionNoProto:
- return functionTypesAreCompatible(LHS, RHS);
- case Type::Tagged: // handle structures, unions
- return areCompatTagTypes(cast<TagType>(LHS), cast<TagType>(RHS), *this);
- case Type::Builtin:
- // Only exactly equal builtin types are compatible, which is tested above.
- return false;
- case Type::Vector:
- return areCompatVectorTypes(cast<VectorType>(LHS), cast<VectorType>(RHS));
- case Type::ObjCInterface:
- return areCompatObjCInterfaces(cast<ObjCInterfaceType>(LHS),
- cast<ObjCInterfaceType>(RHS));
- default:
- assert(0 && "unexpected type");
- }
- return true; // should never get here...
-}
-
-//===----------------------------------------------------------------------===//
-// Serialization Support
-//===----------------------------------------------------------------------===//
-
-/// Emit - Serialize an ASTContext object to Bitcode.
-void ASTContext::Emit(llvm::Serializer& S) const {
- 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) {
- 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(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 e2bf5ca007b5..000000000000
--- a/clang/lib/AST/Builtins.cpp
+++ /dev/null
@@ -1,195 +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/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] != '.')
- ArgTypes.push_back(DecodeTypeFromStr(TypeStr, Context));
-
- 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 aa5bbe437daf..000000000000
--- a/clang/lib/AST/CFG.cpp
+++ /dev/null
@@ -1,1634 +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/Expr.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 <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;
-};
-
-/// CFGBuilder - This class is 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();
- }
-
-private:
- CFGBlock* createBlock(bool add_successor = true);
- CFGBlock* addStmt(Stmt* Terminator);
- CFGBlock* WalkAST(Stmt* Terminator, bool AlwaysAddStmt);
- CFGBlock* WalkAST_VisitChildren(Stmt* Terminator);
- CFGBlock* WalkAST_VisitDeclSubExprs(StmtIterator& I);
- CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* Terminator);
- void FinishBlock(CFGBlock* B);
-
- bool badCFG;
-};
-
-/// 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: {
- ScopedDecl* D = cast<DeclStmt>(Terminator)->getDecl();
- Block->appendStmt(Terminator);
-
- StmtIterator I(D);
- return WalkAST_VisitDeclSubExprs(I);
- }
-
- 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::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());
-
- // 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;
- }
-
- case Stmt::ParenExprClass:
- return WalkAST(cast<ParenExpr>(Terminator)->getSubExpr(), AlwaysAddStmt);
-
- default:
- break;
- };
-
- if (AlwaysAddStmt) Block->appendStmt(Terminator);
- return WalkAST_VisitChildren(Terminator);
-}
-
-/// WalkAST_VisitDeclSubExprs - Utility method to handle Decls contained in
-/// DeclStmts. Because the initialization code (and sometimes the
-/// the type declarations) for DeclStmts can contain arbitrary expressions,
-/// we must linearize declarations to handle arbitrary control-flow induced by
-/// those expressions.
-CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExprs(StmtIterator& I) {
- if (I == StmtIterator())
- return Block;
-
- Stmt* Terminator = *I;
- ++I;
- WalkAST_VisitDeclSubExprs(I);
-
- // Optimization: Don't create separate block-level statements for literals.
-
- switch (Terminator->getStmtClass()) {
- case Stmt::IntegerLiteralClass:
- case Stmt::CharacterLiteralClass:
- case Stmt::StringLiteralClass:
- break;
-
- // All other cases.
-
- default:
- Block = addStmt(Terminator);
- }
-
- 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);
-
- // 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;
-
- // Create a new block to contain the (bottom) of the loop body.
- Block = NULL;
-
- // If we have increment code, insert it at the end of the body block.
- if (Stmt* I = F->getInc()) Block = addStmt(I);
-
- // 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();
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Internal Block-Edge Set; used for modeling persistent <CFGBlock*,CFGBlock*>
-// pairs for use with ProgramPoint.
-//===----------------------------------------------------------------------===//
-
-typedef std::pair<CFGBlock*,CFGBlock*> BPairTy;
-
-namespace llvm {
- template<> struct FoldingSetTrait<BPairTy*> {
- static void Profile(const BPairTy* X, FoldingSetNodeID& profile) {
- profile.AddPointer(X->first);
- profile.AddPointer(X->second);
- }
- };
-}
-
-typedef llvm::FoldingSetNodeWrapper<BPairTy*> PersistPairTy;
-typedef llvm::FoldingSet<PersistPairTy> BlkEdgeSetTy;
-
-const std::pair<CFGBlock*,CFGBlock*>*
-CFG::getBlockEdgeImpl(const CFGBlock* B1, const CFGBlock* B2) {
-
- llvm::BumpPtrAllocator*& Alloc =
- reinterpret_cast<llvm::BumpPtrAllocator*&>(Allocator);
-
- if (!Alloc)
- Alloc = new llvm::BumpPtrAllocator();
-
- BlkEdgeSetTy*& p = reinterpret_cast<BlkEdgeSetTy*&>(BlkEdgeSet);
-
- if (!p)
- p = new BlkEdgeSetTy();
-
- // Profile the edges.
- llvm::FoldingSetNodeID profile;
- void* InsertPos;
-
- profile.AddPointer(B1);
- profile.AddPointer(B2);
-
- PersistPairTy* V = p->FindNodeOrInsertPos(profile, InsertPos);
-
- if (!V) {
- assert (llvm::AlignOf<BPairTy>::Alignment_LessEqual_8Bytes);
-
- // Allocate the pair, forcing an 8-byte alignment.
- BPairTy* pair = (BPairTy*) Alloc->Allocate(sizeof(*pair), 8);
-
- new (pair) BPairTy(const_cast<CFGBlock*>(B1),
- const_cast<CFGBlock*>(B2));
-
- // Allocate the meta data to store the pair in the FoldingSet.
- PersistPairTy* ppair = (PersistPairTy*) Alloc->Allocate<PersistPairTy>();
- new (ppair) PersistPairTy(pair);
-
- p->InsertNode(ppair, InsertPos);
-
- return pair;
- }
-
- return V->getValue();
-}
-
-//===----------------------------------------------------------------------===//
-// Cleanup: CFG dstor.
-//===----------------------------------------------------------------------===//
-
-CFG::~CFG() {
- delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
- delete reinterpret_cast<BlkEdgeSetTy*>(BlkEdgeSet);
- delete reinterpret_cast<llvm::BumpPtrAllocator*> (Allocator);
-}
-
-//===----------------------------------------------------------------------===//
-// 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, std::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> {
-
- std::ostream& OS;
- StmtPrinterHelper* Helper;
-public:
- CFGBlockTerminatorPrint(std::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(std::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(std::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 << std::setw(3) << 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::cerr.stream()); }
-
-/// print - A simple pretty printer of a CFG that outputs to an ostream.
-void CFG::print(std::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::cerr.stream(), 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(std::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(std::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;
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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::ostringstream Out;
- 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 1a7eecac32ad..000000000000
--- a/clang/lib/AST/Decl.cpp
+++ /dev/null
@@ -1,574 +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 class and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
-#include "clang/Basic/IdentifierTable.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 nEnumConst = 0;
-static unsigned nEnumDecls = 0;
-static unsigned nNamespaces = 0;
-static unsigned nTypedef = 0;
-static unsigned nFieldDecls = 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 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 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+
- nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
- nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
- 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 struct/union/class decls, %d each (%d bytes)\n",
- nSUC, (int)sizeof(RecordDecl),
- int(nSUC*sizeof(RecordDecl)));
- 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)+
- 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 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 TranslationUnit: break;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// 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);
-}
-
-VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, QualType T,
- StorageClass S, ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<VarDecl>();
- return new (Mem) VarDecl(Var, DC, L, Id, T, S, PrevDecl);
-}
-
-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) {
- void *Mem = C.getAllocator().Allocate<FunctionDecl>();
- return new (Mem) FunctionDecl(DC, L, Id, T, S, isInline, PrevDecl);
-}
-
-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);
-}
-
-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);
-}
-
-RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ScopedDecl *PrevDecl) {
- void *Mem = C.getAllocator().Allocate<RecordDecl>();
- return new (Mem) RecordDecl(DK, DC, L, Id, PrevDecl);
-}
-
-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);
-}
-
-//===----------------------------------------------------------------------===//
-// 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!");
-
- delete it->second;
- DeclAttrs->erase(it);
- if (DeclAttrs->empty()) {
- delete DeclAttrs;
- DeclAttrs = 0;
- }
-}
-
-void Decl::addAttr(Attr *NewAttr) {
- if (!DeclAttrs)
- DeclAttrs = new DeclAttrMapTy();
-
- Attr *&ExistingAttr = (*DeclAttrs)[this];
-
- NewAttr->setNext(ExistingAttr);
- ExistingAttr = NewAttr;
-
- HasAttrs = true;
-}
-
-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;
-}
-
-
-#define CASE(KIND) \
- case KIND: \
- static_cast<KIND##Decl *>(const_cast<Decl *>(this))->~KIND##Decl(); \
- break
-
-void Decl::Destroy(ASTContext& C) const {
- switch (getKind()) {
- CASE(TranslationUnit);
- CASE(Field);
- CASE(ObjCIvar);
- CASE(ObjCCategory);
- CASE(ObjCCategoryImpl);
- CASE(ObjCImplementation);
- CASE(ObjCProtocol);
- CASE(ObjCProperty);
- CASE(Namespace);
- CASE(Typedef);
- CASE(Enum);
- CASE(EnumConstant);
- CASE(Function);
- CASE(Var);
- CASE(ParmVar);
- CASE(ObjCInterface);
- CASE(ObjCCompatibleAlias);
- CASE(ObjCMethod);
- CASE(ObjCClass);
- CASE(ObjCForwardProtocol);
- CASE(LinkageSpec);
-
- case Struct: case Union: case Class:
- static_cast<RecordDecl *>(const_cast<Decl *>(this))->~RecordDecl();
- break;
-
- default: assert(0 && "Unknown decl kind!");
- }
-
- C.getAllocator().Deallocate((void *)this);
-}
-
-#undef CASE
-
-//===----------------------------------------------------------------------===//
-// 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);
-}
-
-//===----------------------------------------------------------------------===//
-// NamedDecl Implementation
-//===----------------------------------------------------------------------===//
-
-const char *NamedDecl::getName() const {
- if (const IdentifierInfo *II = getIdentifier())
- return II->getName();
- return "";
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionDecl Implementation
-//===----------------------------------------------------------------------===//
-
-FunctionDecl::~FunctionDecl() {
- delete[] ParamInfo;
- delete Body;
- delete PreviousDeclaration;
-}
-
-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;
-}
-
-/// AddRedeclaration - Specifies that this function declaration has been
-/// redeclared by the function declaration FD. FD must be a
-/// redeclaration of this based on the semantics of the language being
-/// translated ("compatible" function types in C, same signatures in
-/// C++).
-void FunctionDecl::AddRedeclaration(FunctionDecl *FD) {
- assert(FD->PreviousDeclaration == 0 &&
- "Redeclaration already has a previous declaration!");
-
- // Insert FD into the list of previous declarations of this
- // function.
- FD->PreviousDeclaration = this->PreviousDeclaration;
- this->PreviousDeclaration = FD;
-
- // Swap the contents of this function declaration and FD. This
- // effectively transforms the original declaration into the most
- // recent declaration, so that all references to this declaration
- // remain valid (and have information from *all* declarations),
- // while retaining all of the information about previous
- // declarations as well.
-
- // Swap parameters, so that the most recent parameter names and
- // exact types (e.g., enum vs int) show up in the original
- // declaration.
- std::swap(this->ParamInfo, FD->ParamInfo);
-
- // Swap the function body: all declarations share the same function
- // body, but we keep track of who actually defined that function
- // body by keeping the pointer to the body stored in that node.
- std::swap(this->Body, FD->Body);
-
- // Swap type information: this is important because in C, later
- // declarations can provide slightly different types (enum vs. int,
- // for example).
- QualType thisType = this->getType();
- this->setType(FD->getType());
- FD->setType(thisType);
-
- // Swap location information: this allows us to produce diagnostics
- // later on that reference the most recent declaration (which has
- // the most information!) while retaining the location of previous
- // declarations (good for "redefinition" diagnostics).
- SourceLocation thisLocation = this->getLocation();
- this->setLocation(FD->getLocation());
- FD->setLocation(thisLocation);
-
- // Swap attributes. FD will have the union of the attributes from
- // all previous declarations.
- this->swapAttrs(FD);
-
- // If any declaration is inline, the function is inline.
- this->IsInline |= FD->IsInline;
-
- // FIXME: Is this the right way to handle storage specifiers?
- if (FD->SClass) this->SClass = FD->SClass;
-}
-
-//===----------------------------------------------------------------------===//
-// RecordDecl Implementation
-//===----------------------------------------------------------------------===//
-
-/// 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(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*));
- }
-}
-
-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/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
deleted file mode 100644
index cda73d2ff9cd..000000000000
--- a/clang/lib/AST/DeclObjC.cpp
+++ /dev/null
@@ -1,589 +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"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// ObjC Decl Allocation/Deallocation Method Implementations
-//===----------------------------------------------------------------------===//
-
-ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc,
- Selector SelInfo, QualType T,
- Decl *contextDecl,
- AttributeList *M, bool isInstance,
- bool isVariadic,
- bool isSynthesized,
- ImplementationControl impControl) {
- void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
- return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
- SelInfo, T, contextDecl,
- M, isInstance,
- isVariadic, isSynthesized, impControl);
-}
-
-ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
- SourceLocation atLoc,
- unsigned numRefProtos,
- IdentifierInfo *Id,
- SourceLocation ClassLoc,
- bool ForwardDecl, bool isInternal){
- void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
- return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
- Id, ClassLoc, ForwardDecl,
- isInternal);
-}
-
-ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T) {
- void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
- return new (Mem) ObjCIvarDecl(L, Id, T);
-}
-
-ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
- SourceLocation L,
- unsigned numRefProtos,
- IdentifierInfo *Id) {
- void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
- return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
-}
-
-ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
- SourceLocation L,
- ObjCInterfaceDecl **Elts, unsigned nElts) {
- void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
- return new (Mem) ObjCClassDecl(L, Elts, nElts);
-}
-
-ObjCForwardProtocolDecl *
-ObjCForwardProtocolDecl::Create(ASTContext &C,
- SourceLocation L,
- ObjCProtocolDecl **Elts, unsigned NumElts) {
- void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
- return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
-}
-
-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::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;
- }
-}
-
-ObjCMethodDecl::~ObjCMethodDecl() {
- delete[] ParamInfo;
-}
-
-/// 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;
- }
- 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*));
- free(PropertyDecl);
- PropertyDecl = newPropertyDecl;
- NumPropertyDecl += NumNewProperties;
- }
- else {
- PropertyDecl = new ObjCPropertyDecl*[NumNewProperties];
- memcpy(PropertyDecl, Properties, NumNewProperties*sizeof(ObjCPropertyDecl*));
- NumPropertyDecl = NumNewProperties;
- }
-}
-
-/// 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) {
- // Find the default getter and if one not found, add one.
- ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
- if (GetterDecl) {
- // An instance method with same name as property getter name found.
- property->setGetterMethodDecl(GetterDecl);
- }
- else {
- // 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.
- QualType resultDeclType = property->getType();
- ObjCMethodDecl* ObjCMethod =
- ObjCMethodDecl::Create(Context, property->getLocation(),
- property->getLocation(),
- property->getGetterName(), resultDeclType,
- this, 0,
- true, false, true, ObjCMethodDecl::Required);
- property->setGetterMethodDecl(ObjCMethod);
- insMethods.push_back(ObjCMethod);
- }
-}
-
-/// 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;
-}
-
-void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
- unsigned NumRPs) {
- assert(NumReferencedProtocols == 0 && "Protocol list already set");
- if (NumRPs == 0) return;
-
- ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
- memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
- NumReferencedProtocols = NumRPs;
-}
-
-
-/// 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;
-}
-
-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.
- ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
- int numProtocols = ClassDecl->getNumIntfRefProtocols();
- for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
- if ((MethodDecl = protocols[pIdx]->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.
- ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
- int numProtocols = ClassDecl->getNumIntfRefProtocols();
- for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
- if ((MethodDecl = protocols[pIdx]->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;
-}
-
-/// lookupInstanceMethod - 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) {
- for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
- if ((*I)->getSelector() == Sel)
- return *I;
- return NULL;
-}
-
-/// lookupClassMethod - 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) {
- 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) {
- 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) {
- 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;
-
- if (getNumReferencedProtocols() > 0) {
- ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
-
- for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
- if ((MethodDecl = RefPDecl[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;
-
- if (getNumReferencedProtocols() > 0) {
- ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
-
- for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
- if ((MethodDecl = RefPDecl[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,
- PropertyImplKind kind,
- ObjCIvarDecl *ivar) {
- void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
- return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
-}
-
-
diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp
deleted file mode 100644
index cbae83130827..000000000000
--- a/clang/lib/AST/DeclSerialization.cpp
+++ /dev/null
@@ -1,513 +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);
-}
-
-Decl* Decl::Create(Deserializer& D, ASTContext& C) {
-
- Kind k = static_cast<Kind>(D.ReadInt());
-
- switch (k) {
- default:
- assert (false && "Not implemented.");
- break;
-
- case TranslationUnit:
- return TranslationUnitDecl::CreateImpl(D, C);
-
- case Namespace:
- return NamespaceDecl::CreateImpl(D, C);
-
- case Var:
- return VarDecl::CreateImpl(D, C);
-
- case Enum:
- return EnumDecl::CreateImpl(D, C);
-
- case EnumConstant:
- return EnumConstantDecl::CreateImpl(D, C);
-
- case Field:
- return FieldDecl::CreateImpl(D, C);
-
- case ParmVar:
- return ParmVarDecl::CreateImpl(D, C);
-
- case Function:
- return FunctionDecl::CreateImpl(D, C);
-
- case Union:
- case Struct:
- return RecordDecl::CreateImpl(k, D, C);
-
- case Typedef:
- return TypedefDecl::CreateImpl(D, C);
-
- case FileScopeAsm:
- return FileScopeAsmDecl::CreateImpl(D, C);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// 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 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.
- Decl *TmpD;
- D.ReadPtr(TmpD); // From ScopedDecl.
- DeclCtx = cast_or_null<DeclContext>(TmpD);
-}
-
- //===------------------------------------------------------------===//
- // 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(ElementList,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->ElementList = 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(DeclChain);
-
- // 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(0, SourceLocation(), NULL, QualType(), SClass, IsInline, 0);
-
- decl->ValueDecl::ReadInRec(D, C);
- D.ReadPtr(decl->DeclChain);
-
- 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],getNextDeclarator());
- }
- 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, NULL);
-
- decl->ScopedDecl::ReadInRec(D, C);
- decl->setDefinition(D.ReadBool());
- decl->setHasFlexibleArrayMember(D.ReadBool());
- decl->NumMembers = D.ReadSInt();
-
- if (decl->getNumMembers() > 0) {
- Decl* next_declarator;
- decl->Members = new FieldDecl*[(unsigned) decl->getNumMembers()];
-
- D.BatchReadOwnedPtrs((unsigned) decl->getNumMembers(),
- (Decl**) &decl->Members[0],
- next_declarator, C);
-
- decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
- }
- 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 61c21b067569..000000000000
--- a/clang/lib/AST/Expr.cpp
+++ /dev/null
@@ -1,1421 +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/ASTContext.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Primary Expressions.
-//===----------------------------------------------------------------------===//
-
-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;
- }
-}
-
-/// 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 Expr*[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.
- Expr **NewSubExprs = new Expr*[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;
-}
-
-bool CallExpr::isBuiltinConstantExpr() 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 false;
-
- const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
- if (!DRE)
- return false;
-
- const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
- if (!FDecl)
- return false;
-
- unsigned builtinID = FDecl->getIdentifier()->getBuiltinID();
- if (!builtinID)
- return false;
-
- // We have a builtin that is a constant expression
- if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
- return true;
- return false;
-}
-
-bool CallExpr::isBuiltinClassifyType(llvm::APSInt &Result) const {
- // The following enum mimics gcc's internal "typeclass.h" file.
- 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
- };
- Result.setIsSigned(true);
-
- // 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 false;
- const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
- if (!DRE)
- return false;
-
- // We have a DeclRefExpr.
- if (strcmp(DRE->getDecl()->getName(), "__builtin_classify_type") == 0) {
- // If no argument was supplied, default to "no_type_class". This isn't
- // ideal, however it's what gcc does.
- Result = static_cast<uint64_t>(no_type_class);
- if (NumArgs >= 1) {
- QualType argType = getArg(0)->getType();
-
- if (argType->isVoidType())
- Result = void_type_class;
- else if (argType->isEnumeralType())
- Result = enumeral_type_class;
- else if (argType->isBooleanType())
- Result = boolean_type_class;
- else if (argType->isCharType())
- Result = string_type_class; // gcc doesn't appear to use char_type_class
- else if (argType->isIntegerType())
- Result = integer_type_class;
- else if (argType->isPointerType())
- Result = pointer_type_class;
- else if (argType->isReferenceType())
- Result = reference_type_class;
- else if (argType->isRealType())
- Result = real_type_class;
- else if (argType->isComplexType())
- Result = complex_type_class;
- else if (argType->isFunctionType())
- Result = function_type_class;
- else if (argType->isStructureType())
- Result = record_type_class;
- else if (argType->isUnionType())
- Result = union_type_class;
- else if (argType->isArrayType())
- Result = array_type_class;
- else if (argType->isUnionType())
- Result = union_type_class;
- else // FIXME: offset_type_class, method_type_class, & lang_type_class?
- assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
- }
- return true;
- }
- return false;
-}
-
-/// 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]);
-}
-
-//===----------------------------------------------------------------------===//
-// 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 CastExprClass:
- // 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 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() 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() && !TR.getCanonicalType().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();
- return LV_Valid;
- case DeclRefExprClass: // C99 6.5.1p2
- if (isa<VarDecl>(cast<DeclRefExpr>(this)->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();
- }
- 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)
- return cast<UnaryOperator>(this)->getSubExpr()->isLvalue(); // GNU.
- break;
- case ParenExprClass: // C99 6.5.1p5
- return cast<ParenExpr>(this)->getSubExpr()->isLvalue();
- 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 PreDefinedExprClass:
- return LV_Valid;
- case CXXDefaultArgExprClass:
- return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue();
- 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() const {
- isLvalueResult lvalResult = isLvalue();
-
- 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;
- }
- if (TR.isConstQualified())
- return MLV_ConstQualified;
- if (TR->isArrayType())
- return MLV_ArrayType;
- if (TR->isIncompleteType())
- return MLV_IncompleteType;
-
- if (const RecordType *r = dyn_cast<RecordType>(TR.getCanonicalType())) {
- if (r->hasConstFields())
- return MLV_ConstQualified;
- }
- 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 if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(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:
- return true;
- case CallExprClass: {
- const CallExpr *CE = cast<CallExpr>(this);
- llvm::APSInt Result(32);
- Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType())));
- if (CE->isBuiltinClassifyType(Result))
- return true;
- if (CE->isBuiltinConstantExpr())
- 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 CastExprClass: {
- const Expr *SubExpr;
- SourceLocation CastLoc;
- if (const CastExpr *C = dyn_cast<CastExpr>(this)) {
- SubExpr = C->getSubExpr();
- CastLoc = C->getLParenLoc();
- } else {
- SubExpr = cast<ImplicitCastExpr>(this)->getSubExpr();
- 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 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 (CE->isBuiltinClassifyType(Result))
- break;
- 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 = 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);
-
- // The LHS of a constant expr is always evaluated and needed.
- if (!Exp->getLHS()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
- return false;
-
- llvm::APSInt RHS(Result);
-
- // 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 = Result != 0;
- else {
- assert(Exp->getOpcode() == BinaryOperator::LOr &&"Unexpected logical");
- RHSEval = Result == 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 *= RHS;
- break;
- case BinaryOperator::Div:
- if (RHS == 0) {
- if (!isEvaluated) break;
- if (Loc) *Loc = getLocStart();
- return false;
- }
- Result /= RHS;
- break;
- case BinaryOperator::Rem:
- if (RHS == 0) {
- if (!isEvaluated) break;
- if (Loc) *Loc = getLocStart();
- return false;
- }
- Result %= RHS;
- break;
- case BinaryOperator::Add: Result += RHS; break;
- case BinaryOperator::Sub: Result -= RHS; break;
- case BinaryOperator::Shl:
- Result <<=
- static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
- break;
- case BinaryOperator::Shr:
- Result >>=
- static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
- break;
- case BinaryOperator::LT: Result = Result < RHS; break;
- case BinaryOperator::GT: Result = Result > RHS; break;
- case BinaryOperator::LE: Result = Result <= RHS; break;
- case BinaryOperator::GE: Result = Result >= RHS; break;
- case BinaryOperator::EQ: Result = Result == RHS; break;
- case BinaryOperator::NE: Result = Result != RHS; break;
- case BinaryOperator::And: Result &= RHS; break;
- case BinaryOperator::Xor: Result ^= RHS; break;
- case BinaryOperator::Or: Result |= RHS; break;
- case BinaryOperator::LAnd:
- Result = Result != 0 && RHS != 0;
- break;
- case BinaryOperator::LOr:
- Result = Result != 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 CastExprClass: {
- const Expr *SubExpr;
- SourceLocation CastLoc;
- if (const CastExpr *C = dyn_cast<CastExpr>(this)) {
- SubExpr = C->getSubExpr();
- CastLoc = C->getLParenLoc();
- } else {
- SubExpr = cast<ImplicitCastExpr>(this)->getSubExpr();
- 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 CastExpr *CE = dyn_cast<CastExpr>(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.
-llvm::Constant *ExtVectorElementExpr::getEncodedElementAccess() const {
- const char *compStr = Accessor.getName();
- llvm::SmallVector<llvm::Constant *, 8> Indices;
-
- 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]);
-
- Indices.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, Index));
- }
- return llvm::ConstantVector::get(&Indices[0], Indices.size());
-}
-
-unsigned
-ExtVectorElementExpr::getAccessedFieldNo(unsigned Idx,
- const llvm::Constant *Elts) {
- if (isa<llvm::ConstantAggregateZero>(Elts))
- return 0;
-
- return cast<llvm::ConstantInt>(Elts->getOperand(Idx))->getZExtValue();
-}
-
-// 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 Expr*[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 Expr*[NumArgs+1];
- SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | 0x1);
- if (NumArgs) {
- for (unsigned i = 0; i != NumArgs; ++i)
- SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
- }
- LBracloc = LBrac;
- RBracloc = RBrac;
-}
-
-bool ChooseExpr::isConditionTrue(ASTContext &C) const {
- llvm::APSInt CondVal(32);
- bool IsConst = getCond()->isIntegerConstantExpr(CondVal, C);
- assert(IsConst && "Condition of choose expr must be i-c-e"); IsConst=IsConst;
- return CondVal != 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();
- llvm::APSInt Idx(32);
- bool ICE = ASE->getIdx()->isIntegerConstantExpr(Idx, C);
- assert(ICE && "Array index is not a constant integer!");
-
- int64_t size = C.getTypeSize(ASE->getType());
- size *= Idx.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, Val) / CharSize;
-}
-
-//===----------------------------------------------------------------------===//
-// 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 reinterpret_cast<Stmt**>(&Base);
-}
-
-Stmt::child_iterator ObjCIvarRefExpr::child_end() {
- return reinterpret_cast<Stmt**>(&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 reinterpret_cast<Stmt**>(&Val);
-}
-Stmt::child_iterator ImaginaryLiteral::child_end() {
- return reinterpret_cast<Stmt**>(&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 reinterpret_cast<Stmt**>(&Val);
-}
-Stmt::child_iterator ParenExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Val)+1;
-}
-
-// UnaryOperator
-Stmt::child_iterator UnaryOperator::child_begin() {
- return reinterpret_cast<Stmt**>(&Val);
-}
-Stmt::child_iterator UnaryOperator::child_end() {
- return reinterpret_cast<Stmt**>(&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 reinterpret_cast<Stmt**>(&SubExprs);
-}
-Stmt::child_iterator ArraySubscriptExpr::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs)+END_EXPR;
-}
-
-// CallExpr
-Stmt::child_iterator CallExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&SubExprs[0]);
-}
-Stmt::child_iterator CallExpr::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs[NumArgs+ARGS_START]);
-}
-
-// MemberExpr
-Stmt::child_iterator MemberExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Base);
-}
-Stmt::child_iterator MemberExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Base)+1;
-}
-
-// ExtVectorElementExpr
-Stmt::child_iterator ExtVectorElementExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Base);
-}
-Stmt::child_iterator ExtVectorElementExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Base)+1;
-}
-
-// CompoundLiteralExpr
-Stmt::child_iterator CompoundLiteralExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Init);
-}
-Stmt::child_iterator CompoundLiteralExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Init)+1;
-}
-
-// ImplicitCastExpr
-Stmt::child_iterator ImplicitCastExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Op);
-}
-Stmt::child_iterator ImplicitCastExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Op)+1;
-}
-
-// CastExpr
-Stmt::child_iterator CastExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Op);
-}
-Stmt::child_iterator CastExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Op)+1;
-}
-
-// BinaryOperator
-Stmt::child_iterator BinaryOperator::child_begin() {
- return reinterpret_cast<Stmt**>(&SubExprs);
-}
-Stmt::child_iterator BinaryOperator::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs)+END_EXPR;
-}
-
-// ConditionalOperator
-Stmt::child_iterator ConditionalOperator::child_begin() {
- return reinterpret_cast<Stmt**>(&SubExprs);
-}
-Stmt::child_iterator ConditionalOperator::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs)+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 reinterpret_cast<Stmt**>(&SubStmt);
-}
-Stmt::child_iterator StmtExpr::child_end() {
- return reinterpret_cast<Stmt**>(&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 reinterpret_cast<Stmt**>(&SubExprs);
-}
-
-Stmt::child_iterator ChooseExpr::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs)+END_EXPR;
-}
-
-// OverloadExpr
-Stmt::child_iterator OverloadExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&SubExprs[0]);
-}
-Stmt::child_iterator OverloadExpr::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs[NumExprs]);
-}
-
-// VAArgExpr
-Stmt::child_iterator VAArgExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Val);
-}
-
-Stmt::child_iterator VAArgExpr::child_end() {
- return reinterpret_cast<Stmt**>(&Val)+1;
-}
-
-// InitListExpr
-Stmt::child_iterator InitListExpr::child_begin() {
- return reinterpret_cast<Stmt**>(InitExprs.size() ?
- &InitExprs[0] : 0);
-}
-Stmt::child_iterator InitListExpr::child_end() {
- return reinterpret_cast<Stmt**>(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 reinterpret_cast<Stmt**>(&SubExprs[ getReceiver() ? 0 : ARGS_START ]);
-}
-Stmt::child_iterator ObjCMessageExpr::child_end() {
- return reinterpret_cast<Stmt**>(&SubExprs[getNumArgs()+ARGS_START]);
-}
-
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
deleted file mode 100644
index 323fdd67a17e..000000000000
--- a/clang/lib/AST/ExprCXX.cpp
+++ /dev/null
@@ -1,55 +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;
-
-//===----------------------------------------------------------------------===//
-// Child Iterators for iterating over subexpressions/substatements
-//===----------------------------------------------------------------------===//
-
-
-// CXXCastExpr
-Stmt::child_iterator CXXCastExpr::child_begin() {
- return reinterpret_cast<Stmt**>(&Op);
-}
-Stmt::child_iterator CXXCastExpr::child_end() {
- return reinterpret_cast<Stmt**>(&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 reinterpret_cast<Stmt**>(&Op);
-}
-Stmt::child_iterator CXXThrowExpr::child_end() {
- // If Op is 0, we are processing throw; which has no children.
- if (Op == 0)
- return reinterpret_cast<Stmt**>(&Op)+0;
- return reinterpret_cast<Stmt**>(&Op)+1;
-}
-
-// CXXDefaultArgExpr
-Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
- return child_iterator();
-}
-Stmt::child_iterator CXXDefaultArgExpr::child_end() {
- return child_iterator();
-}
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/Stmt.cpp b/clang/lib/AST/Stmt.cpp
deleted file mode 100644
index 572280bc0545..000000000000
--- a/clang/lib/AST/Stmt.cpp
+++ /dev/null
@@ -1,293 +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/StmtVisitor.h"
-#include "clang/Basic/IdentifierTable.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::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;
- if (!atCatchList)
- SubExprs[NEXT_CATCH] = NULL;
- else {
- 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 getDecl(); }
-Stmt::child_iterator DeclStmt::child_end() { return child_iterator(); }
-
-// 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
-Stmt::child_iterator IndirectGotoStmt::child_begin() {
- return reinterpret_cast<Stmt**>(&Target);
-}
-
-Stmt::child_iterator IndirectGotoStmt::child_end() { return ++child_begin(); }
-
-// 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
-Stmt::child_iterator ReturnStmt::child_begin() {
- if (RetExpr) return reinterpret_cast<Stmt**>(&RetExpr);
- else return child_iterator();
-}
-
-Stmt::child_iterator ReturnStmt::child_end() {
- if (RetExpr) return reinterpret_cast<Stmt**>(&RetExpr)+1;
- else return child_iterator();
-}
-
-// 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 77fbad5faa79..000000000000
--- a/clang/lib/AST/StmtDumper.cpp
+++ /dev/null
@@ -1,490 +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/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Basic/IdentifierTable.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 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 (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
- ++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'\n", 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::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->getBase());
-
- fprintf(F, " ObjCIvarRefExpr");
- fprintf(F, "='%s' %p", Node->getDecl()->getName(), (void*)Node->getDecl());
-}
-
-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;
- }
-}
-
-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->getValueAsDouble());
-}
-
-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());
-}
-//===----------------------------------------------------------------------===//
-// 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 14083e30a992..000000000000
--- a/clang/lib/AST/StmtIterator.cpp
+++ /dev/null
@@ -1,118 +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/Expr.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 && decl) {
- if (VarDecl* VD = dyn_cast<VarDecl>(decl))
- if (VD->Init)
- return;
-
- NextDecl();
- }
- else {
- 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 reinterpret_cast<Stmt*&>(VAPtr->SizeExpr);
- }
-
- if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
- assert (VD->Init);
- return reinterpret_cast<Stmt*&>(VD->Init);
- }
-
- EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
- return reinterpret_cast<Stmt*&>(ECD->Init);
-}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
deleted file mode 100644
index bd6d0d44bf21..000000000000
--- a/clang/lib/AST/StmtPrinter.cpp
+++ /dev/null
@@ -1,869 +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/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Streams.h"
-#include <iomanip>
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// StmtPrinter Visitor
-//===----------------------------------------------------------------------===//
-
-namespace {
- class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
- std::ostream &OS;
- unsigned IndentLevel;
- clang::PrinterHelper* Helper;
- public:
- StmtPrinter(std::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 PrintRawIfStmt(IfStmt *If);
-
- void PrintExpr(Expr *E) {
- if (E)
- Visit(E);
- else
- OS << "<null expr>";
- }
-
- std::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::VisitNullStmt(NullStmt *Node) {
- Indent() << ";\n";
-}
-
-void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
- for (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
- Indent();
- PrintRawDecl(D);
- 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()))
- PrintRawDecl(DS->getDecl());
- 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()))
- PrintRawDecl(DS->getDecl());
- 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()))
- PrintRawDecl(DS->getDecl());
- }
- 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::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;
- }
-}
-
-void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
- // FIXME should print an L for wchar_t constants
- unsigned value = Node->getValue();
- 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" << std::hex << value << std::dec << "'";
- } 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 (cast<BuiltinType>(Node->getType().getCanonicalType())->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->getValueAsDouble();
-}
-
-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 *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::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
-}
-
-// 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 << "]";
-}
-
-//===----------------------------------------------------------------------===//
-// Stmt method implementations
-//===----------------------------------------------------------------------===//
-
-void Stmt::dumpPretty() const {
- printPretty(*llvm::cerr.stream());
-}
-
-void Stmt::printPretty(std::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 adaa559b06fe..000000000000
--- a/clang/lib/AST/StmtSerialization.cpp
+++ /dev/null
@@ -1,1082 +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 "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 CastExprClass:
- return CastExpr::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 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);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// 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();
- Expr** SubExprs = new Expr*[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 CastExpr::EmitImpl(Serializer& S) const {
- S.Emit(getType());
- S.Emit(Loc);
- S.EmitOwnedPtr(Op);
-}
-
-CastExpr* CastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- QualType t = QualType::ReadVal(D);
- SourceLocation Loc = SourceLocation::ReadVal(D);
- Expr* Op = D.ReadOwnedPtr<Expr>(C);
- return new CastExpr(t,Op,Loc);
-}
-
-
-void CharacterLiteral::EmitImpl(Serializer& S) const {
- S.Emit(Value);
- S.Emit(Loc);
- S.Emit(getType());
-}
-
-CharacterLiteral* CharacterLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
- unsigned value = D.ReadInt();
- SourceLocation Loc = SourceLocation::ReadVal(D);
- QualType T = QualType::ReadVal(D);
- return new CharacterLiteral(value,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 {
- // FIXME: special handling for struct decls.
- S.EmitOwnedPtr(getDecl());
- S.Emit(StartLoc);
- S.Emit(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);
-}
-
-DeclStmt* DeclStmt::CreateImpl(Deserializer& D, ASTContext& C) {
- ScopedDecl* decl = cast<ScopedDecl>(D.ReadOwnedPtr<Decl>(C));
- SourceLocation StartLoc = SourceLocation::ReadVal(D);
- SourceLocation EndLoc = SourceLocation::ReadVal(D);
- return new DeclStmt(decl, StartLoc, EndLoc);
-}
-
-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(Op);
-}
-
-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 ObjCMessageExpr::EmitImpl(Serializer& S) const {
- S.EmitBool(getReceiver() ? true : false);
- 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 {
- S.EmitPtr(getClassName());
- S.BatchEmitOwnedPtrs(NumArgs, &SubExprs[ARGS_START]);
- }
-}
-
-ObjCMessageExpr* ObjCMessageExpr::CreateImpl(Deserializer& D, ASTContext& C) {
- bool isReceiver = D.ReadBool();
- 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();
- Expr** SubExprs = new Expr*[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 (isReceiver)
- D.BatchReadOwnedPtrs(NumArgs+1, SubExprs, C);
- else {
- // Read the pointer for ClassName. The Deserializer will handle the
- // bit-mangling automatically.
- SubExprs[RECEIVER] = (Expr*) ((uintptr_t) 0x1);
- 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);
-}
-
-//===----------------------------------------------------------------------===//
-// 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);
-}
diff --git a/clang/lib/AST/StmtViz.cpp b/clang/lib/AST/StmtViz.cpp
deleted file mode 100644
index 51d514b20aaa..000000000000
--- a/clang/lib/AST/StmtViz.cpp
+++ /dev/null
@@ -1,59 +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::ostringstream Out;
-
- 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 5c043efeb317..000000000000
--- a/clang/lib/AST/TranslationUnit.cpp
+++ /dev/null
@@ -1,245 +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 <stdio.h>
-
-using namespace clang;
-
-enum { BasicMetadataBlock = 1,
- ASTContextBlock = 2,
- DeclsBlock = 3 };
-
-TranslationUnit::~TranslationUnit() {
- for (iterator I=begin(), E=end(); I!=E; ++I)
- (*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::EmitASTBitcodeFile(const TranslationUnit& TU,
- const llvm::sys::Path& Filename) {
-
- // Reserve 256K for bitstream buffer.
- std::vector<unsigned char> Buffer;
- Buffer.reserve(256*1024);
-
- // 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);
- }
-
- // 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, LangOptions, 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 LangOptions.
- Sezr.Emit(LangOpts);
-
- // 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::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;
- }
-
- // 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* 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 LangOptions.
- TU->LangOpts.Read(Dezr);
-
- { // 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 741d59bc7668..000000000000
--- a/clang/lib/AST/Type.cpp
+++ /dev/null
@@ -1,1022 +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/Type.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/ADT/StringExtras.h"
-#include <sstream>
-using namespace clang;
-
-Type::~Type() {}
-
-/// 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);
- const Decl::Kind Kind = TT->getDecl()->getKind();
- return Kind == Decl::Struct || Kind == Decl::Union;
- }
- default:
- return false;
- }
-}
-
-bool Type::isClassType() const {
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
- if (RT->getDecl()->getKind() == Decl::Class)
- return true;
- return false;
-}
-bool Type::isStructureType() const {
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
- if (RT->getDecl()->getKind() == Decl::Struct)
- return true;
- return false;
-}
-bool Type::isUnionType() const {
- if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType))
- if (RT->getDecl()->getKind() == Decl::Union)
- 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();
-}
-
-/// 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.
-const Type *Type::getDesugaredType() const {
- if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
- return TDT->LookThroughTypedefs().getTypePtr();
- if (const TypeOfExpr *TOE = dyn_cast<TypeOfExpr>(this))
- return TOE->getUnderlyingExpr()->getType().getTypePtr();
- if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
- return TOT->getUnderlyingType().getTypePtr();
- return this;
-}
-
-
-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 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 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();
-}
-
-const ArrayType *Type::getAsArrayType() const {
- // If this is directly an array type, return it.
- if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
- return ATy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ArrayType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<ArrayType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsArrayType();
- return 0;
- }
-
- // If this is a typedef for an array type, strip the typedef off without
- // losing all typedef information.
- return getDesugaredType()->getAsArrayType();
-}
-
-const ConstantArrayType *Type::getAsConstantArrayType() const {
- // If this is directly a constant array type, return it.
- if (const ConstantArrayType *ATy = dyn_cast<ConstantArrayType>(this))
- return ATy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ConstantArrayType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<ConstantArrayType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsConstantArrayType();
- return 0;
- }
-
- // If this is a typedef for a constant array type, strip the typedef off
- // without losing all typedef information.
- return getDesugaredType()->getAsConstantArrayType();
-}
-
-const VariableArrayType *Type::getAsVariableArrayType() const {
- // If this is directly a variable array type, return it.
- if (const VariableArrayType *ATy = dyn_cast<VariableArrayType>(this))
- return ATy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<VariableArrayType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<VariableArrayType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsVariableArrayType();
- return 0;
- }
-
- // If this is a typedef for a variable array type, strip the typedef off
- // without losing all typedef information.
- return getDesugaredType()->getAsVariableArrayType();
-}
-
-/// 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 veriably modified type
- if (getAsVariableArrayType())
- return true;
-
- // An array can contain a variably modified type
- if (const ArrayType* AT = getAsArrayType())
- return AT->getElementType()->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;
-}
-
-bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType);
-}
-
-const IncompleteArrayType *Type::getAsIncompleteArrayType() const {
- // If this is directly a variable array type, return it.
- if (const IncompleteArrayType *ATy = dyn_cast<IncompleteArrayType>(this))
- return ATy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<IncompleteArrayType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsIncompleteArrayType();
- return 0;
- }
-
- // If this is a typedef for a variable array type, strip the typedef off
- // without losing all typedef information.
- return getDesugaredType()->getAsIncompleteArrayType();
-}
-
-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()->getKind() == Decl::Struct)
- 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()->getKind() != Decl::Struct)
- 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()->getKind() == Decl::Union)
- 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()->getKind() != Decl::Union)
- 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 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))
- if (TT->getDecl()->getKind() == Decl::Enum)
- 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()->getKind() == Decl::Enum)
- return true;
- 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()->getKind() == Decl::Enum;
- 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;
-}
-
-/// 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()->getKind() == Decl::Enum;
- 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)) {
- if (TT->getDecl()->getKind() == Decl::Enum)
- return true;
- return false;
- }
- if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
- return ASQT->getBaseType()->isScalarType();
- return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
- isa<ObjCQualifiedIdType>(CanonicalType);
-}
-
-bool Type::isAggregateType() const {
- if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
- if (TT->getDecl()->getKind() == Decl::Struct)
- 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";
- }
-}
-
-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 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());
-}
-
-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 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::ostringstream s;
- getSizeExpr()->printPretty(s);
- S += s.str();
- }
- S += ']';
-
- getElementType().getAsStringInternal(S);
-}
-
-void VectorType::getAsStringInternal(std::string &S) const {
- S += " __attribute__((__vector_size__(";
- // FIXME: should multiply by element size somehow.
- S += llvm::utostr_32(NumElements*4); // convert back to bytes.
- S += ")))";
- ElementType.getAsStringInternal(S);
-}
-
-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::ostringstream s;
- 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 += '<';
- int num = getNumProtocols();
- for (int i = 0; i < num; i++) {
- ObjCQIString += getProtocols(i)->getName();
- if (i < num-1)
- ObjCQIString += ',';
- }
- 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 ff86d82f2668..000000000000
--- a/clang/lib/AST/TypeSerialization.cpp
+++ /dev/null
@@ -1,293 +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/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::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();
-}
-
-//===----------------------------------------------------------------------===//
-// 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(QualType((Type*)this,0).getCanonicalType());
- 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/BasicObjCFoundationChecks.cpp b/clang/lib/Analysis/BasicObjCFoundationChecks.cpp
deleted file mode 100644
index 8e8feec1d1a3..000000000000
--- a/clang/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ /dev/null
@@ -1,290 +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/ValueState.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/Support/Compiler.h"
-
-#include <vector>
-#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 NilArg : public BugTypeCacheLocation {
-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<ValueState>* 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;
- ValueStateManager* VMgr;
-
- typedef std::vector<BugReport*> ErrorsTy;
- ErrorsTy Errors;
-
- RVal GetRVal(ValueState* 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, ValueStateManager* 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<ValueState>* N);
-
- 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,
- ValueStateManager* VMgr) {
-
- return new BasicObjCFoundationChecks(Ctx, VMgr);
-}
-
-
-
-bool BasicObjCFoundationChecks::Audit(ExplodedNode<ValueState>* N) {
-
- ObjCMessageExpr* ME =
- cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
-
- ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
-
- if (!ReceiverType)
- return NULL;
-
- 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;
-}
diff --git a/clang/lib/Analysis/BasicObjCFoundationChecks.h b/clang/lib/Analysis/BasicObjCFoundationChecks.h
deleted file mode 100644
index df2992b05453..000000000000
--- a/clang/lib/Analysis/BasicObjCFoundationChecks.h
+++ /dev/null
@@ -1,39 +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/ValueState.h"
-#include "clang/Analysis/PathSensitive/AnnotatedPath.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 ValueStateManager;
-
-GRSimpleAPICheck* CreateBasicObjCFoundationChecks(ASTContext& Ctx,
- ValueStateManager* VMgr);
-
-} // end clang namespace
-
-#endif
diff --git a/clang/lib/Analysis/BasicValueFactory.cpp b/clang/lib/Analysis/BasicValueFactory.cpp
deleted file mode 100644
index 8d737a9472de..000000000000
--- a/clang/lib/Analysis/BasicValueFactory.cpp
+++ /dev/null
@@ -1,249 +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();
-}
-
diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp
deleted file mode 100644
index e2d98b0cf60e..000000000000
--- a/clang/lib/Analysis/BugReporter.cpp
+++ /dev/null
@@ -1,524 +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 <sstream>
-
-using namespace clang;
-
-BugReporter::~BugReporter() {}
-BugType::~BugType() {}
-BugReport::~BugReport() {}
-RangedBugReport::~RangedBugReport() {}
-
-ExplodedGraph<ValueState>& BugReporter::getGraph() { return Eng.getGraph(); }
-
-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<ValueState>*
-GetNextNode(ExplodedNode<ValueState>* N) {
- return N->pred_empty() ? NULL : *(N->pred_begin());
-}
-
-static Stmt* GetLastStmt(ExplodedNode<ValueState>* 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<ValueState>* 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<ValueState>* 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<ValueState>* N,
- ExplodedNode<ValueState>* PrevN,
- ExplodedGraph<ValueState>& G,
- BugReporter& BR) {
- return NULL;
-}
-
-static std::pair<ExplodedGraph<ValueState>*, ExplodedNode<ValueState>*>
-MakeReportGraph(ExplodedGraph<ValueState>* G, ExplodedNode<ValueState>* N) {
-
- llvm::OwningPtr<ExplodedGraph<ValueState> > GTrim(G->Trim(&N, &N+1));
-
- // Find the error node in the trimmed graph.
-
- ExplodedNode<ValueState>* NOld = N;
- N = 0;
-
- for (ExplodedGraph<ValueState>::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<ValueState>(GTrim->getCFG(), GTrim->getCodeDecl(),
- GTrim->getContext());
-
-
- ExplodedNode<ValueState> *Last = 0, *First = 0;
-
- while (N) {
- ExplodedNode<ValueState>* NewN =
- G->getNode(N->getLocation(), N->getState());
-
- if (!First) First = NewN;
- if (Last) Last->addPredecessor(NewN);
-
- Last = NewN;
- N = N->pred_empty() ? 0 : *(N->pred_begin());
- }
-
- return std::make_pair(G, First);
-}
-
-void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
- BugReport& R) {
-
- ExplodedNode<ValueState>* 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<ValueState>*,ExplodedNode<ValueState>*>
- GPair = MakeReportGraph(&getGraph(), N);
-
- llvm::OwningPtr<ExplodedGraph<ValueState> > 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<ValueState>* NextNode = N->pred_empty()
- ? NULL : *(N->pred_begin());
-
- SourceManager& SMgr = Ctx.getSourceManager();
-
- while (NextNode) {
-
- ExplodedNode<ValueState>* 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;
- }
-
- os << V.toString();
- }
-
- 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);
- }
-}
-
-bool BugTypeCacheLocation::isCached(BugReport& R) {
-
- ExplodedNode<ValueState>* 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.
-
- void* p = N->getLocation().getRawData();
-
- 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()));
- 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.
-
- 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(Ctx.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;
- os << "[CHECKER] ";
-
- if (D->empty())
- os << R.getDescription();
- else
- os << D->back()->getString();
-
-
- unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning,
- os.str().c_str());
-
- Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg);
- }
-}
diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
deleted file mode 100644
index fd47f03d3e12..000000000000
--- a/clang/lib/Analysis/CFRefCount.cpp
+++ /dev/null
@@ -1,2139 +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/ValueState.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/BugReporter.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 <ostream>
-#include <sstream>
-
-using namespace clang;
-using llvm::CStrInCStrNoCase;
-
-//===----------------------------------------------------------------------===//
-// Utility 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);
-}
-
-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 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;
-}
-
-//===----------------------------------------------------------------------===//
-// Symbolic Evaluation of Reference Counting Logic
-//===----------------------------------------------------------------------===//
-
-namespace {
- enum ArgEffect { IncRef, DecRef, DoNothing, StopTracking };
- 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 {
-
-class RetEffect {
-public:
- enum Kind { NoRet = 0x0, Alias = 0x1, OwnedSymbol = 0x2,
- NotOwnedSymbol = 0x3, ReceiverAlias=0x4 };
-
-private:
- unsigned Data;
- RetEffect(Kind k, unsigned D) { Data = (D << 3) | (unsigned) k; }
-
-public:
-
- Kind getKind() const { return (Kind) (Data & 0x7); }
-
- unsigned getValue() const {
- assert(getKind() == Alias);
- return Data >> 3;
- }
-
- static RetEffect MakeAlias(unsigned Idx) { return RetEffect(Alias, Idx); }
-
- static RetEffect MakeReceiverAlias() { return RetEffect(ReceiverAlias, 0); }
-
- static RetEffect MakeOwned() { return RetEffect(OwnedSymbol, 0); }
-
- static RetEffect MakeNotOwned() { return RetEffect(NotOwnedSymbol, 0); }
-
- static RetEffect MakeNoRet() { return RetEffect(NoRet, 0); }
-
- operator Kind() const { return getKind(); }
-
- void Profile(llvm::FoldingSetNodeID& ID) const { ID.AddInteger(Data); }
-};
-
-
-class 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;
-
- ArgEffect Receiver;
- RetEffect Ret;
-public:
-
- RetainSummary(ArgEffects* A, RetEffect R, ArgEffect defaultEff,
- ArgEffect ReceiverEff)
- : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R) {}
-
- 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;
- }
-
- RetEffect getRetEffect() const {
- return Ret;
- }
-
- ArgEffect getReceiverEffect() const {
- return Receiver;
- }
-
- typedef ArgEffects::const_iterator arg_iterator;
-
- arg_iterator begin_args() const { return Args->begin(); }
- arg_iterator end_args() const { return Args->end(); }
-
- static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects* A,
- RetEffect RetEff, ArgEffect DefaultEff,
- ArgEffect ReceiverEff) {
- ID.AddPointer(A);
- ID.Add(RetEff);
- ID.AddInteger((unsigned) DefaultEff);
- ID.AddInteger((unsigned) ReceiverEff);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, Args, Ret, DefaultArgEffect, Receiver);
- }
-};
-
-
-class RetainSummaryManager {
-
- //==-----------------------------------------------------------------==//
- // Typedefs.
- //==-----------------------------------------------------------------==//
-
- typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<ArgEffects> >
- ArgEffectsSetTy;
-
- typedef llvm::FoldingSet<RetainSummary>
- SummarySetTy;
-
- typedef llvm::DenseMap<FunctionDecl*, RetainSummary*>
- FuncSummariesTy;
-
- typedef llvm::DenseMap<Selector, RetainSummary*>
- ObjCMethSummariesTy;
-
- //==-----------------------------------------------------------------==//
- // Data.
- //==-----------------------------------------------------------------==//
-
- // Ctx - The ASTContext object for the analyzed ASTs.
- ASTContext& Ctx;
-
- // 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;
-
- // ObjCInstMethSummaries - A map from selectors (for instance methods)
- // to summaries.
- ObjCMethSummariesTy ObjCInstMethSummaries;
-
- // ObjCMethSummaries - A map from selectors to summaries.
- ObjCMethSummariesTy ObjCMethSummaries;
-
- // 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* getCFSummaryCreateRule(FunctionDecl* FD);
- RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
-
- RetainSummary* getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = DoNothing);
-
-
- RetainSummary* getPersistentSummary(RetEffect RE,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = DoNothing) {
- return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
- }
-
-
-
- RetainSummary* getPersistentStopSummary() {
- if (StopSummary)
- return StopSummary;
-
- StopSummary = getPersistentSummary(RetEffect::MakeNoRet(),
- StopTracking, StopTracking);
-
- return StopSummary;
- }
-
- RetainSummary* getInitMethodSummary(Selector S);
-
- void InitializeInstMethSummaries();
- void InitializeMethSummaries();
-
-public:
-
- RetainSummaryManager(ASTContext& ctx, bool gcenabled)
- : Ctx(ctx), GCEnabled(gcenabled), StopSummary(0) {
-
- InitializeInstMethSummaries();
- InitializeMethSummaries();
- }
-
- ~RetainSummaryManager();
-
- RetainSummary* getSummary(FunctionDecl* FD, ASTContext& Ctx);
-
- RetainSummary* getMethodSummary(ObjCMessageExpr* ME);
- RetainSummary* getInstanceMethodSummary(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) {
-
- // Generate a profile for the summary.
- llvm::FoldingSetNodeID profile;
- RetainSummary::Profile(profile, AE, RetEff, DefaultEff, ReceiverEff);
-
- // 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);
- SummarySet.InsertNode(Summ, InsertPos);
-
- return Summ;
-}
-
-//===----------------------------------------------------------------------===//
-// Summary creation for functions (largely uses of Core Foundation).
-//===----------------------------------------------------------------------===//
-
-RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD,
- ASTContext& Ctx) {
-
- 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());
-
- if (FT && isCFRefType(FT->getResultType()))
- S = getCFSummary(FD, FName);
- else if (FName[0] == 'C' && FName[1] == 'F')
- S = getCFSummary(FD, FName);
- else if (FName[0] == 'N' && FName[1] == 'S')
- S = getNSSummary(FD, FName);
-
- 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;
-}
-
-RetainSummary* RetainSummaryManager::getCFSummary(FunctionDecl* FD,
- const char* FName) {
-
- if (FName[0] == 'C' && FName[1] == 'F')
- FName += 2;
-
- if (strcmp(FName, "Retain") == 0)
- return getUnarySummary(FD, cfretain);
-
- if (strcmp(FName, "Release") == 0)
- return getUnarySummary(FD, cfrelease);
-
- if (strcmp(FName, "MakeCollectable") == 0)
- return getUnarySummary(FD, cfmakecollectable);
-
- 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));
- }
-
- case cfrelease: {
- ScratchArgs.push_back(std::make_pair(0, DecRef));
- return getPersistentSummary(RetEffect::MakeNoRet());
- }
-
- case cfmakecollectable: {
- if (GCEnabled)
- ScratchArgs.push_back(std::make_pair(0, DecRef));
-
- return getPersistentSummary(RetEffect::MakeAlias(0));
- }
-
- default:
- assert (false && "Not a supported unary function.");
- }
-}
-
-RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
-
- FunctionType* FT =
- dyn_cast<FunctionType>(FD->getType().getTypePtr());
-
- if (FT && !isCFRefType(FT->getResultType()))
- return 0;
-
- // FIXME: Add special-cases for functions that retain/release. For now
- // just handle the default case.
-
- assert (ScratchArgs.empty());
- return getPersistentSummary(RetEffect::MakeOwned());
-}
-
-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 0;
- }
-
- // FIXME: Add special-cases for functions that retain/release. For now
- // just handle the default case.
-
- assert (ScratchArgs.empty());
- return getPersistentSummary(RetEffect::MakeNotOwned());
-}
-
-//===----------------------------------------------------------------------===//
-// Summary creation for Selectors.
-//===----------------------------------------------------------------------===//
-
-RetainSummary*
-RetainSummaryManager::getInitMethodSummary(Selector S) {
- assert(ScratchArgs.empty());
-
- RetainSummary* Summ =
- getPersistentSummary(RetEffect::MakeReceiverAlias());
-
- ObjCMethSummaries[S] = Summ;
- return Summ;
-}
-
-RetainSummary*
-RetainSummaryManager::getMethodSummary(ObjCMessageExpr* ME) {
-
- Selector S = ME->getSelector();
-
- // Look up a summary in our cache of Selectors -> Summaries.
- ObjCMethSummariesTy::iterator I = ObjCMethSummaries.find(S);
-
- if (I != ObjCMethSummaries.end())
- return I->second;
-
-#if 0
- // Only generate real summaries for methods involving
- // NSxxxx objects.
-
- if (!isNSType(ME->getReceiver()->getType())) {
- RetainSummary* Summ = getPersistentStopSummary();
- ObjCMethSummaries[S] = Summ;
- return Summ;
- }
-#endif
-
- 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)
- return getInitMethodSummary(S);
-
- // "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();
-
- RetainSummary* Summ = getPersistentSummary(E);
- ObjCMethSummaries[S] = Summ;
- return Summ;
- }
-
- return 0;
-}
-
-RetainSummary*
-RetainSummaryManager::getInstanceMethodSummary(IdentifierInfo* ClsName,
- Selector S) {
-
- // Look up a summary in our cache of Selectors -> Summaries.
- ObjCMethSummariesTy::iterator I = ObjCInstMethSummaries.find(S);
-
- if (I != ObjCInstMethSummaries.end())
- return I->second;
-
- return 0;
-
-#if 0
- return 0;
-
- // Don't track anything if using GC.
- if (isGCEnabled())
- return 0;
-
- // Inspect the class name and selecrtor to determine if this method
- // creates new objects.
- const char* cls = ClsName->getName();
-
- if (cls[0] == 'N' && cls[1] == 'S') // Ignore preceding "NS" (if present).
- cls += 2;
-
- // Heuristic: XXXwithYYY, where XXX is the class name with the "NS"
- // stripped off is usually an allocation.
-
- const char* s = S.getIdentifierInfoForSlot(0)->getName();
-
- if (cls[0] == '\0' || s[0] == '\0' || tolower(cls[0]) != s[0])
- return 0;
-
- // Now look at the rest of the characters.
- ++cls; ++s;
- unsigned len = strlen(cls);
-
- // If the prefix doesn't match, don't generate a special summary.
- if (strncmp(cls, s, len) != 0)
- return 0;
-
- // Look at the text after the prefix.
- s += len;
-
- if (!(s[0] == '\0' || strncmp(s, "With", 4) == 0))
- return 0;
-
- // Generate and return the summary.
- assert (ScratchArgs.empty());
-
- RetainSummary* Summ = getPersistentSummary(RetEffect::MakeOwned());
- ObjCInstMethSummaries[S] = Summ;
- return Summ;
-#endif
-}
-
-void RetainSummaryManager::InitializeInstMethSummaries() {
-
- assert (ScratchArgs.empty());
-
- RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet() : RetEffect::MakeOwned();
- RetainSummary* Summ = getPersistentSummary(E);
-
- // Create the "alloc" selector.
- ObjCInstMethSummaries[ GetNullarySelector("alloc", Ctx) ] = Summ;
-
- // Create the "new" selector.
- ObjCInstMethSummaries[ GetNullarySelector("new", Ctx) ] = Summ;
-
- // Create the "allocWithZone:" selector.
- ObjCInstMethSummaries[ GetUnarySelector("allocWithZone", Ctx) ] = Summ;
-}
-
-void RetainSummaryManager::InitializeMethSummaries() {
-
- assert (ScratchArgs.empty());
-
- // Create the "init" selector. It just acts as a pass-through for the
- // receiver.
- RetainSummary* Summ = getPersistentSummary(RetEffect::MakeReceiverAlias());
- ObjCMethSummaries[ GetNullarySelector("init", Ctx) ] = Summ;
-
- // The next methods are allocators.
- RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet() : RetEffect::MakeOwned();
- Summ = getPersistentSummary(E);
-
- // Create the "copy" selector.
- ObjCMethSummaries[ GetNullarySelector("copy", Ctx) ] = Summ;
-
- // Create the "mutableCopy" selector.
- ObjCMethSummaries[ GetNullarySelector("mutableCopy", Ctx) ] = Summ;
-
- // Create the "retain" selector.
- E = RetEffect::MakeReceiverAlias();
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : IncRef);
- ObjCMethSummaries[ GetNullarySelector("retain", Ctx) ] = Summ;
-
- // Create the "release" selector.
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
- ObjCMethSummaries[ GetNullarySelector("release", Ctx) ] = Summ;
-
- // Create the "drain" selector.
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
- ObjCMethSummaries[ GetNullarySelector("drain", Ctx) ] = Summ;
-
- // Create the "autorelease" selector.
- Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : StopTracking);
- ObjCMethSummaries[ GetNullarySelector("autorelease", Ctx) ] = Summ;
-}
-
-//===----------------------------------------------------------------------===//
-// 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;
-
- RefVal(Kind k, unsigned cnt) : kind(k), Cnt(cnt) {}
-
- RefVal(Kind k) : kind(k), Cnt(0) {}
-
-public:
-
- Kind getKind() const { return kind; }
-
- unsigned getCount() const { return Cnt; }
-
- // 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(unsigned Count = 0) {
- return RefVal(Owned, Count);
- }
-
- static RefVal makeNotOwned(unsigned Count = 0) {
- return RefVal(NotOwned, Count);
- }
-
- static RefVal makeReturnedOwned(unsigned Count) {
- return RefVal(ReturnedOwned, Count);
- }
-
- static RefVal makeReturnedNotOwned() {
- return RefVal(ReturnedNotOwned);
- }
-
- // State creation: errors.
-
- static RefVal makeLeak(unsigned Count) { return RefVal(ErrorLeak, Count); }
- static RefVal makeReleased() { return RefVal(Released); }
- static RefVal makeUseAfterRelease() { return RefVal(ErrorUseAfterRelease); }
- static RefVal makeReleaseNotOwned() { return RefVal(ErrorReleaseNotOwned); }
-
- // Comparison, profiling, and pretty-printing.
-
- bool operator==(const RefVal& X) const {
- return kind == X.kind && Cnt == X.Cnt;
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned) kind);
- ID.AddInteger(Cnt);
- }
-
- void print(std::ostream& Out) const;
-};
-
-void RefVal::print(std::ostream& Out) const {
- 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;
- }
-}
-
-static inline unsigned GetCount(RefVal V) {
- switch (V.getKind()) {
- default:
- return V.getCount();
-
- case RefVal::Owned:
- return V.getCount()+1;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions.
-//===----------------------------------------------------------------------===//
-
-class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals {
-public:
- // Type definitions.
-
- typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings;
- typedef RefBindings::Factory RefBFactoryTy;
-
- 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 ValueState::CheckerStatePrinter {
- public:
- virtual void PrintCheckerState(std::ostream& Out, void* State,
- const char* nl, const char* sep);
- };
-
-private:
- // Instance variables.
-
- RetainSummaryManager Summaries;
- const bool EmitStandardWarnings;
- const LangOptions& LOpts;
- RefBFactoryTy RefBFactory;
-
- UseAfterReleasesTy UseAfterReleases;
- ReleasesNotOwnedTy ReleasesNotOwned;
- LeaksTy Leaks;
-
- BindingsPrinter Printer;
-
- Selector RetainSelector;
- Selector ReleaseSelector;
- Selector AutoreleaseSelector;
-
-public:
-
- static RefBindings GetRefBindings(ValueState& StImpl) {
- return RefBindings((RefBindings::TreeTy*) StImpl.CheckerState);
- }
-
-private:
-
- static void SetRefBindings(ValueState& StImpl, RefBindings B) {
- StImpl.CheckerState = B.getRoot();
- }
-
- RefBindings Remove(RefBindings B, SymbolID sym) {
- return RefBFactory.Remove(B, sym);
- }
-
- RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E,
- RefVal::Kind& hasErr);
-
- void ProcessNonLeakError(ExplodedNodeSet<ValueState>& Dst,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* NodeExpr, Expr* ErrorExpr,
- ExplodedNode<ValueState>* Pred,
- ValueState* St,
- RefVal::Kind hasErr, SymbolID Sym);
-
- ValueState* HandleSymbolDeath(ValueStateManager& VMgr, ValueState* St,
- SymbolID sid, RefVal V, bool& hasLeak);
-
- ValueState* NukeBinding(ValueStateManager& VMgr, ValueState* St,
- SymbolID sid);
-
-public:
-
- CFRefCount(ASTContext& Ctx, bool gcenabled, bool StandardWarnings,
- const LangOptions& lopts)
- : Summaries(Ctx, gcenabled),
- EmitStandardWarnings(StandardWarnings),
- LOpts(lopts),
- RetainSelector(GetNullarySelector("retain", Ctx)),
- ReleaseSelector(GetNullarySelector("release", Ctx)),
- AutoreleaseSelector(GetNullarySelector("autorelease", Ctx)) {}
-
- virtual ~CFRefCount() {
- for (LeaksTy::iterator I = Leaks.begin(), E = Leaks.end(); I!=E; ++I)
- delete I->second;
- }
-
- virtual void RegisterChecks(GRExprEngine& Eng);
-
- virtual ValueState::CheckerStatePrinter* getCheckerStatePrinter() {
- return &Printer;
- }
-
- bool isGCEnabled() const { return Summaries.isGCEnabled(); }
- const LangOptions& getLangOptions() const { return LOpts; }
-
- // Calls.
-
- void EvalSummary(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* Ex,
- Expr* Receiver,
- RetainSummary* Summ,
- Expr** arg_beg, Expr** arg_end,
- ExplodedNode<ValueState>* Pred);
-
- virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<ValueState>* Pred);
-
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<ValueState>* Pred);
-
- bool EvalObjCMessageExprAux(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<ValueState>* Pred);
-
- // Stores.
-
- virtual void EvalStore(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* E, ExplodedNode<ValueState>* Pred,
- ValueState* St, RVal TargetLV, RVal Val);
- // End-of-path.
-
- virtual void EvalEndPath(GRExprEngine& Engine,
- GREndPathNodeBuilder<ValueState>& Builder);
-
- virtual void EvalDeadSymbols(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ExplodedNode<ValueState>* Pred,
- Stmt* S,
- ValueState* St,
- const ValueStateManager::DeadSymbolsTy& Dead);
- // Return statements.
-
- virtual void EvalReturn(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ReturnStmt* S,
- ExplodedNode<ValueState>* Pred);
-
- // Assumptions.
-
- virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* 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::PrintCheckerState(std::ostream& Out,
- void* State, const char* nl,
- const char* sep) {
- RefBindings B((RefBindings::TreeTy*) State);
-
- if (State)
- 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) : DoNothing;
-}
-
-static inline RetEffect GetRetEffect(RetainSummary* Summ) {
- return Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
-}
-
-static inline ArgEffect GetReceiverE(RetainSummary* Summ) {
- return Summ ? Summ->getReceiverEffect() : DoNothing;
-}
-
-void CFRefCount::ProcessNonLeakError(ExplodedNodeSet<ValueState>& Dst,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* NodeExpr, Expr* ErrorExpr,
- ExplodedNode<ValueState>* Pred,
- ValueState* 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;
- }
-}
-
-void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* Ex,
- Expr* Receiver,
- RetainSummary* Summ,
- Expr** arg_beg, Expr** arg_end,
- ExplodedNode<ValueState>* Pred) {
-
-
- // Get the state.
- ValueStateManager& StateMgr = Eng.getStateManager();
- ValueState* St = Builder.GetState(Pred);
-
-
- // Evaluate the effect of the arguments.
-
- ValueState StVals = *St;
- RefVal::Kind hasErr = (RefVal::Kind) 0;
- unsigned idx = 0;
- Expr* ErrorExpr = NULL;
- SymbolID ErrorSym = 0;
-
- for (Expr **I = arg_beg, **E = arg_end; I != E; ++I, ++idx) {
-
- RVal V = StateMgr.GetRVal(St, *I);
-
- if (isa<lval::SymbolVal>(V)) {
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
- RefBindings B = GetRefBindings(StVals);
-
- if (RefBindings::TreeTy* T = B.SlimFind(Sym)) {
- B = Update(B, Sym, T->getValue().second, GetArgE(Summ, idx), hasErr);
- SetRefBindings(StVals, B);
-
- if (hasErr) {
- ErrorExpr = *I;
- ErrorSym = T->getValue().first;
- break;
- }
- }
- }
- else if (isa<LVal>(V)) {
- // Nuke all arguments passed by reference.
- StateMgr.Unbind(StVals, cast<LVal>(V));
- }
- else if (isa<nonlval::LValAsInteger>(V))
- StateMgr.Unbind(StVals, cast<nonlval::LValAsInteger>(V).getLVal());
- }
-
- // Evaluate the effect on the message receiver.
-
- if (!ErrorExpr && Receiver) {
- RVal V = StateMgr.GetRVal(St, Receiver);
-
- if (isa<lval::SymbolVal>(V)) {
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
- RefBindings B = GetRefBindings(StVals);
-
- if (RefBindings::TreeTy* T = B.SlimFind(Sym)) {
- B = Update(B, Sym, T->getValue().second, GetReceiverE(Summ), hasErr);
- SetRefBindings(StVals, B);
-
- if (hasErr) {
- ErrorExpr = Receiver;
- ErrorSym = T->getValue().first;
- }
- }
- }
- }
-
- // Get the persistent state.
-
- St = StateMgr.getPersistentState(StVals);
-
- // Process any errors.
-
- if (hasErr) {
- ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, St,
- hasErr, ErrorSym);
- return;
- }
-
- // Finally, 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));
-
- St = StateMgr.SetRVal(St, Ex, X, Eng.getCFG().isBlkExpr(Ex), false);
- }
-
- break;
-
- case RetEffect::Alias: {
- unsigned idx = RE.getValue();
- assert ((arg_end - arg_beg) >= 0);
- assert (idx < (unsigned) (arg_end - arg_beg));
- RVal V = StateMgr.GetRVal(St, arg_beg[idx]);
- St = StateMgr.SetRVal(St, Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
- break;
- }
-
- case RetEffect::ReceiverAlias: {
- assert (Receiver);
- RVal V = StateMgr.GetRVal(St, Receiver);
- St = StateMgr.SetRVal(St, Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
- break;
- }
-
- case RetEffect::OwnedSymbol: {
- unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
-
- ValueState StImpl = *St;
- RefBindings B = GetRefBindings(StImpl);
- SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned()));
-
- St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
- Ex, lval::SymbolVal(Sym),
- Eng.getCFG().isBlkExpr(Ex), false);
-
- break;
- }
-
- case RetEffect::NotOwnedSymbol: {
- unsigned Count = Builder.getCurrentBlockCount();
- SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
-
- ValueState StImpl = *St;
- RefBindings B = GetRefBindings(StImpl);
- SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeNotOwned()));
-
- St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
- Ex, lval::SymbolVal(Sym),
- Eng.getCFG().isBlkExpr(Ex), false);
-
- break;
- }
- }
-
- Builder.MakeNode(Dst, Ex, Pred, St);
-}
-
-
-void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<ValueState>* Pred) {
-
-
- RetainSummary* Summ = NULL;
-
- // Get the summary.
-
- if (isa<lval::FuncVal>(L)) {
- lval::FuncVal FV = cast<lval::FuncVal>(L);
- FunctionDecl* FD = FV.getDecl();
- Summ = Summaries.getSummary(FD, Eng.getContext());
- }
-
- EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
- CE->arg_begin(), CE->arg_end(), Pred);
-}
-
-
-void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<ValueState>* Pred) {
-
- RetainSummary* Summ;
-
- if (ME->getReceiver())
- Summ = Summaries.getMethodSummary(ME);
- else
- Summ = Summaries.getInstanceMethodSummary(ME->getClassName(),
- ME->getSelector());
-
- EvalSummary(Dst, Eng, Builder, ME, ME->getReceiver(), Summ,
- ME->arg_begin(), ME->arg_end(), Pred);
-}
-
-// Stores.
-
-void CFRefCount::EvalStore(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* E, ExplodedNode<ValueState>* Pred,
- ValueState* 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::DeclVal>(TargetLV))
- escapes = true;
- else
- escapes = cast<lval::DeclVal>(TargetLV).getDecl()->hasGlobalStorage();
-
- if (!escapes)
- return;
-
- SymbolID Sym = cast<lval::SymbolVal>(Val).getSymbol();
- RefBindings B = GetRefBindings(*St);
- RefBindings::TreeTy* T = B.SlimFind(Sym);
-
- if (!T)
- return;
-
- // Nuke the binding.
- St = NukeBinding(Eng.getStateManager(), St, Sym);
-
- // Hand of the remaining logic to the parent implementation.
- GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, St, TargetLV, Val);
-}
-
-
-ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr, ValueState* St,
- SymbolID sid) {
- ValueState StImpl = *St;
- RefBindings B = GetRefBindings(StImpl);
- StImpl.CheckerState = RefBFactory.Remove(B, sid).getRoot();
- return VMgr.getPersistentState(StImpl);
-}
-
-// End-of-path.
-
-ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr,
- ValueState* St, SymbolID sid,
- RefVal V, bool& hasLeak) {
-
- hasLeak = V.isOwned() ||
- ((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
-
- if (!hasLeak)
- return NukeBinding(VMgr, St, sid);
-
- RefBindings B = GetRefBindings(*St);
- ValueState StImpl = *St;
-
- StImpl.CheckerState =
- RefBFactory.Add(B, sid, RefVal::makeLeak(GetCount(V))).getRoot();
-
- return VMgr.getPersistentState(StImpl);
-}
-
-void CFRefCount::EvalEndPath(GRExprEngine& Eng,
- GREndPathNodeBuilder<ValueState>& Builder) {
-
- ValueState* St = Builder.getState();
- RefBindings B = GetRefBindings(*St);
-
- 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<ValueState>* 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<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- ExplodedNode<ValueState>* Pred,
- Stmt* S,
- ValueState* St,
- const ValueStateManager::DeadSymbolsTy& Dead) {
-
- // FIXME: a lot of copy-and-paste from EvalEndPath. Refactor.
-
- RefBindings B = GetRefBindings(*St);
- llvm::SmallVector<SymbolID, 10> Leaked;
-
- for (ValueStateManager::DeadSymbolsTy::const_iterator
- I=Dead.begin(), E=Dead.end(); I!=E; ++I) {
-
- RefBindings::TreeTy* T = B.SlimFind(*I);
-
- if (!T)
- continue;
-
- bool hasLeak = false;
-
- St = HandleSymbolDeath(Eng.getStateManager(), St,
- *I, T->getValue().second, hasLeak);
-
- if (hasLeak) Leaked.push_back(*I);
- }
-
- if (Leaked.empty())
- return;
-
- ExplodedNode<ValueState>* 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<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- ReturnStmt* S,
- ExplodedNode<ValueState>* Pred) {
-
- Expr* RetE = S->getRetValue();
- if (!RetE) return;
-
- ValueStateManager& StateMgr = Eng.getStateManager();
- ValueState* St = Builder.GetState(Pred);
- RVal V = StateMgr.GetRVal(St, RetE);
-
- if (!isa<lval::SymbolVal>(V))
- return;
-
- // Get the reference count binding (if any).
- SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
- RefBindings B = GetRefBindings(*St);
- RefBindings::TreeTy* T = B.SlimFind(Sym);
-
- if (!T)
- return;
-
- // Change the reference count.
-
- RefVal X = T->getValue().second;
-
- switch (X.getKind()) {
-
- case RefVal::Owned: {
- unsigned cnt = X.getCount();
- X = RefVal::makeReturnedOwned(cnt);
- break;
- }
-
- case RefVal::NotOwned: {
- unsigned cnt = X.getCount();
- X = cnt ? RefVal::makeReturnedOwned(cnt - 1)
- : RefVal::makeReturnedNotOwned();
- break;
- }
-
- default:
- return;
- }
-
- // Update the binding.
-
- ValueState StImpl = *St;
- StImpl.CheckerState = RefBFactory.Add(B, Sym, X).getRoot();
- Builder.MakeNode(Dst, S, Pred, StateMgr.getPersistentState(StImpl));
-}
-
-// Assumptions.
-
-ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng, ValueState* 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 = GetRefBindings(*St);
-
- if (B.isEmpty())
- return St;
-
- bool changed = false;
-
- 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 (St->getSymVal(I.getKey())) {
- changed = true;
- B = RefBFactory.Remove(B, I.getKey());
- }
- }
-
- if (!changed)
- return St;
-
- ValueState StImpl = *St;
- StImpl.CheckerState = B.getRoot();
- return Eng.getStateManager().getPersistentState(StImpl);
-}
-
-CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
- RefVal V, ArgEffect E,
- RefVal::Kind& hasErr) {
-
- // 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 DoNothing:
- if (!isGCEnabled() && V.getKind() == RefVal::Released) {
- V = RefVal::makeUseAfterRelease();
- hasErr = V.getKind();
- break;
- }
-
- return B;
-
- case StopTracking:
- return RefBFactory.Remove(B, sym);
-
- case IncRef:
- switch (V.getKind()) {
- default:
- assert(false);
-
- case RefVal::Owned:
- V = RefVal::makeOwned(V.getCount()+1);
- break;
-
- case RefVal::NotOwned:
- V = RefVal::makeNotOwned(V.getCount()+1);
- break;
-
- case RefVal::Released:
- if (isGCEnabled())
- V = RefVal::makeOwned();
- else {
- V = RefVal::makeUseAfterRelease();
- hasErr = V.getKind();
- }
-
- break;
- }
-
- break;
-
- case DecRef:
- switch (V.getKind()) {
- default:
- assert (false);
-
- case RefVal::Owned: {
- unsigned Count = V.getCount();
- V = Count > 0 ? RefVal::makeOwned(Count - 1) : RefVal::makeReleased();
- break;
- }
-
- case RefVal::NotOwned: {
- unsigned Count = V.getCount();
-
- if (Count > 0)
- V = RefVal::makeNotOwned(Count - 1);
- else {
- V = RefVal::makeReleaseNotOwned();
- hasErr = V.getKind();
- }
-
- break;
- }
-
- case RefVal::Released:
- V = RefVal::makeUseAfterRelease();
- 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; }
- };
-
- 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 "Memory Leak (GC)";
-
- if (getTF().getLangOptions().getGCMode() == LangOptions::HybridGC)
- return "Memory Leak (Hybrid MM, non-GC)";
-
- assert (getTF().getLangOptions().getGCMode() == LangOptions::NonGC);
- return "Memory Leak";
- }
-
- virtual const char* getDescription() const {
- return "Object leaked.";
- }
-
- virtual void EmitWarnings(BugReporter& BR);
- virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);
- virtual bool isLeak() const { return true; }
- };
-
- //===---------===//
- // Bug Reports. //
- //===---------===//
-
- class VISIBILITY_HIDDEN CFRefReport : public RangedBugReport {
- SymbolID Sym;
- public:
- CFRefReport(CFRefBug& D, ExplodedNode<ValueState> *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 = 0;
- end = 0;
- }
- }
-
- virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
- ExplodedNode<ValueState>* N);
-
- virtual std::pair<const char**,const char**> getExtraDescriptiveText();
-
- virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
- ExplodedNode<ValueState>* PrevN,
- ExplodedGraph<ValueState>& G,
- BugReporter& BR);
- };
-
-
-} // end anonymous namespace
-
-void CFRefCount::RegisterChecks(GRExprEngine& Eng) {
- if (EmitStandardWarnings) GRSimpleVals::RegisterChecks(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<ValueState>* N,
- ExplodedNode<ValueState>* PrevN,
- ExplodedGraph<ValueState>& G,
- BugReporter& BR) {
-
- // Check if the type state has changed.
-
- ValueState* PrevSt = PrevN->getState();
- ValueState* CurrSt = N->getState();
-
- CFRefCount::RefBindings PrevB = CFRefCount::GetRefBindings(*PrevSt);
- CFRefCount::RefBindings CurrB = CFRefCount::GetRefBindings(*CurrSt);
-
- CFRefCount::RefBindings::TreeTy* PrevT = PrevB.SlimFind(Sym);
- CFRefCount::RefBindings::TreeTy* CurrT = CurrB.SlimFind(Sym);
-
- if (!CurrT)
- return NULL;
-
- const char* Msg = NULL;
- RefVal CurrV = CurrB.SlimFind(Sym)->getValue().second;
-
- 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.SlimFind(Sym)->getValue().second;
-
- if (PrevV == CurrV)
- return NULL;
-
- // The typestate has changed.
-
- std::ostringstream os;
-
- switch (CurrV.getKind()) {
- case RefVal::Owned:
- case RefVal::NotOwned:
- assert (PrevV.getKind() == CurrV.getKind());
-
- if (PrevV.getCount() > CurrV.getCount())
- os << "Reference count decremented.";
- else
- os << "Reference count incremented.";
-
- if (unsigned Count = GetCount(CurrV)) {
-
- os << " Object has +" << Count;
-
- if (Count > 1)
- os << " retain counts.";
- else
- os << " retain count.";
- }
-
- Msg = os.str().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.
-
- ValueStateManager& VSM = BR.getEngine().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;
-}
-
-
-PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
- ExplodedNode<ValueState>* EndN) {
-
- if (!getBugType().isLeak())
- return RangedBugReport::getEndPath(BR, EndN);
-
- typedef CFRefCount::RefBindings RefBindings;
-
- // Get the retain count.
- unsigned long RetCount = 0;
-
- {
- ValueState* St = EndN->getState();
- RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
- RefBindings::TreeTy* T = B.SlimFind(Sym);
- assert (T);
- RetCount = GetCount(T->getValue().second);
- }
-
- // We are a leak. Walk up the graph to get to the first node where the
- // symbol appeared.
-
- ExplodedNode<ValueState>* N = EndN;
- ExplodedNode<ValueState>* Last = N;
-
- // Find the first node that referred to the tracked symbol. We also
- // try and find the first VarDecl the value was stored to.
-
- VarDecl* FirstDecl = 0;
-
- while (N) {
- ValueState* St = N->getState();
- RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
- RefBindings::TreeTy* T = B.SlimFind(Sym);
-
- if (!T)
- break;
-
- VarDecl* VD = 0;
-
- // Determine if there is an LVal binding to the symbol.
- for (ValueState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E; ++I) {
- if (!isa<lval::SymbolVal>(I->second) // Is the value a symbol?
- || cast<lval::SymbolVal>(I->second).getSymbol() != Sym)
- continue;
-
- if (VD) { // Multiple decls map to this symbol.
- VD = 0;
- break;
- }
-
- VD = I->first;
- }
-
- if (VD) FirstDecl = VD;
-
- Last = N;
- N = N->pred_empty() ? NULL : *(N->pred_begin());
- }
-
- // Get the allocate site.
-
- assert (Last);
- Stmt* FirstStmt = cast<PostStmt>(Last->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<ValueState> *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 (FirstDecl)
- os << " and stored into '" << FirstDecl->getName() << '\'';
-
- 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<ValueState>*>& Nodes) {
- for (CFRefCount::leaks_iterator I=TF.leaks_begin(), E=TF.leaks_end();
- I!=E; ++I)
- Nodes.push_back(I->first);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function creation for external clients.
-//===----------------------------------------------------------------------===//
-
-GRTransferFuncs* clang::MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
- bool StandardWarnings,
- const LangOptions& lopts) {
- return new CFRefCount(Ctx, GCEnabled, StandardWarnings, lopts);
-}
diff --git a/clang/lib/Analysis/DeadStores.cpp b/clang/lib/Analysis/DeadStores.cpp
deleted file mode 100644
index f7523e508f08..000000000000
--- a/clang/lib/Analysis/DeadStores.cpp
+++ /dev/null
@@ -1,206 +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 "llvm/Support/Compiler.h"
-
-using namespace clang;
-
-namespace {
-
-class VISIBILITY_HIDDEN DeadStoreObs : public LiveVariables::ObserverTy {
- ASTContext &Ctx;
- Diagnostic &Diags;
- DiagnosticClient &Client;
-public:
- DeadStoreObs(ASTContext &ctx, Diagnostic &diags, DiagnosticClient &client)
- : Ctx(ctx), Diags(diags), Client(client) {}
-
- virtual ~DeadStoreObs() {}
-
- void CheckDeclRef(DeclRefExpr* DR, Expr* Val,
- const LiveVariables::AnalysisDataTy& AD,
- const LiveVariables::ValTy& Live) {
-
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
- if (VD->hasLocalStorage() && !Live(VD, AD)) {
- SourceRange R = Val->getSourceRange();
- Diags.Report(&Client,
- Ctx.getFullLoc(DR->getSourceRange().getBegin()),
- diag::warn_dead_store, 0, 0, &R, 1);
- }
- }
-
- 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()))
- CheckDeclRef(DR, B->getRHS(), 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, 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 (ScopedDecl* SD = DS->getDecl(); SD; SD = SD->getNextDeclarator()) {
-
- VarDecl* V = dyn_cast<VarDecl>(SD);
- if (!V) continue;
-
- if (V->hasLocalStorage())
- if (Expr* E = V->getInit()) {
- if (!Live(V, AD)) {
- // 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)) {
- // Flag a warning.
- SourceRange R = E->getSourceRange();
- Diags.Report(&Client,
- Ctx.getFullLoc(V->getLocation()),
- diag::warn_dead_store, 0, 0, &R, 1);
- }
- }
- }
- }
- }
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Driver function to invoke the Dead-Stores checker on a CFG.
-//===----------------------------------------------------------------------===//
-
-void clang::CheckDeadStores(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags) {
- LiveVariables L(cfg);
- L.runOnCFG(cfg);
- DeadStoreObs A(Ctx, Diags, Diags.getClient());
- L.runOnAllBlocks(cfg, &A);
-}
-
-//===----------------------------------------------------------------------===//
-// BugReporter-based invocation of the Dead-Stores checker.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN DiagBugReport : public RangedBugReport {
- std::list<std::string> Strs;
- FullSourceLoc L;
-public:
- DiagBugReport(BugType& D, FullSourceLoc l) :
- RangedBugReport(D, NULL), L(l) {}
-
- virtual ~DiagBugReport() {}
- virtual FullSourceLoc getLocation(SourceManager&) { return L; }
-
- 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 VISIBILITY_HIDDEN 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(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 VISIBILITY_HIDDEN DeadStoresChecker : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "dead store";
- }
-
- virtual const char* getDescription() const {
- return "Value stored to variable is never subsequently read.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
-
- // Run the dead store checker and collect the diagnostics.
- DiagCollector C(*this);
- DeadStoreObs A(BR.getContext(), BR.getDiagnostic(), C);
- GRExprEngine& Eng = BR.getEngine();
- Eng.getLiveness().runOnAllBlocks(Eng.getCFG(), &A);
-
- // Emit the bug reports.
-
- for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I)
- BR.EmitWarning(*I);
- }
-};
-} // end anonymous namespace
-
-BugType* clang::MakeDeadStoresChecker() {
- return new DeadStoresChecker();
-}
diff --git a/clang/lib/Analysis/ExplodedGraph.cpp b/clang/lib/Analysis/ExplodedGraph.cpp
deleted file mode 100644
index 95904cd3878f..000000000000
--- a/clang/lib/Analysis/ExplodedGraph.cpp
+++ /dev/null
@@ -1,259 +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;
-
-
-static inline std::vector<ExplodedNodeImpl*>& getVector(void* P) {
- return *reinterpret_cast<std::vector<ExplodedNodeImpl*>*>(P);
-}
-
-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 3ecc39d32248..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::TreeTy* T = M.SlimFind(BlockID);
- return T ? T->getValue().second : 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 05f930385652..000000000000
--- a/clang/lib/Analysis/GRCoreEngine.cpp
+++ /dev/null
@@ -1,464 +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(getCFG(), Entry, Succ);
-
- // Set the current block counter to being empty.
- WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
-
- // Generate the root.
- GenerateNode(StartLoc, getInitialState());
- }
-
- 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);
-}
-
-
-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(getCFG(),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);
- }
-}
-
-typedef llvm::DenseMap<Stmt*,Stmt*> ParentMapTy;
-/// PopulateParentMap - Recurse the AST starting at 'Parent' and add the
-/// mappings between child and parent to ParentMap.
-static void PopulateParentMap(Stmt* Parent, ParentMapTy& M) {
- for (Stmt::child_iterator I=Parent->child_begin(),
- E=Parent->child_end(); I!=E; ++I) {
-
- assert (M.find(*I) == M.end());
- M[*I] = Parent;
- PopulateParentMap(*I, M);
- }
-}
-
-/// GenerateNode - Utility method to generate nodes, hook up successors,
-/// and add nodes to the worklist.
-void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, 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);
-}
-
-ExplodedNodeImpl*
-GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, void* State,
- ExplodedNodeImpl* Pred, bool isLoad) {
-
- bool IsNew;
- ProgramPoint Loc = isLoad ? PostLoad(S) : PostStmt(S);
- 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(void* State,
- bool branch) {
- bool IsNew;
-
- ExplodedNodeImpl* Succ =
- Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), 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,
- void* St,
- bool isSink) {
- bool IsNew;
-
- ExplodedNodeImpl* Succ =
- Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src, I.getBlock(), true),
- 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, void* St) {
-
- bool IsNew;
-
- ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src,
- I.getBlock()),
- St, &IsNew);
- Succ->addPredecessor(Pred);
-
- if (IsNew) {
- Eng.WList->Enqueue(Succ);
- return Succ;
- }
-
- return NULL;
-}
-
-
-ExplodedNodeImpl*
-GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(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(Eng.getCFG(), 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(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 a974c7a6b0c4..000000000000
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ /dev/null
@@ -1,2622 +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"
-
-#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.
-//===----------------------------------------------------------------------===//
-
-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)
- : CoreEngine(cfg, CD, Ctx, *this),
- G(CoreEngine.getGraph()),
- Liveness(G.getCFG()),
- Builder(NULL),
- StateMgr(G.getContext(), G.getAllocator()),
- BasicVals(StateMgr.getBasicValueFactory()),
- TF(NULL), // FIXME
- SymMgr(StateMgr.getSymbolManager()),
- CurrentStmt(NULL),
- NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
- RaiseSel(GetNullarySelector("raise", G.getContext())) {
-
- // Compute liveness information.
- Liveness.runOnCFG(G.getCFG());
- Liveness.runOnAllBlocks(G.getCFG(), NULL, true);
-}
-
-GRExprEngine::~GRExprEngine() {
- for (BugTypeSet::iterator I = BugTypes.begin(), E = BugTypes.end(); I!=E; ++I)
- delete *I;
-
- for (SimpleChecksTy::iterator I = CallChecks.begin(), E = CallChecks.end();
- I != E; ++I)
- delete *I;
-
- for (SimpleChecksTy::iterator I=MsgExprChecks.begin(), E=MsgExprChecks.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(Diagnostic& Diag, PathDiagnosticClient* PD) {
- for (bug_type_iterator I = bug_types_begin(), E = bug_types_end(); I!=E; ++I){
- BugReporter BR(Diag, PD, getContext(), *this);
- (*I)->EmitWarnings(BR);
- }
-
- for (SimpleChecksTy::iterator I = CallChecks.begin(), E = CallChecks.end();
- I != E; ++I) {
- BugReporter BR(Diag, PD, getContext(), *this);
- (*I)->EmitWarnings(BR);
- }
-
- for (SimpleChecksTy::iterator I=MsgExprChecks.begin(), E=MsgExprChecks.end();
- I != E; ++I) {
- BugReporter BR(Diag, PD, getContext(), *this);
- (*I)->EmitWarnings(BR);
- }
-}
-
-void GRExprEngine::setTransferFunctions(GRTransferFuncs* tf) {
- TF = tf;
- TF->RegisterChecks(*this);
-}
-
-void GRExprEngine::AddCallCheck(GRSimpleAPICheck* A) {
- CallChecks.push_back(A);
-}
-
-void GRExprEngine::AddObjCMessageExprCheck(GRSimpleAPICheck* A) {
- MsgExprChecks.push_back(A);
-}
-
-ValueState* GRExprEngine::getInitialState() {
-
- // 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 = Liveness.getAnalysisData();
-
- ValueState StateImpl = *StateMgr.getInitialState();
-
- for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
-
- VarDecl* VD = cast<VarDecl>(const_cast<ScopedDecl*>(I->first));
-
- if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
- RVal X = RVal::GetSymbolValue(SymMgr, VD);
- StateMgr.BindVar(StateImpl, VD, X);
- }
- }
-
- return StateMgr.getPersistentState(StateImpl);
-}
-
-ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) {
-
- bool isBlkExpr = false;
-
- if (Ex == CurrentStmt) {
- isBlkExpr = getCFG().isBlkExpr(Ex);
-
- if (!isBlkExpr)
- return St;
- }
-
- return StateMgr.SetRVal(St, Ex, V, isBlkExpr, true);
-}
-
-//===----------------------------------------------------------------------===//
-// Top-level transfer function logic (Dispatcher).
-//===----------------------------------------------------------------------===//
-
-void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
-
- Builder = &builder;
- EntryNode = builder.getLastNode();
- CurrentStmt = S;
-
- // Set up our simple checks.
-
- // FIXME: This can probably be installed directly in GRCoreEngine, obviating
- // the need to do a copy every time we hit a block-level statement.
-
- if (!MsgExprChecks.empty())
- Builder->setObjCMsgExprAuditors((GRAuditor<ValueState>**) &MsgExprChecks[0],
- (GRAuditor<ValueState>**) (&MsgExprChecks[0] + MsgExprChecks.size()));
-
-
- if (!CallChecks.empty())
- Builder->setCallExprAuditors((GRAuditor<ValueState>**) &CallChecks[0],
- (GRAuditor<ValueState>**) (&CallChecks[0] + CallChecks.size()));
-
- // 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);
-
- TF->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;
- CurrentStmt = NULL;
- 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) {
- ValueState* 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;
- }
-
- case Stmt::CastExprClass: {
- CastExpr* C = cast<CastExpr>(S);
- VisitCast(C, C->getSubExpr(), Pred, 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: {
- ImplicitCastExpr* C = cast<ImplicitCastExpr>(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);
-
- ValueState* 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, ValueState*,
- GRBlockCounter BC) {
-
- return BC.getNumVisited(B->getBlockID()) < 3;
-}
-
-//===----------------------------------------------------------------------===//
-// Branch processing.
-//===----------------------------------------------------------------------===//
-
-ValueState* GRExprEngine::MarkBranch(ValueState* 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.
- ValueState* 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;
- ValueState* 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) {
-
- ValueState* 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));
-
- ValueState* 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;
-
- ValueState* 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;
- }
-
- ValueState* 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(BasicVals.getValue(V1));
-
- RVal Res = EvalBinOp(BinaryOperator::EQ, CondV, CaseVal);
-
- // Now "assume" that the case matches.
-
- bool isFeasible = false;
- ValueState* 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));
-
- ValueState* 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;
- ValueState* 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) {
-
- ValueState* St = GetState(Pred);
- RVal X = RVal::MakeVal(BasicVals, D);
-
- if (asLVal)
- MakeNode(Dst, D, Pred, SetRVal(St, D, cast<LVal>(X)));
- else {
- RVal V = isa<lval::DeclVal>(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) {
-
- ValueState* 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(BasicVals, 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) {
- ValueState* St = GetState(*I);
- RVal BaseV = GetRVal(St, Base);
-
- RVal V = lval::FieldOffset::Make(BasicVals, 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) {
-
- ValueState* St = GetState(*I);
- RVal BaseV = GetRVal(St, Base);
-
- if (LVal::IsLValType(Base->getType())) {
-
- assert (M->isArrow());
-
- RVal V = lval::FieldOffset::Make(BasicVals, 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,
- ValueState* 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);
- SaveOr OldHasGen(Builder->HasGeneratedNode);
-
- assert (!location.isUndef());
-
- TF->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)
- TF->GRTransferFuncs::EvalStore(Dst, *this, *Builder, Ex, Pred, St,
- location, Val);
-}
-
-void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
- ValueState* 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.
-
- // 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);
- else if (location.isUnknown()) {
- // This is important. We must nuke the old binding.
- MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, UnknownVal()));
- }
- else
- MakeNode(Dst, Ex, Pred, SetRVal(St, Ex, GetRVal(St, cast<LVal>(location),
- Ex->getType())));
-}
-
-ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
- ValueState* St, RVal location,
- bool isLoad) {
-
- // Check for loads/stores from/to undefined values.
- if (location.isUndef()) {
- if (NodeTy* Succ = Builder->generateNode(Ex, St, Pred, isLoad)) {
- 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;
- ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull);
-
- // "Assume" that the pointer is NULL.
-
- bool isFeasibleNull = false;
- ValueState* StNull = Assume(St, LV, false, isFeasibleNull);
-
- if (isFeasibleNull) {
-
- // We don't use "MakeNode" here because the node will be a sink
- // and we have no intention of processing it later.
-
- NodeTy* NullNode = Builder->generateNode(Ex, StNull, Pred, isLoad);
-
- 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) {
-
- ValueState* 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;
-
- // 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 14:
- if (!memcmp(s, "dtrace_assfail", 14)) 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.
-
- ValueState* 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;
- ValueState* 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;
- }
-
- // 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(BasicVals, 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) {
- VisitDeclStmtAux(DS, DS->getDecl(), Pred, Dst);
-}
-
-void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
- NodeTy* Pred, NodeSet& Dst) {
-
- if (!D)
- return;
-
- if (!isa<VarDecl>(D)) {
- VisitDeclStmtAux(DS, D->getNextDeclarator(), Pred, Dst);
- return;
- }
-
- const VarDecl* VD = dyn_cast<VarDecl>(D);
-
- // FIXME: Add support for local arrays.
- if (VD->getType()->isArrayType()) {
- VisitDeclStmtAux(DS, D->getNextDeclarator(), Pred, Dst);
- 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) {
-
- ValueState* St = GetState(*I);
-
- if (!Ex && VD->hasGlobalStorage()) {
-
- // Handle variables with global storage and no initializers.
-
- // FIXME: static variables may have an initializer, but the second
- // time a function is called those values may not be current.
-
-
- // In this context, Static => Local variable.
-
- assert (!VD->getStorageClass() == VarDecl::Static ||
- !VD->isFileVarDecl());
-
- // If there is no initializer, set the value of the
- // variable to "Undefined".
-
- 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;
-
- // FIXME: Handle structs. Now we treat their values as unknown.
-
- QualType T = VD->getType();
-
- if (LVal::IsLValType(T))
- St = SetRVal(St, lval::DeclVal(VD),
- lval::ConcreteInt(BasicVals.getValue(0, T)));
- else if (T->isIntegerType())
- St = SetRVal(St, lval::DeclVal(VD),
- nonlval::ConcreteInt(BasicVals.getValue(0, T)));
-
- // FIXME: Handle structs. Now we treat them as unknown. What
- // we need to do is treat their members as unknown.
- }
- }
- else {
-
- // FIXME: Handle structs. Now we treat them as unknown. What
- // we need to do is treat their members as unknown.
-
- QualType T = VD->getType();
-
- if (LVal::IsLValType(T) || T->isIntegerType()) {
-
- RVal V = Ex ? GetRVal(St, Ex) : UndefinedVal();
-
- if (Ex && V.isUnknown()) {
-
- // EXPERIMENTAL: "Conjured" symbols.
-
- unsigned Count = Builder->getCurrentBlockCount();
- SymbolID Sym = SymMgr.getConjuredSymbol(Ex, Count);
-
- V = LVal::IsLValType(Ex->getType())
- ? cast<RVal>(lval::SymbolVal(Sym))
- : cast<RVal>(nonlval::SymbolVal(Sym));
- }
-
- St = SetRVal(St, lval::DeclVal(VD), V);
- }
- }
-
- // Create a new node. We don't really need to create a new NodeSet
- // here, but it simplifies things and doesn't cost much.
- NodeSet Tmp2;
- MakeNode(Tmp2, DS, *I, St);
- if (Tmp2.empty()) Tmp2.Add(*I);
-
- for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2)
- VisitDeclStmtAux(DS, D->getNextDeclarator(), *I2, Dst);
- }
-}
-
-
-/// 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(BasicVals, 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) {
-
- ValueState* St = GetState(*I);
- RVal location = GetRVal(St, Ex);
-
- if (asLVal)
- MakeNode(Dst, U, *I, SetRVal(St, U, location));
- else
- EvalLoad(Dst, Ex, *I, St, location);
- }
-
- return;
- }
-
-
- case UnaryOperator::OffsetOf:
- // FIXME: Just report "Unknown" known for 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) {
- ValueState* 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) {
- ValueState* 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) {
- ValueState* St = GetState(*I);
- RVal V = GetRVal(St, Ex);
-
- if (V.isUnknownOrUndef()) {
- MakeNode(Dst, U, *I, SetRVal(St, U, V));
- continue;
- }
-
- switch (U->getOpcode()) {
- default:
- assert(false && "Invalid Opcode.");
- break;
-
- case UnaryOperator::Not:
- St = SetRVal(St, U, EvalComplement(cast<NonLVal>(V)));
- break;
-
- case UnaryOperator::Minus:
- 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(BasicVals.getZeroWithPtrWidth());
- RVal Result = EvalBinOp(BinaryOperator::EQ, cast<LVal>(V), X);
- St = SetRVal(St, U, Result);
- }
- else {
- nonlval::ConcreteInt X(BasicVals.getValue(0, Ex->getType()));
- RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
- St = SetRVal(St, U, Result);
- }
-
- 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;
- ValueState* St = GetState(Pred);
- St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, 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) {
-
- ValueState* 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.
-
- ValueState* 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);
-
- TF->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::DeclVal>(X)) {
-
- if (cast<lval::DeclVal>(X).getDecl()->hasLocalStorage()) {
-
- // 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, ValueState* 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;
- ValueState* 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) {
-
- ValueState* 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, *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, *I3, SetRVal(St, B, V), location, V);
- continue;
- }
-
- // Propagate unknown values (left and right-side).
- if (RightV.isUnknown() || V.isUnknown()) {
- EvalStore(Dst, B, *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, *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, *I3, SetRVal(St, B, Result), location, Result);
- }
- }
- }
-}
-
-//===----------------------------------------------------------------------===//
-// "Assume" logic.
-//===----------------------------------------------------------------------===//
-
-ValueState* GRExprEngine::Assume(ValueState* St, LVal Cond,
- bool Assumption, bool& isFeasible) {
-
- St = AssumeAux(St, Cond, Assumption, isFeasible);
-
- return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
- : St;
-}
-
-ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
- bool Assumption, bool& isFeasible) {
-
- 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::DeclValKind:
- 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;
- }
- }
-}
-
-ValueState* GRExprEngine::Assume(ValueState* St, NonLVal Cond,
- bool Assumption, bool& isFeasible) {
-
- St = AssumeAux(St, Cond, Assumption, isFeasible);
-
- return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
- : St;
-}
-
-ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond,
- bool Assumption, bool& isFeasible) {
- switch (Cond.getSubKind()) {
- default:
- assert (false && "'Assume' not implemented for this NonLVal.");
- return St;
-
-
- 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);
- }
- }
-}
-
-ValueState*
-GRExprEngine::AssumeSymNE(ValueState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
- // First, determine if sym == X, where X != V.
- if (const llvm::APSInt* X = St->getSymVal(sym)) {
- isFeasible = *X != V;
- return St;
- }
-
- // Second, determine if sym != V.
- if (St->isNotEqual(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 StateMgr.AddNE(St, sym, V);
-}
-
-ValueState*
-GRExprEngine::AssumeSymEQ(ValueState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
- // First, determine if sym == X, where X != V.
- if (const llvm::APSInt* X = St->getSymVal(sym)) {
- isFeasible = *X == V;
- return St;
- }
-
- // Second, determine if sym != V.
- if (St->isNotEqual(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 StateMgr.AddEQ(St, sym, V);
-}
-
-ValueState*
-GRExprEngine::AssumeSymInt(ValueState* 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);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Visualization.
-//===----------------------------------------------------------------------===//
-
-#ifndef NDEBUG
-static GRExprEngine* GraphPrintCheckerState;
-static SourceManager* GraphPrintSourceManager;
-static ValueState::CheckerStatePrinter* GraphCheckerStatePrinter;
-
-namespace llvm {
-template<>
-struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
- public DefaultDOTGraphTraits {
-
- static void PrintVarBindings(std::ostream& Out, ValueState* St) {
-
- Out << "Variables:\\l";
-
- bool isFirst = true;
-
- for (ValueState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E;++I) {
-
- if (isFirst)
- isFirst = false;
- else
- Out << "\\l";
-
- Out << ' ' << I.getKey()->getName() << " : ";
- I.getData().print(Out);
- }
-
- }
-
-
- static void PrintSubExprBindings(std::ostream& Out, ValueState* St){
-
- bool isFirst = true;
-
- for (ValueState::seb_iterator I=St->seb_begin(), E=St->seb_end();I!=E;++I) {
-
- if (isFirst) {
- Out << "\\l\\lSub-Expressions:\\l";
- isFirst = false;
- }
- else
- Out << "\\l";
-
- Out << " (" << (void*) I.getKey() << ") ";
- I.getKey()->printPretty(Out);
- Out << " : ";
- I.getData().print(Out);
- }
- }
-
- static void PrintBlkExprBindings(std::ostream& Out, ValueState* St){
-
- bool isFirst = true;
-
- for (ValueState::beb_iterator I=St->beb_begin(), E=St->beb_end(); I!=E;++I){
- if (isFirst) {
- Out << "\\l\\lBlock-level Expressions:\\l";
- isFirst = false;
- }
- else
- Out << "\\l";
-
- Out << " (" << (void*) I.getKey() << ") ";
- I.getKey()->printPretty(Out);
- Out << " : ";
- I.getData().print(Out);
- }
- }
-
- static void PrintEQ(std::ostream& Out, ValueState* St) {
- ValueState::ConstEqTy CE = St->ConstEq;
-
- if (CE.isEmpty())
- return;
-
- Out << "\\l\\|'==' constraints:";
-
- for (ValueState::ConstEqTy::iterator I=CE.begin(), E=CE.end(); I!=E;++I)
- Out << "\\l $" << I.getKey() << " : " << I.getData()->toString();
- }
-
- static void PrintNE(std::ostream& Out, ValueState* St) {
- ValueState::ConstNotEqTy NE = St->ConstNotEq;
-
- if (NE.isEmpty())
- return;
-
- Out << "\\l\\|'!=' constraints:";
-
- for (ValueState::ConstNotEqTy::iterator I=NE.begin(), EI=NE.end();
- I != EI; ++I){
-
- Out << "\\l $" << I.getKey() << " : ";
- bool isFirst = true;
-
- ValueState::IntSetTy::iterator J=I.getData().begin(),
- EJ=I.getData().end();
- for ( ; J != EJ; ++J) {
- if (isFirst) isFirst = false;
- else Out << ", ";
-
- Out << (*J)->toString();
- }
- }
- }
-
- 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::PostStmtKind: {
- const PostStmt& L = cast<PostStmt>(Loc);
- Stmt* S = L.getStmt();
- SourceLocation SLoc = S->getLocStart();
-
- Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
- S->printPretty(Out);
-
- 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: ";
-
- E.getSrc()->printTerminator(Out);
-
- 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 ";
- C->getLHS()->printPretty(Out);
-
- if (Stmt* RHS = C->getRHS()) {
- Out << " .. ";
- RHS->printPretty(Out);
- }
-
- 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() << "\\|";
-
- N->getState()->printDOT(Out, GraphCheckerStatePrinter);
-
- 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::SmallPtrSet<void*,10> CachedSources;
-
- for ( ; I != E; ++I ) {
- GRExprEngine::NodeTy* N = GetGraphNode(I);
- void* p = N->getLocation().getRawData();
-
- 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();
- GraphCheckerStatePrinter = TF->getCheckerStatePrinter();
-
- llvm::ViewGraph(*G.roots_begin(), "GRExprEngine");
-
- GraphPrintCheckerState = NULL;
- GraphPrintSourceManager = NULL;
- GraphCheckerStatePrinter = NULL;
- }
-#endif
-}
-
-void GRExprEngine::ViewGraph(NodeTy** Beg, NodeTy** End) {
-#ifndef NDEBUG
- GraphPrintCheckerState = this;
- GraphPrintSourceManager = &getContext().getSourceManager();
- GraphCheckerStatePrinter = TF->getCheckerStatePrinter();
-
- 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;
- GraphCheckerStatePrinter = NULL;
-#endif
-}
diff --git a/clang/lib/Analysis/GRSimpleVals.cpp b/clang/lib/Analysis/GRSimpleVals.cpp
deleted file mode 100644
index b57cb57c3244..000000000000
--- a/clang/lib/Analysis/GRSimpleVals.cpp
+++ /dev/null
@@ -1,712 +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/ValueState.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;
-
-//===----------------------------------------------------------------------===//
-// Utility functions.
-//===----------------------------------------------------------------------===//
-
-template <typename ITERATOR> inline
-ExplodedNode<ValueState>* GetNode(ITERATOR I) {
- return *I;
-}
-
-template <> inline
-ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
- return I->first;
-}
-
-template <typename ITER>
-void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
-
- for (; I != E; ++I) {
- BugReport R(D, GetNode(I));
- BR.EmitWarning(R);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Bug Descriptions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "null dereference";
- }
-
- virtual const char* getDescription() const {
- return "Dereference of null pointer.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
- GenericEmitWarnings(BR, *this, Eng.null_derefs_begin(),
- Eng.null_derefs_end());
- }
-};
-
-class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "bad dereference";
- }
-
- virtual const char* getDescription() const {
- return "Dereference of undefined value.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
- GenericEmitWarnings(BR, *this, Eng.undef_derefs_begin(),
- Eng.undef_derefs_end());
- }
-};
-
-class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "uninitialized value";
- }
-
- virtual const char* getDescription() const {
- return "Branch condition evaluates to an uninitialized value.";
- }
-
- virtual void EmitWarnings(BugReporter& BR);
-};
-
-class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "divide-by-zero";
- }
-
- virtual const char* getDescription() const {
- return "Division by zero/undefined value.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
- GenericEmitWarnings(BR, *this, Eng.explicit_bad_divides_begin(),
- Eng.explicit_bad_divides_end());
- }
-};
-
-class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "undefined result";
- }
-
- virtual const char* getDescription() const {
- return "Result of operation is undefined.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
- GenericEmitWarnings(BR, *this, Eng.undef_results_begin(),
- Eng.undef_results_end());
- }
-};
-
-class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "invalid function call";
- }
-
- virtual const char* getDescription() const {
- return "Called function is a NULL or undefined function pointer value.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
- GenericEmitWarnings(BR, *this, Eng.bad_calls_begin(),
- Eng.bad_calls_end());
- }
-};
-
-
-class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
-public:
-
- virtual ~BadArg() {}
-
- virtual const char* getName() const {
- return "bad argument";
- }
-
- virtual const char* getDescription() const {
- return "Pass-by-value argument in function is undefined.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
-
- 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:
- virtual const char* getName() const {
- return "bad argument";
- }
-
- virtual const char* getDescription() const {
- return "Pass-by-value argument in message expression is undefined.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
-
- 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 BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "bad receiver";
- }
-
- virtual const char* getDescription() const {
- return "Receiver in message expression is an uninitialized value.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
-
- 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<ValueState>* 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 BugTypeCacheLocation {
-public:
- virtual const char* getName() const {
- return "return of stack address";
- }
-
- virtual const char* getDescription() const {
- return "Address of stack-allocated variable returned.";
- }
-
- virtual void EmitWarnings(BugReporter& BR) {
- GRExprEngine& Eng = BR.getEngine();
- GenericEmitWarnings(BR, *this, Eng.ret_stackaddr_begin(),
- Eng.ret_stackaddr_end());
- }
-};
-
-} // end anonymous namespace
-
-
-namespace {
-
-struct VISIBILITY_HIDDEN FindUndefExpr {
- ValueStateManager& VM;
- ValueState* St;
-
- FindUndefExpr(ValueStateManager& V, ValueState* 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(); }
-};
-
-} // end anonymous namespace
-
-
-void UndefBranch::EmitWarnings(BugReporter& BR) {
-
- GRExprEngine& Eng = BR.getEngine();
-
- 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<ValueState> *N = *(*I)->pred_begin();
- ProgramPoint P = N->getLocation();
-
- ValueState* 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);
- }
-}
-
-
-void GRSimpleVals::RegisterChecks(GRExprEngine& Eng) {
-
- // Path-sensitive checks.
- Eng.Register(new NullDeref());
- Eng.Register(new UndefDeref());
- Eng.Register(new UndefBranch());
- Eng.Register(new DivZero());
- Eng.Register(new UndefResult());
- Eng.Register(new BadCall());
- Eng.Register(new RetStack());
- Eng.Register(new BadArg());
- Eng.Register(new BadMsgExprArg());
- Eng.Register(new BadReceiver());
-
- // Flow-sensitive checks.
- Eng.Register(MakeDeadStoresChecker());
-
- // Add extra checkers.
-
- GRSimpleAPICheck* FoundationCheck =
- CreateBasicObjCFoundationChecks(Eng.getContext(), &Eng.getStateManager());
-
- Eng.AddObjCMessageExprCheck(FoundationCheck);
-}
-
-//===----------------------------------------------------------------------===//
-// 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();
-
- 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 (LVal::IsLValType(T))
- 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.
-
-RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
- NonLVal L, NonLVal R) {
-
- BasicValueFactory& BasicVals = Eng.getBasicVals();
-
- while (1) {
-
- switch (L.getSubKind()) {
- default:
- return UnknownVal();
-
- 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 {
- NonLVal tmp = R;
- R = L;
- L = tmp;
- 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::DeclValKind:
- case lval::FuncValKind:
- case lval::GotoLabelKind:
- 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::DeclValKind:
- case lval::FuncValKind:
- case lval::GotoLabelKind:
- return NonLVal::MakeIntTruthVal(BasicVals, L != R);
- }
-
- return NonLVal::MakeIntTruthVal(BasicVals, true);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer function for function calls.
-//===----------------------------------------------------------------------===//
-
-void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<ValueState>* Pred) {
-
- ValueStateManager& StateMgr = Eng.getStateManager();
- ValueState* 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<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<ValueState>* Pred) {
-
-
- // The basic transfer function logic for message expressions does nothing.
- // We just invalidate all arguments passed in by references.
-
- ValueStateManager& StateMgr = Eng.getStateManager();
- ValueState* 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 d86db51511cd..000000000000
--- a/clang/lib/Analysis/GRSimpleVals.h
+++ /dev/null
@@ -1,87 +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 {
-public:
- GRSimpleVals() {}
- virtual ~GRSimpleVals() {}
-
- virtual void RegisterChecks(GRExprEngine& Eng);
-
- // 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,
- NonLVal L, NonLVal R);
-
- 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<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- CallExpr* CE, RVal L,
- ExplodedNode<ValueState>* Pred);
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<ValueState>& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode<ValueState>* Pred);
-
-
-
- static void GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
- ExplodedNode<ValueState>* 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/GRTransferFuncs.cpp b/clang/lib/Analysis/GRTransferFuncs.cpp
deleted file mode 100644
index 9c96e3d9817e..000000000000
--- a/clang/lib/Analysis/GRTransferFuncs.cpp
+++ /dev/null
@@ -1,39 +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<ValueState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<ValueState>& Builder,
- Expr* E, ExplodedNode<ValueState>* Pred,
- ValueState* 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));
-}
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp
deleted file mode 100644
index 4148d9e838d1..000000000000
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ /dev/null
@@ -1,323 +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 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 (AD.Observer)
- AD.Observer->ObserveStmt(S,AD,LiveState);
-
- if (S == getCurrentBlkStmt()) {
- if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
- StmtVisitor<TransferFuncs,void>::Visit(S);
- }
- else if (!getCFG().isBlkExpr(S))
- 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 (ScopedDecl* D = DS->getDecl(); D != NULL; D = D->getNextDeclarator())
- if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
-
- // Update liveness information.
- unsigned bit = AD.getIdx(VD);
- LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
-
- if (Expr* Init = VD->getInit())
- Visit(Init);
- }
-}
-
-} // 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/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp
deleted file mode 100644
index 28b76b38f13b..000000000000
--- a/clang/lib/Analysis/PathDiagnostic.cpp
+++ /dev/null
@@ -1,74 +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();
-
- // Ripped from TextDiagnostics::FormatDiagnostic. Perhaps we should
- // centralize it somewhere?
-
- 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 = Diags.getDescription(ID);
-
- 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());
- }
- }
-
- 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/ProgramPoint.cpp b/clang/lib/Analysis/ProgramPoint.cpp
deleted file mode 100644
index d95680ff3892..000000000000
--- a/clang/lib/Analysis/ProgramPoint.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-//= ProgramPoint.cpp - 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 implements methods for subclasses of ProgramPoint.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/CFG.h"
-#include "clang/Analysis/ProgramPoint.h"
-
-using namespace clang;
-
-BlockEdge::BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2) {
- if (B1->succ_size() == 1) {
- assert (*(B1->succ_begin()) == B2);
- setRawData(B1, BlockEdgeSrcKind);
- }
- else if (B2->pred_size() == 1) {
- assert (*(B2->pred_begin()) == B1);
- setRawData(B2, BlockEdgeDstKind);
- }
- else
- setRawData(cfg.getBlockEdgeImpl(B1,B2), BlockEdgeAuxKind);
-}
-
-CFGBlock* BlockEdge::getSrc() const {
- switch (getKind()) {
- default:
- assert (false && "Invalid BlockEdgeKind.");
- return NULL;
-
- case BlockEdgeSrcKind:
- return reinterpret_cast<CFGBlock*>(getRawPtr());
-
- case BlockEdgeDstKind:
- return *(reinterpret_cast<CFGBlock*>(getRawPtr())->pred_begin());
-
- case BlockEdgeAuxKind:
- return reinterpret_cast<BPair*>(getRawPtr())->first;
- }
-}
-
-CFGBlock* BlockEdge::getDst() const {
- switch (getKind()) {
- default:
- assert (false && "Invalid BlockEdgeKind.");
- return NULL;
-
- case BlockEdgeSrcKind:
- return *(reinterpret_cast<CFGBlock*>(getRawPtr())->succ_begin());
-
- case BlockEdgeDstKind:
- return reinterpret_cast<CFGBlock*>(getRawPtr());
-
- case BlockEdgeAuxKind:
- return reinterpret_cast<BPair*>(getRawPtr())->second;
- }
-}
diff --git a/clang/lib/Analysis/RValues.cpp b/clang/lib/Analysis/RValues.cpp
deleted file mode 100644
index 60c349420a3d..000000000000
--- a/clang/lib/Analysis/RValues.cpp
+++ /dev/null
@@ -1,432 +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/RValues.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;
-}
-
-//===----------------------------------------------------------------------===//
-// 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::DeclValKind:
- if (isa<lval::DeclVal>(R)) {
- bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(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::DeclValKind:
- if (isa<lval::DeclVal>(R)) {
- bool b = cast<lval::DeclVal>(*this) == cast<lval::DeclVal>(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 (T->isPointerLikeType() || T->isObjCQualifiedIdType())
- 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(BasicValueFactory& BasicVals, DeclRefExpr* E) {
-
- ValueDecl* D = cast<DeclRefExpr>(E)->getDecl();
-
- if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
- return lval::DeclVal(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.
-
- 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().toString();
-
- 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().toString();
-
- 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().toString()
- << " (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::DeclValKind:
- Out << '&'
- << cast<lval::DeclVal>(this)->getDecl()->getIdentifier()->getName();
- 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 f243fa667b33..000000000000
--- a/clang/lib/Analysis/SymbolManager.cpp
+++ /dev/null
@@ -1,124 +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) || 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, unsigned Count) {
-
- llvm::FoldingSetNodeID profile;
- SymbolConjured::Profile(profile, E, Count);
- void* InsertPos;
-
- SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
-
- if (SD)
- return SD->getSymbol();
-
- SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
- new (SD) SymbolConjured(SymbolCounter, E, 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)->getExpr()->getType();
- }
-}
-
-SymbolManager::~SymbolManager() {}
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
deleted file mode 100644
index 15c11ba6b0d7..000000000000
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-//==- UninitializedValues.cpp - Find Unintialized 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 (ScopedDecl* D = S->getDecl(); D != NULL; D = D->getNextDeclarator()) {
- VarDecl *VD = dyn_cast<VarDecl>(D);
- 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 unintialized values, e.g. Unitialized + ___ = Unitialized.
-//
-// 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;
-}
-
-//===----------------------------------------------------------------------===//
-// Unitialized 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 unitialized 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/Analysis/ValueState.cpp b/clang/lib/Analysis/ValueState.cpp
deleted file mode 100644
index 96b94ea8cfaf..000000000000
--- a/clang/lib/Analysis/ValueState.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-//= ValueState*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 ValueState*
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/ValueState.h"
-#include "llvm/ADT/SmallSet.h"
-
-using namespace clang;
-
-bool ValueState::isNotEqual(SymbolID sym, const llvm::APSInt& V) const {
-
- // Retrieve the NE-set associated with the given symbol.
- ConstNotEqTy::TreeTy* T = ConstNotEq.SlimFind(sym);
-
- // See if V is present in the NE-set.
- return T ? T->getValue().second.contains(&V) : false;
-}
-
-const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const {
- ConstEqTy::TreeTy* T = ConstEq.SlimFind(sym);
- return T ? T->getValue().second : NULL;
-}
-
-ValueState*
-ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
- const LiveVariables& Liveness,
- DeadSymbolsTy& DeadSymbols) {
-
- // 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<ValueDecl*, 10> WList;
- llvm::SmallPtrSet<ValueDecl*, 10> Marked;
- llvm::SmallSet<SymbolID, 20> MarkedSymbols;
-
- ValueState NewSt = *St;
-
- // Drop bindings for subexpressions.
- NewSt.SubExprBindings = EXFactory.GetEmptyMap();
-
- // Iterate over the block-expr bindings.
-
- for (ValueState::beb_iterator I = St->beb_begin(), E = St->beb_end();
- I!=E ; ++I) {
- Expr* BlkExpr = I.getKey();
-
- if (Liveness.isLive(Loc, BlkExpr)) {
- RVal X = I.getData();
-
- if (isa<lval::DeclVal>(X)) {
- lval::DeclVal LV = cast<lval::DeclVal>(X);
- WList.push_back(LV.getDecl());
- }
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI) {
- MarkedSymbols.insert(*SI);
- }
- }
- else {
- RVal X = I.getData();
-
- if (X.isUndef() && cast<UndefinedVal>(X).getData())
- continue;
-
- NewSt.BlockExprBindings = Remove(NewSt, BlkExpr);
- }
- }
-
- // Iterate over the variable bindings.
-
- for (ValueState::vb_iterator I = St->vb_begin(), E = St->vb_end(); I!=E ; ++I)
- if (Liveness.isLive(Loc, I.getKey())) {
- WList.push_back(I.getKey());
-
- RVal X = I.getData();
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI) {
- MarkedSymbols.insert(*SI);
- }
- }
-
- // Perform the mark-and-sweep.
-
- while (!WList.empty()) {
-
- ValueDecl* V = WList.back();
- WList.pop_back();
-
- if (Marked.count(V))
- continue;
-
- Marked.insert(V);
-
- RVal X = GetRVal(St, lval::DeclVal(cast<VarDecl>(V)));
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI) {
- MarkedSymbols.insert(*SI);
- }
-
- if (!isa<lval::DeclVal>(X))
- continue;
-
- const lval::DeclVal& LVD = cast<lval::DeclVal>(X);
- WList.push_back(LVD.getDecl());
- }
-
- // Remove dead variable bindings.
-
- DeadSymbols.clear();
-
- for (ValueState::vb_iterator I = St->vb_begin(), E = St->vb_end(); I!=E ; ++I)
- if (!Marked.count(I.getKey())) {
- NewSt.VarBindings = Remove(NewSt, I.getKey());
-
- RVal X = I.getData();
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI)
- if (!MarkedSymbols.count(*SI)) DeadSymbols.insert(*SI);
- }
-
- // Remove dead symbols.
-
- for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
-
- SymbolID sym = I.getKey();
-
- if (!MarkedSymbols.count(sym)) {
- DeadSymbols.insert(sym);
- NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, sym);
- }
- }
-
- for (ValueState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){
-
- SymbolID sym = I.getKey();
-
- if (!MarkedSymbols.count(sym)) {
- DeadSymbols.insert(sym);
- NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
- }
- }
-
- return getPersistentState(NewSt);
-}
-
-
-RVal ValueStateManager::GetRVal(ValueState* St, LVal LV, QualType T) {
-
- if (isa<UnknownVal>(LV))
- return UnknownVal();
-
- assert (!isa<UndefinedVal>(LV));
-
- switch (LV.getSubKind()) {
- case lval::DeclValKind: {
- ValueState::VarBindingsTy::TreeTy* T =
- St->VarBindings.SlimFind(cast<lval::DeclVal>(LV).getDecl());
-
- return T ? T->getValue().second : UnknownVal();
- }
-
- // FIXME: We should limit how far a "ContentsOf" will go...
-
- case lval::SymbolValKind: {
-
-
- // FIXME: This is a broken representation of memory, and is prone
- // to crashing the analyzer when addresses to symbolic values are
- // passed through casts. We need a better representation of symbolic
- // memory (or just memory in general); probably we should do this
- // as a plugin class (similar to GRTransferFuncs).
-
-#if 0
- const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
- assert (T.getTypePtr());
-
- // Punt on "symbolic" function pointers.
- if (T->isFunctionType())
- return UnknownVal();
-
- if (T->isPointerType())
- return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
- else
- return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
-#endif
-
- 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();
-}
-
-ValueState* ValueStateManager::AddNE(ValueState* St, SymbolID sym,
- const llvm::APSInt& V) {
-
- // First, retrieve the NE-set associated with the given symbol.
- ValueState::ConstNotEqTy::TreeTy* T = St->ConstNotEq.SlimFind(sym);
- ValueState::IntSetTy S = T ? T->getValue().second : ISetFactory.GetEmptySet();
-
- // Now add V to the NE set.
- S = ISetFactory.Add(S, &V);
-
- // Create a new state with the old binding replaced.
- ValueState NewSt = *St;
- NewSt.ConstNotEq = CNEFactory.Add(NewSt.ConstNotEq, sym, S);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
-}
-
-ValueState* ValueStateManager::AddEQ(ValueState* St, SymbolID sym,
- const llvm::APSInt& V) {
-
- // Create a new state with the old binding replaced.
- ValueState NewSt = *St;
- NewSt.ConstEq = CEFactory.Add(NewSt.ConstEq, sym, &V);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
-}
-
-RVal ValueStateManager::GetRVal(ValueState* St, Expr* E) {
-
- 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: {
- ImplicitCastExpr* C = cast<ImplicitCastExpr>(E);
- QualType CT = C->getType();
-
- if (CT->isVoidType())
- return UnknownVal();
-
- QualType ST = C->getSubExpr()->getType();
-
- break;
- }
-
- case Stmt::CastExprClass: {
- 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;
- }
-
- ValueState::ExprBindingsTy::TreeTy* T = St->SubExprBindings.SlimFind(E);
-
- if (T)
- return T->getValue().second;
-
- T = St->BlockExprBindings.SlimFind(E);
- return T ? T->getValue().second : UnknownVal();
-}
-
-RVal ValueStateManager::GetBlkExprRVal(ValueState* St, Expr* E) {
-
- 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: {
- ValueState::ExprBindingsTy::TreeTy* T = St->BlockExprBindings.SlimFind(E);
- return T ? T->getValue().second : UnknownVal();
- }
- }
-}
-
-ValueState*
-ValueStateManager::SetRVal(ValueState* St, Expr* E, RVal V,
- bool isBlkExpr, bool Invalidate) {
-
- assert (E);
-
- if (V.isUnknown()) {
-
- if (Invalidate) {
-
- ValueState NewSt = *St;
-
- if (isBlkExpr)
- NewSt.BlockExprBindings = EXFactory.Remove(NewSt.BlockExprBindings, E);
- else
- NewSt.SubExprBindings = EXFactory.Remove(NewSt.SubExprBindings, E);
-
- return getPersistentState(NewSt);
- }
-
- return St;
- }
-
- ValueState NewSt = *St;
-
- if (isBlkExpr) {
- NewSt.BlockExprBindings = EXFactory.Add(NewSt.BlockExprBindings, E, V);
- }
- else {
- NewSt.SubExprBindings = EXFactory.Add(NewSt.SubExprBindings, E, V);
- }
-
- return getPersistentState(NewSt);
-}
-
-
-ValueState* ValueStateManager::SetRVal(ValueState* St, LVal LV, RVal V) {
-
- switch (LV.getSubKind()) {
-
- case lval::DeclValKind:
- return V.isUnknown()
- ? UnbindVar(St, cast<lval::DeclVal>(LV).getDecl())
- : BindVar(St, cast<lval::DeclVal>(LV).getDecl(), V);
-
- default:
- assert ("SetRVal for given LVal type not yet implemented.");
- return St;
- }
-}
-
-void ValueStateManager::BindVar(ValueState& StImpl, VarDecl* D, RVal V) {
- StImpl.VarBindings = VBFactory.Add(StImpl.VarBindings, D, V);
-}
-
-ValueState* ValueStateManager::BindVar(ValueState* St, VarDecl* D, RVal V) {
-
- // Create a new state with the old binding removed.
- ValueState NewSt = *St;
- NewSt.VarBindings = VBFactory.Add(NewSt.VarBindings, D, V);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
-}
-
-ValueState* ValueStateManager::UnbindVar(ValueState* St, VarDecl* D) {
-
- // Create a new state with the old binding removed.
- ValueState NewSt = *St;
- NewSt.VarBindings = VBFactory.Remove(NewSt.VarBindings, D);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
-}
-
-void ValueStateManager::Unbind(ValueState& StImpl, LVal LV) {
-
- if (isa<lval::DeclVal>(LV))
- StImpl.VarBindings = VBFactory.Remove(StImpl.VarBindings,
- cast<lval::DeclVal>(LV).getDecl());
-
-}
-
-ValueState* ValueStateManager::getInitialState() {
-
- // Create a state with empty variable bindings.
- ValueState StateImpl(EXFactory.GetEmptyMap(),
- VBFactory.GetEmptyMap(),
- CNEFactory.GetEmptyMap(),
- CEFactory.GetEmptyMap());
-
- return getPersistentState(StateImpl);
-}
-
-ValueState* ValueStateManager::getPersistentState(ValueState& State) {
-
- llvm::FoldingSetNodeID ID;
- State.Profile(ID);
- void* InsertPos;
-
- if (ValueState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
- return I;
-
- ValueState* I = (ValueState*) Alloc.Allocate<ValueState>();
- new (I) ValueState(State);
- StateSet.InsertNode(I, InsertPos);
- return I;
-}
-
-void ValueState::printDOT(std::ostream& Out, CheckerStatePrinter* P) const {
- print(Out, P, "\\l", "\\|");
-}
-
-void ValueState::printStdErr(CheckerStatePrinter* P) const {
- print(*llvm::cerr, P);
-}
-
-void ValueState::print(std::ostream& Out, CheckerStatePrinter* P,
- const char* nl, const char* sep) const {
-
- // Print Variable Bindings
- Out << "Variables:" << nl;
-
- bool isFirst = true;
-
- for (vb_iterator I = vb_begin(), E = vb_end(); I != E; ++I) {
-
- if (isFirst) isFirst = false;
- else Out << nl;
-
- Out << ' ' << I.getKey()->getName() << " : ";
- I.getData().print(Out);
- }
-
- // Print Subexpression bindings.
-
- 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() << ") ";
- I.getKey()->printPretty(Out);
- 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() << ") ";
- I.getKey()->printPretty(Out);
- Out << " : ";
- I.getData().print(Out);
- }
-
- // Print equality constraints.
-
- if (!ConstEq.isEmpty()) {
-
- Out << nl << sep << "'==' constraints:";
-
- for (ConstEqTy::iterator I = ConstEq.begin(),
- E = ConstEq.end(); I!=E; ++I) {
-
- Out << nl << " $" << I.getKey()
- << " : " << I.getData()->toString();
- }
- }
-
- // Print != constraints.
-
- if (!ConstNotEq.isEmpty()) {
-
- Out << nl << sep << "'!=' constraints:";
-
- for (ConstNotEqTy::iterator I = ConstNotEq.begin(),
- EI = ConstNotEq.end(); I != EI; ++I) {
-
- Out << nl << " $" << I.getKey() << " : ";
- isFirst = true;
-
- IntSetTy::iterator J = I.getData().begin(), EJ = I.getData().end();
-
- for ( ; J != EJ; ++J) {
- if (isFirst) isFirst = false;
- else Out << ", ";
-
- Out << (*J)->toString();
- }
- }
- }
-
- // Print checker-specific data.
-
- if (P && CheckerState)
- P->PrintCheckerState(Out, CheckerState, nl, sep);
-}
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
deleted file mode 100644
index 5835e75c1a7a..000000000000
--- a/clang/lib/Basic/Diagnostic.cpp
+++ /dev/null
@@ -1,241 +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,
- ERROR = 0x04,
- 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) {
- WarningsAsErrors = false;
- WarnOnExtensions = false;
- ErrorOnExtensions = 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 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;
- }
-
- // If warnings are to be treated as errors, indicate this as such.
- if (DiagClass == WARNING && 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. If the client wants us to stop
-/// compilation, return true, otherwise return false. DiagID is a member of
-/// the diag::kind enum.
-void Diagnostic::Report(DiagnosticClient* C,
- FullSourceLoc Pos, 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 class here, because we also want to ignore
- // extensions and warnings in -Werror and -pedantic-errors modes, which *map*
- // warnings/extensions to errors.
- if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
- getBuiltinDiagClass(DiagID) != ERROR &&
- Client.isInSystemHeader(Pos))
- return;
-
- if (DiagLevel >= Diagnostic::Error) {
- ErrorOccurred = true;
-
- if (C == &Client)
- ++NumErrors;
- }
-
- // Finally, report it.
-
- C->HandleDiagnostic(*this, DiagLevel, Pos, (diag::kind)DiagID,
- Strs, NumStrs, Ranges, NumRanges);
-
- if (C == &Client)
- ++NumDiagnostics;
-}
-
-DiagnosticClient::~DiagnosticClient() {}
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 65e984a0f78d..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.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 83c264ad0b0c..000000000000
--- a/clang/lib/Basic/SourceLocation.cpp
+++ /dev/null
@@ -1,94 +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() {
- assert (isValid());
- return FullSourceLoc(SrcMgr->getLogicalLoc(Loc),*SrcMgr);
-}
-
-FullSourceLoc FullSourceLoc::getIncludeLoc() {
- 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);
-}
-
-const char* FullSourceLoc::getSourceName() const {
- assert (isValid());
- return SrcMgr->getSourceName(Loc);
-}
-
-const FileEntry* FullSourceLoc::getFileEntryForLoc() const {
- assert (isValid());
- return SrcMgr->getFileEntryForLoc(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);
-}
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
deleted file mode 100644
index d7d2c84a4c1a..000000000000
--- a/clang/lib/Basic/SourceManager.cpp
+++ /dev/null
@@ -1,514 +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) {
- // 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));
- 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));
-
- 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 e8fc9232e129..000000000000
--- a/clang/lib/Basic/TargetInfo.cpp
+++ /dev/null
@@ -1,217 +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 "clang/Basic/Diagnostic.h"
-#include "clang/AST/Builtins.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. 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;
- DoubleWidth = 64;
- DoubleAlign = 32;
- FloatFormat = &llvm::APFloat::IEEEsingle;
- DoubleFormat = &llvm::APFloat::IEEEdouble;
- LongDoubleFormat = &llvm::APFloat::IEEEdouble;
-}
-
-// 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 assert is in place temporarily
- // so we can add more constraints as we hit it.
- // Eventually, an unknown constraint should just be treated as 'g'.
- assert(0 && "Unknown input constraint type!");
- }
- 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 d7bbe50618bc..000000000000
--- a/clang/lib/Basic/Targets.cpp
+++ /dev/null
@@ -1,933 +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/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/STLExtras.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');
-}
-
-
-namespace {
-class DarwinTargetInfo : public TargetInfo {
-public:
- DarwinTargetInfo(const std::string& triple) : TargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defs) const {
-// FIXME: we need a real target configuration system. For now, only define
-// __APPLE__ if the host has it.
-#ifdef __APPLE__
- Define(Defs, "__APPLE__");
- Define(Defs, "__MACH__");
-#endif
-
- if (1) {// -fobjc-gc controls this.
- Define(Defs, "__weak", "");
- Define(Defs, "__strong", "");
- } else {
- Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
- Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
- Define(Defs, "__OBJC_GC__");
- }
-
- // darwin_constant_cfstrings controls this.
- Define(Defs, "__CONSTANT_CFSTRINGS__");
-
- if (0) // darwin_pascal_strings
- Define(Defs, "__PASCAL_STRINGS__");
- }
-
-};
-
-
-class SolarisTargetInfo : public TargetInfo {
-public:
- SolarisTargetInfo(const std::string& triple) : TargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defs) const {
-// FIXME: we need a real target configuration system. For now, only define
-// __SUN__ if the host has it.
-#ifdef __SUN__
- Define(Defs, "__SUN__");
- Define(Defs, "__SOLARIS__");
-#endif
-
- if (1) {// -fobjc-gc controls this.
- Define(Defs, "__weak", "");
- Define(Defs, "__strong", "");
- } else {
- Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
- Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
- Define(Defs, "__OBJC_GC__");
- }
- }
-
-};
-} // end anonymous namespace.
-
-
-/// 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__");
-
- if (is64Bit) {
- Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
- Define(Defs, "__INTMAX_TYPE__", "long int");
- Define(Defs, "__LONG_MAX__", "9223372036854775807L");
- Define(Defs, "__PTRDIFF_TYPE__", "long int");
- Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
- } else {
- Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
- Define(Defs, "__INTMAX_TYPE__", "long long int");
- Define(Defs, "__LONG_MAX__", "2147483647L");
- Define(Defs, "__PTRDIFF_TYPE__", "int");
- Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
- }
- Define(Defs, "__INT_MAX__", "2147483647");
- Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
- Define(Defs, "__CHAR_BIT__", "8");
- Define(Defs, "__SCHAR_MAX__", "127");
- Define(Defs, "__SHRT_MAX__", "32767");
- Define(Defs, "__SIZE_TYPE__", "long unsigned int");
-
- // Subtarget options.
- Define(Defs, "__USER_LABEL_PREFIX__", "_");
- Define(Defs, "__NATURAL_ALIGNMENT__");
- Define(Defs, "__REGISTER_PREFIX__", "");
-
- Define(Defs, "__WCHAR_MAX__", "2147483647");
- Define(Defs, "__WCHAR_TYPE__", "int");
- Define(Defs, "__WINT_TYPE__", "int");
-
- // Float macros.
- Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
- Define(Defs, "__FLT_DIG__", "6");
- Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
- Define(Defs, "__FLT_EVAL_METHOD__", "0");
- Define(Defs, "__FLT_HAS_INFINITY__");
- Define(Defs, "__FLT_HAS_QUIET_NAN__");
- Define(Defs, "__FLT_MANT_DIG__", "24");
- Define(Defs, "__FLT_MAX_10_EXP__", "38");
- Define(Defs, "__FLT_MAX_EXP__", "128");
- Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
- Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
- Define(Defs, "__FLT_MIN_EXP__", "(-125)");
- Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
- Define(Defs, "__FLT_RADIX__", "2");
-
- // double macros.
- Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
- Define(Defs, "__DBL_DIG__", "15");
- Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
- Define(Defs, "__DBL_HAS_INFINITY__");
- Define(Defs, "__DBL_HAS_QUIET_NAN__");
- Define(Defs, "__DBL_MANT_DIG__", "53");
- Define(Defs, "__DBL_MAX_10_EXP__", "308");
- Define(Defs, "__DBL_MAX_EXP__", "1024");
- Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
- Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
- Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
- Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
- Define(Defs, "__DECIMAL_DIG__", "33");
-
- // 128-bit long double macros.
- Define(Defs, "__LDBL_DENORM_MIN__",
- "4.94065645841246544176568792868221e-324L");
- Define(Defs, "__LDBL_DIG__", "31");
- Define(Defs, "__LDBL_EPSILON__",
- "4.94065645841246544176568792868221e-324L");
- Define(Defs, "__LDBL_HAS_INFINITY__");
- Define(Defs, "__LDBL_HAS_QUIET_NAN__");
- Define(Defs, "__LDBL_MANT_DIG__", "106");
- Define(Defs, "__LDBL_MAX_10_EXP__", "308");
- Define(Defs, "__LDBL_MAX_EXP__", "1024");
- Define(Defs, "__LDBL_MAX__",
- "1.79769313486231580793728971405301e+308L");
- Define(Defs, "__LDBL_MIN_10_EXP__", "(-291)");
- Define(Defs, "__LDBL_MIN_EXP__", "(-968)");
- Define(Defs, "__LDBL_MIN__",
- "2.00416836000897277799610805135016e-292L");
- 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__");
-
- if (is64Bit) {
- Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
- Define(Defs, "__INTMAX_TYPE__", "long int");
- Define(Defs, "__LONG_MAX__", "9223372036854775807L");
- Define(Defs, "__PTRDIFF_TYPE__", "long int");
- Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
- Define(Defs, "__SIZE_TYPE__", "long unsigned int");
- } else {
- Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
- Define(Defs, "__INTMAX_TYPE__", "long long int");
- Define(Defs, "__LONG_MAX__", "2147483647L");
- Define(Defs, "__PTRDIFF_TYPE__", "int");
- Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
- Define(Defs, "__SIZE_TYPE__", "unsigned int");
- }
- Define(Defs, "__CHAR_BIT__", "8");
- Define(Defs, "__INT_MAX__", "2147483647");
- Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
- Define(Defs, "__SCHAR_MAX__", "127");
- Define(Defs, "__SHRT_MAX__", "32767");
-
- // 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__", "");
-
- Define(Defs, "__WCHAR_MAX__", "2147483647");
- Define(Defs, "__WCHAR_TYPE__", "int");
- Define(Defs, "__WINT_TYPE__", "int");
-
- // Float macros.
- Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
- Define(Defs, "__FLT_DIG__", "6");
- Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
- Define(Defs, "__FLT_EVAL_METHOD__", "0");
- Define(Defs, "__FLT_HAS_INFINITY__");
- Define(Defs, "__FLT_HAS_QUIET_NAN__");
- Define(Defs, "__FLT_MANT_DIG__", "24");
- Define(Defs, "__FLT_MAX_10_EXP__", "38");
- Define(Defs, "__FLT_MAX_EXP__", "128");
- Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
- Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
- Define(Defs, "__FLT_MIN_EXP__", "(-125)");
- Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
- Define(Defs, "__FLT_RADIX__", "2");
-
- // Double macros.
- Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
- Define(Defs, "__DBL_DIG__", "15");
- Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
- Define(Defs, "__DBL_HAS_INFINITY__");
- Define(Defs, "__DBL_HAS_QUIET_NAN__");
- Define(Defs, "__DBL_MANT_DIG__", "53");
- Define(Defs, "__DBL_MAX_10_EXP__", "308");
- Define(Defs, "__DBL_MAX_EXP__", "1024");
- Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
- Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
- Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
- Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
- Define(Defs, "__DECIMAL_DIG__", "21");
-
- // 80-bit Long double macros.
- Define(Defs, "__LDBL_DENORM_MIN__", "3.64519953188247460253e-4951L");
- Define(Defs, "__LDBL_DIG__", "18");
- Define(Defs, "__LDBL_EPSILON__", "1.08420217248550443401e-19L");
- Define(Defs, "__LDBL_HAS_INFINITY__");
- Define(Defs, "__LDBL_HAS_QUIET_NAN__");
- Define(Defs, "__LDBL_MANT_DIG__", "64");
- Define(Defs, "__LDBL_MAX_10_EXP__", "4932");
- Define(Defs, "__LDBL_MAX_EXP__", "16384");
- Define(Defs, "__LDBL_MAX__", "1.18973149535723176502e+4932L");
- Define(Defs, "__LDBL_MIN_10_EXP__", "(-4931)");
- Define(Defs, "__LDBL_MIN_EXP__", "(-16381)");
- Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
-}
-
-/// 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__");
-
- Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
- Define(Defs, "__INTMAX_TYPE__", "long long int");
- Define(Defs, "__LONG_MAX__", "2147483647L");
- Define(Defs, "__PTRDIFF_TYPE__", "int");
- Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
- Define(Defs, "__SIZE_TYPE__", "long unsigned int");
-
- Define(Defs, "__CHAR_BIT__", "8");
- Define(Defs, "__INT_MAX__", "2147483647");
- Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
- Define(Defs, "__SCHAR_MAX__", "127");
- Define(Defs, "__SHRT_MAX__", "32767");
-
- // 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");
-
- Define(Defs, "__WCHAR_MAX__", "2147483647");
- Define(Defs, "__WCHAR_TYPE__", "int");
- Define(Defs, "__WINT_TYPE__", "int");
- Define(Defs, "__DECIMAL_DIG__", "17");
- Define(Defs, "__FLT_RADIX__", "2");
-
- // Float macros.
- Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
- Define(Defs, "__FLT_DIG__", "6");
- Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
- Define(Defs, "__FLT_EVAL_METHOD__", "0");
- Define(Defs, "__FLT_HAS_INFINITY__");
- Define(Defs, "__FLT_HAS_QUIET_NAN__");
- Define(Defs, "__FLT_MANT_DIG__", "24");
- Define(Defs, "__FLT_MAX_10_EXP__", "38");
- Define(Defs, "__FLT_MAX_EXP__", "128");
- Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
- Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
- Define(Defs, "__FLT_MIN_EXP__", "(-125)");
- Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
-
- // Double macros.
- Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
- Define(Defs, "__DBL_DIG__", "15");
- Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
- Define(Defs, "__DBL_HAS_INFINITY__");
- Define(Defs, "__DBL_HAS_QUIET_NAN__");
- Define(Defs, "__DBL_MANT_DIG__", "53");
- Define(Defs, "__DBL_MAX_10_EXP__", "308");
- Define(Defs, "__DBL_MAX_EXP__", "1024");
- Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
- Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
- Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
- Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
-
- // 64-bit Long double macros (same as double).
- Define(Defs, "__LDBL_DENORM_MIN__", "4.9406564584124654e-324");
- Define(Defs, "__LDBL_DIG__", "15");
- Define(Defs, "__LDBL_EPSILON__", "2.2204460492503131e-16");
- Define(Defs, "__LDBL_HAS_INFINITY__");
- Define(Defs, "__LDBL_HAS_QUIET_NAN__");
- Define(Defs, "__LDBL_MANT_DIG__", "53");
- Define(Defs, "__LDBL_MAX_10_EXP__", "308");
- Define(Defs, "__LDBL_MAX_EXP__", "1024");
- Define(Defs, "__LDBL_MAX__", "1.7976931348623157e+308");
- Define(Defs, "__LDBL_MIN_10_EXP__", "(-307)");
- Define(Defs, "__LDBL_MIN_EXP__", "(-1021)");
- Define(Defs, "__LDBL_MIN__", "2.2250738585072014e-308");
-}
-
-static const char* getI386VAListDeclaration() {
- return "typedef char* __builtin_va_list;";
-}
-
-static const char* getX86_64VAListDeclaration() {
- return
- "typedef struct __va_list_tag {"
- " unsigned gp_offset;"
- " unsigned fp_offset;"
- " void* overflow_arg_area;"
- " void* reg_save_area;"
- "} __builtin_va_list[1];";
-}
-
-static const char* getPPCVAListDeclaration() {
- 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];";
-}
-
-static const char* getARMVAListDeclaration() {
- return "typedef char* __builtin_va_list;";
-}
-
-/// PPC builtin info.
-namespace clang {
-namespace PPC {
-
- static const Builtin::Info BuiltinInfo[] = {
-#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
-#include "clang/AST/PPCBuiltins.def"
- };
-
- static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
- Records = BuiltinInfo;
- NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
- }
-
- static const char * const 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"
- };
-
- static void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
- }
-
- static const TargetInfo::GCCRegAlias 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" },
- };
-
- static void getGCCRegAliases(const TargetInfo::GCCRegAlias *&Aliases,
- unsigned &NumAliases) {
- Aliases = GCCRegAliases;
- NumAliases = llvm::array_lengthof(GCCRegAliases);
- }
-
- static bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) {
- 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;
- }
- }
-
- const char *getClobbers() {
- return 0;
- }
-
- const char *getTargetPrefix() {
- return "ppc";
- }
-
-} // End namespace PPC
-
-/// X86 builtin info.
-namespace X86 {
- static const Builtin::Info BuiltinInfo[] = {
-#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
-#include "clang/AST/X86Builtins.def"
- };
-
- static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
- Records = BuiltinInfo;
- NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
- }
-
- static 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"
- };
-
- static void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
- }
-
- static 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" },
- { { "esp", "rsp" }, "sp" },
- { { "ebp", "rbp" }, "bp" },
- };
-
- static void getGCCRegAliases(const TargetInfo::GCCRegAlias *&Aliases,
- unsigned &NumAliases) {
- Aliases = GCCRegAliases;
- NumAliases = llvm::array_lengthof(GCCRegAliases);
- }
-
- static bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) {
- 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': // a, b, c, d registers or any integer register in 64-bit.
- 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;
- }
- }
-
- static std::string convertConstraint(const char Constraint) {
- 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);
- }
- }
-
- const char *getClobbers() {
- return "~{dirflag},~{fpsr},~{flags}";
- }
-
- const char *getTargetPrefix() {
- return "x86";
- }
-
-} // End namespace X86
-
-
-/// ARM builtin info.
-namespace ARM {
- const char *getTargetPrefix() {
- return "arm";
- }
-} // End namespace ARM
-
-} // end namespace clang.
-
-//===----------------------------------------------------------------------===//
-// Specific target implementations.
-//===----------------------------------------------------------------------===//
-
-
-namespace {
-class DarwinPPCTargetInfo : public DarwinTargetInfo {
-public:
- DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- DarwinTargetInfo::getTargetDefines(Defines);
- getPowerPCDefines(Defines, false);
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- PPC::getBuiltins(Records, NumRecords);
- }
- virtual const char *getVAListDeclaration() const {
- return getPPCVAListDeclaration();
- }
- virtual const char *getTargetPrefix() const {
- return PPC::getTargetPrefix();
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- PPC::getGCCRegNames(Names, NumNames);
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- PPC::getGCCRegAliases(Aliases, NumAliases);
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- return PPC::validateAsmConstraint(c, info);
- }
- virtual const char *getClobbers() const {
- return PPC::getClobbers();
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class DarwinPPC64TargetInfo : public DarwinTargetInfo {
-public:
- DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
- }
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- DarwinTargetInfo::getTargetDefines(Defines);
- getPowerPCDefines(Defines, true);
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- PPC::getBuiltins(Records, NumRecords);
- }
- virtual const char *getVAListDeclaration() const {
- return getPPCVAListDeclaration();
- }
- virtual const char *getTargetPrefix() const {
- return PPC::getTargetPrefix();
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- PPC::getGCCRegNames(Names, NumNames);
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- PPC::getGCCRegAliases(Aliases, NumAliases);
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- return PPC::validateAsmConstraint(c, info);
- }
- virtual const char *getClobbers() const {
- return PPC::getClobbers();
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class DarwinI386TargetInfo : public DarwinTargetInfo {
-public:
- DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- DarwinTargetInfo::getTargetDefines(Defines);
- getX86Defines(Defines, false);
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- X86::getBuiltins(Records, NumRecords);
- }
- virtual const char *getVAListDeclaration() const {
- return getI386VAListDeclaration();
- }
- virtual const char *getTargetPrefix() const {
- return X86::getTargetPrefix();
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- X86::getGCCRegNames(Names, NumNames);
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- X86::getGCCRegAliases(Aliases, NumAliases);
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- return X86::validateAsmConstraint(c, info);
- }
-
- virtual std::string convertConstraint(const char Constraint) const {
- return X86::convertConstraint(Constraint);
- }
-
- virtual const char *getClobbers() const {
- return X86::getClobbers();
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class DarwinX86_64TargetInfo : public DarwinTargetInfo {
-public:
- DarwinX86_64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
- }
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- DarwinTargetInfo::getTargetDefines(Defines);
- getX86Defines(Defines, true);
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- X86::getBuiltins(Records, NumRecords);
- }
- virtual const char *getVAListDeclaration() const {
- return getX86_64VAListDeclaration();
- }
- virtual const char *getTargetPrefix() const {
- return X86::getTargetPrefix();
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- X86::getGCCRegNames(Names, NumNames);
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- X86::getGCCRegAliases(Aliases, NumAliases);
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- return X86::validateAsmConstraint(c, info);
- }
- virtual std::string convertConstraint(const char Constraint) const {
- return X86::convertConstraint(Constraint);
- }
- virtual const char *getClobbers() const {
- return X86::getClobbers();
- }
-};
-} // end anonymous namespace.
-
-
-namespace {
-class DarwinARMTargetInfo : public DarwinTargetInfo {
-public:
- DarwinARMTargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- DarwinTargetInfo::getTargetDefines(Defines);
- getARMDefines(Defines);
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- NumRecords = 0;
- }
- virtual const char *getVAListDeclaration() const {
- return getARMVAListDeclaration();
- }
- virtual const char *getTargetPrefix() const {
- return ARM::getTargetPrefix();
- }
-
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- NumNames = 0;
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- NumAliases = 0;
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- 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 {
- return "";
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class SolarisSparcV8TargetInfo : public SolarisTargetInfo {
-public:
- SolarisSparcV8TargetInfo(const std::string& triple) : SolarisTargetInfo(triple) {}
-
- virtual void getTargetDefines(std::vector<char> &Defines) const {
- SolarisTargetInfo::getTargetDefines(Defines);
-// getSparcDefines(Defines, false);
- Define(Defines, "__sparc");
- Define(Defines, "__sparcv8");
- }
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- PPC::getBuiltins(Records, NumRecords);
- }
- virtual const char *getVAListDeclaration() const {
- return getPPCVAListDeclaration();
- }
- virtual const char *getTargetPrefix() const {
- return PPC::getTargetPrefix();
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- PPC::getGCCRegNames(Names, NumNames);
- }
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- PPC::getGCCRegAliases(Aliases, NumAliases);
- }
- virtual bool validateAsmConstraint(char c,
- TargetInfo::ConstraintInfo &info) const {
- return PPC::validateAsmConstraint(c, info);
- }
- virtual const char *getClobbers() const {
- return PPC::getClobbers();
- }
-};
-
-} // end anonymous namespace.
-
-
-namespace {
- class PIC16TargetInfo : public TargetInfo{
- public:
- PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
- IntWidth = IntAlign = 16;
- }
- 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) {
- if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
- return new DarwinPPCTargetInfo(T);
-
- if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
- return new DarwinPPC64TargetInfo(T);
-
- if (T.find("armv6-") == 0 || T.find("arm-") == 0)
- return new DarwinARMTargetInfo(T);
-
- if (T.find("sparc-") == 0)
- return new SolarisSparcV8TargetInfo(T); // ugly hack
-
- if (T.find("x86_64-") == 0)
- return new DarwinX86_64TargetInfo(T);
-
- if (T.find("pic16-") == 0)
- return new PIC16TargetInfo(T);
-
- if (IsX86(T))
- return new DarwinI386TargetInfo(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 1574ae108519..000000000000
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ /dev/null
@@ -1,830 +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/ASTContext.h"
-#include "clang/AST/Builtins.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/TargetBuiltins.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.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 = CFG.ConvertType(E->getType());
- Value *AtomF = CFG.CGM.getIntrinsic(Id, &ResType, 1);
- 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) {
- switch (BuiltinID) {
- default: {
- if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
- return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID),
- E->getCallee()->getType(), E->arg_begin(),
- E->getNumArgs());
-
- // 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);
-
- WarnUnsupported(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())));
- }
- case 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 RValue::get(CGM.GetAddrOfConstantCFString(S));
- }
- 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_start) ?
- Intrinsic::vastart : Intrinsic::vaend;
- 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");
-
- // FIXME: Volatile
- 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_classify_type: {
- APSInt Result(32);
- if (!E->isBuiltinClassifyType(Result))
- assert(0 && "Expr not __builtin_classify_type!");
- return RValue::get(ConstantInt::get(Result));
- }
- case Builtin::BI__builtin_constant_p: {
- APSInt Result(32);
- // FIXME: Analyze the parameter and check if it is a constant.
- Result = 0;
- return RValue::get(ConstantInt::get(Result));
- }
- case Builtin::BI__builtin_abs: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- llvm::BinaryOperator *NegOp =
- Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
- Value *CmpResult =
- Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "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_expect:
- 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_inff: {
- APFloat f(APFloat::IEEEsingle, APFloat::fcInfinity, false);
- return RValue::get(ConstantFP::get(f));
- }
- case Builtin::BI__builtin_huge_val:
- case Builtin::BI__builtin_inf:
- // FIXME: mapping long double onto double.
- case Builtin::BI__builtin_infl: {
- APFloat f(APFloat::IEEEdouble, APFloat::fcInfinity, false);
- return RValue::get(ConstantFP::get(f));
- }
- 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:
- return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty,
- EmitScalarExpr(E->getArg(0)),
- "tmp"));
- case Builtin::BI__sync_fetch_and_add:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_las, E);
- case Builtin::BI__sync_fetch_and_sub:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_lss, 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: {
- Value *Args[3];
- Args[0]= EmitScalarExpr(E->getArg(0));
- Args[1] = EmitScalarExpr(E->getArg(1));
- Args[2] = EmitScalarExpr(E->getArg(2));
- const llvm::Type *ResType = ConvertType(E->getType());
- Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_lcs, &ResType, 1);
- return RValue::get(Builder.CreateCall(AtomF, &Args[0], &Args[1]+2));
- }
- case Builtin::BI__sync_lock_test_and_set:
- return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); }
- return RValue::get(0);
-}
-
-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_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_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;
- 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_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 & 0x60) >> 6) + 4, "shufps");
- }
- 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_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_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_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/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
deleted file mode 100644
index e0c76d32fb60..000000000000
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ /dev/null
@@ -1,171 +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 "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/AST/ASTContext.h"
-using namespace clang;
-using namespace clang::CodeGen;
-
-CGDebugInfo::CGDebugInfo(CodeGenModule *m)
-: M(m)
-, CurLoc()
-, PrevLoc()
-, CompileUnitCache()
-, StopPointFn(NULL)
-, RegionStartFn(NULL)
-, RegionEndFn(NULL)
-, RegionStack()
-{
- SR = new llvm::DISerializer();
- SR->setModule (&M->getModule());
-}
-
-CGDebugInfo::~CGDebugInfo()
-{
- delete SR;
-}
-
-
-/// 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());
-}
-
-/// 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 = FE->getName();
- const char *DirName = FE->getDir()->getName();
-
- 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;
-}
-
-
-void
-CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) {
-
- // 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;
- if (CurLoc.isInvalid()) 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.
- Builder.CreateCall(RegionEndFn, getCastValueFor(RegionStack.back()), "");
- RegionStack.pop_back();
- // FIXME: Free here the memory created for BlockDesc in RegionStart?
-}
-
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
deleted file mode 100644
index 2097a1d2f06c..000000000000
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ /dev/null
@@ -1,84 +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/Basic/SourceLocation.h"
-#include <map>
-#include <vector>
-
-
-namespace llvm {
- class Function;
- class IRBuilder;
- class DISerializer;
- class CompileUnitDesc;
- class BasicBlock;
- class AnchorDesc;
- class DebugInfoDesc;
- class Value;
-}
-
-namespace clang {
-namespace CodeGen {
- class CodeGenModule;
-
-/// DebugInfo - 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;
-
- /// CompileUnitCache - Cache of previously constructed CompileUnits.
- std::map<unsigned, llvm::CompileUnitDesc *> CompileUnitCache;
-
- llvm::Function *StopPointFn;
- llvm::AnchorDesc *CompileUnitAnchor;
- llvm::Function *RegionStartFn;
- llvm::Function *RegionEndFn;
- std::vector<llvm::DebugInfoDesc *> RegionStack;
-
-public:
- CGDebugInfo(CodeGenModule *m);
- ~CGDebugInfo();
-
- void setLocation(SourceLocation loc) { CurLoc = loc; };
-
- /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
- /// source line.
- void EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder);
-
- /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start
- /// of a new block.
- void EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder);
-
- /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a
- /// block.
- void EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder);
-
- /// getOrCreateCompileUnit - Get the compile unit from the cache or create a
- /// new one if necessary.
- llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc);
-
- /// getCastValueFor - Return a llvm representation for a given debug
- /// information descriptor cast to an empty struct pointer.
- llvm::Value *getCastValueFor(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 bd68288bba30..000000000000
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ /dev/null
@@ -1,192 +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 "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/AST.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Type.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;
- // None of these decls require codegen support.
- return;
-
- case Decl::Var:
- if (cast<VarDecl>(D).isBlockVarDecl())
- return EmitBlockVarDecl(cast<VarDecl>(D));
- assert(0 && "Should not see file-scope variables inside a function!");
-
- case Decl::EnumConstant:
- return EmitEnumConstantDecl(cast<EnumConstantDecl>(D));
- }
-}
-
-void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
- assert(0 && "FIXME: Enum constant decls not implemented yet!");
-}
-
-/// 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 {
- Init = CGM.EmitConstantExpr(D.getInit(), this);
- }
-
- assert(Init && "Unable to create initialiser for static decl");
-
- std::string ContextName;
- if (const FunctionDecl * FD = dyn_cast<FunctionDecl>(CurFuncDecl))
- ContextName = FD->getName();
- else
- assert(0 && "Unknown context for block var decl"); // FIXME Handle objc.
-
- llvm::GlobalValue *GV =
- new llvm::GlobalVariable(LTy, 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);
- }
-
- DMEntry = GV;
-}
-
-/// 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);
- // TODO: Alignment
- DeclPtr = CreateTempAlloca(LTy, D.getName());
- } 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 {
- // TODO: Create a dynamic alloca.
- assert(0 && "FIXME: Local VLAs not implemented yet");
- }
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
- DMEntry = DeclPtr;
-
- // 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 ParmVarDecl &D, llvm::Value *Arg) {
- 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 first class variable becomes an alloca in the entry block.
- const llvm::Type *LTy = ConvertType(Ty);
- if (LTy->isFirstClassType()) {
- // TODO: Alignment
- DeclPtr = new llvm::AllocaInst(LTy, 0, std::string(D.getName())+".addr",
- AllocaInsertPt);
-
- // Store the initial value into the alloca.
- Builder.CreateStore(Arg, DeclPtr);
- } 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;
-}
-
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
deleted file mode 100644
index 043cfa1d507d..000000000000
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ /dev/null
@@ -1,673 +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 "clang/AST/AST.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/MathExtras.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);
-}
-
-
-//===----------------------------------------------------------------------===//
-// LValue Expression Emission
-//===----------------------------------------------------------------------===//
-
-/// 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: {
- printf("Statement class: %d\n", E->getStmtClass());
- WarnUnsupported(E, "l-value expression");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return LValue::MakeAddr(llvm::UndefValue::get(Ty));
- }
-
- 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::ObjCIvarRefExprClass:
- return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(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));
- }
-}
-
-/// 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->isFirstClassType()) {
- llvm::Value *V = Builder.CreateLoad(Ptr, "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(), "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);
-
- 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) {
- llvm::Value *Ptr = LV.getBitfieldAddr();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
- unsigned short BitfieldSize = LV.getBitfieldSize();
- unsigned short EndBit = LV.getBitfieldStartBit() + BitfieldSize;
-
- llvm::Value *V = Builder.CreateLoad(Ptr, "tmp");
-
- llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, EltTySize - EndBit);
- V = Builder.CreateShl(V, ShAmt, "tmp");
-
- ShAmt = llvm::ConstantInt::get(EltTy, EltTySize - BitfieldSize);
- V = LV.isBitfieldSigned() ?
- Builder.CreateAShr(V, ShAmt, "tmp") :
- Builder.CreateLShr(V, ShAmt, "tmp");
- return RValue::get(V);
-}
-
-// 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(), "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 = ExtVectorElementExpr::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 = ExtVectorElementExpr::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 = ExtVectorElementExpr::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.
- // FIXME: Volatility.
- llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(), "tmp");
- Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
- Dst.getVectorIdx(), "vecins");
- Builder.CreateStore(Vec, Dst.getVectorAddr());
- 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);
-
- 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);
-}
-
-void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
- QualType Ty) {
- unsigned short StartBit = Dst.getBitfieldStartBit();
- unsigned short BitfieldSize = Dst.getBitfieldSize();
- llvm::Value *Ptr = Dst.getBitfieldAddr();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
-
- llvm::Value *NewVal = Src.getScalarVal();
- llvm::Value *OldVal = Builder.CreateLoad(Ptr, "tmp");
-
- llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, StartBit);
- NewVal = Builder.CreateShl(NewVal, ShAmt, "tmp");
-
- llvm::Constant *Mask = llvm::ConstantInt::get(
- llvm::APInt::getBitsSet(EltTySize, StartBit,
- StartBit + BitfieldSize));
-
- // Mask out any bits that shouldn't be set in the result.
- NewVal = Builder.CreateAnd(NewVal, Mask, "tmp");
-
- // Next, mask out the bits this bit-field should include from the old value.
- Mask = llvm::ConstantExpr::getNot(Mask);
- OldVal = Builder.CreateAnd(OldVal, Mask, "tmp");
-
- // Finally, merge the two together and store it.
- NewVal = Builder.CreateOr(OldVal, NewVal, "tmp");
-
- Builder.CreateStore(NewVal, Ptr);
-}
-
-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(), "tmp");
- // FIXME: Volatility.
- 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 = ExtVectorElementExpr::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 = ExtVectorElementExpr::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());
-}
-
-
-LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
- const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
-
- if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD))) {
- if (VD->getStorageClass() == VarDecl::Extern)
- return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
- else {
- llvm::Value *V = LocalDeclMap[VD];
- assert(V && "BlockVarDecl not entered in LocalDeclMap?");
- return LValue::MakeAddr(V);
- }
- } else if (VD && VD->isFileVarDecl()) {
- return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
- return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false));
- }
- 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());
-
- switch (E->getOpcode()) {
- default: assert(0 && "Unknown unary operator lvalue!");
- case UnaryOperator::Deref:
- return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()));
- 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"));
- }
-}
-
-LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
- assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
- const char *StrData = E->getStrData();
- unsigned Len = E->getByteLength();
- std::string StringLiteral(StrData, StrData+Len);
- return LValue::MakeAddr(CGM.GetAddrOfConstantString(StringLiteral));
-}
-
-LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) {
- std::string FunctionName;
- if(const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
- FunctionName = FD->getName();
- }
- else {
- assert(0 && "Attempting to load predefined constant for invalid decl type");
- }
- std::string GlobalVarName;
-
- switch (E->getIdentType()) {
- default:
- assert(0 && "unknown pre-defined ident type");
- 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);
-}
-
-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->getLHS()->getType()->isVectorType()) {
- // Emit the vector as an lvalue to get its address.
- LValue LHS = EmitLValue(E->getLHS());
- 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);
- }
-
- // 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())
- assert(0 && "VLA idx not implemented");
- return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"));
-}
-
-LValue CodeGenFunction::
-EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
- // Emit the base vector as an l-value.
- LValue Base = EmitLValue(E->getBase());
-
- if (Base.isExtVectorElt()) {
- llvm::Constant *BaseElts = Base.getExtVectorElts();
- llvm::Constant *ExprElts = E->getEncodedElementAccess();
-
- llvm::SmallVector<llvm::Constant *, 8> Indices;
-
- for (unsigned i = 0, e = E->getNumElements(); i != e; ++i) {
- unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, ExprElts);
-
- if (isa<llvm::ConstantAggregateZero>(BaseElts))
- Indices.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
- else
- Indices.push_back(cast<llvm::ConstantInt>(BaseElts->getOperand(Idx)));
- }
- llvm::Constant *NewElts = llvm::ConstantVector::get(&Indices[0], Indices.size());
- return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), NewElts);
- }
-
- assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
-
- return LValue::MakeExtVectorElt(Base.getAddress(),
- E->getEncodedElementAccess());
-}
-
-LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
- bool isUnion = false;
- Expr *BaseExpr = E->getBase();
- llvm::Value *BaseValue = NULL;
-
- // 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>(BaseExpr->getType().getCanonicalType());
- if (PTy->getPointeeType()->isUnionType())
- isUnion = true;
- }
- else {
- LValue BaseLV = EmitLValue(BaseExpr);
- // FIXME: this isn't right for bitfields.
- BaseValue = BaseLV.getAddress();
- if (BaseExpr->getType()->isUnionType())
- isUnion = true;
- }
-
- FieldDecl *Field = E->getMemberDecl();
- return EmitLValueForField(BaseValue, Field, isUnion);
-}
-
-LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
- FieldDecl* Field,
- bool isUnion)
-{
- llvm::Value *V;
- unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
-
- if (!Field->isBitField()) {
- V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
- } else {
- const llvm::Type *FieldTy = ConvertType(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");
- }
-
- // Match union field type.
- if (isUnion) {
- const llvm::Type * FieldTy = ConvertType(Field->getType());
- const llvm::PointerType * BaseTy =
- cast<llvm::PointerType>(BaseValue->getType());
- if (FieldTy != BaseTy->getElementType()) {
- unsigned AS = BaseTy->getAddressSpace();
- V = Builder.CreateBitCast(V,
- llvm::PointerType::get(FieldTy, AS),
- "tmp");
- }
- }
-
- if (!Field->isBitField())
- return LValue::MakeAddr(V);
-
- CodeGenTypes::BitFieldInfo bitFieldInfo =
- CGM.getTypes().getBitFieldInfo(Field);
- return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
- Field->getType()->isSignedIntegerType());
-}
-
-//===--------------------------------------------------------------------===//
-// 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->getNumArgs());
-}
-
-RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr, Expr *const *Args,
- unsigned NumArgs) {
- llvm::Value *Callee = EmitScalarExpr(FnExpr);
- return EmitCallExpr(Callee, FnExpr->getType(), Args, NumArgs);
-}
-
-LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
- // Can only get l-value for call expression returning aggregate type
- RValue RV = EmitCallExpr(E);
- return LValue::MakeAddr(RV.getAggregateAddr());
-}
-
-LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
- // 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 && "FIXME: Implement support for late-bound instance variables");
- return LValue(); // Not reached.
- }
-
- // Get a structure type for the object
- QualType ExprTy = E->getBase()->getType();
- const llvm::Type *ObjectType = ConvertType(ExprTy);
- // TODO: Add a special case for isa (index 0)
- // Work out which index the ivar is
- const ObjCIvarDecl *Decl = E->getDecl();
- unsigned Index = CGM.getTypes().getLLVMFieldNo(Decl);
-
- // Get object pointer and coerce object pointer to correct type.
- llvm::Value *Object = EmitLValue(E->getBase()).getAddress();
- Object = Builder.CreateLoad(Object, E->getDecl()->getName());
- if (Object->getType() != ObjectType)
- Object = Builder.CreateBitCast(Object, ObjectType);
-
-
- // Return a pointer to the right element.
- return LValue::MakeAddr(Builder.CreateStructGEP(Object, Index,
- Decl->getName()));
-}
-
-RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
- Expr *const *ArgExprs, unsigned NumArgs) {
- // The callee type will always be a pointer to function type, get the function
- // type.
- FnType = cast<PointerType>(FnType.getCanonicalType())->getPointeeType();
- QualType ResultType = cast<FunctionType>(FnType)->getResultType();
-
- llvm::SmallVector<llvm::Value*, 16> Args;
-
- // Handle struct-return functions by passing a pointer to the location that
- // we would like to return into.
- if (hasAggregateLLVMType(ResultType)) {
- // Create a temporary alloca to hold the result of the call. :(
- Args.push_back(CreateTempAlloca(ConvertType(ResultType)));
- // FIXME: set the stret attribute on the argument.
- }
-
- for (unsigned i = 0, e = NumArgs; i != e; ++i) {
- QualType ArgTy = ArgExprs[i]->getType();
-
- if (!hasAggregateLLVMType(ArgTy)) {
- // Scalar argument is passed by-value.
- Args.push_back(EmitScalarExpr(ArgExprs[i]));
- } else if (ArgTy->isAnyComplexType()) {
- // Make a temporary alloca to pass the argument.
- llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
- EmitComplexExprIntoAddr(ArgExprs[i], DestMem, false);
- Args.push_back(DestMem);
- } else {
- llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
- EmitAggExpr(ArgExprs[i], DestMem, false);
- Args.push_back(DestMem);
- }
- }
-
- llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
- if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
- CI->setCallingConv(F->getCallingConv());
- if (CI->getType() != llvm::Type::VoidTy)
- CI->setName("call");
- else if (ResultType->isAnyComplexType())
- return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
- else if (hasAggregateLLVMType(ResultType))
- // Struct return.
- return RValue::getAggregate(Args[0]);
- else {
- // void return.
- assert(ResultType->isVoidType() && "Should only have a void expr here");
- CI = 0;
- }
-
- return RValue::get(CI);
-}
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
deleted file mode 100644
index 508bf753832a..000000000000
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ /dev/null
@@ -1,430 +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/AST.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 EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
- QualType EltTy);
-
- void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
-
- void EmitNonConstInit(InitListExpr *E);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- void VisitStmt(Stmt *S) {
- CGF.WarnUnsupported(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 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 VisitConditionalOperator(const ConditionalOperator *CO);
- void VisitInitListExpr(InitListExpr *E);
- void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
- Visit(DAE->getExpr());
- }
-
- void EmitInitializationToLValue(Expr *E, LValue Address);
- void EmitNullInitializationToLValue(LValue Address, QualType T);
- // case Expr::ChooseExprClass:
-
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-void AggExprEmitter::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
- assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
-
- // Aggregate assignment turns into llvm.memset.
- 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 = CGF.getContext().getTypeInfo(Ty);
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
-
- llvm::Value *MemSetOps[4] = {
- 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)
- };
-
- Builder.CreateCall(CGF.CGM.getMemSetFn(), MemSetOps, MemSetOps+4);
-}
-
-void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr,
- llvm::Value *SrcPtr, QualType Ty) {
- assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
-
- // Aggregate assignment turns into llvm.memcpy.
- 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 = CGF.getContext().getTypeInfo(Ty);
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
-
- llvm::Value *MemCpyOps[4] = {
- DestPtr, SrcPtr,
- // TypeInfo.first describes size in bits.
- llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second/8)
- };
-
- Builder.CreateCall(CGF.CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
-}
-
-
-/// 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;
-
- EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
-}
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-void AggExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *E)
-{
- QualType STy = E->getSubExpr()->getType().getCanonicalType();
- QualType Ty = E->getType().getCanonicalType();
-
- assert(CGF.getContext().typesAreCompatible(
- STy.getUnqualifiedType(), Ty.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;
-
- EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E)
-{
- RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->getNumArgs(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;
-
- EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
-}
-
-void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
- CGF.WarnUnsupported(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());
-
- // 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.
- 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::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
- 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->isFirstClassType())
- Builder.CreateStore(llvm::Constant::getNullValue(EType), NextVal);
- else
- 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);
- return;
- }
- RValue RV = CGF.EmitAnyExpr(E, LV.getAddress(), false);
- if (CGF.hasAggregateLLVMType(E->getType()))
- return;
- CGF.EmitStoreThroughLValue(RV, LV, E->getType());
-}
-
-void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
- if (!CGF.hasAggregateLLVMType(T)) {
- // For non-aggregates, we can store zero
- const llvm::Type *T =
- cast<llvm::PointerType>(LV.getAddress()->getType())->getElementType();
- Builder.CreateStore(llvm::Constant::getNullValue(T), LV.getAddress());
- } 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) {
- if (E->isConstantExpr(CGF.getContext(), 0)) {
- // FIXME: 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();
- uint64_t NumArrayElements = AType->getNumElements();
- QualType ElementType = E->getType()->getAsArrayType()->getElementType();
-
- 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));
- else
- EmitNullInitializationToLValue(LValue::MakeAddr(NextVal),
- 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) {
- if (CurInitVal >= NumInitElements) {
- // No more initializers; we're done.
- break;
- }
-
- FieldDecl *CurField = SD->getMember(CurFieldNo);
- if (CurField->getIdentifier() == 0) {
- // Initializers can't initialize unnamed fields, e.g. "int : 20;"
- continue;
- }
- LValue FieldLoc = CGF.EmitLValueForField(DestPtr, CurField, isUnion);
- 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));
-}
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
deleted file mode 100644
index 92b17e04d8e3..000000000000
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ /dev/null
@@ -1,532 +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/AST.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());
- }
-
- 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);
-};
-} // 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.WarnUnsupported(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->getNumArgs(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 = cast<ComplexType>(SrcType.getCanonicalType())->getElementType();
- DestType = cast<ComplexType>(DestType.getCanonicalType())->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 = cast<ComplexType>(DestTy.getCanonicalType())->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(E->getLHS()->getType().getCanonicalType() ==
- E->getRHS()->getType().getCanonicalType() && "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());
-}
-
-//===----------------------------------------------------------------------===//
-// 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);
-}
-
-/// 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 94ff8f779c3c..000000000000
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ /dev/null
@@ -1,633 +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 "clang/AST/AST.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/Compiler.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.WarnUnsupported(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 *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- return Visit(E->getInitializer());
- }
-
- llvm::Constant *VisitCastExpr(const 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,
- const llvm::ArrayType *AType) {
- std::vector<llvm::Constant*> Elts;
- unsigned NumInitElements = ILE->getNumInits();
- // FIXME: Check for wide strings
- if (NumInitElements > 0 && isa<StringLiteral>(ILE->getInit(0)) &&
- ILE->getType()->getAsArrayType()->getElementType()->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;
- for (; i < NumInitableElts; ++i) {
-
- llvm::Constant *C = Visit(ILE->getInit(i));
- // FIXME: Remove this when sema of initializers is finished (and the code
- // above).
- if (C == 0 && ILE->getInit(i)->getType()->isVoidType()) {
- if (ILE->getType()->isVoidType()) return 0;
- return llvm::UndefValue::get(AType);
- }
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- }
-
- // Initialize remaining array elements.
- for (; i < NumElements; ++i)
- Elts.push_back(llvm::Constant::getNullValue(ElemTy));
-
- return llvm::ConstantArray::get(AType, Elts);
- }
-
- llvm::Constant *EmitStructInitialization(InitListExpr *ILE,
- const llvm::StructType *SType) {
-
- TagDecl *TD = ILE->getType()->getAsRecordType()->getDecl();
- std::vector<llvm::Constant*> Elts;
- const CGRecordLayout *CGR = CGM.getTypes().getCGRecordLayout(TD);
- unsigned NumInitElements = ILE->getNumInits();
- unsigned NumElements = SType->getNumElements();
-
- // Initialising an structure requires us to automatically
- // initialise any elements that have not been initialised explicitly
- unsigned NumInitableElts = std::min(NumInitElements, NumElements);
-
- // Copy initializer elements. Skip padding fields.
- unsigned EltNo = 0; // Element no in ILE
- unsigned FieldNo = 0; // Field no in SType
- while (EltNo < NumInitableElts) {
-
- // Zero initialize padding field.
- if (CGR->isPaddingField(FieldNo)) {
- const llvm::Type *FieldTy = SType->getElementType(FieldNo);
- Elts.push_back(llvm::Constant::getNullValue(FieldTy));
- FieldNo++;
- continue;
- }
-
- llvm::Constant *C = Visit(ILE->getInit(EltNo));
- // FIXME: Remove this when sema of initializers is finished (and the code
- // above).
- if (C == 0 && ILE->getInit(EltNo)->getType()->isVoidType()) {
- if (ILE->getType()->isVoidType()) return 0;
- return llvm::UndefValue::get(SType);
- }
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- EltNo++;
- FieldNo++;
- }
-
- // Initialize remaining structure elements.
- for (unsigned i = Elts.size(); i < NumElements; ++i) {
- const llvm::Type *FieldTy = SType->getElementType(i);
- Elts.push_back(llvm::Constant::getNullValue(FieldTy));
- }
-
- return llvm::ConstantStruct::get(SType, Elts);
- }
-
- llvm::Constant *EmitVectorInitialization(InitListExpr *ILE,
- const llvm::VectorType *VType) {
-
- std::vector<llvm::Constant*> Elts;
- unsigned NumInitElements = ILE->getNumInits();
- unsigned NumElements = VType->getNumElements();
-
- assert (NumInitElements == NumElements
- && "Unsufficient vector init elelments");
- // Copy initializer elements.
- unsigned i = 0;
- for (; i < NumElements; ++i) {
-
- llvm::Constant *C = Visit(ILE->getInit(i));
- // FIXME: Remove this when sema of initializers is finished (and the code
- // above).
- if (C == 0 && ILE->getInit(i)->getType()->isVoidType()) {
- if (ILE->getType()->isVoidType()) return 0;
- return llvm::UndefValue::get(VType);
- }
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- }
-
- return llvm::ConstantVector::get(VType, Elts);
- }
-
- llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
- const llvm::CompositeType *CType =
- dyn_cast<llvm::CompositeType>(ConvertType(ILE->getType()));
-
- if (!CType) {
- // We have a scalar in braces. Just use the first element.
- return Visit(ILE->getInit(0));
- }
-
- if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(CType))
- return EmitArrayInitialization(ILE, AType);
-
- if (const llvm::StructType *SType = dyn_cast<llvm::StructType>(CType))
- return EmitStructInitialization(ILE, SType);
-
- if (const llvm::VectorType *VType = dyn_cast<llvm::VectorType>(CType))
- return EmitVectorInitialization(ILE, VType);
-
- // Make sure we have an array at this point
- 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);
-
- QualType ElemType = SType->getAsArrayType()->getElementType();
- T = CGM.getContext().getPointerType(ElemType);
- } 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) {
- const char *StrData = E->getStrData();
- unsigned Len = E->getByteLength();
- 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.
- const ConstantArrayType *CAT = E->getType()->getAsConstantArrayType();
- assert(CAT && "String isn't pointer or array!");
-
- std::string Str(StrData, StrData + Len);
- // Null terminate the string before potentially truncating it.
- // FIXME: What about wchar_t strings?
- Str.push_back(0);
-
- uint64_t RealLen = CAT->getSize().getZExtValue();
- // String or grow the initializer to the required size.
- if (RealLen != Str.size())
- Str.resize(RealLen);
-
- return llvm::ConstantArray::get(Str, 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());
- }
-
- // 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));
- }
-
- // 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(0 && "Unhandled bin sub case!");
- return 0;
- }
-
- 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);
- }
-
- // 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 = SrcType.getCanonicalType();
- DstType = DstType.getCanonicalType();
- 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<PointerType>(DstType)) {
- // 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<PointerType>(SrcType)) {
- // 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.GetAddrOfFunctionDecl(FD, false);
- if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
- if (VD->isFileVarDecl())
- return CGM.GetAddrOfGlobalVar(VD, false);
- 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: {
- StringLiteral *String = cast<StringLiteral>(E);
- assert(!String->isWide() && "Cannot codegen wide strings yet");
- const char *StrData = String->getStrData();
- unsigned Len = String->getByteLength();
-
- return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
- }
- 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.WarnUnsupported(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 = E->getType().getCanonicalType();
-
- if (type->isIntegerType()) {
- llvm::APSInt Value(static_cast<uint32_t>(Context.getTypeSize(type)));
- if (E->isIntegerConstantExpr(Value, Context)) {
- return llvm::ConstantInt::get(Value);
- }
- }
-
- return ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
-}
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
deleted file mode 100644
index a501145a4958..000000000000
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ /dev/null
@@ -1,1183 +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/AST.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;
- CGObjCRuntime *Runtime;
-
-public:
-
- ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf),
- Builder(CGF.Builder),
- Runtime(CGF.CGM.getObjCRuntime()) {
- }
-
- //===--------------------------------------------------------------------===//
- // 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 *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());
- }
-
- // 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 *VisitObjCMessageExpr(ObjCMessageExpr *E);
- Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);}
- Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
- Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
- Value *VisitExtVectorElementExpr(Expr *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 *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- return Visit(E->getInitializer());
- }
-
- 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);
- // (Sub) - Sub is handled specially below for ptr-ptr subtract.
- HANDLEBINOP(Shl);
- HANDLEBINOP(Shr);
- HANDLEBINOP(And);
- HANDLEBINOP(Xor);
- HANDLEBINOP(Or);
-#undef HANDLEBINOP
- Value *VisitBinSub(const BinaryOperator *E);
- Value *VisitBinSubAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ScalarExprEmitter::EmitSub);
- }
-
- // 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() || SrcType->isPointerType()) &&
- "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 = SrcType.getCanonicalType();
- DstType = DstType.getCanonicalType();
- 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.
- if (isa<PointerType>(DstType)) {
- // 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<PointerType>(SrcType)) {
- // 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 = cast<ComplexType>(SrcTy.getCanonicalType())->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.WarnUnsupported(E, "scalar expression");
- if (E->getType()->isVoidType())
- return 0;
- return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
-}
-
-Value *ScalarExprEmitter::VisitObjCMessageExpr(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.
-
- // Find the receiver
- llvm::Value *Receiver = CGF.EmitScalarExpr(E->getReceiver());
-
- // Process the arguments
- unsigned ArgC = E->getNumArgs();
- llvm::SmallVector<llvm::Value*, 16> Args;
- for (unsigned i = 0; i != ArgC; ++i) {
- Expr *ArgExpr = E->getArg(i);
- QualType ArgTy = ArgExpr->getType();
- if (!CGF.hasAggregateLLVMType(ArgTy)) {
- // Scalar argument is passed by-value.
- Args.push_back(CGF.EmitScalarExpr(ArgExpr));
- } else if (ArgTy->isAnyComplexType()) {
- // Make a temporary alloca to pass the argument.
- llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
- CGF.EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
- Args.push_back(DestMem);
- } else {
- llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
- CGF.EmitAggExpr(ArgExpr, DestMem, false);
- Args.push_back(DestMem);
- }
- }
-
- // Get the selector string
- std::string SelStr = E->getSelector().getName();
- llvm::Constant *Selector = CGF.CGM.GetAddrOfConstantString(SelStr);
-
- llvm::Value *SelPtr = Builder.CreateStructGEP(Selector, 0);
- return Runtime->generateMessageSend(Builder, ConvertType(E->getType()),
- CGF.LoadObjCSelf(),
- Receiver, SelPtr,
- &Args[0], Args.size());
-}
-
-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.
-
- assert(isa<llvm::PointerType>(V->getType()) &&
- isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
- ->getElementType()) &&
- "Doesn't support VLAs yet!");
- V = Builder.CreateStructGEP(V, 0, "arraydecay");
-
- // The resultant pointer type can be implicitly casted to other pointer
- // types as well, for example void*.
- const llvm::Type *DestPTy = ConvertType(E->getType());
- assert(isa<llvm::PointerType>(DestPTy) &&
- "Only expect implicit cast to pointer");
- if (V->getType() != DestPTy)
- V = Builder.CreateBitCast(V, DestPTy, "ptrconv");
- return V;
-
- } else if (E->getType()->isReferenceType()) {
- assert(cast<ReferenceType>(E->getType().getCanonicalType())->
- getPointeeType() ==
- Op->getType().getCanonicalType() && "Incompatible types!");
-
- 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(), true).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.
- if (TypeToSize->isVoidType())
- 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());
- }
-
- // Convert the LHS/RHS values to the computation type.
- OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, ComputeType);
-
- // Do not merge types for -= or += where the LHS is a pointer.
- if (!(E->getOpcode() == BinaryOperator::SubAssign ||
- E->getOpcode() == BinaryOperator::AddAssign) ||
- !E->getLHS()->getType()->isPointerType()) {
- OpInfo.RHS = EmitScalarConversion(OpInfo.RHS, RHSTy, ComputeType);
- }
- OpInfo.Ty = ComputeType;
- OpInfo.E = E;
-
- // Expand the binary operator.
- Value *Result = (this->*Func)(OpInfo);
-
- // Truncate the result back to the LHS type.
- Result = EmitScalarConversion(Result, ComputeType, LHSTy);
-
- // Store the result value into the LHS lvalue.
- CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, E->getType());
-
- 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().getCanonicalType()->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");
-
- // pointer - int
- assert(!isa<llvm::PointerType>(Ops.RHS->getType()) &&
- "ptr-ptr shouldn't get here");
- // FIXME: The pointer could point to a VLA.
- Value *Idx = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
-
- 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().getCanonicalType()->isSignedIntegerType())
- Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
- else
- Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
- }
-
- return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
-}
-
-Value *ScalarExprEmitter::VisitBinSub(const BinaryOperator *E) {
- // "X - Y" is different from "X -= Y" in one case: when Y is a pointer. In
- // the compound assignment case it is invalid, so just handle it here.
- if (!E->getRHS()->getType()->isPointerType())
- return EmitSub(EmitBinOps(E));
-
- // pointer - pointer
- Value *LHS = Visit(E->getLHS());
- Value *RHS = Visit(E->getRHS());
-
- const QualType LHSType = E->getLHS()->getType().getCanonicalType();
- const QualType LHSElementType = cast<PointerType>(LHSType)->getPointeeType();
- uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- 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.
- 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()) {
- Value *LHS = Visit(E->getLHS());
- Value *RHS = Visit(E->getRHS());
-
- if (LHS->getType()->isFloatingPoint()) {
- Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
- LHS, RHS, "cmp");
- } else if (LHSTy->isUnsignedIntegerType()) {
- Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
- LHS, RHS, "cmp");
- } else {
- // Signed integers and pointers.
- Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
- LHS, RHS, "cmp");
- }
- } 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 =
- cast<ComplexType>(LHSTy.getCanonicalType())->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());
-
- // 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) {
- 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->getNumArgs(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 299698f1f38b..000000000000
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ /dev/null
@@ -1,27 +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/Expr.h"
-#include "llvm/Constant.h"
-using namespace clang;
-using namespace CodeGen;
-
-llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
- std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
- return CGM.GetAddrOfConstantCFString(S);
-}
-
-CGObjCRuntime::~CGObjCRuntime() {}
diff --git a/clang/lib/CodeGen/CGObjCEtoile.cpp b/clang/lib/CodeGen/CGObjCEtoile.cpp
deleted file mode 100644
index d5023b4240c6..000000000000
--- a/clang/lib/CodeGen/CGObjCEtoile.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-//===------- CGObjCEtoile.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 Etoile runtime.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGObjCRuntime.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace {
-class CGObjCEtoile : public clang::CodeGen::CGObjCRuntime {
-private:
- llvm::Module &TheModule;
- const llvm::Type *SelectorTy;
- const llvm::PointerType *PtrToInt8Ty;
- const llvm::Type *IMPTy;
- const llvm::Type *IntTy;
- const llvm::Type *PtrTy;
- const llvm::Type *LongTy;
- const llvm::Type *PtrToIntTy;
- const llvm::Type *IdTy;
- const llvm::Type *CallTy;
- const llvm::Type *SlotTy;
- const llvm::Type *LookupFunctionTy;
-public:
- CGObjCEtoile(llvm::Module &Mp,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType);
- virtual llvm::Value *generateMessageSend(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC);
- llvm::Value *getSelector(llvm::IRBuilder &Builder,
- llvm::Value *SelName,
- llvm::Value *SelTypes);
- virtual llvm::Function *MethodPreamble(const llvm::Type *ReturnTy,
- const llvm::Type *SelfTy,
- const llvm::Type **ArgTy,
- unsigned ArgC,
- bool isVarArg);
-};
-} // end anonymous namespace
-
-CGObjCEtoile::CGObjCEtoile(llvm::Module &M,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType) :
- TheModule(M),
- IntTy(LLVMIntType),
- LongTy(LLVMLongType)
-{
- // C string type. Used in lots of places.
- PtrToInt8Ty =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- // Get the selector Type.
- SelectorTy = llvm::Type::Int32Ty;
- PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
- PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-
- // 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);
-
- // Call structure type.
- llvm::PATypeHolder OpaqueSlotTy = llvm::OpaqueType::get();
- CallTy = llvm::StructType::get(
- llvm::PointerType::getUnqual(OpaqueSlotTy),
- SelectorTy,
- IdTy,
- NULL);
- //CallTy = llvm::PointerType::getUnqual(CallTy);
-
- // IMP type
- std::vector<const llvm::Type*> IMPArgs;
- IMPArgs.push_back(IdTy);
- IMPArgs.push_back(llvm::PointerType::getUnqual(CallTy));
- IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
-
- // Slot type
- SlotTy = llvm::StructType::get(IntTy,
- IMPTy,
- PtrToInt8Ty,
- PtrToInt8Ty,
- llvm::Type::Int32Ty,
- NULL);
- llvm::cast<llvm::OpaqueType>(
- OpaqueSlotTy.get())->refineAbstractTypeTo(SlotTy);
- SlotTy = llvm::PointerType::getUnqual(
- llvm::cast<llvm::StructType>(OpaqueSlotTy.get()));
-
- // Lookup function type
- std::vector<const llvm::Type*> LookupFunctionArgs;
- LookupFunctionArgs.push_back(llvm::PointerType::getUnqual(IdTy));
- LookupFunctionArgs.push_back(IdTy);
- LookupFunctionArgs.push_back(SelectorTy);
- LookupFunctionArgs.push_back(IdTy);
- LookupFunctionTy =
- llvm::FunctionType::get(SlotTy, LookupFunctionArgs, false);
- LookupFunctionTy = llvm::PointerType::getUnqual(LookupFunctionTy);
-
-}
-
-/// Looks up the selector for the specified name / type pair.
-llvm::Value *CGObjCEtoile::getSelector(llvm::IRBuilder &Builder,
- llvm::Value *SelName,
- llvm::Value *SelTypes)
-{
- // Look up the selector.
- if(SelTypes == 0) {
- SelTypes = llvm::ConstantPointerNull::get(PtrToInt8Ty);
- }
- llvm::Constant *SelFunction =
- TheModule.getOrInsertFunction("lookup_typed_selector",
- SelectorTy,
- PtrToInt8Ty,
- PtrToInt8Ty,
- NULL);
- return Builder.CreateCall2(SelFunction, SelName, SelTypes);
-}
-
-static void SetField(llvm::IRBuilder &Builder, llvm::Value *Structure,
- unsigned Index, llvm::Value *Value) {
- llvm::Value *element_ptr = Builder.CreateStructGEP(Structure, Index);
- Builder.CreateStore(Value, element_ptr);
-}
-// Generate code for a message send expression on the Etoile runtime.
-// BIG FAT WARNING: Much of this code will need factoring out later.
-llvm::Value *CGObjCEtoile::generateMessageSend(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC) {
- // FIXME: Selectors should be statically cached, not looked up on every call.
- llvm::Value *cmd = getSelector(Builder, Selector, 0);
- // TODO: [Polymorphic] inline caching
-
- // Get the lookup function for this object:
- llvm::Value *ObjAddr = Builder.CreateBitCast(Receiver, PtrToInt8Ty);
- llvm::Value *FunctionOffset = new llvm::GlobalVariable(llvm::Type::Int32Ty,
- false,
- llvm::GlobalValue::ExternalLinkage,
- 0,
- "lookup_offset",
- &TheModule);
- FunctionOffset = Builder.CreateLoad(FunctionOffset);
- llvm::Value *Tag = Builder.CreateGEP(ObjAddr, FunctionOffset);
- llvm::Value *Lookup = Builder.CreateBitCast(Tag, LookupFunctionTy);
-
- // TODO: Remove this when the caller is providing sensible sender info
- if(Sender == 0) {
- Sender = llvm::ConstantPointerNull::get((llvm::PointerType*)IdTy);
- }
- Receiver = Builder.CreateBitCast(Receiver, IdTy);
- llvm::Value *ReceiverAddr = Builder.CreateAlloca(IdTy);
- Builder.CreateStore(Receiver, ReceiverAddr);
- // Look up the method implementation.
- llvm::SmallVector<llvm::Value*, 4> LookupArgs;
- LookupArgs.push_back(ReceiverAddr);
- LookupArgs.push_back(Receiver);
- LookupArgs.push_back(cmd);
- LookupArgs.push_back(Sender);
- llvm::Value *Slot = Builder.CreateCall(Lookup, LookupArgs.begin(),
- LookupArgs.end());
-
- // Create the call structure
- llvm::Value *Call = Builder.CreateAlloca(CallTy);
- SetField(Builder, Call, 0, Slot);
- SetField(Builder, Call, 1, cmd);
- SetField(Builder, Call, 2, Sender);
-
- // Get the IMP from the slot and call it
- // TODO: Property load / store optimisations
- llvm::Value *IMP = Builder.CreateStructGEP(Slot, 1);
- // If the return type of the IMP is wrong, cast it so it isn't.
- if(ReturnTy != IdTy) {
- std::vector<const llvm::Type*> IMPArgs;
- IMPArgs.push_back(IdTy);
- IMPArgs.push_back(llvm::PointerType::getUnqual(CallTy));
- llvm::Type *NewIMPTy = llvm::FunctionType::get(ReturnTy, IMPArgs, true);
- IMP = Builder.CreateBitCast(IMP, llvm::PointerType::getUnqual(NewIMPTy));
- }
- llvm::SmallVector<llvm::Value*, 16> Args;
- Args.push_back(Receiver);
- Args.push_back(Call);
- Args.insert(Args.end(), ArgV, ArgV+ArgC);
- return Builder.CreateCall(IMP, Args.begin(), Args.end());
-}
-
-/// Generates an LLVM Function object corresponding to the Objective-C method,
-/// including the implicit arguments.
-llvm::Function *CGObjCEtoile::MethodPreamble(
- const llvm::Type *ReturnTy,
- const llvm::Type *SelfTy,
- const llvm::Type **ArgTy,
- unsigned ArgC,
- bool isVarArg) {
- std::vector<const llvm::Type*> Args;
- //Args.push_back(SelfTy);
- Args.push_back(IdTy);
- Args.push_back(llvm::PointerType::getUnqual(CallTy));
- for (unsigned i=0; i<ArgC ; i++) {
- Args.push_back(ArgTy[i]);
- }
- llvm::FunctionType *MethodTy =
- llvm::FunctionType::get(ReturnTy, Args, isVarArg);
- llvm::Function *Method = llvm::Function::Create(MethodTy,
- llvm::GlobalValue::InternalLinkage,
- ".objc.method",
- &TheModule);
- //llvm::BasicBlock *EntryBB = new llvm::BasicBlock("entry", Method);
- // Set the names of the hidden arguments
- llvm::Function::arg_iterator AI = Method->arg_begin();
- AI[0].setName("self");
- AI[1].setName("_call");
- // FIXME: Should create the _cmd variable as _call->selector
- return Method;
-}
-
-/*
-clang::CodeGen::CGObjCRuntime *clang::CodeGen::CreateObjCRuntime(
- llvm::Module &M,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType) {
- return new CGObjCEtoile(M, LLVMIntType, LLVMLongType);
-}
-*/
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
deleted file mode 100644
index 8373cfd84f2c..000000000000
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ /dev/null
@@ -1,185 +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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGObjCRuntime.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace {
-class CGObjCGNU : public clang::CodeGen::CGObjCRuntime {
-private:
- llvm::Module &TheModule;
- 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;
-public:
- CGObjCGNU(llvm::Module &Mp,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType);
- virtual llvm::Value *generateMessageSend(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC);
- llvm::Value *getSelector(llvm::IRBuilder &Builder,
- llvm::Value *SelName,
- llvm::Value *SelTypes);
- virtual llvm::Function *MethodPreamble(const llvm::Type *ReturnTy,
- const llvm::Type *SelfTy,
- const llvm::Type **ArgTy,
- unsigned ArgC,
- bool isVarArg);
-};
-} // end anonymous namespace
-
-CGObjCGNU::CGObjCGNU(llvm::Module &M,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType) :
- TheModule(M),
- IntTy(LLVMIntType),
- LongTy(LLVMLongType)
-{
- // C string type. Used in lots of places.
- PtrToInt8Ty =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- // Get the selector Type.
- const llvm::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);
-
-}
-
-/// Looks up the selector for the specified name / type pair.
-// FIXME: Selectors should be statically cached, not looked up on every call.
-llvm::Value *CGObjCGNU::getSelector(llvm::IRBuilder &Builder,
- llvm::Value *SelName,
- llvm::Value *SelTypes)
-{
- // Look up the selector.
- llvm::Value *cmd;
- if(SelTypes == 0) {
- llvm::Constant *SelFunction = TheModule.getOrInsertFunction("sel_get_uid",
- SelectorTy,
- PtrToInt8Ty,
- NULL);
- cmd = Builder.CreateCall(SelFunction, SelName);
- }
- else {
- llvm::Constant *SelFunction =
- TheModule.getOrInsertFunction("sel_get_typed_uid",
- SelectorTy,
- PtrToInt8Ty,
- PtrToInt8Ty,
- NULL);
- cmd = Builder.CreateCall2(SelFunction, SelName, SelTypes);
- }
- return cmd;
-}
-
-
-/// Generate code for a message send expression on the GNU runtime.
-// FIXME: Much of this code will need factoring out later.
-// TODO: This should take a sender argument (pointer to self in the calling
-// context)
-llvm::Value *CGObjCGNU::generateMessageSend(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC) {
- llvm::Value *cmd = getSelector(Builder, Selector, 0);
-
- // Look up the method implementation.
- 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);
-
- llvm::Constant *lookupFunction =
- TheModule.getOrInsertFunction("objc_msg_lookup",
- llvm::PointerType::getUnqual(impType),
- Receiver->getType(), SelectorTy, NULL);
- llvm::Value *imp = Builder.CreateCall2(lookupFunction, Receiver, cmd);
-
- // Call the method.
- llvm::SmallVector<llvm::Value*, 16> lookupArgs;
- lookupArgs.push_back(Receiver);
- lookupArgs.push_back(cmd);
- lookupArgs.insert(lookupArgs.end(), ArgV, ArgV+ArgC);
- return Builder.CreateCall(imp, lookupArgs.begin(), lookupArgs.end());
-}
-
-llvm::Function *CGObjCGNU::MethodPreamble(
- const llvm::Type *ReturnTy,
- const llvm::Type *SelfTy,
- const llvm::Type **ArgTy,
- unsigned ArgC,
- bool isVarArg) {
- std::vector<const llvm::Type*> Args;
- Args.push_back(SelfTy);
- Args.push_back(SelectorTy);
- Args.insert(Args.end(), ArgTy, ArgTy+ArgC);
-
- llvm::FunctionType *MethodTy = llvm::FunctionType::get(ReturnTy,
- Args,
- isVarArg);
- llvm::Function *Method = llvm::Function::Create(MethodTy,
- llvm::GlobalValue::InternalLinkage,
- ".objc.method",
- &TheModule);
- // Set the names of the hidden arguments
- llvm::Function::arg_iterator AI = Method->arg_begin();
- AI->setName("self");
- ++AI;
- AI->setName("_cmd");
- return Method;
-}
-
-clang::CodeGen::CGObjCRuntime *clang::CodeGen::CreateObjCRuntime(
- llvm::Module &M,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType) {
- return new CGObjCGNU(M, LLVMIntType, LLVMLongType);
-}
diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h
deleted file mode 100644
index 9ee067bb2101..000000000000
--- a/clang/lib/CodeGen/CGObjCRuntime.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===----- CGObjCRuntime.h - 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 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
-
-namespace llvm {
- class IRBuilder;
- class Constant;
- class Type;
- class Value;
- class Module;
- class Function;
-}
-
-
-namespace clang {
-namespace CodeGen {
-
-// Implements runtime-specific code generation functions
-class CGObjCRuntime {
-public:
- virtual ~CGObjCRuntime();
-
- /// Generate an Objective-C message send operation
- virtual llvm::Value *generateMessageSend(llvm::IRBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Sender,
- llvm::Value *Receiver,
- llvm::Value *Selector,
- llvm::Value** ArgV,
- unsigned ArgC) = 0;
- /// Generate the function required to register all Objective-C components in
- /// this compilation unit with the runtime library.
- virtual llvm::Function *ModuleInitFunction() { return 0; }
- /// Generate a function preamble for a method with the specified types
- virtual llvm::Function *MethodPreamble(const llvm::Type *ReturnTy,
- const llvm::Type *SelfTy,
- const llvm::Type **ArgTy,
- unsigned ArgC,
- bool isVarArg) = 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() { return false; }
-};
-
-/// Creates an instance of an Objective-C runtime class.
-//TODO: This should include some way of selecting which runtime to target.
-CGObjCRuntime *CreateObjCRuntime(llvm::Module &M,
- const llvm::Type *LLVMIntType,
- const llvm::Type *LLVMLongType);
-}
-}
-#endif
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
deleted file mode 100644
index d804ee6665fd..000000000000
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ /dev/null
@@ -1,801 +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/AST.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.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 {
- WarnUnsupported(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::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: EmitBreakStmt(); break;
- case Stmt::ContinueStmtClass: 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;
- }
-}
-
-/// 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.
- if (S.body_empty() || !isa<Expr>(S.body_back())) GetLast = false;
-
- 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);
-
- return EmitAnyExpr(cast<Expr>(S.body_back()), 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() && LastBB->getValueName() == 0) {
- // If the last block was an empty placeholder, remove it now.
- // TODO: cache and reuse these.
- Builder.GetInsertBlock()->eraseFromParent();
- } else {
- // Otherwise, create a fall-through branch.
- Builder.CreateBr(BB);
- }
- CurFn->getBasicBlockList().push_back(BB);
- Builder.SetInsertPoint(BB);
-}
-
-void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
- llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
-
- EmitBlock(NextBB);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
- 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::EmitIfStmt(const IfStmt &S) {
- // 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 (S.getInc())
- EmitBlock(ContinueBlock);
-
- // If there is an increment, emit it next.
- if (S.getInc())
- EmitStmt(S.getInc());
-
- // Finally, branch back up to the condition for the next iteration.
- Builder.CreateBr(CondBlock);
-
- // Emit the fall-through block.
- EmitBlock(AfterFor);
-}
-
-/// 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();
-
- if (FnRetTy->isVoidType()) {
- // If the function returns void, emit ret void.
- Builder.CreateRetVoid();
- } else if (RV == 0) {
- // Handle "return;" in a function that returns a value.
- const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType();
- if (RetTy == llvm::Type::VoidTy)
- Builder.CreateRetVoid(); // struct return etc.
- else
- Builder.CreateRet(llvm::UndefValue::get(RetTy));
- } else if (!hasAggregateLLVMType(RV->getType())) {
- Builder.CreateRet(EmitScalarExpr(RV));
- } else if (RV->getType()->isAnyComplexType()) {
- llvm::Value *SRetPtr = CurFn->arg_begin();
- EmitComplexExprIntoAddr(RV, SRetPtr, false);
- } else {
- llvm::Value *SRetPtr = CurFn->arg_begin();
- EmitAggExpr(RV, SRetPtr, false);
- }
-
- // 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 (const ScopedDecl *Decl = S.getDecl(); Decl;
- Decl = Decl->getNextDeclarator())
- EmitDecl(*Decl);
-}
-
-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() && "Unexpected RHS value in CaseStmt");
-
- const Expr *L = S.getLHS();
- const Expr *R = S.getRHS();
- llvm::ConstantInt *LV = cast<llvm::ConstantInt>(EmitScalarExpr(L));
- llvm::ConstantInt *RV = cast<llvm::ConstantInt>(EmitScalarExpr(R));
- llvm::APInt LHS = LV->getValue();
- const llvm::APInt &RHS = RV->getValue();
-
- llvm::APInt Range = RHS - LHS;
- if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
- // Range is small enough to add multiple switch instruction cases.
- StartBlock("sw.bb");
- llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
- SwitchInsn->addCase(LV, CaseDest);
- LHS++;
- while (LHS != RHS) {
- SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest);
- LHS++;
- }
- SwitchInsn->addCase(RV, CaseDest);
- EmitStmt(S.getSubStmt());
- return;
- }
-
- // The range is too big. Emit "if" condition.
- llvm::BasicBlock *FalseDest = NULL;
- llvm::BasicBlock *CaseDest = llvm::BasicBlock::Create("sw.bb");
-
- // If we have already seen one case statement range for this switch
- // instruction then piggy-back otherwise use default block as false
- // destination.
- if (CaseRangeBlock)
- FalseDest = CaseRangeBlock;
- else
- FalseDest = SwitchInsn->getDefaultDest();
-
- // Start new block to hold case statement range check instructions.
- StartBlock("case.range");
- CaseRangeBlock = Builder.GetInsertBlock();
-
- // Emit range check.
- llvm::Value *Diff =
- Builder.CreateSub(SwitchInsn->getCondition(), LV, "tmp");
- llvm::Value *Cond =
- Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp");
- Builder.CreateCondBr(Cond, CaseDest, FalseDest);
-
- // Now emit case statement body.
- EmitBlock(CaseDest);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
- if (S.getRHS()) {
- EmitCaseStmtRange(S);
- return;
- }
-
- StartBlock("sw.bb");
- llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
- llvm::APSInt CaseVal(32);
- S.getLHS()->isIntegerConstantExpr(CaseVal, getContext());
- llvm::ConstantInt *LV = llvm::ConstantInt::get(CaseVal);
- SwitchInsn->addCase(LV, CaseDest);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
- StartBlock("sw.default");
- // Current insert block is the default destination.
- SwitchInsn->setSuccessor(0, Builder.GetInsertBlock());
- 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;
- CaseRangeBlock = NULL;
-
- // Create basic block to hold stuff that comes after switch statement.
- // Initially use it to hold DefaultStmt.
- llvm::BasicBlock *NextBlock = llvm::BasicBlock::Create("after.sw");
- SwitchInsn = Builder.CreateSwitch(CondV, NextBlock);
-
- // 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();
-
- // If one or more case statement range is seen then use CaseRangeBlock
- // as the default block. False edge of CaseRangeBlock will lead to
- // original default block.
- if (CaseRangeBlock)
- SwitchInsn->setSuccessor(0, CaseRangeBlock);
-
- // Prune insert block if it is dummy.
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB))
- BB->eraseFromParent();
- else // Otherwise, branch to continuation.
- Builder.CreateBr(NextBlock);
-
- // Place NextBlock as the new insert point.
- CurFn->getBasicBlockList().push_back(NextBlock);
- Builder.SetInsertPoint(NextBlock);
- SwitchInsn = SavedSwitchInsn;
- CaseRangeBlock = SavedCRBlock;
-}
-
-static inline 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->isFirstClassType()) {
- 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())->isFirstClassType()) {
- Arg = EmitScalarExpr(InputExpr);
- } else {
- assert(0 && "FIXME: Implement passing non first class 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())->isFirstClassType()) {
- Arg = EmitScalarExpr(InputExpr);
- } else {
- assert(0 && "FIXME: Implement passing non first class 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)
- Builder.CreateStore(Result, ResultAddr);
-}
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
deleted file mode 100644
index 9c5c45de5e90..000000000000
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ /dev/null
@@ -1,273 +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 "clang/Basic/TargetInfo.h"
-#include "clang/AST/AST.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.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) {}
-
-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]);
-}
-
-const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
- return CGM.getTypes().ConvertType(T);
-}
-
-bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
- return !T->isRealType() && !T->isPointerLikeType() &&
- !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
-}
-
-/// Generate an Objective-C method. An Objective-C method is a C function with
-/// its pointer, name, and types registered in the class struture.
-// FIXME: This method contains a lot of code copied and pasted from
-// GenerateCode. This should be factored out.
-void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
- llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
- for (unsigned i=0 ; i<OMD->param_size() ; i++) {
- ParamTypes.push_back(ConvertType(OMD->getParamDecl(i)->getType()));
- }
- CurFn =CGM.getObjCRuntime()->MethodPreamble(ConvertType(OMD->getResultType()),
- llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
- ParamTypes.begin(),
- OMD->param_size(),
- OMD->isVariadic());
- 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);
-
- FnRetTy = OMD->getResultType();
-
- Builder.SetInsertPoint(EntryBB);
-
- // Emit allocs for param decls. Give the LLVM Argument nodes names.
- llvm::Function::arg_iterator AI = CurFn->arg_begin();
-
- // Name the struct return argument.
- // FIXME: Probably should be in the runtime, or it will trample the other
- // hidden arguments.
- if (hasAggregateLLVMType(OMD->getResultType())) {
- AI->setName("agg.result");
- ++AI;
- }
-
- // Add implicit parameters to the decl map.
- // TODO: Add something to AST to let the runtime specify the names and types
- // of these.
- llvm::Value *&DMEntry = LocalDeclMap[&(*OMD->getSelfDecl())];
- const llvm::Type *SelfTy = AI->getType();
- llvm::Value *DeclPtr = new llvm::AllocaInst(SelfTy, 0, "self.addr",
- AllocaInsertPt);
-
- // Store the initial value into the alloca.
- Builder.CreateStore(AI, DeclPtr);
- DMEntry = DeclPtr;
- ++AI; ++AI;
-
-
- for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
- assert(AI != CurFn->arg_end() && "Argument mismatch!");
- EmitParmDecl(*OMD->getParamDecl(i), AI);
- }
-
- // Emit the function body.
- EmitStmt(OMD->getBody());
-
- // Emit a return for code that falls off the end. If insert point
- // is a dummy block with no predecessors then remove the block itself.
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB))
- BB->eraseFromParent();
- else {
- if (CurFn->getReturnType() == llvm::Type::VoidTy)
- Builder.CreateRetVoid();
- else
- Builder.CreateRet(llvm::UndefValue::get(CurFn->getReturnType()));
- }
- assert(BreakContinueStack.empty() &&
- "mismatched push/pop in break/continue stack!");
-
- // Remove the AllocaInsertPt instruction, which is just a convenience for us.
- AllocaInsertPt->eraseFromParent();
- AllocaInsertPt = 0;
- // Verify that the function is well formed.
- assert(!verifyFunction(*CurFn) && "Generated method is not well formed.");
-}
-
-llvm::Value *CodeGenFunction::LoadObjCSelf(void)
-{
- if(const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
- llvm::Value *SelfPtr = LocalDeclMap[&(*OMD->getSelfDecl())];
- return Builder.CreateLoad(SelfPtr, "self");
- }
- return NULL;
-}
-
-void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
- LLVMIntTy = ConvertType(getContext().IntTy);
- LLVMPointerWidth = static_cast<unsigned>(
- getContext().getTypeSize(getContext().getPointerType(getContext().VoidTy)));
-
- CurFuncDecl = FD;
- FnRetTy = FD->getType()->getAsFunctionType()->getResultType();
-
- CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
- assert(CurFn->isDeclaration() && "Function already has body?");
-
- // TODO: Set up linkage and many other things. Note, this is a simple
- // approximation of what we really want.
- if (FD->getStorageClass() == FunctionDecl::Static)
- CurFn->setLinkage(llvm::Function::InternalLinkage);
- else if (FD->getAttr<DLLImportAttr>())
- CurFn->setLinkage(llvm::Function::DLLImportLinkage);
- else if (FD->getAttr<DLLExportAttr>())
- CurFn->setLinkage(llvm::Function::DLLExportLinkage);
- else if (FD->getAttr<WeakAttr>() || FD->isInline())
- CurFn->setLinkage(llvm::Function::WeakLinkage);
-
- if (FD->getAttr<FastCallAttr>())
- CurFn->setCallingConv(llvm::CallingConv::Fast);
-
- if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
- CurFn->setVisibility(attr->getVisibility());
- // FIXME: else handle -fvisibility
-
-
- unsigned FuncAttrs = 0;
- if (FD->getAttr<NoThrowAttr>())
- FuncAttrs |= llvm::ParamAttr::NoUnwind;
- if (FD->getAttr<NoReturnAttr>())
- FuncAttrs |= llvm::ParamAttr::NoReturn;
-
- if (FuncAttrs) {
- llvm::ParamAttrsWithIndex PAWI =
- llvm::ParamAttrsWithIndex::get(0, FuncAttrs);
- CurFn->setParamAttrs(llvm::PAListPtr::get(&PAWI, 1));
- }
-
- 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);
-
- Builder.SetInsertPoint(EntryBB);
-
- // Emit allocs for param decls. Give the LLVM Argument nodes names.
- llvm::Function::arg_iterator AI = CurFn->arg_begin();
-
- // Name the struct return argument.
- if (hasAggregateLLVMType(FD->getResultType())) {
- AI->setName("agg.result");
- ++AI;
- }
-
- for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
- assert(AI != CurFn->arg_end() && "Argument mismatch!");
- EmitParmDecl(*FD->getParamDecl(i), AI);
- }
-
- // Emit the function body.
- EmitStmt(FD->getBody());
-
- // Emit a return for code that falls off the end. If insert point
- // is a dummy block with no predecessors then remove the block itself.
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB))
- BB->eraseFromParent();
- else {
- // FIXME: if this is C++ main, this should return 0.
- if (CurFn->getReturnType() == llvm::Type::VoidTy)
- Builder.CreateRetVoid();
- else
- Builder.CreateRet(llvm::UndefValue::get(CurFn->getReturnType()));
- }
- assert(BreakContinueStack.empty() &&
- "mismatched push/pop in break/continue stack!");
-
- // Remove the AllocaInsertPt instruction, which is just a convenience for us.
- AllocaInsertPt->eraseFromParent();
- AllocaInsertPt = 0;
-
- // Verify that the function is well formed.
- assert(!verifyFunction(*CurFn) && "Generated function is not well formed.");
-}
-
-/// 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))
- 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());
-}
-
-/// WarnUnsupported - Print out a warning that codegen doesn't support the
-/// specified stmt yet.
-void CodeGenFunction::WarnUnsupported(const Stmt *S, const char *Type) {
- CGM.WarnUnsupported(S, Type);
-}
-
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
deleted file mode 100644
index f067a0e2250b..000000000000
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ /dev/null
@@ -1,505 +0,0 @@
-//===--- CodeGenFunction.h - Per-Function state 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 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 <vector>
-
-namespace llvm {
- class Module;
-}
-
-namespace clang {
- class ASTContext;
- class Decl;
- class FunctionDecl;
- class ObjCMethodDecl;
- class TargetInfo;
- class FunctionTypeProto;
-
- class Stmt;
- class CompoundStmt;
- class LabelStmt;
- class GotoStmt;
- class IfStmt;
- class WhileStmt;
- class DoStmt;
- class ForStmt;
- class ReturnStmt;
- class DeclStmt;
- class CaseStmt;
- class DefaultStmt;
- class SwitchStmt;
- class AsmStmt;
-
- class Expr;
- class DeclRefExpr;
- class StringLiteral;
- class IntegerLiteral;
- class FloatingLiteral;
- class CharacterLiteral;
- class TypesCompatibleExpr;
-
- class ImplicitCastExpr;
- class CastExpr;
- class CallExpr;
- class UnaryOperator;
- class BinaryOperator;
- class CompoundAssignOperator;
- class ArraySubscriptExpr;
- class ExtVectorElementExpr;
- class ConditionalOperator;
- class ChooseExpr;
- class PreDefinedExpr;
- class ObjCStringLiteral;
- class ObjCIvarRefExpr;
- class MemberExpr;
-
- class VarDecl;
- class EnumConstantDecl;
- class ParmVarDecl;
- class FieldDecl;
-namespace CodeGen {
- class CodeGenModule;
- class CodeGenTypes;
- class CGRecordLayout;
-
-/// 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: Volatility. Restrict?
- // 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
- } LVType;
-
- llvm::Value *V;
-
- union {
- // Index into a vector subscript: V[i]
- llvm::Value *VectorIdx;
-
- // ExtVector element subset: V.xyx
- llvm::Constant *VectorElts;
-
- struct {
- unsigned short StartBit;
- unsigned short Size;
- bool IsSigned;
- } BitfieldData; // BitField start bit and size
- };
-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; }
-
- // 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;
- }
-
- static LValue MakeAddr(llvm::Value *V) {
- LValue R;
- R.LVType = Simple;
- R.V = V;
- return R;
- }
-
- static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx) {
- LValue R;
- R.LVType = VectorElt;
- R.V = Vec;
- R.VectorIdx = Idx;
- return R;
- }
-
- static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts) {
- LValue R;
- R.LVType = ExtVectorElt;
- R.V = Vec;
- R.VectorElts = Elts;
- return R;
- }
-
- static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
- unsigned short Size, bool IsSigned) {
- LValue R;
- R.LVType = BitField;
- R.V = V;
- R.BitfieldData.StartBit = StartBit;
- R.BitfieldData.Size = Size;
- R.BitfieldData.IsSigned = IsSigned;
- return R;
- }
-};
-
-/// 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;
-
- /// 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;
-
-private:
- /// 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 GenerateCode(const FunctionDecl *FD);
-
- const llvm::Type *ConvertType(QualType T);
-
- llvm::Value *LoadObjCSelf();
-
- /// 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);
-
- /// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified stmt yet.
- void WarnUnsupported(const Stmt *S, const char *Type);
-
- //===--------------------------------------------------------------------===//
- // 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);
-
- /// 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);
- //===--------------------------------------------------------------------===//
- // Declaration Emission
- //===--------------------------------------------------------------------===//
-
- void EmitDecl(const Decl &D);
- void EmitEnumConstantDecl(const EnumConstantDecl &D);
- void EmitBlockVarDecl(const VarDecl &D);
- void EmitLocalBlockVarDecl(const VarDecl &D);
- void EmitStaticBlockVarDecl(const VarDecl &D);
- void EmitParmDecl(const ParmVarDecl &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 EmitLabelStmt(const LabelStmt &S);
- void EmitGotoStmt(const GotoStmt &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);
-
- //===--------------------------------------------------------------------===//
- // LValue Expression Emission
- //===--------------------------------------------------------------------===//
-
- /// 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);
-
-
- /// 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);
-
- // 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 EmitLValueForField(llvm::Value* Base, FieldDecl* Field,
- bool isUnion);
-
- LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
- //===--------------------------------------------------------------------===//
- // Scalar Expression Emission
- //===--------------------------------------------------------------------===//
-
- RValue EmitCallExpr(const CallExpr *E);
- RValue EmitCallExpr(Expr *FnExpr, Expr *const *Args, unsigned NumArgs);
- RValue EmitCallExpr(llvm::Value *Callee, QualType FnType,
- Expr *const *Args, unsigned NumArgs);
- 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 *EmitObjCStringLiteral(const ObjCStringLiteral *E);
-
- //===--------------------------------------------------------------------===//
- // 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);
- /// 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);
-};
-} // 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 b234788a08f8..000000000000
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ /dev/null
@@ -1,670 +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 "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Analysis/Verifier.h"
-#include <algorithm>
-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), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
- //TODO: Make this selectable at runtime
- Runtime = CreateObjCRuntime(M,
- getTypes().ConvertType(getContext().IntTy),
- getTypes().ConvertType(getContext().LongTy));
-
- // If debug info generation is enabled, create the CGDebugInfo object.
- if (GenerateDebugInfo)
- DebugInfo = new CGDebugInfo(this);
- else
- DebugInfo = NULL;
-}
-
-CodeGenModule::~CodeGenModule() {
- llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction();
- if (ObjCInitFunction)
- AddGlobalCtor(ObjCInitFunction);
- EmitStatics();
- EmitGlobalCtors();
- EmitAnnotations();
- delete Runtime;
- delete DebugInfo;
- // Run the verifier to check that the generated code is consistent.
- assert(!verifyModule(TheModule));
-}
-
-/// WarnUnsupported - Print out a warning that codegen doesn't support the
-/// specified stmt yet.
-void CodeGenModule::WarnUnsupported(const Stmt *S, const char *Type) {
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
- "cannot codegen this %0 yet");
- SourceRange Range = S->getSourceRange();
- std::string Msg = Type;
- getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID,
- &Msg, 1, &Range, 1);
-}
-
-/// WarnUnsupported - Print out a warning that codegen doesn't support the
-/// specified decl yet.
-void CodeGenModule::WarnUnsupported(const Decl *D, const char *Type) {
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
- "cannot codegen this %0 yet");
- std::string Msg = Type;
- getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID,
- &Msg, 1);
-}
-
-/// AddGlobalCtor - Add a function to the list that will be called before
-/// main() runs.
-void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor) {
- // TODO: Type coercion of void()* types.
- GlobalCtors.push_back(Ctor);
-}
-
-/// EmitGlobalCtors - Generates the array of contsturctor functions to be
-/// called on module load, if any have been registered with AddGlobalCtor.
-void CodeGenModule::EmitGlobalCtors() {
- if (GlobalCtors.empty()) return;
-
- // Get the type of @llvm.global_ctors
- std::vector<const llvm::Type*> CtorFields;
- CtorFields.push_back(llvm::IntegerType::get(32));
- // Constructor function type
- std::vector<const llvm::Type*> VoidArgs;
- llvm::FunctionType* CtorFuncTy =
- llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false);
-
- // i32, function type pair
- const llvm::Type *FPType = llvm::PointerType::getUnqual(CtorFuncTy);
- llvm::StructType* CtorStructTy =
- llvm::StructType::get(llvm::Type::Int32Ty, FPType, NULL);
- // Array of fields
- llvm::ArrayType* GlobalCtorsTy =
- llvm::ArrayType::get(CtorStructTy, GlobalCtors.size());
-
- // Define the global variable
- llvm::GlobalVariable *GlobalCtorsVal =
- new llvm::GlobalVariable(GlobalCtorsTy, false,
- llvm::GlobalValue::AppendingLinkage,
- (llvm::Constant*)0, "llvm.global_ctors",
- &TheModule);
-
- // Populate the array
- std::vector<llvm::Constant*> CtorValues;
- llvm::Constant *MagicNumber =
- llvm::ConstantInt::get(llvm::Type::Int32Ty, 65535, false);
- std::vector<llvm::Constant*> StructValues;
- for (std::vector<llvm::Constant*>::iterator I = GlobalCtors.begin(),
- E = GlobalCtors.end(); I != E; ++I) {
- StructValues.clear();
- StructValues.push_back(MagicNumber);
- StructValues.push_back(*I);
-
- CtorValues.push_back(llvm::ConstantStruct::get(CtorStructTy, StructValues));
- }
-
- GlobalCtorsVal->setInitializer(llvm::ConstantArray::get(GlobalCtorsTy,
- CtorValues));
-}
-
-
-
-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");
-}
-
-/// ReplaceMapValuesWith - This is a really slow and bad function that
-/// searches for any entries in GlobalDeclMap that point to OldVal, changing
-/// them to point to NewVal. This is badbadbad, FIXME!
-void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal,
- llvm::Constant *NewVal) {
- for (llvm::DenseMap<const Decl*, llvm::Constant*>::iterator
- I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I)
- if (I->second == OldVal) I->second = NewVal;
-}
-
-
-llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
- bool isDefinition) {
- // See if it is already in the map. If so, just return it.
- llvm::Constant *&Entry = GlobalDeclMap[D];
- if (Entry) return Entry;
-
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
-
- // Check to see if the function already exists.
- llvm::Function *F = getModule().getFunction(D->getName());
- const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
-
- // If it doesn't already exist, just create and return an entry.
- if (F == 0) {
- // FIXME: param attributes for sext/zext etc.
- F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
- D->getName(), &getModule());
-
- // Set the appropriate calling convention for the Function.
- if (D->getAttr<FastCallAttr>())
- F->setCallingConv(llvm::CallingConv::Fast);
- return Entry = F;
- }
-
- // If the pointer type matches, just return it.
- llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty);
- if (PFTy == F->getType()) return Entry = F;
-
- // If this isn't a definition, just return it casted to the right type.
- if (!isDefinition)
- return Entry = llvm::ConstantExpr::getBitCast(F, PFTy);
-
- // 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::Function *NewFn = llvm::Function::Create(FTy,
- llvm::Function::ExternalLinkage,
- "", &getModule());
- NewFn->takeName(F);
-
- // Replace uses of F with the Function we will endow with a body.
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(NewFn, F->getType());
- F->replaceAllUsesWith(NewPtrForOldDecl);
-
- // FIXME: Update the globaldeclmap for the previous decl of this name. We
- // really want a way to walk all of these, but we don't have it yet. This
- // is incredibly slow!
- ReplaceMapValuesWith(F, NewPtrForOldDecl);
-
- // Ok, delete the old function now, which is dead.
- assert(F->isDeclaration() && "Shouldn't replace non-declaration");
- F->eraseFromParent();
-
- // Return the new function which has the right type.
- return Entry = NewFn;
-}
-
-static bool IsZeroElementArray(const llvm::Type *Ty) {
- if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(Ty))
- return ATy->getNumElements() == 0;
- return false;
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
- bool isDefinition) {
- assert(D->hasGlobalStorage() && "Not a global variable");
-
- // See if it is already in the map.
- llvm::Constant *&Entry = GlobalDeclMap[D];
- if (Entry) return Entry;
-
- QualType ASTTy = D->getType();
- const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
-
- // Check to see if the global already exists.
- llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true);
-
- // If it doesn't already exist, just create and return an entry.
- if (GV == 0) {
- return Entry = new llvm::GlobalVariable(Ty, false,
- llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
- }
-
- // If the pointer type matches, just return it.
- llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
- if (PTy == GV->getType()) return Entry = GV;
-
- // If this isn't a definition, just return it casted to the right type.
- if (!isDefinition)
- return Entry = llvm::ConstantExpr::getBitCast(GV, PTy);
-
-
- // Otherwise, we have a definition after a prototype with the wrong type.
- // GV is the GlobalVariable* for the one with the wrong type, we must make a
- /// new GlobalVariable* and update everything that used GV (a declaration)
- // 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];"). Start by
- // making a new global of the correct type, RAUW, then steal the name.
- llvm::GlobalVariable *NewGV =
- new llvm::GlobalVariable(Ty, false, llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
- NewGV->takeName(GV);
-
- // Replace uses of GV with the globalvalue we will endow with a body.
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(NewGV, GV->getType());
- GV->replaceAllUsesWith(NewPtrForOldDecl);
-
- // FIXME: Update the globaldeclmap for the previous decl of this name. We
- // really want a way to walk all of these, but we don't have it yet. This
- // is incredibly slow!
- ReplaceMapValuesWith(GV, NewPtrForOldDecl);
-
- // Verify that GV was a declaration or something like x[] which turns into
- // [0 x type].
- assert((GV->isDeclaration() ||
- IsZeroElementArray(GV->getType()->getElementType())) &&
- "Shouldn't replace non-declaration");
-
- // Ok, delete the old global now, which is dead.
- GV->eraseFromParent();
-
- // Return the new global which has the right type.
- return Entry = NewGV;
-}
-
-
-void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
- // If this is not a prototype, emit the body.
- if (OMD->getBody())
- CodeGenFunction(*this).GenerateObjCMethod(OMD);
-}
-
-void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
- // If this is not a prototype, emit the body.
- if (!FD->isThisDeclarationADefinition())
- return;
-
- // If the function is a static, defer code generation until later so we can
- // easily omit unused statics.
- if (FD->getStorageClass() != FunctionDecl::Static) {
- CodeGenFunction(*this).GenerateCode(FD);
- return;
- }
-
- // We need to check the Module here to see if GetAddrOfFunctionDecl() has
- // already added this function to the Module because the address of the
- // function's prototype was taken. If this is the case, call
- // GetAddrOfFunctionDecl to insert the static FunctionDecl into the used
- // GlobalDeclsMap, so that EmitStatics will generate code for it later.
- //
- // Example:
- // static int foo();
- // int bar() { return foo(); }
- // static int foo() { return 5; }
- if (getModule().getFunction(FD->getName()))
- GetAddrOfFunctionDecl(FD, true);
-
- StaticDecls.push_back(FD);
-}
-
-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) {
- // Check the map of used decls for our static. If not found, continue.
- const Decl *D = StaticDecls[i];
- if (!GlobalDeclMap.count(D))
- continue;
-
- // If this is a function decl, generate code for the static function if it
- // has a body. Otherwise, we must have a var decl for a static global
- // variable.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (FD->getBody())
- CodeGenFunction(*this).GenerateCode(FD);
- } else {
- EmitGlobalVarInit(cast<VarDecl>(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);
-}
-
-llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
- return EmitConstantExpr(Expr);
-}
-
-/// 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 filed is thee 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::EmitGlobalVar(const VarDecl *D) {
- // If the VarDecl is a static, defer code generation until later so we can
- // easily omit unused statics.
- if (D->getStorageClass() == VarDecl::Static) {
- StaticDecls.push_back(D);
- return;
- }
-
- // If this is just a forward declaration of the variable, don't emit it now,
- // allow it to be emitted lazily on its first use.
- if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
- return;
-
- EmitGlobalVarInit(D);
-}
-
-void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) {
- // Get the global, forcing it to be a direct reference.
- llvm::GlobalVariable *GV =
- cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, true));
-
- // Convert the initializer, or use zero if appropriate.
- llvm::Constant *Init = 0;
- if (D->getInit() == 0) {
- Init = llvm::Constant::getNullValue(GV->getType()->getElementType());
- } else if (D->getType()->isIntegerType()) {
- llvm::APSInt Value(static_cast<uint32_t>(
- getContext().getTypeSize(D->getInit()->getType())));
- if (D->getInit()->isIntegerConstantExpr(Value, Context))
- Init = llvm::ConstantInt::get(Value);
- }
-
- if (!Init)
- Init = EmitGlobalInit(D->getInit());
-
- if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
- SourceManager &SM = Context.getSourceManager();
- AddAnnotation(EmitAnnotateAttr(GV, AA,
- SM.getLogicalLineNumber(D->getLocation())));
- }
-
- assert(GV->getType()->getElementType() == Init->getType() &&
- "Initializer codegen type mismatch!");
- GV->setInitializer(Init);
-
- if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
- GV->setVisibility(attr->getVisibility());
- // FIXME: else handle -fvisibility
-
- // 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::WeakLinkage);
- break;
- case VarDecl::Extern:
- case VarDecl::PrivateExtern:
- // todo: common
- break;
- }
- }
-}
-
-/// EmitGlobalVarDeclarator - Emit all the global vars attached to the specified
-/// declarator chain.
-void CodeGenModule::EmitGlobalVarDeclarator(const VarDecl *D) {
- for (; D; D = cast_or_null<VarDecl>(D->getNextDeclarator()))
- if (D->isFileVarDecl())
- EmitGlobalVar(D);
-}
-
-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::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);
-}
-
-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();
-
- std::vector<llvm::Constant*> Fields;
-
- if (!CFConstantStringClassRef) {
- const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
- Ty = llvm::ArrayType::get(Ty, 0);
-
- CFConstantStringClassRef =
- new llvm::GlobalVariable(Ty, false,
- llvm::GlobalVariable::ExternalLinkage, 0,
- "__CFConstantStringClassReference",
- &getModule());
- }
-
- // Class pointer.
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
- llvm::Constant *Zeros[] = { Zero, Zero };
- llvm::Constant *C =
- llvm::ConstantExpr::getGetElementPtr(CFConstantStringClassRef, Zeros, 2);
- Fields.push_back(C);
-
- // Flags.
- const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
- Fields.push_back(llvm::ConstantInt::get(Ty, 1992));
-
- // String pointer.
- C = llvm::ConstantArray::get(str);
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &getModule());
-
- C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
- Fields.push_back(C);
-
- // String length.
- Ty = getTypes().ConvertType(getContext().LongTy);
- Fields.push_back(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;
-}
-
-/// 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
- llvm::Constant *C=llvm::ConstantArray::get(str);
-
- // Create a global variable for this string
- C = new llvm::GlobalVariable(C->getType(), constant,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &CGM.getModule());
- return C;
-}
-
-/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the character
-/// array containing the literal. The result is 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;
-}
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
deleted file mode 100644
index 8a3069e648b8..000000000000
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ /dev/null
@@ -1,143 +0,0 @@
-//===--- CodeGenModule.h - Per-Module state 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 internal per-translation-unit state used for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENMODULE_H
-#define CLANG_CODEGEN_CODEGENMODULE_H
-
-#include "CodeGenTypes.h"
-#include "CGObjCRuntime.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringMap.h"
-
-namespace llvm {
- class Module;
- class Constant;
- class Function;
- class GlobalValue;
- class TargetData;
-}
-
-namespace clang {
- class ASTContext;
- class FunctionDecl;
- class ObjCMethodDecl;
- class Decl;
- class Expr;
- class Stmt;
- class NamedDecl;
- class VarDecl;
- struct LangOptions;
- class Diagnostic;
- class AnnotateAttr;
-
-namespace CodeGen {
-
- class CodeGenFunction;
- class CGDebugInfo;
-
-/// CodeGenModule - This class organizes the cross-module state that is used
-/// while generating LLVM code.
-class CodeGenModule {
- 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 *MemSetFn;
- llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
- std::vector<const NamedDecl*> StaticDecls;
-
- std::vector<llvm::Constant*> GlobalCtors;
- std::vector<llvm::Constant*> Annotations;
-
- llvm::StringMap<llvm::Constant*> CFConstantStringMap;
- llvm::StringMap<llvm::Constant*> ConstantStringMap;
- 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();
-
- CGObjCRuntime *getObjCRuntime() { 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; }
-
- llvm::Constant *GetAddrOfFunctionDecl(const FunctionDecl *D,
- bool isDefinition);
- llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, bool isDefinition);
-
-
- /// getBuiltinLibFunction - Given a builtin id for a function like
- /// "__builtin_fabsf", return a Function* for "fabsf".
- ///
- llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
- llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
-
- /// GetAddrOfConstantString -- returns a pointer to the character
- /// array containing the literal. The result is pointer to array type.
- llvm::Constant *GetAddrOfConstantString(const std::string& str);
- llvm::Function *getMemCpyFn();
- llvm::Function *getMemSetFn();
- llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
- unsigned NumTys = 0);
-
- void AddGlobalCtor(llvm::Function * Ctor);
- void EmitGlobalCtors(void);
- void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
- void EmitAnnotations(void);
- void EmitStatics(void);
-
- void EmitObjCMethod(const ObjCMethodDecl *OMD);
- void EmitFunction(const FunctionDecl *FD);
- void EmitGlobalVar(const VarDecl *D);
- void EmitGlobalVarInit(const VarDecl *D);
- void EmitGlobalVarDeclarator(const VarDecl *D);
- void UpdateCompletedType(const TagDecl *D);
- llvm::Constant *EmitGlobalInit(const Expr *E);
- llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
- llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
- const AnnotateAttr *AA, unsigned LineNo);
-
- /// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified stmt yet.
-
- void WarnUnsupported(const Stmt *S, const char *Type);
-
- /// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified decl yet.
- void WarnUnsupported(const Decl *D, const char *Type);
-
-private:
- /// ReplaceMapValuesWith - This is a really slow and bad function that
- /// searches for any entries in GlobalDeclMap that point to OldVal, changing
- /// them to point to NewVal. This is badbadbad, FIXME!
- void ReplaceMapValuesWith(llvm::Constant *OldVal, llvm::Constant *NewVal);
-
-};
-} // 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 154405015592..000000000000
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ /dev/null
@@ -1,665 +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/Basic/TargetInfo.h"
-#include "clang/AST/AST.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.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) :
- CGT(Types), STy(NULL), llvmFieldNo(0), Cursor(0),
- llvmSize(0) {}
-
- /// addField - Add new field.
- void addField(const FieldDecl *FD);
-
- /// addLLVMField - Add llvm struct field that corresponds to llvm type Ty.
- /// Increment field count.
- void addLLVMField(const llvm::Type *Ty, bool isPaddingField = false);
-
- /// addPaddingFields - Current cursor is not suitable place to add next
- /// field. Add required padding fields.
- void addPaddingFields(unsigned WaterMark);
-
- /// 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();
-
- /// getLLVMType - Return associated llvm struct type. This may be NULL
- /// if fields are not laid out.
- llvm::Type *getLLVMType() const {
- return STy;
- }
-
- /// placeBitField - Find a place for FD, which is a bit-field.
- void placeBitField(const FieldDecl *FD);
-
- llvm::SmallSet<unsigned, 8> &getPaddingFields() {
- return PaddingFields;
- }
-
- private:
- CodeGenTypes &CGT;
- llvm::Type *STy;
- unsigned llvmFieldNo;
- uint64_t Cursor;
- uint64_t llvmSize;
- llvm::SmallVector<const FieldDecl *, 8> FieldDecls;
- std::vector<const llvm::Type*> LLVMFields;
- 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 TagDecl *, 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) {
- // See if type is already cached.
- llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator
- I = TypeCache.find(T.getCanonicalType().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.getCanonicalType().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) {
- llvm::DenseMap<const TagDecl*, llvm::PATypeHolder>::iterator TDTI =
- TagDeclTypes.find(TD);
- 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;
- }
-}
-
-const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
- const clang::Type &Ty = *T.getCanonicalType();
-
- 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()) {
- 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:
- return llvm::IntegerType::get(
- static_cast<unsigned>(Context.getTypeSize(T)));
-
- case BuiltinType::Float: return llvm::Type::FloatTy;
- case BuiltinType::Double:
- return (Context.Target.getDoubleFormat() == &llvm::APFloat::IEEEdouble) ?
- llvm::Type::DoubleTy : llvm::Type::FloatTy;
- case BuiltinType::LongDouble:
- // FIXME: mapping long double onto double.
- return llvm::Type::DoubleTy;
- }
- 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:
- case Type::FunctionProto: {
- const FunctionType &FP = cast<FunctionType>(Ty);
- const llvm::Type *ResultType;
-
- if (FP.getResultType()->isVoidType())
- ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
- else
- ResultType = ConvertTypeRecursive(FP.getResultType());
-
- // FIXME: Convert argument types.
- bool isVarArg;
- std::vector<const llvm::Type*> ArgTys;
-
- // Struct return passes the struct byref.
- if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) {
- ArgTys.push_back(llvm::PointerType::get(ResultType,
- FP.getResultType().getAddressSpace()));
- ResultType = llvm::Type::VoidTy;
- }
-
- if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
- DecodeArgumentTypes(*FTP, ArgTys);
- isVarArg = FTP->isVariadic();
- } else {
- isVarArg = true;
- }
-
- return llvm::FunctionType::get(ResultType, ArgTys, isVarArg);
- }
-
- case Type::ASQual:
- return
- ConvertTypeRecursive(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
-
- case Type::ObjCInterface: {
- // 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;
- // Pointer to the class. This is just a placeholder. Operations that
- // actually use the isa pointer should cast it to the Class type provided
- // by the runtime.
- IvarTypes.push_back(llvm::PointerType::getUnqual(llvm::Type::Int8Ty));
- CollectObjCIvarTypes(OIT.getDecl(), IvarTypes);
- return llvm::StructType::get(IvarTypes);
- }
-
- case Type::ObjCQualifiedInterface:
- assert(0 && "FIXME: add missing functionality here");
- break;
-
- case Type::ObjCQualifiedId:
- assert(0 && "FIXME: add missing functionality here");
- break;
-
- 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;
- }
- }
-
- // FIXME: implement.
- return llvm::OpaqueType::get();
-}
-
-void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
- std::vector<const llvm::Type*> &ArgTys) {
- for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
- const llvm::Type *Ty = ConvertTypeRecursive(FTP.getArgType(i));
- if (Ty->isFirstClassType())
- ArgTys.push_back(Ty);
- else
- // byval arguments are always on the stack, which is addr space #0.
- ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
- }
-}
-
-/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
-/// enum.
-const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
- llvm::DenseMap<const TagDecl*, llvm::PATypeHolder>::iterator TDTI =
- TagDeclTypes.find(TD);
-
- // 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(TD, ResultType));
- return ResultType;
- }
-
- // Okay, this is a definition of a type. Compile the implementation now.
-
- if (TD->getKind() == Decl::Enum) {
- // 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(TD, ResultHolder));
-
- const llvm::Type *ResultType;
- const RecordDecl *RD = cast<const RecordDecl>(TD);
- if (TD->getKind() == Decl::Struct || TD->getKind() == Decl::Class) {
- // Layout fields.
- RecordOrganizer RO(*this);
- for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
- RO.addField(RD->getMember(i));
-
- RO.layoutStructFields(Context.getASTRecordLayout(RD));
-
- // Get llvm::StructType.
- CGRecordLayouts[TD] = new CGRecordLayout(RO.getLLVMType(),
- RO.getPaddingFields());
- ResultType = RO.getLLVMType();
-
- } else if (TD->getKind() == Decl::Union) {
- // Just use the largest element of the union, breaking ties with the
- // highest aligned member.
- if (RD->getNumMembers() != 0) {
- RecordOrganizer RO(*this);
- for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
- RO.addField(RD->getMember(i));
-
- RO.layoutUnionFields();
-
- // Get llvm::StructType.
- CGRecordLayouts[TD] = 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 {
- llvm::DenseMap<const TagDecl*, CGRecordLayout *>::iterator I
- = CGRecordLayouts.find(TD);
- assert (I != CGRecordLayouts.end()
- && "Unable to find record layout information for type");
- return I->second;
-}
-
-/// addField - Add new field.
-void RecordOrganizer::addField(const FieldDecl *FD) {
- assert (!STy && "Record fields are already laid out");
- FieldDecls.push_back(FD);
-}
-
-/// 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.
-/// FIXME : At the moment assume
-/// - one to one mapping between AST FieldDecls and
-/// llvm::StructType elements.
-/// - Ignore bit fields
-/// - Ignore field aligments
-/// - Ignore packed structs
-void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
- // FIXME : Use SmallVector
- llvmSize = 0;
- llvmFieldNo = 0;
- Cursor = 0;
- LLVMFields.clear();
-
- for (llvm::SmallVector<const FieldDecl *, 8>::iterator I = FieldDecls.begin(),
- E = FieldDecls.end(); I != E; ++I) {
- const FieldDecl *FD = *I;
-
- if (FD->isBitField())
- placeBitField(FD);
- else {
- const llvm::Type *Ty = CGT.ConvertTypeRecursive(FD->getType());
- addLLVMField(Ty);
- CGT.addFieldInfo(FD, llvmFieldNo - 1);
- Cursor = llvmSize;
- }
- }
-
- unsigned StructAlign = RL.getAlignment();
- if (llvmSize % StructAlign) {
- unsigned StructPadding = StructAlign - (llvmSize % StructAlign);
- bool needStructPadding = true;
- if (!LLVMFields.empty()) {
- const llvm::Type *LastFieldType = LLVMFields.back();
- const llvm::Type *LastFieldDeclType =
- CGT.ConvertTypeRecursive(FieldDecls.back()->getType());
- if (LastFieldType != LastFieldDeclType) {
- unsigned LastFieldTypeSize =
- CGT.getTargetData().getABITypeSizeInBits(LastFieldType);
- unsigned LastFieldDeclTypeSize =
- CGT.getTargetData().getABITypeSizeInBits(LastFieldDeclType);
- if (LastFieldDeclTypeSize > LastFieldTypeSize
- && StructPadding == (LastFieldDeclTypeSize - LastFieldTypeSize)) {
- // Replace last LLVMField with a LastFieldDeclType field will
- // to avoid extra padding fields.
- LLVMFields.pop_back();
- LLVMFields.push_back(LastFieldDeclType);
- needStructPadding = false;
- }
- }
- }
- if (needStructPadding)
- addPaddingFields(llvmSize + StructPadding);
- }
-
- STy = llvm::StructType::get(LLVMFields);
-}
-
-/// addPaddingFields - Current cursor is not suitable place to add next field.
-/// Add required padding fields.
-void RecordOrganizer::addPaddingFields(unsigned WaterMark) {
- assert(WaterMark >= llvmSize && "Invalid padding Field");
- unsigned RequiredBits = WaterMark - llvmSize;
- unsigned RequiredBytes = (RequiredBits + 7) / 8;
- if (RequiredBytes == 1)
- // This is a bitfield that is using few bits from this byte.
- // It is not a padding field.
- addLLVMField(llvm::Type::Int8Ty, false);
- else
- for (unsigned i = 0; i != RequiredBytes; ++i)
- addLLVMField(llvm::Type::Int8Ty, true);
-}
-
-/// addLLVMField - Add llvm struct field that corresponds to llvm type Ty.
-/// Increment field count.
-void RecordOrganizer::addLLVMField(const llvm::Type *Ty, bool isPaddingField) {
-
- unsigned AlignmentInBits = CGT.getTargetData().getABITypeAlignment(Ty) * 8;
- if (llvmSize % AlignmentInBits) {
- // At the moment, insert padding fields even if target specific llvm
- // type alignment enforces implict padding fields for FD. Later on,
- // optimize llvm fields by removing implicit padding fields and
- // combining consequetive padding fields.
- unsigned Padding = AlignmentInBits - (llvmSize % AlignmentInBits);
- addPaddingFields(llvmSize + Padding);
- }
-
- unsigned TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
- llvmSize += TySize;
- if (isPaddingField)
- PaddingFields.insert(llvmFieldNo);
- LLVMFields.push_back(Ty);
- ++llvmFieldNo;
-}
-
-/// 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() {
-
- unsigned PrimaryEltNo = 0;
- std::pair<uint64_t, unsigned> PrimaryElt =
- CGT.getContext().getTypeInfo(FieldDecls[0]->getType());
- if (FieldDecls[0]->isBitField())
- placeBitField(FieldDecls[0]);
- else
- CGT.addFieldInfo(FieldDecls[0], 0);
-
- unsigned Size = FieldDecls.size();
- for(unsigned i = 1; i != Size; ++i) {
- const FieldDecl *FD = FieldDecls[i];
- std::pair<uint64_t, unsigned> EltInfo =
- CGT.getContext().getTypeInfo(FD->getType());
-
- // Use largest element, breaking ties with the hightest aligned member.
- if (EltInfo.first > PrimaryElt.first ||
- (EltInfo.first == PrimaryElt.first &&
- EltInfo.second > PrimaryElt.second)) {
- PrimaryElt = EltInfo;
- PrimaryEltNo = i;
- }
-
- // In union, each field gets first slot.
- if (FD->isBitField())
- placeBitField(FD);
- else
- CGT.addFieldInfo(FD, 0);
- }
-
- std::vector<const llvm::Type*> Fields;
- const llvm::Type *Ty =
- CGT.ConvertTypeRecursive(FieldDecls[PrimaryEltNo]->getType());
- Fields.push_back(Ty);
- STy = llvm::StructType::get(Fields);
-}
-
-/// placeBitField - Find a place for FD, which is a bit-field.
-/// This function searches for the last aligned field. If the bit-field fits in
-/// it, it is reused. Otherwise, the bit-field is placed in a new field.
-void RecordOrganizer::placeBitField(const FieldDecl *FD) {
-
- assert (FD->isBitField() && "FD is not a bit-field");
- 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();
-
- const llvm::Type *Ty = CGT.ConvertTypeRecursive(FD->getType());
- uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
-
- unsigned Idx = Cursor / TySize;
- unsigned BitsLeft = TySize - (Cursor % TySize);
-
- if (BitsLeft >= BitFieldSize) {
- // The bitfield fits in the last aligned field.
- // This is : struct { char a; int CurrentField:10;};
- // where 'CurrentField' shares first field with 'a'.
- CGT.addFieldInfo(FD, Idx);
- CGT.addBitFieldInfo(FD, TySize - BitsLeft, BitFieldSize);
- Cursor += BitFieldSize;
- } else {
- // Place the bitfield in a new LLVM field.
- // This is : struct { char a; short CurrentField:10;};
- // where 'CurrentField' needs a new llvm field.
- CGT.addFieldInfo(FD, Idx + 1);
- CGT.addBitFieldInfo(FD, 0, BitFieldSize);
- Cursor = (Idx + 1) * TySize + BitFieldSize;
- }
- if (Cursor > llvmSize)
- addPaddingFields(Cursor);
-}
diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h
deleted file mode 100644
index 9bfd6bdb3a49..000000000000
--- a/clang/lib/CodeGen/CodeGenTypes.h
+++ /dev/null
@@ -1,179 +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>
-
-namespace llvm {
- class Module;
- class Type;
- class OpaqueType;
- class PATypeHolder;
- class TargetData;
-}
-
-namespace clang {
- class ASTContext;
- class TagDecl;
- class TargetInfo;
- class QualType;
- class PointerType;
- class PointerLikeType;
- class Type;
- class FunctionTypeProto;
- class FieldDecl;
- class RecordDecl;
- class ObjCInterfaceDecl;
- class ObjCIvarDecl;
-
-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 TagDecl*, 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 TagDecl*, 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);
-
- void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
- std::vector<const llvm::Type*> &IvarTypes);
-
- const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
-
- /// 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.
- void DecodeArgumentTypes(const FunctionTypeProto &FTP,
- std::vector<const llvm::Type*> &ArgTys);
-
- /// 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);
-};
-
-} // 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 6387c622791e..000000000000
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ /dev/null
@@ -1,113 +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/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// LLVM Emitter
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-
-namespace {
- class CodeGenerator : public ASTConsumer {
- Diagnostic &Diags;
- const llvm::TargetData *TD;
- ASTContext *Ctx;
- const LangOptions &Features;
- bool GenerateDebugInfo;
- protected:
- llvm::Module *&M;
- CodeGen::CodeGenModule *Builder;
- public:
- CodeGenerator(Diagnostic &diags, const LangOptions &LO,
- llvm::Module *&DestModule, bool DebugInfoFlag)
- : Diags(diags), Features(LO), GenerateDebugInfo(DebugInfoFlag),
- M(DestModule) {}
-
- ~CodeGenerator() {
- delete Builder;
- }
-
- virtual void Initialize(ASTContext &Context) {
- Ctx = &Context;
-
- M->setTargetTriple(Ctx->Target.getTargetTriple());
- M->setDataLayout(Ctx->Target.getTargetDescription());
- TD = new llvm::TargetData(Ctx->Target.getTargetDescription());
- Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags,
- GenerateDebugInfo);
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- // If an error occurred, stop code generation, but continue parsing and
- // semantic analysis (to ensure all warnings and errors are emitted).
- if (Diags.hasErrorOccurred())
- return;
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- Builder->EmitFunction(FD);
- } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (VD->isFileVarDecl())
- Builder->EmitGlobalVarDeclarator(VD);
- } else if (isa<ObjCClassDecl>(D) || isa<ObjCCategoryDecl>(D)) {
- // Forward declaration. Only used for type checking.
- } else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){
- Builder->EmitObjCMethod(OMD);
- } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
- if (LSD->getLanguage() == LinkageSpecDecl::lang_cxx)
- Builder->WarnUnsupported(LSD, "linkage spec");
- // FIXME: implement C++ linkage, C linkage works mostly by C
- // language reuse already.
- } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) {
- std::string AsmString(AD->getAsmString()->getStrData(),
- AD->getAsmString()->getByteLength());
-
- const std::string &S = Builder->getModule().getModuleInlineAsm();
- if (S.empty())
- Builder->getModule().setModuleInlineAsm(AsmString);
- else
- Builder->getModule().setModuleInlineAsm(S + '\n' + AsmString);
- } else {
- assert(isa<TypeDecl>(D) && "Unknown top level decl");
- // TODO: handle debug info?
- }
- }
-
- /// 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);
- }
-
- };
-}
-
-ASTConsumer *clang::CreateLLVMCodeGen(Diagnostic &Diags,
- const LangOptions &Features,
- llvm::Module *&DestModule,
- bool GenerateDebugInfo) {
- return new CodeGenerator(Diags, Features, DestModule, GenerateDebugInfo);
-}
-
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/mmintrin.devel.h b/clang/lib/Headers/mmintrin.devel.h
deleted file mode 100644
index 70cded027ecd..000000000000
--- a/clang/lib/Headers/mmintrin.devel.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*===---- mmintrin.h - MMX intrinsics --------------------------------------===
- *
- * Copyright (c) 2008 Anders Carlsson
- *
- * 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)
-{
- return ((__v2si)m)[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)
-{
- // FIXME: use __builtin_shuffle_vector
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpackhi_pi16(__m64 m1, __m64 m2)
-{
- // FIXME: use __builtin_shuffle_vector
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpackhi_pi32(__m64 m1, __m64 m2)
-{
- // FIXME: use __builtin_shuffle_vector
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpacklo_pi8(__m64 m1, __m64 m2)
-{
- // FIXME: use __builtin_shuffle_vector
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpacklo_pi16(__m64 m1, __m64 m2)
-{
- // FIXME: use __builtin_shuffle_vector
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_unpacklo_pi32(__m64 m1, __m64 m2)
-{
- // FIXME: use __builtin_shuffle_vector
-}
-
-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_pi64(__m64 m, __m64 count)
-{
- return __builtin_ia32_psllq(m, count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_slli_pi64(__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_pi64(__m64 m, __m64 count)
-{
- return (__m64)__builtin_ia32_psrlq(m, count);
-}
-
-inline __m64 __attribute__((__always_inline__)) _mm_srli_pi64(__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/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/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 4fbbe3cc4644..000000000000
--- a/clang/lib/Lex/Lexer.cpp
+++ /dev/null
@@ -1,1662 +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;
-}
-
-/// isNamedIdentifier - Return true if this token is a ppidentifier with the
-/// specified name. For example, tok.isNamedIdentifier("this").
-bool Token::isNamedIdentifier(const char *Name) const {
- return IdentInfo && !strcmp(IdentInfo->getName(), Name);
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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 c763c8b9da26..000000000000
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ /dev/null
@@ -1,729 +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/SourceManager.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;
- Overflow |= (ResultChar & 0xF0000000) ? true : false; // About to shift out a digit?
- 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) {
- 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
- s++;
- 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') && PP.getLangOptions().HexFloats) {
- 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;
- }
- } else if (saw_period) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_hexconstant_requires_exponent);
- return;
- }
- } else if (*s == 'b' || *s == 'B') {
- // 0b101010 is a GCC extension.
- ++s;
- radix = 2;
- DigitsBegin = s;
- s = SkipBinaryDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (isxdigit(*s)) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_invalid_binary_digit, std::string(s, s+1));
- return;
- }
- PP.Diag(TokLoc, diag::ext_binary_literal);
- } else {
- // 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) {
- // Done.
- } else if (isxdigit(*s) && !(*s == 'e' || *s == 'E')) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_invalid_octal_digit, std::string(s, s+1));
- return;
- } else if (*s == '.') {
- s++;
- radix = 10;
- saw_period = true;
- s = SkipDigits(s);
- }
- 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-begin),
- diag::err_exponent_has_no_digits);
- 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;
- }
-}
-
-/// 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/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
deleted file mode 100644
index b24f5b63760d..000000000000
--- a/clang/lib/Lex/PPDirectives.cpp
+++ /dev/null
@@ -1,1153 +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/Lex/PPCallbacks.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.
-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 (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
- // If it returns true, #including this file will have no effect.
- return;
- }
-
- // Look up the file, create a File ID for it.
- unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation());
- 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);
-
- // Should we include the stuff contained by this directive?
- if (ConditionalTrue) {
- // 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();
- }
-
- // 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 5f11df089368..000000000000
--- a/clang/lib/Lex/PPExpressions.cpp
+++ /dev/null
@@ -1,713 +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/TokenKinds.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/SmallString.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()) {
- if (ValueLive)
- 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;
-
- bool Overflow = false;
- if (Result.isUnsigned())
- Overflow = Result.Val.isNegative();
- else if (Result.Val.isMinSignedValue())
- Overflow = true; // -MININT is the only thing that overflows.
-
- // 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.toStringSigned() + " to "+LHS.Val.toStringUnsigned(),
- LHS.getRange(), RHS.getRange());
- if (!RHS.isUnsigned() && RHS.Val.isNegative())
- PP.Diag(OpLoc, diag::warn_pp_convert_rhs_to_positive,
- RHS.Val.toStringSigned() + " to "+RHS.Val.toStringUnsigned(),
- 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 c15675114d31..000000000000
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ /dev/null
@@ -1,401 +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/Lex/PPCallbacks.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;
-}
-
-/// LookAhead - 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: is a relatively expensive method, so it should not be used in common
-/// code paths if possible!
-///
-Token Preprocessor::LookAhead(unsigned N) {
- // FIXME: Optimize the case where multiple lookahead calls are used back to
- // back. Consider if the the parser contained (dynamically):
- // Lookahead(1); Lookahead(1); Lookahead(1)
- // This would return the same token 3 times, but would end up making lots of
- // token stream lexers to do it. To handle this common case, see if the top
- // of the lexer stack is a TokenStreamLexer with macro expansion disabled. If
- // so, see if it has 'N' tokens available in it. If so, just return the
- // token.
-
- // FIXME: Optimize the case when the parser does multiple nearby lookahead
- // calls. For example, consider:
- // Lookahead(0); Lookahead(1); Lookahead(2);
- // The previous optimization won't apply, and there won't be any space left in
- // the array that was previously new'd. To handle this, always round up the
- // size we new to a multiple of 16 tokens. If the previous buffer has space
- // left, we can just grow it. This means we only have to do the new 1/16th as
- // often.
-
- Token *LookaheadTokens = new Token[N+1];
-
- // Read N+1 tokens into LookaheadTokens. After this loop, Tok is the token
- // to return.
- Token Tok;
- unsigned NumTokens = 0;
- for (; N != ~0U; --N, ++NumTokens) {
- Lex(Tok);
- LookaheadTokens[NumTokens] = Tok;
-
- // If we got to EOF, don't lex past it. This will cause LookAhead to return
- // the EOF token.
- if (Tok.is(tok::eof))
- break;
- }
-
- // Okay, at this point, we have the token we want to return in Tok. However,
- // we read it and a bunch of other stuff (in LookaheadTokens) that we must
- // allow subsequent calls to 'Lex' to return. To do this, we push a new token
- // lexer onto the lexer stack with the tokens we read here. This passes
- // ownership of LookaheadTokens to EnterTokenStream.
- //
- // Note that we disable macro expansion of the tokens from this buffer, since
- // any macros have already been expanded, and the internal preprocessor state
- // may already read past new macros. Consider something like LookAhead(1) on
- // X
- // #define X 14
- // Y
- // The lookahead call should return 'Y', and the next Lex call should return
- // 'X' even though X -> 14 has already been entered as a macro.
- //
- EnterTokenStream(LookaheadTokens, NumTokens, true /*DisableExpansion*/,
- true /*OwnsTokens*/);
- return Tok;
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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) {
- DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
-
- // Get the file entry for the current file.
- if (const FileEntry *FE =
- SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc()))
- FileType = HeaderInfo.getFileDirFlavor(FE);
-
- 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) {
- DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
-
- // Get the file entry for the current file.
- if (const FileEntry *FE =
- SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc()))
- FileType = HeaderInfo.getFileDirFlavor(FE);
-
- 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 fb9b613f5c8e..000000000000
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ /dev/null
@@ -1,530 +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.
- sprintf(TmpBuffer, "%u", SourceMgr.getLogicalLineNumber(Tok.getLocation()));
- unsigned Length = strlen(TmpBuffer);
- Tok.setKind(tok::numeric_constant);
- Tok.setLength(Length);
- Tok.setLocation(CreateString(TmpBuffer, Length, 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.
- sprintf(TmpBuffer, "%u", Depth);
- unsigned Length = strlen(TmpBuffer);
- 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, 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 08ad1cf1d2f2..000000000000
--- a/clang/lib/Lex/Pragma.cpp
+++ /dev/null
@@ -1,386 +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/PPCallbacks.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"
-#include "llvm/ADT/SmallVector.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::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,
- DirectoryLookup::SystemHeaderDir);
-}
-
-/// 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);
-}
-
-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 ccc9a8781ff6..000000000000
--- a/clang/lib/Lex/Preprocessor.cpp
+++ /dev/null
@@ -1,577 +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/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;
-
- // "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() {
- // 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.getLineNumber(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');
-}
-
-
-static void InitializePredefinedMacros(Preprocessor &PP,
- std::vector<char> &Buf) {
- // FIXME: Implement magic like cpp_init_builtins for things like __STDC__
- // and __DATE__ etc.
-#if 0
- /* __STDC__ has the value 1 under normal circumstances.
- However, if (a) we are in a system header, (b) the option
- stdc_0_in_system_headers is true (set by target config), and
- (c) we are not in strictly conforming mode, then it has the
- value 0. (b) and (c) are already checked in cpp_init_builtins. */
- //case BT_STDC:
- if (cpp_in_system_header (pfile))
- number = 0;
- else
- number = 1;
- break;
-#endif
- // 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");
-
- // Add __builtin_va_list typedef.
- {
- const char *VAList = PP.getTargetInfo().getVAListDeclaration();
- Buf.insert(Buf.end(), VAList, VAList+strlen(VAList));
- Buf.push_back('\n');
- }
-
- // Get the target #defines.
- PP.getTargetInfo().getTargetDefines(Buf);
-
- // Compiler set macros.
- DefineBuiltinMacro(Buf, "__APPLE_CC__=5250");
- DefineBuiltinMacro(Buf, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=1050");
- DefineBuiltinMacro(Buf, "__GNUC_MINOR__=0");
- DefineBuiltinMacro(Buf, "__GNUC_PATCHLEVEL__=1");
- DefineBuiltinMacro(Buf, "__GNUC__=4");
- DefineBuiltinMacro(Buf, "__GXX_ABI_VERSION=1002");
- DefineBuiltinMacro(Buf, "__VERSION__=\"4.0.1 (Apple Computer, Inc. "
- "build 5250)\"");
-
- // Build configuration options.
- DefineBuiltinMacro(Buf, "__DYNAMIC__=1");
- DefineBuiltinMacro(Buf, "__FINITE_MATH_ONLY__=0");
- DefineBuiltinMacro(Buf, "__NO_INLINE__=1");
- DefineBuiltinMacro(Buf, "__PIC__=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");
- }
- 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)=");
- }
- // 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.
- // FIXME: tried (unsuccesfully) to shut this up when compiling with gnu99
- // For now, I'm just commenting it out (while I work on attributes).
- if (II.isExtensionToken() && Features.C99)
- 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 fc8cfd715c48..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 is another ## after it, chomp it 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 f6514d57c777..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
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp
deleted file mode 100644
index 2d8de97f3c0f..000000000000
--- a/clang/lib/Parse/AttributeList.cpp
+++ /dev/null
@@ -1,101 +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;
- }
-
- switch (Len) {
- case 4:
- if (!memcmp(Str, "weak", 4)) return AT_weak;
- if (!memcmp(Str, "pure", 4)) return AT_pure;
- 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;
- 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, "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;
- 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;
- break;
- case 11:
- if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
- 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 52c6a3395433..000000000000
--- a/clang/lib/Parse/DeclSpec.cpp
+++ /dev/null
@@ -1,288 +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/LangOptions.h"
-#include "clang/Basic/SourceLocation.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_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, void *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.
- 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) {
- 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'?
-}
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 9b2f351158a1..000000000000
--- a/clang/lib/Parse/MinimalAction.cpp
+++ /dev/null
@@ -1,136 +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::DeclTy *
-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 AtInterafceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperName, SourceLocation SuperLoc,
- IdentifierInfo **ProtocolNames, 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/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
deleted file mode 100644
index f20c72e61ce8..000000000000
--- a/clang/lib/Parse/ParseDecl.cpp
+++ /dev/null
@@ -1,1529 +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/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
-///
-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))
- ParseSimpleAsm();
-
- // 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.
- ExprResult Init;
- if (Tok.is(tok::equal)) {
- ConsumeToken();
- Init = ParseInitializer();
- if (Init.isInvalid) {
- SkipUntil(tok::semi);
- return 0;
- }
- Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
- }
-
- // 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)
- 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++] '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()) {
- // 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()) {
- // It has to be available as a typedef too!
- if (void *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(),
- CurScope)) {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
- TypeRep);
- if (isInvalid)
- break;
- // FIXME: restrict this to "id" and ObjC classnames.
- DS.SetRangeEnd(Tok.getLocation());
- ConsumeToken(); // The identifier
- if (Tok.is(tok::less)) {
- SourceLocation endProtoLoc;
- llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
- ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc);
- llvm::SmallVector<DeclTy *, 8> *ProtocolDecl =
- new llvm::SmallVector<DeclTy *, 8>;
- DS.setProtocolQualifiers(ProtocolDecl);
- Actions.FindProtocolDeclaration(Loc,
- &ProtocolRefs[0], ProtocolRefs.size(),
- *ProtocolDecl);
- }
- continue;
- }
- }
- // FALL THROUGH.
- default:
- // 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;
-
- // 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_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;
- }
- // 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();
- }
-}
-
-/// ParseTag - Parse "struct-or-union-or-class-or-enum identifier[opt]", where
-/// the first token has already been read and has been turned into an instance
-/// of DeclSpec::TST (TagType). This returns true if there is an error parsing,
-/// otherwise it returns false and fills in Decl.
-bool Parser::ParseTag(DeclTy *&Decl, unsigned TagType, SourceLocation StartLoc){
- AttributeList *Attr = 0;
- // If attributes exist after tag, parse them.
- if (Tok.is(tok::kw___attribute))
- Attr = ParseAttributes();
-
- // Must have either 'struct name' or 'struct {...}'.
- 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 true;
- }
-
- // 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 'struct foo;', then this is a
- // forward declaration. If we have 'struct foo {...' then this is a
- // definition. Otherwise we have something like 'struct foo xyz', a reference.
- //
- // This is needed to handle stuff like this right (C99 6.7.2.3p11):
- // struct foo {..}; void bar() { struct foo; } <- new foo in bar.
- // struct foo {..}; void bar() { struct 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;
- Decl = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, Name, NameLoc, Attr);
- return false;
-}
-
-/// 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 ')' [TODO]
-///
-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();
- 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);
- }
-
-
- 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);
-
- Actions.ActOnFields(CurScope,
- RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size(),
- LBraceLoc, RBraceLoc);
-
- AttributeList *AttrList = 0;
- // If attributes exist after struct contents, parse them.
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseAttributes(); // FIXME: where should I put them?
-}
-
-
-/// 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.
- DeclTy *TagDecl;
- if (ParseTag(TagDecl, DeclSpec::TST_enum, StartLoc))
- return;
-
- 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:
-
- // 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_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_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;
-
- // 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 or C++ reference.
- if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus))
- return ParseDirectDeclarator(D);
-
- // Otherwise, '*' -> pointer or '&' -> reference.
- SourceLocation Loc = ConsumeToken(); // Eat the * or &.
-
- if (Kind == tok::star) {
- // Is a pointer.
- DeclSpec DS;
-
- ParseTypeQualifierListOpt(DS);
-
- // Recursively parse the declarator.
- ParseDeclaratorInternal(D);
-
- // Remember that we parsed a pointer type, and remember the type-quals.
- D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
- DS.TakeAttributes()));
- } 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)) {
- 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.
- 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) {
- 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 (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 )
-///
-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)) {
- Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
- return;
- }
- SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
-
- if (isTypeSpecifierQualifier()) {
- 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);
- }
-}
-
-
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
deleted file mode 100644
index 0a20911c7d32..000000000000
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ /dev/null
@@ -1,359 +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))
- 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.
- DeclTy *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;
- }
-}
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
deleted file mode 100644
index 523f6473417b..000000000000
--- a/clang/lib/Parse/ParseExpr.cpp
+++ /dev/null
@@ -1,1047 +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/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);
-}
-
-Parser::ExprResult Parser::ParseConstantExpression() {
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
-
- return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
-}
-
-/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
-/// in contexts where we have already consumed an identifier (which we saved in
-/// 'IdTok'), then discovered that the identifier was really the leading token
-/// of part of an expression. For example, in "A[1]+B", we consumed "A" (which
-/// is now in 'IdTok') and the current token is "[".
-Parser::ExprResult Parser::
-ParseExpressionWithLeadingIdentifier(const Token &IdTok) {
- // We know that 'IdTok' must correspond to this production:
- // primary-expression: identifier
-
- // Let the actions module handle the identifier.
- ExprResult Res = Actions.ActOnIdentifierExpr(CurScope, IdTok.getLocation(),
- *IdTok.getIdentifierInfo(),
- Tok.is(tok::l_paren));
-
- // Because we have to parse an entire cast-expression before starting the
- // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
- // need to handle the 'postfix-expression' rules. We do this by invoking
- // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
- Res = ParsePostfixExpressionSuffix(Res);
- if (Res.isInvalid) return Res;
-
- // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
- // done, we know we don't have to do anything for cast-expression, because the
- // only non-postfix-expression production starts with a '(' token, and we know
- // we have an identifier. As such, we can invoke ParseRHSOfBinaryExpression
- // to consume any trailing operators (e.g. "+" in this example) and connected
- // chunks of the expression.
- return ParseRHSOfBinaryExpression(Res, prec::Comma);
-}
-
-/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
-/// in contexts where we have already consumed an identifier (which we saved in
-/// 'IdTok'), then discovered that the identifier was really the leading token
-/// of part of an assignment-expression. For example, in "A[1]+B", we consumed
-/// "A" (which is now in 'IdTok') and the current token is "[".
-Parser::ExprResult Parser::
-ParseAssignmentExprWithLeadingIdentifier(const Token &IdTok) {
- // We know that 'IdTok' must correspond to this production:
- // primary-expression: identifier
-
- // Let the actions module handle the identifier.
- ExprResult Res = Actions.ActOnIdentifierExpr(CurScope, IdTok.getLocation(),
- *IdTok.getIdentifierInfo(),
- Tok.is(tok::l_paren));
-
- // Because we have to parse an entire cast-expression before starting the
- // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
- // need to handle the 'postfix-expression' rules. We do this by invoking
- // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
- Res = ParsePostfixExpressionSuffix(Res);
- if (Res.isInvalid) return Res;
-
- // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
- // done, we know we don't have to do anything for cast-expression, because the
- // only non-postfix-expression production starts with a '(' token, and we know
- // we have an identifier. As such, we can invoke ParseRHSOfBinaryExpression
- // to consume any trailing operators (e.g. "+" in this example) and connected
- // chunks of the expression.
- return ParseRHSOfBinaryExpression(Res, prec::Assignment);
-}
-
-
-/// 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++] '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]
-///
-/// 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: { // 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:
- return ParseCXXCasts();
- 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.
- default:
- 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] ')'
- llvm::SmallVector<ExprTy*, 8> ArgExprs;
- llvm::SmallVector<SourceLocation, 8> CommaLocs;
-
- Loc = ConsumeParen();
-
- 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());
- }
- }
-
- // 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 Res;
- }
-
- 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 && isTypeSpecifierQualifier()) {
- // 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());
-}
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
deleted file mode 100644
index a71eb4807b24..000000000000
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ /dev/null
@@ -1,105 +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"
-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);
- }
-}
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
deleted file mode 100644
index c40fe88c217b..000000000000
--- a/clang/lib/Parse/ParseInit.cpp
+++ /dev/null
@@ -1,241 +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();
- ExprResult R = ParseObjCMessageExpressionBody(StartLoc, Name, 0);
- return ParsePostfixExpressionSuffix(R);
- }
-
- // 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.
- 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].
- ExprResult R = ParseObjCMessageExpressionBody(StartLoc, 0, Idx.Val);
- return ParsePostfixExpressionSuffix(R);
- }
-
- // 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.
- Token Ident = Tok;
- ConsumeToken();
-
- // If this is the gross GNU extension, handle it now.
- if (Tok.is(tok::colon)) {
- Diag(Ident, diag::ext_gnu_old_style_field_designator);
- ConsumeToken();
- return ParseInitializer();
- }
-
- // Otherwise, we just consumed the first token of an expression. Parse
- // the rest of it now.
- return ParseAssignmentExprWithLeadingIdentifier(Ident);
- }
- }
- }
-}
-
-
-/// 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 4795a464f549..000000000000
--- a/clang/lib/Parse/ParseObjc.cpp
+++ /dev/null
@@ -1,1588 +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;
- llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
-
- // 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();
- SourceLocation endProtoLoc;
- // Next, we need to check for any protocol references.
- if (Tok.is(tok::less)) {
- if (ParseObjCProtocolReferences(ProtocolRefs, 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<IdentifierInfo *, 8> ProtocolRefs;
- SourceLocation endProtoLoc;
- if (Tok.is(tok::less)) {
- if (ParseObjCProtocolReferences(ProtocolRefs, 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;
-}
-
-/// 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());
- Selector SetterSel =
- PP.getSelectorTable().getNullarySelector(OCDS.getSetterName()
- ? OCDS.getSetterName()
- // FIXME. This is not right!
- : FD.D.getIdentifier());
- DeclTy *Property = Actions.ActOnProperty(CurScope,
- DS.getSourceRange().getBegin(), 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[0], allMethods.size(),
- &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_typeof:
- case tok::kw___alignof:
- case tok::kw_auto:
- case tok::kw_break:
- case tok::kw_case:
- case tok::kw_char:
- case tok::kw_const:
- case tok::kw_continue:
- case tok::kw_default:
- case tok::kw_do:
- case tok::kw_double:
- case tok::kw_else:
- case tok::kw_enum:
- case tok::kw_extern:
- case tok::kw_float:
- case tok::kw_for:
- case tok::kw_goto:
- case tok::kw_if:
- case tok::kw_inline:
- case tok::kw_int:
- case tok::kw_long:
- case tok::kw_register:
- 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_struct:
- case tok::kw_switch:
- case tok::kw_typedef:
- case tok::kw_union:
- case tok::kw_unsigned:
- case tok::kw_void:
- case tok::kw_volatile:
- case tok::kw_while:
- case tok::kw_bool:
- case tok::kw__Bool:
- case tok::kw__Complex:
- 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() == ObjCForCollectionInKW);
-}
-
-/// 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;
- 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)) {
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return 0; // FIXME: decide how we want to handle this error...
- }
- 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.
- TypeTy *ReturnType = 0;
- ObjCDeclSpec DSRet;
- if (Tok.is(tok::l_paren))
- ReturnType = ParseObjCTypeName(DSRet);
- SourceLocation selLoc;
- IdentifierInfo *SelIdent = ParseObjCSelector(selLoc);
- if (Tok.isNot(tok::colon)) {
- if (!SelIdent) {
- Diag(Tok, diag::err_expected_ident); // missing selector name.
- // FIXME: this creates a unary selector with a null identifier, is this
- // ok?? Maybe we should skip to the next semicolon or something.
- }
-
- // 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<IdentifierInfo*> &ProtocolRefs, SourceLocation &endLoc){
- assert(Tok.is(tok::less) && "expected <");
-
- ConsumeToken(); // the "<"
-
- while (1) {
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::greater);
- return true;
- }
- ProtocolRefs.push_back(Tok.getIdentifierInfo());
- ConsumeToken();
-
- if (Tok.isNot(tok::comma))
- break;
- ConsumeToken();
- }
-
- // Consume the '>'.
- if (Tok.is(tok::greater)) {
- endLoc = ConsumeAnyToken();
- return false;
- }
- Diag(Tok, diag::err_expected_greater);
- return true;
-}
-
-/// 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 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);
- // 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);
- 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) {
- 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();
-
- llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
- if (Tok.is(tok::semi)) { // forward declaration of one protocol.
- ConsumeToken();
- ProtocolRefs.push_back(protocolName);
- }
- if (Tok.is(tok::comma)) { // list of forward declarations.
- // Parse the list of forward declarations.
- ProtocolRefs.push_back(protocolName);
-
- while (1) {
- ConsumeToken(); // the ','
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- SkipUntil(tok::semi);
- return 0;
- }
- ProtocolRefs.push_back(Tok.getIdentifierInfo());
- ConsumeToken(); // the identifier
-
- if (Tok.isNot(tok::comma))
- break;
- }
- // Consume the ';'.
- if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
- return 0;
- }
- if (!ProtocolRefs.empty())
- return Actions.ActOnForwardProtocolDeclaration(AtLoc,
- &ProtocolRefs[0],
- ProtocolRefs.size());
- // Last, and definitely not least, parse a protocol declaration.
- SourceLocation endProtoLoc;
- if (Tok.is(tok::less)) {
- if (ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc))
- return 0;
- }
-
- DeclTy *ProtoType = Actions.ActOnStartProtocolInterface(AtLoc,
- protocolName, nameLoc,
- &ProtocolRefs[0],
- ProtocolRefs.size(), endProtoLoc);
- 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;
- }
- StmtResult SynchBody = ParseCompoundStatementBody();
- 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;
- StmtResult TryBody = ParseCompoundStatementBody();
- 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);
- // FIXME: Is BlockContext right?
- Declarator DeclaratorInfo(DS, Declarator::BlockContext);
- ParseDeclarator(DeclaratorInfo);
- 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
-
- 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;
- 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:
- break;
- }
-
- 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:
- Diag(AtLoc, diag::err_unexpected_at);
- SkipUntil(tok::semi);
- return true;
- }
-}
-
-/// 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 = ParseAssignmentExpression();
- if (Res.isInvalid) {
- Diag(Tok, diag::err_invalid_receiver_to_message);
- 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);
- SkipUntil(tok::semi);
- return true;
- }
- ConsumeToken(); // Eat the ':'.
- /// Parse the expression after ':'
- ExprResult Res = ParseAssignmentExpression();
- if (Res.isInvalid) {
- SkipUntil(tok::identifier);
- 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) {
- SkipUntil(tok::identifier);
- return Res;
- }
- // We have a valid expression.
- KeyExprs.push_back(Res.Val);
- }
- } else if (!selIdent) {
- Diag(Tok, diag::err_expected_ident); // missing selector name.
- SkipUntil(tok::semi);
- return true;
- }
-
- if (Tok.isNot(tok::r_square)) {
- Diag(Tok, diag::err_expected_rsquare);
- SkipUntil(tok::semi);
- 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)) {
- Diag(Tok, diag::err_expected_lparen_after, "@encode");
- return true;
- }
-
- 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)) {
- Diag(Tok, diag::err_expected_lparen_after, "@protocol");
- return true;
- }
-
- SourceLocation LParenLoc = ConsumeParen();
-
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return true;
- }
- 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)) {
- Diag(Tok, diag::err_expected_lparen_after, "@selector");
- return 0;
- }
-
- llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
- SourceLocation LParenLoc = ConsumeParen();
- SourceLocation sLoc;
- IdentifierInfo *SelIdent = ParseObjCSelector(sLoc);
- if (!SelIdent && Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_ident); // missing selector name.
- return 0;
- }
- KeyIdents.push_back(SelIdent);
- unsigned nColons = 0;
- if (Tok.isNot(tok::r_paren)) {
- while (1) {
- if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon);
- break;
- }
- 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/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
deleted file mode 100644
index 670181e2245b..000000000000
--- a/clang/lib/Parse/ParseStmt.cpp
+++ /dev/null
@@ -1,1159 +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
-/// [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::identifier: // C99 6.8.1: labeled-statement
- // identifier ':' statement
- // declaration (if !OnlyStatement)
- // expression[opt] ';'
- return ParseIdentifierStatement(OnlyStatement);
-
- case tok::at: // May be a @try or @throw statement
- {
- AtLoc = ConsumeToken(); // consume @
- return ParseObjCAtStatement(AtLoc);
- }
-
- default:
- if (!OnlyStatement && isDeclarationSpecifier()) {
- 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;
-}
-
-/// ParseIdentifierStatement - Because we don't have two-token lookahead, we
-/// have a bit of a quandry here. Reading the identifier is necessary to see if
-/// there is a ':' after it. If there is, this is a label, regardless of what
-/// else the identifier can mean. If not, this is either part of a declaration
-/// (if the identifier is a type-name) or part of an expression.
-///
-/// labeled-statement:
-/// identifier ':' statement
-/// [GNU] identifier ':' attributes[opt] statement
-/// declaration (if !OnlyStatement)
-/// expression[opt] ';'
-///
-Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) {
- assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
- "Not an identifier!");
-
- Token IdentTok = Tok; // Save the whole token.
- ConsumeToken(); // eat the identifier.
-
- // identifier ':' statement
- if (Tok.is(tok::colon)) {
- 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);
- }
-
- // Check to see if this is a declaration.
- void *TypeRep;
- if (!OnlyStatement &&
- (TypeRep = Actions.isTypeName(*IdentTok.getIdentifierInfo(), CurScope))) {
- // Handle this. Warn/disable if in middle of block and !C99.
- DeclSpec DS;
-
- // Add the typedef name to the start of the decl-specs.
- const char *PrevSpec = 0;
- int isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef,
- IdentTok.getLocation(), PrevSpec,
- TypeRep);
- assert(!isInvalid && "First declspec can't be invalid!");
- SourceLocation endProtoLoc;
- if (Tok.is(tok::less)) {
- llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
- ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc);
- llvm::SmallVector<DeclTy *, 8> *ProtocolDecl =
- new llvm::SmallVector<DeclTy *, 8>;
- DS.setProtocolQualifiers(ProtocolDecl);
- Actions.FindProtocolDeclaration(IdentTok.getLocation(),
- &ProtocolRefs[0], ProtocolRefs.size(),
- *ProtocolDecl);
- }
-
- // ParseDeclarationSpecifiers will continue from there.
- 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)) {
- // TODO: emit error on 'int;' or 'const enum foo;'.
- // if (!DS.isMissingDeclaratorOk()) Diag(...);
-
- ConsumeToken();
- // FIXME: Return this as a type decl.
- return 0;
- }
-
- // Parse all the declarators.
- Declarator DeclaratorInfo(DS, Declarator::BlockContext);
- ParseDeclarator(DeclaratorInfo);
-
- DeclTy *Decl = ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
- if (!Decl) return 0;
- return Actions.ActOnDeclStmt(Decl, DS.getSourceRange().getBegin(),
- DeclaratorInfo.getSourceRange().getEnd());
- }
-
- // Otherwise, this is an expression. Seed it with II and parse it.
- ExprResult Res = ParseExpressionWithLeadingIdentifier(IdentTok);
- if (Res.isInvalid) {
- SkipUntil(tok::semi);
- return true;
- } else if (Tok.isNot(tok::semi)) {
- Diag(Tok, diag::err_expected_semi_after, "expression");
- SkipUntil(tok::semi);
- return true;
- } else {
- ConsumeToken();
- // Convert expr to a stmt.
- return Actions.ActOnExprStmt(Res.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 (isDeclarationSpecifier()) {
- // 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
-///
-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;
- }
-
- // C99 6.8.4p3 - In C99, the if statement is a block. This is not
- // the case for C90.
- if (getLang().C99)
- EnterScope(Scope::DeclScope);
-
- // Parse the condition.
- ExprResult CondExp = ParseSimpleParenExpression();
- if (CondExp.isInvalid) {
- SkipUntil(tok::semi);
- if (getLang().C99)
- 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.
- bool NeedsInnerScope = getLang().C99 && 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.
- NeedsInnerScope = getLang().C99 && 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 (getLang().C99)
- 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
-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;
- }
-
- // C99 6.8.4p3 - In C99, the switch statement is a block. This is
- // not the case for C90. Start the switch scope.
- if (getLang().C99)
- EnterScope(Scope::BreakScope|Scope::DeclScope);
- else
- EnterScope(Scope::BreakScope);
-
- // Parse the condition.
- ExprResult 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.
- bool NeedsInnerScope = getLang().C99 && 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
-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;
- }
-
- // C99 6.8.5p5 - In C99, the while 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);
-
- // Parse the condition.
- ExprResult 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.
- bool NeedsInnerScope = getLang().C99 && 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.
- bool NeedsInnerScope = getLang().C99 && 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
-/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
-/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
-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;
- }
-
- // C99 6.8.5p5 - In C99, the for 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);
-
- 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 (isDeclarationSpecifier()) { // for (int X = 4;
- // Parse declaration, which eats the ';'.
- if (!getLang().C99) // 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 = ParseDeclaration(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 = 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.
- bool NeedsInnerScope = getLang().C99 && 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/Parser.cpp b/clang/lib/Parse/Parser.cpp
deleted file mode 100644
index 7e41bcc92e33..000000000000
--- a/clang/lib/Parse/Parser.cpp
+++ /dev/null
@@ -1,667 +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/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.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;
-}
-
-/// Out-of-line virtual destructor to provide home for Action class.
-Action::~Action() {}
-
-
-void Parser::Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg) {
- Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, &Msg, 1);
-}
-
-/// 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];
-}
-
-/// 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");
- ObjCForCollectionInKW = &PP.getIdentifierTable().get("in");
- }
-}
-
-/// 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)) return true;
-
- Result = ParseExternalDeclaration();
- return false;
-}
-
-/// Finalize - Shut down the parser.
-///
-void Parser::Finalize() {
- ExitScope();
- assert(CurScope == 0 && "Scope imbalance!");
-}
-
-/// ParseTranslationUnit:
-/// translation-unit: [C99 6.9]
-/// external-declaration
-/// translation-unit external-declaration
-void Parser::ParseTranslationUnit() {
- Initialize();
-
- DeclTy *Res;
- while (!ParseTopLevelDecl(Res))
- /*parse them all*/;
-
- Finalize();
-}
-
-/// 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);
- }
- 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.
- if (getLang().ObjC2 && Tok.is(tok::at)) {
- SourceLocation AtLoc = ConsumeToken(); // the "@"
- if (!Tok.isObjCAtKeyword(tok::objc_interface)) {
- Diag(Tok, diag::err_objc_expected_property_attr);//FIXME:better diagnostic
- 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);
- 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
- // FALL THROUGH.
- } else if (DeclaratorInfo.isFunctionDeclarator() &&
- (Tok.is(tok::l_brace) || // int X() {}
- 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.getDeclSpec().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::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 0;
- }
-
- ConsumeParen();
-
- ExprResult Result = ParseAsmStringLiteral();
-
- 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 f17aa537ef29..000000000000
--- a/clang/lib/Rewrite/HTMLRewrite.cpp
+++ /dev/null
@@ -1,480 +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 <sstream>
-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::ostringstream os;
-
- 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)
- for (unsigned i = 0; i < 4; ++i)
- os << "&nbsp;";
- 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 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);
-
- // Generate header
- R.InsertCStrBefore(StartLoc,
- "<!doctype html>\n" // Use HTML 5 doctype
- "<html>\n<head>\n"
- "<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"
- " .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"
- " .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 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::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 9d5d7a741053..000000000000
--- a/clang/lib/Rewrite/RewriteRope.cpp
+++ /dev/null
@@ -1,785 +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.
- const RopePieceBTreeLeaf *NextLeaf;
- public:
- RopePieceBTreeLeaf() : RopePieceBTreeNode(true), NumPieces(0), NextLeaf(0){}
-
- 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 setNextLeafInOrder(const RopePieceBTreeLeaf *NL) { NextLeaf = NL; }
-
- /// 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->setNextLeafInOrder(this->getNextLeafInOrder());
- this->setNextLeafInOrder(NewNode);
-
- // 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+1 != 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 = sizeof(RopeRefCountString)-1+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 4f54102d02b5..000000000000
--- a/clang/lib/Rewrite/Rewriter.cpp
+++ /dev/null
@@ -1,176 +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 <sstream>
-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, true);
- 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;
-}
-
-
-unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
- unsigned &FileID) const {
- 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::ostringstream S;
- 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/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp
deleted file mode 100644
index fada62f10b46..000000000000
--- a/clang/lib/Sema/IdentifierResolver.cpp
+++ /dev/null
@@ -1,191 +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 <list>
-#include <vector>
-
-using namespace clang;
-
-
-/// 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);
-};
-
-
-IdentifierResolver::IdentifierResolver() : IdDeclInfos(new IdDeclInfoMap) {}
-IdentifierResolver::~IdentifierResolver() {
- delete IdDeclInfos;
-}
-
-/// 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 'CIT' 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 all decls, starting at the given
-/// declaration context.
-IdentifierResolver::iterator
-IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx) {
- assert(Ctx && "null param passed");
-
- void *Ptr = II->getFETokenInfo<void>();
- if (!Ptr) return end(II);
-
- LookupContext LC(Ctx);
-
- if (isDeclPtr(Ptr)) {
- NamedDecl *D = static_cast<NamedDecl*>(Ptr);
-
- if (LC.isEqOrContainedBy(LookupContext(D)))
- return iterator(D);
- else
- return end(II);
-
- }
-
- IdDeclInfo *IDI = toIdDeclInfo(Ptr);
- return iterator(IDI->FindContext(LC));
-}
-
-/// ctx_begin - Returns an iterator for only decls that belong to the given
-/// declaration context.
-IdentifierResolver::ctx_iterator
-IdentifierResolver::ctx_begin(const IdentifierInfo *II, DeclContext *Ctx) {
- assert(Ctx && "null param passed");
-
- void *Ptr = II->getFETokenInfo<void>();
- if (!Ptr) return ctx_end(II);
-
- LookupContext LC(Ctx);
-
- if (isDeclPtr(Ptr)) {
- NamedDecl *D = static_cast<NamedDecl*>(Ptr);
-
- if (LC == LookupContext(D))
- return ctx_iterator(D);
- else
- return ctx_end(II);
-
- }
-
- IdDeclInfo *IDI = toIdDeclInfo(Ptr);
- IdDeclInfo::DeclsTy::iterator I = IDI->FindContext(LookupContext(Ctx));
- if (I != IDI->decls_begin() && LC != LookupContext(*(I-1)))
- I = IDI->decls_begin();
-
- return ctx_iterator(I);
-}
-
-
-/// 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 da1327be485a..000000000000
--- a/clang/lib/Sema/IdentifierResolver.h
+++ /dev/null
@@ -1,370 +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"
-
-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) {
- DeclContext *Ctx;
-
- 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;
- }
-
- 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 {
- if (PC.isTU()) return true;
-
- for (LookupContext Next = *this; !Next.isTU(); Next = Next.getParent())
- if (Next.Ctx == PC.Ctx) return true;
-
- return false;
- }
-
- 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) {
- for (DeclsTy::iterator I = Start; I != Decls.begin(); --I) {
- if (Ctx.isEqOrContainedBy(LookupContext(*(I-1))))
- return I;
- }
-
- return Decls.begin();
- }
-
- /// iterator - Iterate over the decls by walking their parent contexts too.
- class iterator {
- public:
- typedef DeclsTy::iterator BaseIter;
-
- iterator(const BaseIter &DeclIt) : DI(DeclIt) {}
- const BaseIter &getBase() { return DI; }
-
- NamedDecl *&operator*() const {
- return *(DI-1);
- }
-
- bool operator==(const iterator &RHS) const {
- return DI == RHS.DI;
- }
- bool operator!=(const iterator &RHS) const {
- return DI != RHS.DI;
- }
-
- // Preincrement.
- iterator& operator++() {
- NamedDecl *D = **this;
- void *Ptr = D->getIdentifier()->getFETokenInfo<void>();
- assert(!isDeclPtr(Ptr) && "Decl with wrong id ?");
- DI = toIdDeclInfo(Ptr)->FindContext(LookupContext(D), DI-1);
- return *this;
- }
-
- private:
- BaseIter DI;
- };
-
- /// ctx_iterator - Iterator over the decls of a specific context only.
- class ctx_iterator {
- public:
- typedef DeclsTy::iterator BaseIter;
-
- ctx_iterator(const BaseIter &DeclIt) : DI(DeclIt) {}
- const BaseIter &getBase() { return DI; }
-
- NamedDecl *&operator*() const {
- return *(DI-1);
- }
-
- bool operator==(const ctx_iterator &RHS) const {
- return DI == RHS.DI;
- }
- bool operator!=(const ctx_iterator &RHS) const {
- return DI != RHS.DI;
- }
-
- // Preincrement.
- ctx_iterator& operator++() {
- NamedDecl *D = **this;
- void *Ptr = D->getIdentifier()->getFETokenInfo<void>();
- assert(!isDeclPtr(Ptr) && "Decl with wrong id ?");
- IdDeclInfo *Info = toIdDeclInfo(Ptr);
-
- --DI;
- if (DI != Info->Decls.begin() &&
- LookupContext(D) != LookupContext(**this))
- DI = Info->Decls.begin();
- return *this;
- }
-
- private:
- BaseIter DI;
- };
-
- 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) {
- 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 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!");
- }
-
- private:
- DeclsTy Decls;
- };
-
- /// SwizzledIterator - Can be instantiated either with a single NamedDecl*
- /// (the common case where only one decl is associated with an identifier) or
- /// with an 'Iter' iterator, when there are more than one decls to lookup.
- template<typename Iter>
- class SwizzledIterator {
- uintptr_t Ptr;
-
- SwizzledIterator() : Ptr(0) {}
- SwizzledIterator(NamedDecl *D) {
- Ptr = reinterpret_cast<uintptr_t>(D);
- }
- SwizzledIterator(Iter I) {
- Ptr = reinterpret_cast<uintptr_t>(I.getBase()) | 0x1;
- }
-
- bool isIterator() const { return (Ptr & 0x1); }
-
- Iter getIterator() const {
- assert(isIterator() && "Ptr not an iterator.");
- return reinterpret_cast<typename Iter::BaseIter>(Ptr & ~0x1);
- }
-
- friend class IdentifierResolver;
- public:
- NamedDecl *operator*() const {
- if (isIterator())
- return *getIterator();
- else
- return reinterpret_cast<NamedDecl*>(Ptr);
- }
-
- bool operator==(const SwizzledIterator &RHS) const {
- return Ptr == RHS.Ptr;
- }
- bool operator!=(const SwizzledIterator &RHS) const {
- return Ptr != RHS.Ptr;
- }
-
- // Preincrement.
- SwizzledIterator& operator++() {
- if (isIterator()) {
- Iter I = getIterator();
- ++I;
- Ptr = reinterpret_cast<uintptr_t>(I.getBase()) | 0x1;
- }
- else // This is a single NamedDecl*.
- Ptr = 0;
-
- return *this;
- }
- };
-
-public:
-
- typedef SwizzledIterator<IdDeclInfo::iterator> iterator;
- typedef SwizzledIterator<IdDeclInfo::ctx_iterator> ctx_iterator;
-
- /// begin - Returns an iterator for all decls, starting at the given
- /// declaration context.
- static iterator begin(const IdentifierInfo *II, DeclContext *Ctx);
-
- static iterator end(const IdentifierInfo *II) {
- void *Ptr = II->getFETokenInfo<void>();
- if (!Ptr || isDeclPtr(Ptr))
- return iterator();
-
- IdDeclInfo *IDI = toIdDeclInfo(Ptr);
- return iterator(IDI->decls_begin());
- }
-
- /// ctx_begin - Returns an iterator for only decls that belong to the given
- /// declaration context.
- static ctx_iterator ctx_begin(const IdentifierInfo *II, DeclContext *Ctx);
-
- static ctx_iterator ctx_end(const IdentifierInfo *II) {
- void *Ptr = II->getFETokenInfo<void>();
- if (!Ptr || isDeclPtr(Ptr))
- return ctx_iterator();
-
- IdDeclInfo *IDI = toIdDeclInfo(Ptr);
- return ctx_iterator(IDI->decls_begin());
- }
-
- /// 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.
- static bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) {
- if (Ctx->isFunctionOrMethod())
- return S->isDeclScope(D);
-
- return LookupContext(D) == LookupContext(Ctx);
- }
-
- /// 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 'CIT' 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);
-
- IdentifierResolver();
- ~IdentifierResolver();
-
-private:
- 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 19a00275f0f7..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 364b07291006..000000000000
--- a/clang/lib/Sema/ParseAST.cpp
+++ /dev/null
@@ -1,69 +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/ASTContext.h"
-#include "clang/AST/ASTConsumer.h"
-#include "Sema.h"
-#include "clang/Parse/Action.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.getSourceManager(), PP.getTargetInfo(),
- PP.getIdentifierTable(), PP.getSelectorTable());
-
- Parser P(PP, *new Sema(PP, Context, *Consumer));
- PP.EnterMainSourceFile();
-
- // Initialize the parser.
- P.Initialize();
-
- Consumer->Initialize(Context);
-
- 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)
- Consumer->HandleTopLevelDecl(static_cast<Decl*>(ADecl));
- };
-
- if (PrintStats) {
- fprintf(stderr, "\nSTATISTICS:\n");
- P.getActions().PrintStats();
- Context.PrintStats();
- Decl::PrintStats();
- Stmt::PrintStats();
- Consumer->PrintStats();
-
- Decl::CollectingStats(false);
- Stmt::CollectingStats(false);
- }
-
- delete Consumer;
-}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
deleted file mode 100644
index bb5316a126ac..000000000000
--- a/clang/lib/Sema/Sema.cpp
+++ /dev/null
@@ -1,226 +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/Lex/Preprocessor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Parse/Scope.h"
-
-using namespace clang;
-
-bool Sema::isBuiltinObjCType(TypedefDecl *TD) {
- const char *typeName = TD->getIdentifier()->getName();
- return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 ||
- strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0;
-}
-
-bool Sema::isObjCObjectPointerType(QualType type) const {
- if (!type->isPointerType() && !type->isObjCQualifiedIdType())
- return false;
- if (type == Context.getObjCIdType() || type == Context.getObjCClassType() ||
- type->isObjCQualifiedIdType())
- return true;
-
- if (type->isPointerType()) {
- PointerType *pointerType = static_cast<PointerType*>(type.getTypePtr());
- type = pointerType->getPointeeType();
- }
- return (type->isObjCInterfaceType() || type->isObjCQualifiedIdType());
-}
-
-void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
- TUScope = S;
- CurContext = Context.getTranslationUnitDecl();
- if (!PP.getLangOptions().ObjC1) return;
-
- TypedefType *t;
-
- // Add the built-in ObjC types.
- t = cast<TypedefType>(Context.getObjCIdType().getTypePtr());
- PushOnScopeChains(t->getDecl(), TUScope);
- t = cast<TypedefType>(Context.getObjCClassType().getTypePtr());
- PushOnScopeChains(t->getDecl(), TUScope);
- ObjCInterfaceType *it = cast<ObjCInterfaceType>(Context.getObjCProtoType());
- ObjCInterfaceDecl *IDecl = it->getDecl();
- PushOnScopeChains(IDecl, TUScope);
-
- // Synthesize "typedef struct objc_selector *SEL;"
- RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, CurContext,
- SourceLocation(),
- &Context.Idents.get("objc_selector"),
- 0);
- 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);
-}
-
-Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
- : PP(pp), Context(ctxt), Consumer(consumer),
- CurFunctionDecl(0), CurMethodDecl(0), CurContext(0) {
-
- // 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_snprintf] = &IT.get("snprintf");
- KnownFunctionIDs[id_asprintf] = &IT.get("asprintf");
- 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_vprintf] = &IT.get("vprintf");
-
- // FIXME: Move this initialization up to Sema::ActOnTranslationUnitScope()
- // and make sure the decls get inserted into TUScope!
- if (PP.getLangOptions().ObjC1) {
- TranslationUnitDecl *TUDecl = Context.getTranslationUnitDecl();
-
- // Synthesize "typedef struct objc_class *Class;"
- RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct,
- TUDecl,
- SourceLocation(),
- &IT.get("objc_class"), 0);
- QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
- TypedefDecl *ClassTypedef =
- TypedefDecl::Create(Context, TUDecl, SourceLocation(),
- &Context.Idents.get("Class"), ClassT, 0);
- Context.setObjCClassType(ClassTypedef);
-
- // Synthesize "@class Protocol;
- ObjCInterfaceDecl *ProtocolDecl =
- ObjCInterfaceDecl::Create(Context, SourceLocation(), 0,
- &Context.Idents.get("Protocol"),
- SourceLocation(), true);
- Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
-
- // Synthesize "typedef struct objc_object { Class isa; } *id;"
- RecordDecl *ObjectTag =
- RecordDecl::Create(Context, Decl::Struct, TUDecl,
- SourceLocation(),
- &IT.get("objc_object"), 0);
- FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), 0,
- Context.getObjCClassType());
- ObjectTag->defineBody(&IsaDecl, 1);
- QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
- TypedefDecl *IdTypedef = TypedefDecl::Create(Context, TUDecl,
- SourceLocation(),
- &Context.Idents.get("id"),
- ObjT, 0);
- Context.setObjCIdType(IdTypedef);
- }
- TUScope = 0;
-}
-
-/// 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 Type) {
- if (Expr->getType().getCanonicalType() == Type.getCanonicalType()) return;
-
- if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr))
- ImpCast->setType(Type);
- else
- Expr = new ImplicitCastExpr(Type, Expr);
-}
-
-
-
-void Sema::DeleteExpr(ExprTy *E) {
- delete static_cast<Expr*>(E);
-}
-void Sema::DeleteStmt(StmtTy *S) {
- delete static_cast<Stmt*>(S);
-}
-
-//===----------------------------------------------------------------------===//
-// 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, 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,
- 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, 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,
- 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,
- SourceRange R1, 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,
- SourceRange R1, 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, SourceRange R1, 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();
-}
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
deleted file mode 100644
index e5aab61bb22a..000000000000
--- a/clang/lib/Sema/Sema.h
+++ /dev/null
@@ -1,930 +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 "clang/Parse/Action.h"
-#include "clang/Parse/DeclSpec.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include <vector>
-#include <string>
-
-namespace llvm {
- class APSInt;
-}
-
-namespace clang {
- class ASTContext;
- class ASTConsumer;
- class Preprocessor;
- class Decl;
- class DeclContext;
- 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;
-
-/// Sema - This implements semantic analysis and AST building for C.
-class Sema : public Action {
- Preprocessor &PP;
- ASTContext &Context;
- ASTConsumer &Consumer;
-
- /// CurFunctionDecl - If inside of a function body, this contains a pointer to
- /// the function decl for the function being parsed.
- FunctionDecl *CurFunctionDecl;
-
- /// CurMethodDecl - If inside of a method body, this contains a pointer to
- /// the method decl for the method being parsed.
- ObjCMethodDecl *CurMethodDecl;
-
- DeclContext *CurContext;
-
- /// 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 of the classes with
- /// @implementation's, so that we can emit errors on duplicates.
- llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
-
- /// 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;
-
- IdentifierResolver IdResolver;
-
- // Enum values used by KnownFunctionIDs (see below).
- enum {
- id_printf,
- id_fprintf,
- id_sprintf,
- id_snprintf,
- id_asprintf,
- id_vsnprintf,
- id_vasprintf,
- id_vfprintf,
- id_vsprintf,
- 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 ];
-
- /// 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, SourceRange R1);
- bool Diag(SourceLocation Loc, unsigned DiagID,
- SourceRange R1, SourceRange R2);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- SourceRange R1);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
- SourceRange R1, SourceRange R2);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, SourceRange R1);
- bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
- const std::string &Msg2, const std::string &Msg3, SourceRange R1);
- bool Diag(SourceLocation Loc, unsigned DiagID,
- const std::string &Msg1, const std::string &Msg2,
- SourceRange R1, SourceRange R2);
-
- virtual void DeleteExpr(ExprTy *E);
- virtual void DeleteStmt(StmtTy *S);
-
- //===--------------------------------------------------------------------===//
- // Type Analysis / Processing: SemaType.cpp.
- //
- QualType ConvertDeclSpecToType(DeclSpec &DS);
- AttributeList *ProcessTypeAttributes(QualType &Result, 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 DeclTy *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 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);
- 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);
- 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:
- /// Set the current declaration context until it gets popped.
- void PushDeclContext(DeclContext *DC);
- void PopDeclContext();
-
- /// Add this decl to the scope shadowed decl chains.
- void PushOnScopeChains(NamedDecl *D, Scope *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);
-
- /// Helpers for dealing with function parameters
- bool CheckParmsForFunctionDef(FunctionDecl *FD);
- ParmVarDecl *CreateImplicitParameter(Scope *S, IdentifierInfo *Id,
- SourceLocation IdLoc, QualType Type);
- 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 HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
- AttributeList *declarator_postfix);
- void HandleDeclAttribute(Decl *New, AttributeList *rawAttr);
-
- /// HandleAddressSpaceTypeAttribute - this attribute is only applicable to
- /// objects without automatic storage duration.
- /// The raw attribute contains 1 argument, the id of the address space
- /// for the type.
- QualType HandleAddressSpaceTypeAttribute(QualType curType,
- AttributeList *rawAttr);
-
- // HandleVectorTypeAttribute - 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.
- QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
- void HandleExtVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr);
-
- void HandleAlignedAttribute(Decl *d, AttributeList *rawAttr);
- void HandlePackedAttribute(Decl *d, AttributeList *rawAttr);
- void HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr);
- void HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr);
- void HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr);
- void HandleWeakAttribute(Decl *d, AttributeList *rawAttr);
- void HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr);
- void HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr);
- void HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr);
- void HandleNothrowAttribute(Decl *d, AttributeList *rawAttr);
- void HandleFormatAttribute(Decl *d, AttributeList *rawAttr);
- void HandleStdCallAttribute(Decl *d, AttributeList *rawAttr);
- void HandleFastCallAttribute(Decl *d, AttributeList *rawAttr);
- void HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr);
-
- void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
- bool &IncompleteImpl);
-
- /// CheckProtocolMethodDefs - This routine checks unimpletented methods
- /// Declared in protocol, and those referenced by it.
- void CheckProtocolMethodDefs(SourceLocation ImpLoc,
- ObjCProtocolDecl *PDecl,
- bool& IncompleteImpl,
- const llvm::DenseSet<Selector> &InsMap,
- const llvm::DenseSet<Selector> &ClsMap);
-
- /// 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);
-
- /// isBuiltinObjCType - Returns true of the type is "id", "SEL", "Class"
- /// or "Protocol".
- bool isBuiltinObjCType(TypedefDecl *TD);
-
- /// isObjCObjectPointerType - Returns true if type is an objective-c pointer
- /// to an object type; such as "id", "Class", Intf*, id<P>, etc.
- bool isObjCObjectPointerType(QualType type) const;
-
- /// 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);
-
- /// 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);
-
- 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);
-
- // Act on C++ namespaces
- virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
- IdentifierInfo *Ident,
- SourceLocation LBrace);
- virtual void ActOnFinishNamespaceDef(DeclTy *Dcl, SourceLocation RBrace);
-
- /// 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);
-
- /// ActOnCXXBoolLiteral - Parse {true,false} literals.
- virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
- tok::TokenKind Kind);
-
- //// ActOnCXXThrow - Parse throw expressions.
- virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
- ExprTy *expr);
-
- // 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,
- DeclTy *basetype, SourceLocation BaseLoc);
-
-
- // Objective-C declarations.
- virtual DeclTy *ActOnStartClassInterface(
- SourceLocation AtInterafceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperName, SourceLocation SuperLoc,
- IdentifierInfo **ProtocolNames, unsigned NumProtocols,
- 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,
- IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
- SourceLocation EndProtoLoc);
-
- virtual DeclTy *ActOnStartCategoryInterface(
- SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
- IdentifierInfo **ProtoRefNames, 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,
- IdentifierInfo **IdentList,
- unsigned NumElts);
-
- virtual void FindProtocolDeclaration(SourceLocation TypeLoc,
- IdentifierInfo **ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVector<DeclTy *, 8> &
- Protocols);
-
- 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);
-
- // 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,
-
- /// 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);
-
- /// 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 CheckVectorOperands(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 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 loc,
- 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 CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
- QualType ElementType);
- bool CheckInitializerListTypes(InitListExpr*& IList, QualType &DeclType,
- bool topLevel, unsigned& startIndex);
- bool CheckForConstantInitializer(Expr *e, QualType t);
-
- StringLiteral *IsStringLiteralInit(Expr *Init, QualType DeclType);
- bool CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT);
-
- // 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);
-
- // returns true if there were any incompatible arguments.
- bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
- ObjCMethodDecl *Method);
-
- /// 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();
-
- //===--------------------------------------------------------------------===//
- // Extra semantic analysis beyond the C type system
-private:
- bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
- bool CheckBuiltinCFStringArgument(Expr* Arg);
- bool SemaBuiltinVAStart(CallExpr *TheCall);
- bool SemaBuiltinUnorderedCompare(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 CheckElementTypes(InitListExpr *IList, QualType &DeclType,
- 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, bool topLevel = false);
- 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; }
-};
-
-
-} // end namespace clang
-
-#endif
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
deleted file mode 100644
index 6d3eea5e730b..000000000000
--- a/clang/lib/Sema/SemaChecking.cpp
+++ /dev/null
@@ -1,802 +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/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/LiteralSupport.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.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.
-bool
-Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
-
- // 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");
- return CheckBuiltinCFStringArgument(TheCall->getArg(0));
- case Builtin::BI__builtin_va_start:
- return SemaBuiltinVAStart(TheCall);
-
- 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:
- return SemaBuiltinUnorderedCompare(TheCall);
- }
-
- // 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 false;
-
- // 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_printf: format_idx = 0; break;
- case id_fprintf: format_idx = 1; break;
- case id_sprintf: format_idx = 1; break;
- case id_snprintf: format_idx = 2; break;
- case id_asprintf: format_idx = 1; break;
- case id_vsnprintf: format_idx = 2; HasVAListArg = true; break;
- case id_vasprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vfprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vsprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vprintf: format_idx = 0; HasVAListArg = true; break;
- }
-
- CheckPrintfArguments(TheCall, HasVAListArg, format_idx);
- }
-
- return false;
-}
-
-/// 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 (CurFunctionDecl)
- isVariadic =
- cast<FunctionTypeProto>(CurFunctionDecl->getType())->isVariadic();
- else
- isVariadic = CurMethodDecl->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 (CurFunctionDecl)
- LastArg = *(CurFunctionDecl->param_end()-1);
- else
- LastArg = *(CurMethodDecl->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;
-}
-
-
-/// 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.
- StringLiteral *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, Fn->getSourceRange());
- return;
- }
-
- // CHECK: is the format string a wide literal?
- if (FExpr->isWide()) {
- Diag(FExpr->getLocStart(),
- diag::warn_printf_format_string_is_wide_literal, Fn->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,
- Fn->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,
- Fn->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,
- Fn->getSourceRange());
- else
- Diag(Loc, diag::warn_printf_asterisk_width_missing_arg,
- Fn->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, Fn->getSourceRange());
- 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),
- Fn->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)),
- Fn->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,
- Fn->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, Fn->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()) {
- if (DeclRefExpr *DR = EvalAddr(RetValExp))
- Diag(DR->getLocStart(), diag::warn_ret_stack_addr,
- DR->getDecl()->getIdentifier()->getName(),
- RetValExp->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()->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 implicit casts, we need to handle conversions from arrays to
- // pointer values, and implicit pointer-to-pointer conversions.
- case Stmt::ImplicitCastExprClass: {
- ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E);
- Expr* SubExpr = IE->getSubExpr();
-
- if (SubExpr->getType()->isPointerType() ||
- SubExpr->getType()->isObjCQualifiedIdType())
- return EvalAddr(SubExpr);
- else
- return EvalVal(SubExpr);
- }
-
- // For casts, we handle pointer-to-pointer conversions (which
- // is essentially a no-op from our mini-interpreter's standpoint).
- // For other casts we abort.
- case Stmt::CastExprClass: {
- CastExpr *C = cast<CastExpr>(E);
- Expr *SubExpr = C->getSubExpr();
-
- if (SubExpr->getType()->isPointerType())
- return EvalAddr(SubExpr);
- else
- return NULL;
- }
-
- // 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())
- 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 933a36181200..000000000000
--- a/clang/lib/Sema/SemaDecl.cpp
+++ /dev/null
@@ -1,2624 +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/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Builtins.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Basic/LangOptions.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/SmallString.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/DenseSet.h"
-using namespace clang;
-
-Sema::DeclTy *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;
-}
-
-void Sema::PushDeclContext(DeclContext *DC) {
- assert( ( (isa<ObjCMethodDecl>(DC) && isa<TranslationUnitDecl>(CurContext))
- || DC->getParent() == CurContext ) &&
- "The next DeclContext should be directly contained in the current one.");
- CurContext = DC;
-}
-
-void Sema::PopDeclContext() {
- assert(CurContext && "DeclContext imbalance!");
- // If CurContext is a ObjC method, getParent() will return NULL.
- CurContext = isa<ObjCMethodDecl>(CurContext)
- ? Context.getTranslationUnitDecl()
- : CurContext->getParent();
-}
-
-/// 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::ctx_iterator
- CIT = IdResolver.ctx_begin(TD->getIdentifier(), TD->getDeclContext());
- if (CIT != IdResolver.ctx_end(TD->getIdentifier()) &&
- IdResolver.isDeclInScope(*CIT, 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, *CIT);
- 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!");
-
- // We only want to remove the decls from the identifier decl chains for local
- // scopes, when inside a function/method.
- if (S->getFnParent() == 0)
- return;
-
- 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??");
- ScopedDecl *D = dyn_cast<ScopedDecl>(TmpD);
- assert(D && "This decl isn't a ScopedDecl?");
-
- IdentifierInfo *II = D->getIdentifier();
- if (!II) continue;
-
- // Unlink this decl from the identifier.
- IdResolver.RemoveDecl(D);
-
- // This will have to be revisited for C++: there we want to nest stuff in
- // namespace decls etc. Even for C, we might want a top-level translation
- // unit decl or something.
- if (!CurFunctionDecl)
- continue;
-
- // Chain this decl to the containing function, it now owns the memory for
- // the decl.
- D->setNext(CurFunctionDecl->getDeclChain());
- CurFunctionDecl->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(II); 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 (BID == Builtin::BI__builtin_va_start ||
- BID == Builtin::BI__builtin_va_copy ||
- BID == Builtin::BI__builtin_va_end)
- 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) {
- // 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;
- }
-
- // Allow multiple definitions for ObjC built-in typedefs.
- // FIXME: Verify the underlying types are equivalent!
- if (getLangOptions().ObjC1 && isBuiltinObjCType(New))
- return Old;
-
- // 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).
- SourceManager &SrcMgr = Context.getSourceManager();
- const FileEntry *OldDeclFile = SrcMgr.getFileEntryForLoc(Old->getLocation());
- const FileEntry *NewDeclFile = SrcMgr.getFileEntryForLoc(New->getLocation());
- HeaderSearch &HdrInfo = PP.getHeaderSearchInfo();
- DirectoryLookup::DirType OldDirType = HdrInfo.getFileDirFlavor(OldDeclFile);
- DirectoryLookup::DirType NewDirType = HdrInfo.getFileDirFlavor(NewDeclFile);
-
- // Allow reclarations in both SystemHeaderDir and ExternCSystemHeaderDir.
- if ((OldDirType != DirectoryLookup::NormalHeaderDir ||
- NewDirType != DirectoryLookup::NormalHeaderDir) ||
- getLangOptions().Microsoft)
- return New;
-
- // 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_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;
-
-// FIXME: fix this code to cleanup the Old attrs correctly
- while (attr) {
- tmp = attr;
- attr = attr->getNext();
-
- if (!DeclHasAttr(New, tmp)) {
- New->addAttr(tmp);
- } else {
- tmp->setNext(0);
- delete(tmp);
- }
- }
-}
-
-/// 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.functionTypesAreCompatible(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;
-}
-
-/// equivalentArrayTypes - Used to determine whether two array types are
-/// equivalent.
-/// We need to check this explicitly as an incomplete array definition is
-/// considered a VariableArrayType, so will not match a complete array
-/// definition that would be otherwise equivalent.
-static bool areEquivalentArrayTypes(QualType NewQType, QualType OldQType) {
- const ArrayType *NewAT = NewQType->getAsArrayType();
- const ArrayType *OldAT = OldQType->getAsArrayType();
-
- if (!NewAT || !OldAT)
- return false;
-
- // If either (or both) array types in incomplete we need to strip off the
- // outer VariableArrayType. Once the outer VAT is removed the remaining
- // types must be identical if the array types are to be considered
- // equivalent.
- // eg. int[][1] and int[1][1] become
- // VAT(null, CAT(1, int)) and CAT(1, CAT(1, int))
- // removing the outermost VAT gives
- // CAT(1, int) and CAT(1, int)
- // which are equal, therefore the array types are equivalent.
- if (NewAT->isIncompleteArrayType() || OldAT->isIncompleteArrayType()) {
- if (NewAT->getIndexTypeQualifier() != OldAT->getIndexTypeQualifier())
- return false;
- NewQType = NewAT->getElementType().getCanonicalType();
- OldQType = OldAT->getElementType().getCanonicalType();
- }
-
- return NewQType == OldQType;
-}
-
-/// 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.
-///
-/// FIXME: Need to carefully consider tentative definition rules (C99 6.9.2p2).
-/// For example, we incorrectly complain about i1, i4 from C99 6.9.2p4.
-///
-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 && !areEquivalentArrayTypes(NewCType, OldCType)) {
- 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;
- }
- // We've verified the types match, now handle "tentative" definitions.
- if (Old->isFileVarDecl() && New->isFileVarDecl()) {
- // Handle C "tentative" external object definitions (C99 6.9.2).
- bool OldIsTentative = false;
- bool NewIsTentative = false;
-
- if (!Old->getInit() &&
- (Old->getStorageClass() == VarDecl::None ||
- Old->getStorageClass() == VarDecl::Static))
- OldIsTentative = true;
-
- // FIXME: this check doesn't work (since the initializer hasn't been
- // attached yet). This check should be moved to FinalizeDeclaratorGroup.
- // Unfortunately, by the time we get to FinializeDeclaratorGroup, we've
- // thrown out the old decl.
- if (!New->getInit() &&
- (New->getStorageClass() == VarDecl::None ||
- New->getStorageClass() == VarDecl::Static))
- ; // change to NewIsTentative = true; once the code is moved.
-
- if (NewIsTentative || OldIsTentative)
- return New;
- }
- if (Old->getStorageClass() != VarDecl::Extern &&
- New->getStorageClass() != VarDecl::Extern) {
- 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;
-}
-
-/// CreateImplicitParameter - Creates an implicit function parameter
-/// in the scope S and with the given type. This routine is used, for
-/// example, to create the implicit "self" parameter in an Objective-C
-/// method.
-ParmVarDecl *
-Sema::CreateImplicitParameter(Scope *S, IdentifierInfo *Id,
- SourceLocation IdLoc, QualType Type) {
- ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, IdLoc, Id, Type,
- VarDecl::None, 0, 0);
- if (Id)
- PushOnScopeChains(New, S);
-
- return New;
-}
-
-/// 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::CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
- QualType ElementType) {
- Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
- if (CheckSingleInitializer(expr, ElementType))
- return true; // types weren't compatible.
-
- if (savExpr != expr) // The type was promoted, update initializer list.
- IList->setInit(slot, expr);
- return false;
-}
-
-bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) {
- if (const IncompleteArrayType *IAT = DeclT->getAsIncompleteArrayType()) {
- // 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 if (const ConstantArrayType *CAT = DeclT->getAsConstantArrayType()) {
- // C99 6.7.8p14. We have an array of character type with known size.
- if (strLiteral->getByteLength() > (unsigned)CAT->getMaximumElements())
- Diag(strLiteral->getSourceRange().getBegin(),
- diag::warn_initializer_string_for_char_array_too_long,
- strLiteral->getSourceRange());
- } else {
- assert(0 && "HandleStringLiteralInit(): Invalid array type");
- }
- // 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 = DeclType->getAsArrayType();
- if (AT && AT->getElementType()->isCharType()) {
- return dyn_cast<StringLiteral>(Init);
- }
- return 0;
-}
-
-// CheckInitializerListTypes - Checks the types of elements of an initializer
-// list. This function is recursive: it calls itself to initialize subelements
-// of aggregate types. Note that the topLevel parameter essentially refers to
-// whether this expression "owns" the initializer list passed in, or if this
-// initialization is taking elements out of a parent initializer. Each
-// call to this function adds zero or more to startIndex, reports any errors,
-// and returns true if it found any inconsistent types.
-bool Sema::CheckInitializerListTypes(InitListExpr*& IList, QualType &DeclType,
- bool topLevel, unsigned& startIndex) {
- bool hadError = false;
-
- if (DeclType->isScalarType()) {
- // The simplest case: initializing a single scalar
- if (topLevel) {
- Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
- IList->getSourceRange());
- }
- if (startIndex < IList->getNumInits()) {
- Expr* expr = IList->getInit(startIndex);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- // FIXME: Should an error be reported here instead?
- unsigned newIndex = 0;
- CheckInitializerListTypes(SubInitList, DeclType, true, newIndex);
- } else {
- hadError |= CheckInitExpr(expr, IList, startIndex, DeclType);
- }
- ++startIndex;
- }
- // FIXME: Should an error be reported for empty initializer list + scalar?
- } else if (DeclType->isVectorType()) {
- if (startIndex < 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 (startIndex >= IList->getNumInits())
- break;
- Expr* expr = IList->getInit(startIndex);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- hadError |= CheckInitializerListTypes(SubInitList, elementType,
- true, newIndex);
- ++startIndex;
- } else {
- hadError |= CheckInitializerListTypes(IList, elementType,
- false, startIndex);
- }
- }
- }
- } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
- if (DeclType->isStructureType() || DeclType->isUnionType()) {
- if (startIndex < IList->getNumInits() && !topLevel &&
- Context.typesAreCompatible(IList->getInit(startIndex)->getType(),
- DeclType)) {
- // We found a compatible struct; per the standard, this initializes the
- // struct. (The C standard technically says that this only applies for
- // initializers for declarations with automatic scope; however, this
- // construct is unambiguous anyway because a struct cannot contain
- // a type compatible with itself. We'll output an error when we check
- // if the initializer is constant.)
- // FIXME: Is a call to CheckSingleInitializer required here?
- ++startIndex;
- } else {
- 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())
- return true;
-
- // 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 = structDecl->getNumMembers() -
- structDecl->hasFlexibleArrayMember();
- for (int i = 0; i < numMembers; i++) {
- // Don't attempt to go past the end of the init list
- if (startIndex >= IList->getNumInits())
- break;
- FieldDecl * curField = structDecl->getMember(i);
- if (!curField->getIdentifier()) {
- // Don't initialize unnamed fields, e.g. "int : 20;"
- continue;
- }
- QualType fieldType = curField->getType();
- Expr* expr = IList->getInit(startIndex);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newStart = 0;
- hadError |= CheckInitializerListTypes(SubInitList, fieldType,
- true, newStart);
- ++startIndex;
- } else {
- hadError |= CheckInitializerListTypes(IList, fieldType,
- false, startIndex);
- }
- 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!)
- }
- } else if (DeclType->isArrayType()) {
- // Check for the special-case of initializing an array with a string.
- if (startIndex < IList->getNumInits()) {
- if (StringLiteral *lit = IsStringLiteralInit(IList->getInit(startIndex),
- DeclType)) {
- CheckStringLiteralInit(lit, DeclType);
- ++startIndex;
- if (topLevel && startIndex < IList->getNumInits()) {
- // We have leftover initializers; warn
- Diag(IList->getInit(startIndex)->getLocStart(),
- diag::err_excess_initializers_in_char_array_initializer,
- IList->getInit(startIndex)->getSourceRange());
- }
- return false;
- }
- }
- int maxElements;
- if (DeclType->isIncompleteArrayType()) {
- // FIXME: use a proper constant
- maxElements = 0x7FFFFFFF;
- } else if (const VariableArrayType *VAT =
- DeclType->getAsVariableArrayType()) {
- // 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).
- Diag(VAT->getSizeExpr()->getLocStart(),
- diag::err_variable_object_no_init,
- VAT->getSizeExpr()->getSourceRange());
- hadError = true;
- maxElements = 0x7FFFFFFF;
- } else {
- const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
- maxElements = static_cast<int>(CAT->getSize().getZExtValue());
- }
- QualType elementType = DeclType->getAsArrayType()->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 (startIndex >= IList->getNumInits())
- break;
- Expr* expr = IList->getInit(startIndex);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- hadError |= CheckInitializerListTypes(SubInitList, elementType,
- true, newIndex);
- ++startIndex;
- } else {
- hadError |= CheckInitializerListTypes(IList, elementType,
- false, startIndex);
- }
- }
- 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
- // (It could in theory be allowed, but it doesn't really matter.)
- Diag(IList->getLocStart(),
- diag::err_at_least_one_initializer_needed_to_size_array);
- hadError = true;
- } else {
- llvm::APSInt ConstVal(32);
- ConstVal = numElements;
- DeclType = Context.getConstantArrayType(elementType, ConstVal,
- ArrayType::Normal, 0);
- }
- }
- } else {
- assert(0 && "Aggregate that isn't a function or array?!");
- }
- } 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");
- }
-
- // If this init list is a base list, we set the type; an initializer doesn't
- // fundamentally have a type, but this makes the ASTs a bit easier to read
- if (topLevel)
- IList->setType(DeclType);
-
- if (topLevel && startIndex < IList->getNumInits()) {
- // We have leftover initializers; warn
- Diag(IList->getInit(startIndex)->getLocStart(),
- diag::warn_excess_initializers,
- IList->getInit(startIndex)->getSourceRange());
- }
- return hadError;
-}
-
-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 = DeclType->getAsVariableArrayType())
- 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);
-
- if (DeclType->isArrayType())
- return Diag(Init->getLocStart(),
- diag::err_array_init_list_required,
- Init->getSourceRange());
-
- return CheckSingleInitializer(Init, DeclType);
- }
-#if 1
- unsigned newIndex = 0;
- return CheckInitializerListTypes(InitList, DeclType, true, newIndex);
-#else
- InitListChecker CheckInitList(this, InitList, DeclType);
- return CheckInitList.HadError();
-#endif
-}
-
-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
- HandleDeclAttributes(NewTD, D.getDeclSpec().getAttributes(),
- D.getAttributes());
- // 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 && IdResolver.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 = FunctionDecl::Create(Context, CurContext,
- D.getIdentifierLoc(),
- II, R, SC, isInline,
- LastDeclarator);
- // Handle attributes.
- HandleDeclAttributes(NewFD, D.getDeclSpec().getAttributes(),
- D.getAttributes());
-
- // Copy the parameter declarations from the declarator D to
- // the function declaration NewFD, if they are available.
- if (D.getNumTypeObjects() > 0 &&
- D.getTypeObject(0).Fun.hasPrototype) {
- 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.
- if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
- FTI.ArgInfo[0].Param &&
- !((ParmVarDecl*)FTI.ArgInfo[0].Param)->getType().getCVRQualifiers() &&
- ((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() != Context.VoidTy) {
- Diag(Param->getLocation(), diag::ext_param_typedef_of_void);
- }
-
- } else {
- 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 ||
- IdResolver.isDeclInScope(PrevDecl, CurContext, S)) ) {
- bool Redeclaration = false;
- NewFD = MergeFunctionDecl(NewFD, PrevDecl, Redeclaration);
- if (NewFD == 0) return 0;
- if (Redeclaration) {
- // Note that the new declaration is a redeclaration of the
- // older declaration. Then return the older declaration: the
- // new one is only kept within the set of previous
- // declarations for this function.
- FunctionDecl *OldFD = (FunctionDecl *)PrevDecl;
- OldFD->AddRedeclaration(NewFD);
- return OldFD;
- }
- }
- 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 (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);
- } else {
- NewVD = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
- II, R, SC, LastDeclarator);
- }
- // Handle attributes prior to checking for duplicates in MergeVarDecl
- HandleDeclAttributes(NewVD, D.getDeclSpec().getAttributes(),
- D.getAttributes());
-
- // 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 && IdResolver.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::CheckForConstantInitializer(Expr *Init, QualType DclT) {
- SourceLocation loc;
- // FIXME: Remove the isReference check and handle assignment to a reference.
- if (!DclT->isReferenceType() && !Init->isConstantExpr(Context, &loc)) {
- assert(loc.isValid() && "isConstantExpr didn't return a loc!");
- Diag(loc, diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
- return false;
-}
-
-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();
- 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();
-
- // 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->getAsVariableArrayType()) {
- 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 (IDecl && !IDecl->getInit() &&
- (IDecl->getStorageClass() == VarDecl::Static ||
- IDecl->getStorageClass() == VarDecl::None)) {
- 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();
- }
- }
- }
- return NewGroup;
-}
-
-/// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
-/// to introduce parameters into function prototype scope.
-Sema::DeclTy *
-Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
- DeclSpec &DS = D.getDeclSpec();
-
- // Verify C99 6.7.5.3p2: The only SCS allowed is '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();
- }
-
- // 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, VarDecl::None,
- 0, 0);
-
- if (D.getInvalidType())
- New->setInvalidDecl();
-
- if (II)
- PushOnScopeChains(New, S);
-
- HandleDeclAttributes(New, D.getDeclSpec().getAttributes(),
- D.getAttributes());
- return New;
-
-}
-
-Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
- assert(CurFunctionDecl == 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);
- }
- }
-
- // Since this is a function definition, act as though we have information
- // about the arguments.
- if (FTI.NumArgs)
- FTI.hasPrototype = true;
- } 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 && IdResolver.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);
- }
- }
- }
- Decl *decl = static_cast<Decl*>(ActOnDeclarator(GlobalScope, D, 0));
- FunctionDecl *FD = cast<FunctionDecl>(decl);
- CurFunctionDecl = FD;
- 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<FunctionDecl>(dcl)) {
- FD->setBody((Stmt*)Body);
- assert(FD == CurFunctionDecl && "Function parsing confused");
- CurFunctionDecl = 0;
- } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(dcl)) {
- MD->setBody((Stmt*)Body);
- CurMethodDecl = 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!");
-
- Decl::Kind Kind;
- switch (TagType) {
- default: assert(0 && "Unknown tag type!");
- case DeclSpec::TST_struct: Kind = Decl::Struct; break;
- case DeclSpec::TST_union: Kind = Decl::Union; break;
- case DeclSpec::TST_class: Kind = Decl::Class; break;
- case DeclSpec::TST_enum: Kind = Decl::Enum; break;
- }
-
- // 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.
- if (ScopedDecl *PrevDecl =
- dyn_cast_or_null<ScopedDecl>(LookupDecl(Name, Decl::IDNS_Tag, S))) {
-
- 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 ||
- IdResolver.isDeclInScope(PrevDecl, CurContext, S)) {
- // Make sure that this wasn't declared as an enum and now used as a struct
- // or something similar.
- if (PrevDecl->getKind() != Kind) {
- Diag(KWLoc, diag::err_use_with_wrong_tag, Name->getName());
- Diag(PrevDecl->getLocation(), diag::err_previous_use);
- }
-
- // 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 {
- // 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;
- switch (Kind) {
- default: assert(0 && "Unknown tag kind!");
- case Decl::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);
- break;
- case Decl::Union:
- case Decl::Struct:
- case Decl::Class:
- // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
- // struct X { int A; } D; D should chain to X.
- New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name, 0);
- break;
- }
-
- // 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);
- }
-
- HandleDeclAttributes(New, Attr, 0);
- return New;
-}
-
-/// 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()) {
- // FIXME: This diagnostic needs work
- Diag(Loc, diag::err_typecheck_illegal_vla, Loc);
- InvalidDecl = true;
- }
- // FIXME: Chain fielddecls together.
- FieldDecl *NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
-
- HandleDeclAttributes(NewFD, D.getDeclSpec().getAttributes(),
- D.getAttributes());
-
- 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;
- }
-
- ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context, Loc, II, T);
-
- HandleDeclAttributes(NewID, D.getDeclSpec().getAttributes(),
- D.getAttributes());
-
- if (D.getInvalidType() || InvalidDecl)
- NewID->setInvalidDecl();
- // If we have visibility info, make sure the AST is set accordingly.
- if (Visibility != tok::objc_not_keyword)
- NewID->setAccessControl(TranslateIvarVisibility(Visibility));
- return NewID;
-}
-
-void Sema::ActOnFields(Scope* S,
- SourceLocation RecLoc, DeclTy *RecDecl,
- DeclTy **Fields, unsigned NumFields,
- SourceLocation LBrac, SourceLocation RBrac) {
- Decl *EnclosingDecl = static_cast<Decl*>(RecDecl);
- assert(EnclosingDecl && "missing record or interface decl");
- RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
-
- if (Record && Record->isDefinition()) {
- // Diagnose code like:
- // struct S { struct S {} X; };
- // We discover this when we complete the outer S. Reject and ignore the
- // outer S.
- Diag(Record->getLocation(), diag::err_nested_redefinition,
- Record->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->getKind() != Decl::Struct || // ... 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->getKind() == Decl::Union) {
- 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(&RecFields[0], RecFields.size());
- 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);
- }
- }
-}
-
-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)) {
- if (IdResolver.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;
-}
-
-void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX,
- DeclTy **Elements, unsigned NumElements) {
- EnumDecl *Enum = cast<EnumDecl>(static_cast<Decl*>(EnumDeclX));
- assert(!Enum->isDefinition() && "Enum redefinitions can't reach here");
-
- // 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());
- }
-
- // 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);
-}
-
-void Sema::HandleDeclAttribute(Decl *New, AttributeList *Attr) {
-
- switch (Attr->getKind()) {
- case AttributeList::AT_vector_size:
- if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
- QualType newType = HandleVectorTypeAttribute(vDecl->getType(), Attr);
- if (!newType.isNull()) // install the new vector type into the decl
- vDecl->setType(newType);
- }
- if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
- QualType newType = HandleVectorTypeAttribute(tDecl->getUnderlyingType(),
- Attr);
- if (!newType.isNull()) // install the new vector type into the decl
- tDecl->setUnderlyingType(newType);
- }
- break;
- case AttributeList::AT_ext_vector_type:
- if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New))
- HandleExtVectorTypeAttribute(tDecl, Attr);
- else
- Diag(Attr->getLoc(),
- diag::err_typecheck_ext_vector_not_typedef);
- break;
- case AttributeList::AT_address_space:
- if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
- QualType newType = HandleAddressSpaceTypeAttribute(
- tDecl->getUnderlyingType(),
- Attr);
- tDecl->setUnderlyingType(newType);
- } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
- QualType newType = HandleAddressSpaceTypeAttribute(vDecl->getType(),
- Attr);
- // install the new addr spaced type into the decl
- vDecl->setType(newType);
- }
- break;
- case AttributeList::AT_deprecated:
- HandleDeprecatedAttribute(New, Attr);
- break;
- case AttributeList::AT_visibility:
- HandleVisibilityAttribute(New, Attr);
- break;
- case AttributeList::AT_weak:
- HandleWeakAttribute(New, Attr);
- break;
- case AttributeList::AT_dllimport:
- HandleDLLImportAttribute(New, Attr);
- break;
- case AttributeList::AT_dllexport:
- HandleDLLExportAttribute(New, Attr);
- break;
- case AttributeList::AT_nothrow:
- HandleNothrowAttribute(New, Attr);
- break;
- case AttributeList::AT_stdcall:
- HandleStdCallAttribute(New, Attr);
- break;
- case AttributeList::AT_fastcall:
- HandleFastCallAttribute(New, Attr);
- break;
- case AttributeList::AT_aligned:
- HandleAlignedAttribute(New, Attr);
- break;
- case AttributeList::AT_packed:
- HandlePackedAttribute(New, Attr);
- break;
- case AttributeList::AT_annotate:
- HandleAnnotateAttribute(New, Attr);
- break;
- case AttributeList::AT_noreturn:
- HandleNoReturnAttribute(New, Attr);
- break;
- case AttributeList::AT_format:
- HandleFormatAttribute(New, Attr);
- break;
- case AttributeList::AT_transparent_union:
- HandleTransparentUnionAttribute(New, Attr);
- break;
- default:
-#if 0
- // TODO: when we have the full set of attributes, warn about unknown ones.
- Diag(Attr->getLoc(), diag::warn_attribute_ignored,
- Attr->getName()->getName());
-#endif
- break;
- }
-}
-
-void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
- AttributeList *declarator_postfix) {
- while (declspec_prefix) {
- HandleDeclAttribute(New, declspec_prefix);
- declspec_prefix = declspec_prefix->getNext();
- }
- while (declarator_postfix) {
- HandleDeclAttribute(New, declarator_postfix);
- declarator_postfix = declarator_postfix->getNext();
- }
-}
-
-void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl,
- AttributeList *rawAttr) {
- QualType curType = tDecl->getUnderlyingType();
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 1) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
- llvm::APSInt vecSize(32);
- if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
- Diag(rawAttr->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.).
- Type *canonType = curType.getCanonicalType().getTypePtr();
- if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
- Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
- curType.getCanonicalType().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) {
- Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
- sizeExpr->getSourceRange());
- return;
- }
- // Instantiate/Install the vector type, the number of elements is > 0.
- tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize));
- // Remember this typedef decl, we will need it later for diagnostics.
- ExtVectorDecls.push_back(tDecl);
-}
-
-QualType Sema::HandleVectorTypeAttribute(QualType curType,
- AttributeList *rawAttr) {
- // check the attribute arugments.
- if (rawAttr->getNumArgs() != 1) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return QualType();
- }
- Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
- llvm::APSInt vecSize(32);
- if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
- Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
- "vector_size", sizeExpr->getSourceRange());
- return QualType();
- }
- // navigate to the base type - we need to provide for vector pointers,
- // vector arrays, and functions returning vectors.
- Type *canonType = curType.getCanonicalType().getTypePtr();
-
- if (canonType->isPointerType() || canonType->isArrayType() ||
- canonType->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 (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
- Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
- curType.getCanonicalType().getAsString());
- return QualType();
- }
- unsigned typeSize = static_cast<unsigned>(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) {
- Diag(rawAttr->getLoc(), diag::err_attribute_invalid_size,
- sizeExpr->getSourceRange());
- return QualType();
- }
- if (vectorSize == 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
- sizeExpr->getSourceRange());
- return QualType();
- }
- // Instantiate the vector type, the number of elements is > 0, and not
- // required to be a power of 2, unlike GCC.
- return Context.getVectorType(curType, vectorSize/typeSize);
-}
-
-void Sema::HandlePackedAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() > 0) {
- Diag(rawAttr->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() &&
- Context.getTypeAlign(FD->getType()) <= 8)
- Diag(rawAttr->getLoc(),
- diag::warn_attribute_ignored_for_field_of_type,
- rawAttr->getName()->getName(), FD->getType().getAsString());
- else
- FD->addAttr(new PackedAttr);
- } else
- Diag(rawAttr->getLoc(), diag::warn_attribute_ignored,
- rawAttr->getName()->getName());
-}
-
-void Sema::HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
-
- if (!Fn) {
- Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
- "noreturn", "function");
- return;
- }
-
- d->addAttr(new NoReturnAttr());
-}
-
-void Sema::HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new DeprecatedAttr());
-}
-
-void Sema::HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 1) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
-
- Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
- Arg = Arg->IgnoreParenCasts();
- StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-
- if (Str == 0 || Str->isWide()) {
- Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
- "visibility", std::string("1"));
- return;
- }
-
- const char *TypeStr = Str->getStrData();
- unsigned TypeLen = Str->getByteLength();
- llvm::GlobalValue::VisibilityTypes type;
-
- if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
- type = llvm::GlobalValue::DefaultVisibility;
- else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
- type = llvm::GlobalValue::HiddenVisibility;
- else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
- type = llvm::GlobalValue::HiddenVisibility; // FIXME
- else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
- type = llvm::GlobalValue::ProtectedVisibility;
- else {
- Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
- "visibility", TypeStr);
- return;
- }
-
- d->addAttr(new VisibilityAttr(type));
-}
-
-void Sema::HandleWeakAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new WeakAttr());
-}
-
-void Sema::HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new DLLImportAttr());
-}
-
-void Sema::HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new DLLExportAttr());
-}
-
-void Sema::HandleStdCallAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new StdCallAttr());
-}
-
-void Sema::HandleFastCallAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new FastCallAttr());
-}
-
-void Sema::HandleNothrowAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- d->addAttr(new NoThrowAttr());
-}
-
-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()) {
- const PointerType *PtrTy = Ty->getAsPointerType();
- Ty = PtrTy->getPointeeType();
- }
-
- if (const FunctionType *FnTy = Ty->getAsFunctionType())
- return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
-
- return 0;
-}
-
-static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
- if (!T->isPointerType())
- return false;
-
- T = T->getAsPointerType()->getPointeeType().getCanonicalType();
- ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
-
- 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");
-}
-
-/// Handle __attribute__((format(type,idx,firstarg))) attributes
-/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
-void Sema::HandleFormatAttribute(Decl *d, AttributeList *rawAttr) {
-
- if (!rawAttr->getParameterName()) {
- Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
- "format", std::string("1"));
- return;
- }
-
- if (rawAttr->getNumArgs() != 2) {
- Diag(rawAttr->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
- const FunctionTypeProto *proto = getFunctionProto(d);
-
- if (!proto) {
- Diag(rawAttr->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 = proto->getNumArgs();
- unsigned FirstIdx = 1;
-
- const char *Format = rawAttr->getParameterName()->getName();
- unsigned FormatLen = rawAttr->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;
-
- 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));
- break;
- }
-
- if (!Supported) {
- Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
- "format", rawAttr->getParameterName()->getName());
- return;
- }
-
- // checks for the 2nd argument
- Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0));
- llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType()));
- if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
- Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
- "format", std::string("2"), IdxExpr->getSourceRange());
- return;
- }
-
- if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
- Diag(rawAttr->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 = proto->getArgType(ArgIdx);
-
- if (is_NSString) {
- // FIXME: do we need to check if the type is NSString*? What are
- // the semantics?
- if (!isNSStringType(Ty, Context)) {
- // FIXME: Should highlight the actual expression that has the
- // wrong type.
- Diag(rawAttr->getLoc(), diag::err_format_attribute_not_NSString,
- IdxExpr->getSourceRange());
- return;
- }
- }
- else if (!Ty->isPointerType() ||
- !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
- // FIXME: Should highlight the actual expression that has the
- // wrong type.
- Diag(rawAttr->getLoc(), diag::err_format_attribute_not_string,
- IdxExpr->getSourceRange());
- return;
- }
-
- // check the 3rd argument
- Expr *FirstArgExpr = static_cast<Expr *>(rawAttr->getArg(1));
- llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType()));
- if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
- Diag(rawAttr->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 (proto->isVariadic()) {
- ++NumArgs; // +1 for ...
- } else {
- 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) {
- Diag(rawAttr->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) {
- Diag(rawAttr->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()));
-}
-
-void Sema::HandleTransparentUnionAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 0) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("0"));
- return;
- }
-
- TypeDecl *decl = dyn_cast<TypeDecl>(d);
-
- if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) {
- Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
- "transparent_union", "union");
- return;
- }
-
- //QualType QTy = Context.getTypeDeclType(decl);
- //const RecordType *Ty = QTy->getAsUnionType();
-
-// FIXME
-// Ty->addAttr(new TransparentUnionAttr());
-}
-
-void Sema::HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr) {
- // check the attribute arguments.
- if (rawAttr->getNumArgs() != 1) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
- Expr *argExpr = static_cast<Expr *>(rawAttr->getArg(0));
- StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
-
- // Make sure that there is a string literal as the annotation's single
- // argument.
- if (!SE) {
- Diag(rawAttr->getLoc(), diag::err_attribute_annotate_no_string);
- return;
- }
- d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
- SE->getByteLength())));
-}
-
-void Sema::HandleAlignedAttribute(Decl *d, AttributeList *rawAttr)
-{
- // check the attribute arguments.
- if (rawAttr->getNumArgs() > 1) {
- Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return;
- }
-
- unsigned Align = 0;
-
- if (rawAttr->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;
- } else {
- Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0));
- llvm::APSInt alignment(32);
- if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) {
- Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
- "aligned", alignmentExpr->getSourceRange());
- return;
- }
-
- Align = alignment.getZExtValue() * 8;
- }
-
- d->addAttr(new AlignedAttr(Align));
-}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
deleted file mode 100644
index f403858e7521..000000000000
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ /dev/null
@@ -1,384 +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/Basic/LangOptions.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/Type.h"
-#include "clang/Parse/Scope.h"
-#include "llvm/ADT/OwningPtr.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 first = Node->child_begin(),
- last = Node->child_end();
- first != last; ++first)
- IsInvalid |= Visit(*first);
-
- 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,
- DeclTy *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->getKind() == Decl::Union) {
- 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.
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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 &&
- IdResolver.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();
-}
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
deleted file mode 100644
index a0fa6ecb2bc2..000000000000
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ /dev/null
@@ -1,1179 +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/Parse/Scope.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(CurFunctionDecl == 0 && "Method parsing confused");
- ObjCMethodDecl *MDecl = dyn_cast<ObjCMethodDecl>(static_cast<Decl *>(D));
- assert(MDecl != 0 && "Not a method declarator!");
-
- // 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.
- CurMethodDecl = MDecl;
- PushDeclContext(MDecl);
-
- // Create Decl objects for each parameter, entrring them in the scope for
- // binding to their use.
- struct DeclaratorChunk::ParamInfo PI;
-
- // Insert the invisible arguments, self and _cmd!
- PI.Ident = &Context.Idents.get("self");
- PI.IdentLoc = SourceLocation(); // synthesized vars have a null location.
- QualType selfTy = Context.getObjCIdType();
- if (MDecl->isInstance()) {
- if (ObjCInterfaceDecl *OID = MDecl->getClassInterface()) {
- // There may be no interface context due to error in declaration of the
- // interface (which has been reported). Recover gracefully
- selfTy = Context.getObjCInterfaceType(OID);
- selfTy = Context.getPointerType(selfTy);
- }
- }
- CurMethodDecl->setSelfDecl(CreateImplicitParameter(FnBodyScope, PI.Ident,
- PI.IdentLoc, selfTy));
-
- PI.Ident = &Context.Idents.get("_cmd");
- CreateImplicitParameter(FnBodyScope, PI.Ident, PI.IdentLoc,
- Context.getObjCSelType());
-
- // 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,
- IdentifierInfo **ProtocolNames, unsigned NumProtocols,
- 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);
- IDecl->AllocIntfRefProtocols(NumProtocols);
- }
- }
- else {
- IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc, NumProtocols,
- ClassName, ClassLoc);
-
- 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(AtInterfaceLoc, diag::err_undef_superclass,
- SuperClassEntry ? SuperClassEntry->getName()
- : SuperName->getName(),
- ClassName->getName());
- }
- }
- IDecl->setSuperClass(SuperClassEntry);
- IDecl->setSuperClassLoc(SuperLoc);
- IDecl->setLocEnd(SuperLoc);
- } else { // we have a root class.
- IDecl->setLocEnd(ClassLoc);
- }
-
- /// Check then save referenced protocols
- if (NumProtocols) {
- for (unsigned int i = 0; i != NumProtocols; i++) {
- ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtocolNames[i]];
- if (!RefPDecl || RefPDecl->isForwardDecl())
- Diag(ClassLoc, diag::warn_undef_protocolref,
- ProtocolNames[i]->getName(),
- ClassName->getName());
- IDecl->setIntfRefProtocols(i, RefPDecl);
- }
- IDecl->setLocEnd(EndProtoLoc);
- }
- return IDecl;
-}
-
-/// ActOnCompatiblityAlias - this action is called after complete parsing of
-/// @compaatibility_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,
- IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs,
- SourceLocation EndProtoLoc) {
- 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;
- }
-
- PDecl->setForwardDecl(false);
- PDecl->AllocReferencedProtocols(NumProtoRefs);
- } else {
- PDecl = ObjCProtocolDecl::Create(Context, AtProtoInterfaceLoc, NumProtoRefs,
- ProtocolName);
- PDecl->setForwardDecl(false);
- ObjCProtocols[ProtocolName] = PDecl;
- }
-
- if (NumProtoRefs) {
- /// Check then save referenced protocols.
- for (unsigned int i = 0; i != NumProtoRefs; i++) {
- ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtoRefNames[i]];
- if (!RefPDecl || RefPDecl->isForwardDecl())
- Diag(ProtocolLoc, diag::warn_undef_protocolref,
- ProtoRefNames[i]->getName(),
- ProtocolName->getName());
- PDecl->setReferencedProtocols(i, RefPDecl);
- }
- PDecl->setLocEnd(EndProtoLoc);
- }
- return PDecl;
-}
-
-/// FindProtocolDeclaration - This routine looks up protocols and
-/// issuer error if they are not declared. It returns list of protocol
-/// declarations in its 'Protocols' argument.
-void
-Sema::FindProtocolDeclaration(SourceLocation TypeLoc,
- IdentifierInfo **ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVector<DeclTy *,8> &Protocols) {
- for (unsigned i = 0; i != NumProtocols; ++i) {
- ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i]];
- if (!PDecl)
- Diag(TypeLoc, diag::err_undeclared_protocol,
- ProtocolId[i]->getName());
- else
- Protocols.push_back(PDecl);
- }
-}
-
-/// DiagnosePropertyMismatch - Compares two properties for their
-/// attributes and types and warns on a variety of inconsistancies.
-///
-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 (Property->getCanonicalType() != SuperProperty->getCanonicalType())
- 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;
- 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)
- MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
- // Merge properties of class (*P) into IDECL's
- ;
- // 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 if (ObjCProtocolDecl *MDecl =
- dyn_cast<ObjCProtocolDecl>(ClassDecl))
- for (ObjCProtocolDecl::protocol_iterator P = MDecl->protocol_begin(),
- E = MDecl->protocol_end(); P != E; ++P)
- MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
- else
- assert(false && "MergeProtocolPropertiesIntoClass - bad object kind");
-}
-
-/// ActOnForwardProtocolDeclaration -
-Action::DeclTy *
-Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
- IdentifierInfo **IdentList, unsigned NumElts) {
- llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
-
- for (unsigned i = 0; i != NumElts; ++i) {
- IdentifierInfo *Ident = IdentList[i];
- ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident];
- if (PDecl == 0) { // Not already seen?
- // FIXME: Pass in the location of the identifier!
- PDecl = ObjCProtocolDecl::Create(Context, AtProtocolLoc, 0, 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,
- IdentifierInfo **ProtoRefNames, 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 (CDeclChain->getIdentifier() == CategoryName) {
- Diag(CategoryLoc, diag::err_dup_category_def, ClassName->getName(),
- CategoryName->getName());
- break;
- }
- }
- if (!CDeclChain)
- CDecl->insertNextClassCategory();
- }
-
- if (NumProtoRefs) {
- llvm::SmallVector<ObjCProtocolDecl*, 32> RefProtocols;
- /// Check and then save the referenced protocols.
- for (unsigned int i = 0; i != NumProtoRefs; i++) {
- ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtoRefNames[i]];
- if (!RefPDecl || RefPDecl->isForwardDecl()) {
- Diag(CategoryLoc, diag::warn_undef_protocolref,
- ProtoRefNames[i]->getName(),
- CategoryName->getName());
- }
- if (RefPDecl)
- RefProtocols.push_back(RefPDecl);
- }
- if (!RefProtocols.empty())
- CDecl->setReferencedProtocolList(&RefProtocols[0], RefProtocols.size());
- }
- 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.
- 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.
- IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, 0, 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 (ImplIvar->getCanonicalType() != ClsIvar->getCanonicalType()) {
- 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());
-}
-
-/// 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) {
- // check unimplemented instance methods.
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
- E = PDecl->instmeth_end(); I != E; ++I) {
- ObjCMethodDecl *method = *I;
- if (!InsMap.count(method->getSelector()) &&
- method->getImplementationControl() != ObjCMethodDecl::Optional)
- 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 (!ClsMap.count(method->getSelector()) &&
- method->getImplementationControl() != ObjCMethodDecl::Optional)
- WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
- }
- // Check on this protocols's referenced protocols, recursively
- ObjCProtocolDecl** RefPDecl = PDecl->getReferencedProtocols();
- for (unsigned i = 0; i < PDecl->getNumReferencedProtocols(); i++)
- CheckProtocolMethodDefs(ImpLoc, RefPDecl[i], IncompleteImpl, InsMap, ClsMap);
-}
-
-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.
- ObjCProtocolDecl** protocols = IDecl->getReferencedProtocols();
- for (unsigned i = 0; i < IDecl->getNumIntfRefProtocols(); i++)
- CheckProtocolMethodDefs(IMPDecl->getLocation(), protocols[i],
- IncompleteImpl, InsMap, ClsMap);
-}
-
-/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
-/// category interface is 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.
- ObjCProtocolDecl** protocols = CatClassDecl->getReferencedProtocols();
- for (unsigned i = 0; i < CatClassDecl->getNumReferencedProtocols(); i++) {
- ObjCProtocolDecl* PDecl = protocols[i];
- CheckProtocolMethodDefs(CatImplDecl->getLocation(), PDecl, IncompleteImpl,
- InsMap, ClsMap);
- }
-}
-
-/// 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)) {
- 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, 0, 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 (Method->getResultType().getCanonicalType() !=
- PrevMethod->getResultType().getCanonicalType())
- 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;
- }
- }
-}
-
-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);
- }
- }
- }
-
- if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
- // Compares properties declaraed in this class to those of its
- // super class.
- ComparePropertiesInBaseAndSuper(I);
- MergeProtocolPropertiesIntoClass(I, I);
- for (ObjCInterfaceDecl::classprop_iterator P = I->classprop_begin(),
- E = I->classprop_end(); P != E; ++P) {
- I->addPropertyMethods(Context, *P, insMethods);
- }
- I->addMethods(&insMethods[0], insMethods.size(),
- &clsMethods[0], clsMethods.size(), AtEndLoc);
-
- } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
- P->addMethods(&insMethods[0], insMethods.size(),
- &clsMethods[0], clsMethods.size(), AtEndLoc);
- }
- else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
- 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 is 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;
- }
- }
- }
- }
-}
-
-
-/// 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, AttrList,
- 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;
-
- // 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;
-}
-
-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);
- 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 (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_readonly)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
-
- if (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_getter)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
-
- if (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_setter)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
-
- if (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_assign)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
-
- if (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_readwrite)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
-
- if (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_retain)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
-
- if (ODS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_copy)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
-
- if (ODS.getPropertyAttributes() & 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;
- }
- // Check that type of property and its ivar match.
- if (Ivar->getCanonicalType() != property->getCanonicalType()) {
- 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::OBJC_PR_IMPL_SYNTHSIZE
- : ObjCPropertyImplDecl::OBJC_PR_IMPL_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 5341ee7faa3f..000000000000
--- a/clang/lib/Sema/SemaExpr.cpp
+++ /dev/null
@@ -1,2341 +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 "SemaUtil.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/LiteralSupport.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-using namespace clang;
-
-/// 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;
- // FIXME: handle wchar_t
- if (Literal.Pascal) StrTy = Context.UnsignedCharTy;
-
- // 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());
-}
-
-
-/// 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 (CurMethodDecl) {
- 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 = CurMethodDecl->getClassInterface(), *DeclClass;
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&II, DeclClass)) {
- // 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);
- }
- }
- }
-
- 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 (ValueDecl *VD = dyn_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;
- return new DeclRefExpr(VD, VD->getType(), Loc);
- }
-
- 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());
-
- assert(0 && "Invalid decl");
- abort();
-}
-
-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 (CurFunctionDecl == 0 && CurMethodDecl == 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 (CurFunctionDecl)
- Length = CurFunctionDecl->getIdentifier()->getLength();
- else
- Length = CurMethodDecl->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(), 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;
- IntegerBuffer.resize(Tok.getLength());
- 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;
- const llvm::fltSemantics *Format;
-
- if (Literal.isFloat) {
- Ty = Context.FloatTy;
- Format = Context.Target.getFloatFormat();
- } else if (!Literal.isLong) {
- Ty = Context.DoubleTy;
- Format = Context.Target.getDoubleFormat();
- } else {
- Ty = Context.LongDoubleTy;
- Format = Context.Target.getLongDoubleFormat();
- }
-
- // 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, bool isSizeof) {
- // C99 6.5.3.4p1:
- if (isa<FunctionType>(exprType) && isSizeof)
- // alignof(function) is allowed.
- Diag(OpLoc, diag::ext_sizeof_function_type);
- else if (exprType->isVoidType())
- Diag(OpLoc, diag::ext_sizeof_void_type, isSizeof ? "sizeof" : "__alignof");
- else if (exprType->isIncompleteType()) {
- Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type :
- diag::err_alignof_incomplete_type,
- exprType.getAsString());
- 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, 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)) {
- 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).
-}
-
-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");
-
- if (OpKind == tok::arrow) {
- if (const PointerType *PT = BaseType->getAsPointerType())
- BaseType = PT->getPointeeType();
- else
- return Diag(OpLoc, diag::err_typecheck_member_reference_arrow,
- SourceRange(MemberLoc));
- }
- // The base type is either a record or an ExtVectorType.
- 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(OpLoc, diag::err_typecheck_no_member, Member.getName(),
- SourceRange(MemberLoc));
-
- // 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);
- } else 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(OpLoc, diag::err_ext_vector_component_access,
- SourceRange(MemberLoc));
- QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc);
- if (ret.isNull())
- return true;
- return new ExtVectorElementExpr(ret, BaseExpr, Member, MemberLoc);
- } else if (BaseType->isObjCInterfaceType()) {
- ObjCInterfaceDecl *IFace;
- if (isa<ObjCInterfaceType>(BaseType.getCanonicalType()))
- IFace = dyn_cast<ObjCInterfaceType>(BaseType)->getDecl();
- else
- IFace = dyn_cast<ObjCQualifiedInterfaceType>(BaseType)->getDecl();
- ObjCInterfaceDecl *clsDeclared;
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member, clsDeclared))
- return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr,
- OpKind==tok::arrow);
- }
- return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion,
- SourceRange(MemberLoc));
-}
-
-/// 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));
-
- // 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(Fn->getLocStart(), diag::err_typecheck_call_not_function,
- SourceRange(Fn->getLocStart(), RParenLoc));
- const FunctionType *FuncT = PT->getPointeeType()->getAsFunctionType();
- if (FuncT == 0)
- return Diag(Fn->getLocStart(), diag::err_typecheck_call_not_function,
- SourceRange(Fn->getLocStart(), RParenLoc));
-
- // 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, diag::err_typecheck_call_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(),
- diag::err_typecheck_call_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 && CheckFunctionCall(FDecl, TheCall.get()))
- return true;
-
- 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);
-
- // FIXME: add more semantic analysis (C99 6.5.2.5).
- if (CheckInitializerTypes(literalExpr, literalType))
- return true;
-
- bool isFileScope = !CurFunctionDecl && !CurMethodDecl;
- 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;
-}
-
-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);
-
- 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.
- if (!castType->isScalarType() && !castType->isVectorType())
- return Diag(LParenLoc, diag::err_typecheck_cond_expect_scalar,
- castType.getAsString(), SourceRange(LParenLoc, RParenLoc));
- if (!castExpr->getType()->isScalarType() &&
- !castExpr->getType()->isVectorType())
- return Diag(castExpr->getLocStart(),
- diag::err_typecheck_expect_scalar_operand,
- castExpr->getType().getAsString(),castExpr->getSourceRange());
-
- if (castExpr->getType()->isVectorType()) {
- if (CheckVectorCast(SourceRange(LParenLoc, RParenLoc),
- castExpr->getType(), castType))
- return true;
- } else if (castType->isVectorType()) {
- if (CheckVectorCast(SourceRange(LParenLoc, RParenLoc),
- castType, castExpr->getType()))
- return true;
- }
- }
- return new CastExpr(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."
- if (lexT->isVoidType() && rexT->isVoidType())
- return lexT.getUnqualifiedType();
-
- // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
- // the type of the other operand."
- if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) {
- ImpCastExprToType(rex, lexT); // promote the null to a pointer.
- return lexT;
- }
- if (rexT->isPointerType() && 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;
- }
-
- 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 voidPtrTy = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(lex, voidPtrTy);
- ImpCastExprToType(rex, voidPtrTy);
- return voidPtrTy;
- }
- // 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 return the composite type.
- // FIXME: Need to add qualifiers
- 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);
-}
-
-/// 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 (Ty == Context.FloatTy)
- ImpCastExprToType(Expr, Context.DoubleTy);
- else
- UsualUnaryConversions(Expr);
-}
-
-/// 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())
- 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;
-}
-
-/// 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 = lhsExpr->getType().getCanonicalType().getUnqualifiedType();
- QualType rhs = rhsExpr->getType().getCanonicalType().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.
- if (Context.getIntegerTypeOrder(lhs, rhs) >= 0) { // convert the rhs
- if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
- return lhs;
- }
- if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
- return rhs;
-}
-
-// 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 = lhptee.getCanonicalType();
- rhptee = rhptee.getCanonicalType();
-
- 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;
- }
-
- // 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;
-}
-
-/// 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 = lhsType.getCanonicalType();
- rhsType = rhsType.getCanonicalType();
-
- if (lhsType.getUnqualifiedType() == rhsType.getUnqualifiedType())
- 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;
- return Incompatible;
- }
-
- if (isa<VectorType>(lhsType) || isa<VectorType>(rhsType)) {
- // For ExtVector, allow vector splats; float -> <n x float>
- if (const ExtVectorType *LV = dyn_cast<ExtVectorType>(lhsType)) {
- if (LV->getElementType().getTypePtr() == rhsType.getTypePtr())
- return Compatible;
- }
-
- // If LHS and RHS are both vectors of integer or both vectors of floating
- // point types, and the total vector length is the same, allow the
- // conversion. This is a bitcast; no bits are changed but the result type
- // is different.
- if (getLangOptions().LaxVectorConversions &&
- lhsType->isVectorType() && rhsType->isVectorType()) {
- if ((lhsType->isIntegerType() && rhsType->isIntegerType()) ||
- (lhsType->isRealFloatingType() && rhsType->isRealFloatingType())) {
- 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);
- return Incompatible;
- }
-
- if (isa<PointerType>(rhsType)) {
- // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
- if (lhsType->isIntegerType() && lhsType != Context.BoolTy)
- return PointerToInt;
-
- if (isa<PointerType>(lhsType))
- return CheckPointerTypesForAssignment(lhsType, rhsType);
- 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())
- && rExpr->isNullPointerConstant(Context)) {
- ImpCastExprToType(rExpr, lhsType);
- return Compatible;
- }
- // 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 = lex->getType().getCanonicalType().getUnqualifiedType();
- QualType rhsType = rex->getType().getCanonicalType().getUnqualifiedType();
-
- // make sure the vector types are identical.
- if (lhsType == rhsType)
- return lhsType;
-
- // if the lhs is an extended vector and the rhs is a scalar of the same type,
- // promote the rhs to the vector type.
- if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
- if (V->getElementType().getCanonicalType().getTypePtr()
- == rhsType.getCanonicalType().getTypePtr()) {
- 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()) {
- if (V->getElementType().getCanonicalType().getTypePtr()
- == lhsType.getCanonicalType().getTypePtr()) {
- 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;
-
- if (lex->getType()->isPointerType() && rex->getType()->isIntegerType())
- return lex->getType();
- if (lex->getType()->isIntegerType() && rex->getType()->isPointerType())
- return rex->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(lpointee.getUnqualifiedType(),
- 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();
-}
-
-// C99 6.5.8
-QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
- bool 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 =
- lType->getAsPointerType()->getPointeeType().getCanonicalType();
- QualType RCanPointeeTy =
- rType->getAsPointerType()->getPointeeType().getCanonicalType();
-
- if (!LHSIsNull && !RHSIsNull && // C99 6.5.9p2
- !LCanPointeeTy->isVoidType() && !RCanPointeeTy->isVoidType() &&
- !Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
- RCanPointeeTy.getUnqualifiedType())) {
- 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;
- }
- if ((lType->isObjCQualifiedIdType() || rType->isObjCQualifiedIdType())
- && ObjCQualifiedIdTypesAreCompatible(lType, rType, true)) {
- ImpCastExprToType(rex, lType);
- return Context.IntTy;
- }
- if (lType->isPointerType() && 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()) {
- 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);
-}
-
-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();
-
- 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();
- }
-
- AssignConvertType ConvTy;
- if (compoundType.isNull())
- ConvTy = CheckSingleAssignmentConstraints(lhsType, rex);
- else
- 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) {
- UsualUnaryConversions(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()->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();
- 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. Here are some
-/// examples: &s.xx, &s.zz[1].yy, &(1+2), &(XX), &"123"[2].
-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] is invalid if X is invalid and 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:
- return getPrimaryDecl(cast<UnaryOperator>(E)->getSubExpr());
- 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();
-
- 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 as a GCC extension.
- if (!resultType->isIntegerType()) {
- if (resultType->isComplexType())
- // C99 does not support '~' for complex conjugation.
- Diag(OpLoc, diag::ext_integer_complement_complex,
- resultType.getAsString());
- else
- return Diag(OpLoc, diag::err_typecheck_unary_expr,
- resultType.getAsString());
- }
- 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, true);
- break;
- case UnaryOperator::AlignOf:
- resultType = CheckSizeOfAlignOfOperand(Input->getType(), OpLoc, 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.
- 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())
- if (Expr *LastExpr = dyn_cast<Expr>(Compound->body_back()))
- 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 = Res->getType()->getAsArrayType();
- 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);
-}
-
-/// 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) {
- unsigned NumParams = FnType->getNumArgs();
- for (unsigned i = 0; i != NumParams; ++i) {
- QualType ExprTy = Args[i]->getType().getCanonicalType();
- QualType ParmTy = FnType->getArgType(i).getCanonicalType();
-
- 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]);
- FunctionTypeProto *FnType = 0;
- if (const PointerType *PT = Fn->getType()->getAsPointerType()) {
- QualType PointeeType = PT->getPointeeType().getCanonicalType();
- FnType = dyn_cast<FunctionTypeProto>(PointeeType);
- }
-
- // 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)) {
- 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();
-
- if (CheckAssignmentConstraints(Context.getBuiltinVaListType(), 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:
- DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
- 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 e49a43c4728c..000000000000
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ /dev/null
@@ -1,51 +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"
-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);
-}
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
deleted file mode 100644
index 62d43616b5db..000000000000
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ /dev/null
@@ -1,465 +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/Expr.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)
- return Diag(S->getLocStart(), diag::err_undef_interface,
- NSIdent->getName());
- Context.setObjCConstantStringInterface(strIFace);
- }
- QualType t = Context.getObjCConstantStringInterface();
- 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,
- ObjCMethodDecl *Method) {
- bool anyIncompatibleArgs = false;
-
- for (unsigned i = 0; i < NumArgs; 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");
- }
- 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;
- if (!strcmp(receiverName->getName(), "super") && CurMethodDecl) {
- ClassDecl = CurMethodDecl->getClassInterface()->getSuperClass();
- if (!ClassDecl)
- return Diag(lbrac, diag::error_no_super_class,
- CurMethodDecl->getClassInterface()->getName());
- if (CurMethodDecl->isInstance()) {
- // Synthesize a cast to the super class. This hack allows us to loosely
- // represent super without creating a special expression node.
- IdentifierInfo &II = Context.Idents.get("self");
- ExprResult ReceiverExpr = ActOnIdentifierExpr(S, lbrac, II, false);
- QualType superTy = Context.getObjCInterfaceType(ClassDecl);
- superTy = Context.getPointerType(superTy);
- ReceiverExpr = ActOnCastExpr(SourceLocation(), superTy.getAsOpaquePtr(),
- SourceLocation(), ReceiverExpr.Val);
- // 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);
-
- // FIXME: can ClassDecl ever be null?
- ObjCMethodDecl *Method = ClassDecl->lookupClassMethod(Sel);
- QualType returnType;
-
- // Before we give up, check if the selector is an instance method.
- if (!Method)
- Method = ClassDecl->lookupInstanceMethod(Sel);
- if (!Method) {
- Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(),
- SourceRange(lbrac, rbrac));
- returnType = Context.getObjCIdType();
- } else {
- returnType = Method->getResultType();
- if (Sel.getNumArgs()) {
- if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
- return true;
- }
- }
- return new ObjCMessageExpr(receiverName, 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 receiverType = RExpr->getType().getCanonicalType();
- QualType returnType;
- ObjCMethodDecl *Method = 0;
-
- // FIXME: This code is not stripping off type qualifiers! Should it?
- if (receiverType == Context.getObjCIdType().getCanonicalType() ||
- receiverType == Context.getObjCClassType().getCanonicalType()) {
- Method = InstanceMethodPool[Sel].Method;
- if (!Method)
- Method = FactoryMethodPool[Sel].Method;
- if (!Method) {
- Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
- SourceRange(lbrac, rbrac));
- returnType = Context.getObjCIdType();
- } else {
- returnType = Method->getResultType();
- if (Sel.getNumArgs())
- if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
- return true;
- }
- } else {
- bool receiverIsQualId = isa<ObjCQualifiedIdType>(receiverType);
- // FIXME (snaroff): checking in this code from Patrick. Needs to be
- // revisited. how do we get the ClassDecl from the receiver expression?
- if (!receiverIsQualId)
- while (const PointerType *PTy = receiverType->getAsPointerType())
- receiverType = PTy->getPointeeType();
-
- ObjCInterfaceDecl* ClassDecl = 0;
- if (ObjCQualifiedInterfaceType *QIT =
- dyn_cast<ObjCQualifiedInterfaceType>(receiverType)) {
- ClassDecl = QIT->getDecl();
- Method = ClassDecl->lookupInstanceMethod(Sel);
- if (!Method) {
- // 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(),
- SourceRange(lbrac, rbrac));
- }
- else if (ObjCQualifiedIdType *QIT =
- dyn_cast<ObjCQualifiedIdType>(receiverType)) {
- // 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(),
- SourceRange(lbrac, rbrac));
- }
- else {
- ObjCInterfaceType *OCIReceiver =dyn_cast<ObjCInterfaceType>(receiverType);
- if (OCIReceiver == 0) {
- Diag(lbrac, diag::error_bad_receiver_type,
- RExpr->getType().getAsString());
- return true;
- }
- ClassDecl = OCIReceiver->getDecl();
- // FIXME: consider using InstanceMethodPool, 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) {
- // 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 = InstanceMethodPool[Sel].Method;
- }
- if (!Method) {
- Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
- SourceRange(lbrac, rbrac));
- returnType = Context.getObjCIdType();
- } else {
- returnType = Method->getResultType();
- if (Sel.getNumArgs())
- if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
- 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;
- ObjCProtocolDecl** RefPDecl = rProto->getReferencedProtocols();
- for (unsigned i = 0; i < rProto->getNumReferencedProtocols(); i++)
- if (ProtocolCompatibleWithProtocol(lProto, RefPDecl[i]))
- 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) {
-
- // 1st, look up the class.
- ObjCProtocolDecl **protoList = IDecl->getReferencedProtocols();
- for (unsigned i = 0; i < IDecl->getNumIntfRefProtocols(); i++) {
- if (ProtocolCompatibleWithProtocol(lProto, protoList[i]))
- return true;
- }
-
- // 2nd, look up the category.
- if (lookupCategory)
- for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
- CDecl = CDecl->getNextClassCategory()) {
- protoList = CDecl->getReferencedProtocols();
- for (unsigned i = 0; i < CDecl->getNumReferencedProtocols(); i++) {
- if (ProtocolCompatibleWithProtocol(lProto, protoList[i]))
- return true;
- }
- }
-
- // 3rd, look up the super class(s)
- if (IDecl->getSuperClass())
- return
- ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory);
-
- 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;
- if (!rhsQID) {
- // Not comparing two ObjCQualifiedIdType's?
- if (!rhs->isPointerType()) return false;
- QualType rtype = rhs->getAsPointerType()->getPointeeType();
-
- rhsQI = rtype->getAsObjCQualifiedInterfaceType();
- if (rhsQI == 0) {
- // If the RHS is an interface pointer ('NSString*'), handle it.
- 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) {
- RHSProtoI = rhsQI->qual_begin();
- RHSProtoE = rhsQI->qual_end();
- } else if (rhsQID) {
- 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 (!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))
- 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 d1f4b25d1dea..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/AST/Type.h"
-
-namespace clang {
-
-InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
- hadError = false;
- SemaRef = S;
-
- if (IL) {
- unsigned newIndex = 0;
-
- // Special case the following, which should produce an error.
- //
- // struct foo { int z; } w;
- // int bar (void) {
- // struct foo bad = { w };
- // return bad.z;
- // }
- if (T->isStructureType() || T->isUnionType())
- CheckStructUnionTypes(IL, T, newIndex, true);
- else
- CheckExplicitInitList(IL, T, newIndex);
-
- if (!hadError && (newIndex < IL->getNumInits())) {
- // We have leftover initializers; warn
- SemaRef->Diag(IL->getInit(newIndex)->getLocStart(),
- diag::warn_excess_initializers,
- IL->getInit(newIndex)->getSourceRange());
- }
- } else {
- // FIXME: Create an implicit InitListExpr with expressions from the
- // parent checker.
- }
-}
-
-int InitListChecker::numArrayElements(QualType DeclType) {
- int maxElements;
- if (DeclType->isIncompleteArrayType()) {
- // FIXME: use a proper constant
- maxElements = 0x7FFFFFFF;
- } else if (const VariableArrayType *VAT =
- DeclType->getAsVariableArrayType()) {
- // 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;
- maxElements = 0x7FFFFFFF;
- } else {
- const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
- maxElements = static_cast<int>(CAT->getSize().getZExtValue());
- }
- return maxElements;
-}
-
-int InitListChecker::numStructUnionElements(QualType DeclType) {
- RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
- return structDecl->getNumMembers() - 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
- assert(0 && "CheckImplicitInitList(): Illegal type");
-
- 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);
- // Now we can check the types.
- // CheckElementTypes(ParentIList, T, Index);
-}
-
-void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
- unsigned &Index) {
- //assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
- if (IList->isExplicit() && T->isScalarType())
- SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
- IList->getSourceRange());
- CheckElementTypes(IList, T, Index);
- IList->setType(T);
-}
-
-void InitListChecker::CheckElementTypes(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 {
- // 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::CheckScalarType(InitListExpr *IList, QualType &DeclType,
- unsigned &Index) {
- if (Index < IList->getNumInits()) {
- Expr* expr = IList->getInit(Index);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- CheckExplicitInitList(SubInitList, DeclType, newIndex);
- } else {
- 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;
- }
- // FIXME: Should an error be reported for empty initializer list + scalar?
-}
-
-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;
- Expr* expr = IList->getInit(Index);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- CheckExplicitInitList(SubInitList, elementType, newIndex);
- newIndex++;
- } else
- CheckImplicitInitList(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;
- if (IList->isExplicit() && Index < IList->getNumInits()) {
- // We have leftover initializers; warn
- SemaRef->Diag(IList->getInit(Index)->getLocStart(),
- diag::err_excess_initializers_in_char_array_initializer,
- IList->getInit(Index)->getSourceRange());
- }
- return;
- }
- }
- int maxElements = numArrayElements(DeclType);
- QualType elementType = DeclType->getAsArrayType()->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;
- Expr* expr = IList->getInit(Index);
- // Now, check the expression against the element type.
- if (elementType->isScalarType())
- CheckScalarType(IList, elementType, Index);
- else if (elementType->isStructureType() || elementType->isUnionType())
- CheckStructUnionTypes(IList, elementType, Index);
- else if (StringLiteral *lit =
- SemaRef->IsStringLiteralInit(expr, elementType)) {
- SemaRef->CheckStringLiteralInit(lit, elementType);
- Index++;
- } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- CheckExplicitInitList(SubInitList, elementType, newIndex);
- Index++;
- } else {
- CheckImplicitInitList(IList, elementType, Index);
- 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
- // (It could in theory be allowed, but it doesn't really matter.)
- SemaRef->Diag(IList->getLocStart(),
- diag::err_at_least_one_initializer_needed_to_size_array);
- hadError = true;
- } else {
- llvm::APSInt ConstVal(32);
- ConstVal = numElements;
- DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
- ArrayType::Normal, 0);
- }
- }
-}
-
-void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
- QualType DeclType,
- unsigned &Index,
- bool topLevel) {
- if (Index < IList->getNumInits() && !topLevel &&
- SemaRef->Context.typesAreCompatible(
- IList->getInit(Index)->getType(), DeclType)) {
- // We found a compatible struct; per the standard, this initializes the
- // struct. (The C standard technically says that this only applies for
- // initializers for declarations with automatic scope; however, this
- // construct is unambiguous anyway because a struct cannot contain
- // a type compatible with itself. We'll output an error when we check
- // if the initializer is constant.)
- // FIXME: Is a call to CheckSingleInitializer required here?
- ++Index;
- } else {
- 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 = numStructUnionElements(DeclType);
- 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;
- }
- QualType elementType = curField->getType();
- Expr* expr = IList->getInit(Index);
- if (elementType->isScalarType())
- CheckScalarType(IList, elementType, Index);
- else if (elementType->isStructureType() || elementType->isUnionType())
- CheckStructUnionTypes(IList, elementType, Index);
- else if (StringLiteral *lit =SemaRef->IsStringLiteralInit(expr, elementType)) {
- SemaRef->CheckStringLiteralInit(lit, elementType);
- Index++;
- } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- unsigned newIndex = 0;
- CheckExplicitInitList(SubInitList, elementType, newIndex);
- Index++;
- } else {
- CheckImplicitInitList(IList, elementType, Index);
- 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 d8f213a973c2..000000000000
--- a/clang/lib/Sema/SemaStmt.cpp
+++ /dev/null
@@ -1,820 +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/Expr.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-#include "llvm/ADT/SmallString.h"
-using namespace clang;
-
-Sema::StmtResult Sema::ActOnExprStmt(ExprTy *expr) {
- Expr *E = static_cast<Expr*>(expr);
- assert(E && "ActOnExprStmt(): missing expression");
- 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])->getDecl();
- 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 (!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);
-
- // 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(), Val.toString());
-
- 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(), ConvVal.toString());
-
- // 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(), Val.toString());
- }
-}
-
-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.
- llvm::APSInt LoVal(32);
- Expr *Lo = CS->getLHS();
- Lo->isIntegerConstantExpr(LoVal, 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());
- 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;
- llvm::APSInt HiVal(32);
- Expr *Hi = CR->getRHS();
- Hi->isIntegerConstantExpr(HiVal, 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());
- 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 (!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 (!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 (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 (ScopedDecl *D = DS->getDecl(); D; D = D->getNextDeclarator()) {
- VarDecl *VD = dyn_cast<VarDecl>(D);
- if (VD && VD->isBlockVarDecl() && !VD->hasLocalStorage())
- VD = 0;
- if (VD == 0)
- Diag(dyn_cast<ScopedDecl>(D)->getLocation(),
- diag::err_non_variable_decl_in_for);
- // FIXME: mark decl erroneous!
- }
- }
- if (Second) {
- DefaultFunctionArrayConversion(Second);
- QualType SecondType = Second->getType();
-
- 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)) {
- FirstType = cast<ValueDecl>(DS->getDecl())->getType();
- // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
- // identifiers for objects having storage class 'auto' or 'register'.
- ScopedDecl *D = DS->getDecl();
- VarDecl *VD = cast<VarDecl>(D);
- if (VD->isBlockVarDecl() && !VD->hasLocalStorage())
- return Diag(VD->getLocation(), diag::err_non_variable_decl_in_for);
- if (D->getNextDeclarator())
- return Diag(D->getLocation(), diag::err_toomany_element_decls);
- } else
- FirstType = static_cast<Expr*>(first)->getType();
- if (!isObjCObjectPointerType(FirstType))
- Diag(ForLoc, diag::err_selector_element_type,
- FirstType.getAsString(), First->getSourceRange());
- }
- if (Second) {
- DefaultFunctionArrayConversion(Second);
- QualType SecondType = Second->getType();
- if (!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) {
- // 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);
-}
-
-
-Action::StmtResult
-Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
- Expr *RetValExp = static_cast<Expr *>(rex);
- QualType FnRetType = CurFunctionDecl ? CurFunctionDecl->getResultType() :
- CurMethodDecl->getResultType();
-
- if (FnRetType->isVoidType()) {
- if (RetValExp) // C99 6.8.6.4p1 (ext_ since GCC warns)
- Diag(ReturnLoc, diag::ext_return_has_expr,
- (CurFunctionDecl ? CurFunctionDecl->getIdentifier()->getName() :
- CurMethodDecl->getSelector().getName()),
- RetValExp->getSourceRange());
- return new ReturnStmt(ReturnLoc, RetValExp);
- } else {
- if (!RetValExp) {
- const char *funcName = CurFunctionDecl ?
- CurFunctionDecl->getIdentifier()->getName() :
- CurMethodDecl->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) {
- Expr *E = (Expr *)AsmString;
-
- for (unsigned i = 0; i < NumOutputs; i++) {
- StringLiteral *Literal = cast<StringLiteral>((Expr *)Constraints[i]);
- assert(!Literal->isWide() &&
- "Output constraint strings should not be wide!");
-
- std::string OutputConstraint(Literal->getStrData(),
- Literal->getByteLength());
-
- TargetInfo::ConstraintInfo info;
- if (!Context.Target.validateOutputConstraint(OutputConstraint.c_str(),
- info)) {
- // FIXME: We currently leak memory here.
- Diag(Literal->getLocStart(),
- diag::err_invalid_output_constraint_in_asm);
- return true;
- }
-
- // Check that the output exprs are valid lvalues.
- Expr *OutputExpr = (Expr *)Exprs[i];
- Expr::isLvalueResult Result = OutputExpr->isLvalue();
- if (Result != Expr::LV_Valid) {
- ParenExpr *PE = cast<ParenExpr>(OutputExpr);
-
- Diag(PE->getSubExpr()->getLocStart(),
- diag::err_invalid_lvalue_in_asm_output,
- PE->getSubExpr()->getSourceRange());
-
- // FIXME: We currently leak memory here.
- return true;
- }
- }
-
- for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
- StringLiteral *Literal = cast<StringLiteral>((Expr *)Constraints[i]);
- assert(!Literal->isWide() &&
- "Output constraint strings should not be wide!");
-
- 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.
- Diag(Literal->getLocStart(),
- diag::err_invalid_input_constraint_in_asm);
- return true;
- }
-
- // Check that the input exprs aren't of type void.
- Expr *InputExpr = (Expr *)Exprs[i];
- if (InputExpr->getType()->isVoidType()) {
- ParenExpr *PE = cast<ParenExpr>(InputExpr);
-
- Diag(PE->getSubExpr()->getLocStart(),
- diag::err_invalid_type_in_asm_input,
- PE->getType().getAsString(),
- PE->getSubExpr()->getSourceRange());
-
- // FIXME: We currently leak memory here.
- return true;
- }
- }
-
- // Check that the clobbers are valid.
- for (unsigned i = 0; i < NumClobbers; i++) {
- StringLiteral *Literal = cast<StringLiteral>((Expr *)Clobbers[i]);
- assert(!Literal->isWide() && "Clobber strings should not be wide!");
-
- llvm::SmallString<16> Clobber(Literal->getStrData(),
- Literal->getStrData() +
- Literal->getByteLength());
-
- if (!Context.Target.isValidGCCRegisterName(Clobber.c_str())) {
- Diag(Literal->getLocStart(),
- diag::err_unknown_register_name_in_asm,
- Clobber.c_str());
-
- // FIXME: We currently leak memory here.
- return true;
- }
- }
-
- return new AsmStmt(AsmLoc,
- IsSimple,
- IsVolatile,
- NumOutputs,
- NumInputs,
- Names,
- reinterpret_cast<StringLiteral**>(Constraints),
- reinterpret_cast<Expr**>(Exprs),
- cast<StringLiteral>(E),
- NumClobbers,
- reinterpret_cast<StringLiteral**>(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 85ff96111a5b..000000000000
--- a/clang/lib/Sema/SemaType.cpp
+++ /dev/null
@@ -1,579 +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/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Basic/LangOptions.h"
-using namespace clang;
-
-/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate
-/// type object. This returns null on error.
-QualType Sema::ConvertDeclSpecToType(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_unspecified:
- // 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!");
-
- // 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 (DS.getProtocolQualifiers() == 0) {
- Result = Context.getObjCInterfaceType(ObjCIntDecl);
- break;
- }
-
- Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
- Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl,
- reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
- DS.getNumProtocolQualifiers());
- break;
- }
- else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
- if (Context.getObjCIdType() == Context.getTypedefType(typeDecl)
- && DS.getProtocolQualifiers()) {
- // id<protocol-list>
- Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
- Result = Context.getObjCQualifiedIdType(typeDecl->getUnderlyingType(),
- reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
- 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 (AttributeList *AL = DS.getAttributes())
- DS.SetAttributes(ProcessTypeAttributes(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::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);
-
- // See if there are any attributes on the pointer that apply to it.
- if (AttributeList *AL = DeclType.Ptr.AttrList)
- DeclType.Ptr.AttrList = ProcessTypeAttributes(T, AL);
-
- 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();
-
- // See if there are any attributes on the pointer that apply to it.
- if (AttributeList *AL = DeclType.Ref.AttrList)
- DeclType.Ref.AttrList = ProcessTypeAttributes(T, AL);
- 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);
- }
- }
- // 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 no expression was provided, we consider it an incomplete array.
- if (!ArraySize) {
- T = Context.getIncompleteArrayType(T, ASM, ATI.TypeQuals);
- } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context)) {
- 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.hasPrototype) {
- // Simple void foo(), where the incoming T is the result type.
- T = Context.getFunctionTypeNoProto(T);
-
- // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
- if (FTI.NumArgs != 0)
- 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;
- }
- }
-
- ArgTys.push_back(ArgTy);
- }
- T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
- FTI.isVariadic);
- }
- break;
- }
- }
-
- 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();
-}
-
-AttributeList *Sema::ProcessTypeAttributes(QualType &Result, 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 and delete attributes that apply to the
- // type and leave the others alone.
- llvm::SmallVector<AttributeList *, 8> LeftOverAttrs;
- while (AL) {
- // Unlink this attribute from the chain, so we can process it independently.
- AttributeList *ThisAttr = AL;
- AL = AL->getNext();
- ThisAttr->setNext(0);
-
- // If this is an attribute we can handle, do so now, otherwise, add it to
- // the LeftOverAttrs list for rechaining.
- switch (ThisAttr->getKind()) {
- default: break;
- case AttributeList::AT_address_space:
- Result = HandleAddressSpaceTypeAttribute(Result, ThisAttr);
- delete ThisAttr; // Consume the attribute.
- continue;
- }
-
- LeftOverAttrs.push_back(ThisAttr);
- }
-
- // Rechain any attributes that haven't been deleted to the DeclSpec.
- AttributeList *List = 0;
- for (unsigned i = 0, e = LeftOverAttrs.size(); i != e; ++i) {
- LeftOverAttrs[i]->setNext(List);
- List = LeftOverAttrs[i];
- }
-
- return List;
-}
-
-/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
-/// specified type.
-QualType Sema::HandleAddressSpaceTypeAttribute(QualType Type,
- AttributeList *Attr) {
- // 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()) {
- Diag(Attr->getLoc(), diag::err_attribute_address_multiple_qualifiers);
- return Type;
- }
-
- // Check the attribute arguments.
- if (Attr->getNumArgs() != 1) {
- Diag(Attr->getLoc(), diag::err_attribute_wrong_number_arguments,
- std::string("1"));
- return Type;
- }
- Expr *ASArgExpr = static_cast<Expr *>(Attr->getArg(0));
- llvm::APSInt addrSpace(32);
- if (!ASArgExpr->isIntegerConstantExpr(addrSpace, Context)) {
- Diag(Attr->getLoc(), diag::err_attribute_address_space_not_int,
- ASArgExpr->getSourceRange());
- return Type;
- }
-
- unsigned ASIdx = static_cast<unsigned>(addrSpace.getZExtValue());
- return Context.getASQualType(Type, ASIdx);
-}
-
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-Apple/CFDate.m b/clang/test/Analysis-Apple/CFDate.m
deleted file mode 100644
index 64894da6c564..000000000000
--- a/clang/test/Analysis-Apple/CFDate.m
+++ /dev/null
@@ -1,109 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-#include <CoreFoundation/CFDate.h>
-#include <Foundation/NSDate.h>
-#include <Foundation/NSCalendarDate.h>
-#include <Foundation/NSString.h>
-
-CFAbsoluteTime f1() {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(NULL, 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(NULL, 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(NULL, 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(NULL, 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(NULL, t);
-
- if (x)
- CFRelease(date);
-
- return t; // expected-warning{{leak}}
-}
-
-// Test a leak involving the return.
-
-CFDateRef f6(int x) {
- CFDateRef date = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
- CFRetain(date);
- return date; // expected-warning{{leak}}
-}
-
-// Test a leak involving an overwrite.
-
-CFDateRef f7() {
- CFDateRef date = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
- CFRetain(date); //expected-warning{{leak}}
- date = CFDateCreate(NULL, 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}}
-}
-
-
diff --git a/clang/test/Analysis-Apple/CFDateGC.m b/clang/test/Analysis-Apple/CFDateGC.m
deleted file mode 100644
index 9511066fe7fe..000000000000
--- a/clang/test/Analysis-Apple/CFDateGC.m
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -checker-cfref -verify -fobjc-gc %s
-
-#include <CoreFoundation/CFDate.h>
-#include <Foundation/NSDate.h>
-#include <Foundation/NSZone.h>
-
-CFAbsoluteTime f1() {
- CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
- CFDateRef date = CFDateCreate(NULL, 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-Apple/CFString.c b/clang/test/Analysis-Apple/CFString.c
deleted file mode 100644
index ebd9275e1059..000000000000
--- a/clang/test/Analysis-Apple/CFString.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-#include <CoreFoundation/CFString.h>
-#include <CoreFoundation/CFArray.h>
-
-void f1() {
-
- // Create the array.
- CFMutableArrayRef A = CFArrayCreateMutable(NULL, 10, &kCFTypeArrayCallBacks);
-
- // Create a string.
- CFStringRef s1 = CFStringCreateWithCString(NULL, "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-Apple/NSString.m b/clang/test/Analysis-Apple/NSString.m
deleted file mode 100644
index 93e51ab73033..000000000000
--- a/clang/test/Analysis-Apple/NSString.m
+++ /dev/null
@@ -1,45 +0,0 @@
-// RUN: clang -checker-cfref -verify %s
-
-#include <CoreFoundation/CFString.h>
-#include <Foundation/NSString.h>
-#include <Foundation/NSObjCRuntime.h>
-#include <Foundation/NSArray.h>
-
-NSComparisonResult f1(NSString* s) {
- NSString *aString = nil;
- return [s compare:aString]; // expected-warning {{Argument to 'NSString' method 'compare:' cannot be nil.}}
-}
-
-NSComparisonResult f2(NSString* s) {
- NSString *aString = nil;
- return [s caseInsensitiveCompare:aString]; // expected-warning {{Argument to 'NSString' method 'caseInsensitiveCompare:' cannot be nil.}}
-}
-
-NSComparisonResult f3(NSString* s, NSStringCompareOptions op) {
- NSString *aString = nil;
- 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 = nil;
- 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 = nil;
- return [s compare:aString options:op range:R locale:nil]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:locale:' cannot be nil.}}
-}
-
-NSComparisonResult f6(NSString* s) {
- return [s componentsSeparatedByCharactersInSet:nil]; // expected-warning {{Argument to 'NSString' method 'componentsSeparatedByCharactersInSet:' cannot be nil.}}
-}
-
-NSString* f7(NSString* s1, NSString* s2, NSString* s3) {
-
- NSString* s4 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- L"%@ %@ (%@)",
- s1, s2, s3);
-
- CFRetain(s4);
- return s4; // expected-warning{{leak}}
-}
diff --git a/clang/test/Analysis-Apple/NoReturn.m b/clang/test/Analysis-Apple/NoReturn.m
deleted file mode 100644
index 3447bfbc94c8..000000000000
--- a/clang/test/Analysis-Apple/NoReturn.m
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-// RUN: clang -checker-cfref -verify %s
-
-
-#include <Foundation/NSException.h>
-#include <Foundation/NSString.h>
-
-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:nil] raise];
-
- return *x; // no-warning
-}
-
diff --git a/clang/test/Analysis-Apple/uninit-msg-expr.m b/clang/test/Analysis-Apple/uninit-msg-expr.m
deleted file mode 100644
index f054d7ab6cff..000000000000
--- a/clang/test/Analysis-Apple/uninit-msg-expr.m
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-
-#include <Foundation/NSString.h>
-#include <Foundation/NSArray.h>
-
-unsigned f1() {
- NSString *aString;
- return [aString length]; // expected-warning {{Receiver in message expression is an uninitialized value}}
-}
-
-unsigned f2() {
- NSString *aString = nil;
- 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/conditional-op-missing-lhs.c b/clang/test/Analysis/conditional-op-missing-lhs.c
deleted file mode 100644
index 917212d38774..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}}
-}
-
-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 2ec9b48f0065..000000000000
--- a/clang/test/Analysis/dead-stores.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// RUN: clang -warn-dead-stores -verify %s
-
-void f1() {
- int k, y;
- int abc=1;
- long idx=abc+3*5; // expected-warning {{value stored to variable is never used}}
-}
-
-void f2(void *b) {
- char *c = (char*)b; // no-warning
- char *d = b+1; // expected-warning {{value stored to variable is never used}}
- 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 {{value stored to variable is never used}}
-}
-
-void f5() {
-
- int x = 4; // no-warning
- int *p = &x; // expected-warning{{value stored to variable is never used}}
-
-}
-
-int f6() {
-
- int x = 4;
- ++x; // expected-warning{{value stored to variable is never used}}
- return 1;
-}
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/null-deref-ps.c b/clang/test/Analysis/null-deref-ps.c
deleted file mode 100644
index 86691bd9a39e..000000000000
--- a/clang/test/Analysis/null-deref-ps.c
+++ /dev/null
@@ -1,58 +0,0 @@
-// RUN: clang -checker-simple -verify %s
-
-#include<stdint.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 = 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
-}
-
diff --git a/clang/test/Analysis/stack-addr-ps.c b/clang/test/Analysis/stack-addr-ps.c
deleted file mode 100644
index c59df0904dd5..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-allocated variable returned.}} expected-warning{{address of stack memory associated with local variable 'x' returned}}
-}
-
-int* f2(int y) {
- return &y; // expected-warning{{Address of stack-allocated variable 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-allocated variable returned.}}
-}
-
-
diff --git a/clang/test/Analysis/uninit-vals-ps.c b/clang/test/Analysis/uninit-vals-ps.c
deleted file mode 100644
index 503ab1abbccf..000000000000
--- a/clang/test/Analysis/uninit-vals-ps.c
+++ /dev/null
@@ -1,35 +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}}
-}
-
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/CodeGen/2007-11-29-ArraySizeFromInitializer.c b/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c
deleted file mode 100644
index 6c53ff0c6fa1..000000000000
--- a/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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 996cc4c56a83..000000000000
--- a/clang/test/CodeGen/2008-02-07-bitfield-bug.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -emit-llvm
-// 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 1a9c266fe7f4..000000000000
--- a/clang/test/CodeGen/2008-02-08-bitfield-bug.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-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/OpaqueStruct.c b/clang/test/CodeGen/OpaqueStruct.c
deleted file mode 100644
index ecf81fa83075..000000000000
--- a/clang/test/CodeGen/OpaqueStruct.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -emit-llvm
-typedef struct a b;
-
-b* x;
-
-struct a {
- b* p;
-};
-
-void f() {
- b* z = x->p;
-}
diff --git a/clang/test/CodeGen/address-space.c b/clang/test/CodeGen/address-space.c
deleted file mode 100644
index 20f41821a12f..000000000000
--- a/clang/test/CodeGen/address-space.c
+++ /dev/null
@@ -1,9 +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
-int foo __attribute__((address_space(1)));
-int ban[10] __attribute__((address_space(1)));
-
-int bar() { return foo; }
-
-int baz(int i) { return ban[i]; }
diff --git a/clang/test/CodeGen/array.c b/clang/test/CodeGen/array.c
deleted file mode 100644
index 58efce7fd779..000000000000
--- a/clang/test/CodeGen/array.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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 a80d4666cbf4..000000000000
--- a/clang/test/CodeGen/atomic.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: clang %s -emit-llvm -o - > %t1
-// RUN: grep @llvm.atomic.las.i32 %t1
-// RUN: grep @llvm.atomic.lss.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.lcs.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 a310a3ab6441..000000000000
--- a/clang/test/CodeGen/attributes.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep 't1.*noreturn'
-void t1() __attribute__((noreturn));
-void t1() {}
-
-// RUN: clang -emit-llvm < %s | grep 't2.*nounwind'
-void t2() __attribute__((nothrow));
-void t2() {}
-
-// RUN: clang -emit-llvm < %s | grep 'weak.*t3'
-void t3() __attribute__((weak));
-void t3() {}
-
-// RUN: clang -emit-llvm < %s | grep 'hidden.*t4'
-void t4() __attribute__((visibility("hidden")));
-void t4() {}
-
-// RUN: clang -emit-llvm < %s | grep 't5.*weak'
-int t5 __attribute__((weak)) = 2;
-
-// RUN: clang -emit-llvm < %s | grep 't6.*protected'
-int t6 __attribute__((visibility("protected")));
-
-// RUN: clang -emit-llvm < %s | grep 't7.*noreturn'
-// RUN: clang -emit-llvm < %s | grep 't7.*nounwind'
-void t7() __attribute__((noreturn, nothrow));
-void t7() {}
diff --git a/clang/test/CodeGen/bitfield-init.c b/clang/test/CodeGen/bitfield-init.c
deleted file mode 100644
index 6e89e1185a4d..000000000000
--- a/clang/test/CodeGen/bitfield-init.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -emit-llvm
-typedef struct { unsigned int i: 1; } c;
-const c d = { 1 };
-
diff --git a/clang/test/CodeGen/bitfield.c b/clang/test/CodeGen/bitfield.c
deleted file mode 100644
index 740c41c5369e..000000000000
--- a/clang/test/CodeGen/bitfield.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: clang %s -emit-llvm -o - > %t1
-// RUN: grep "shl i32 %tmp, 19" %t1 &&
-// RUN: grep "ashr i32 %tmp1, 19" %t1 &&
-// RUN: grep "shl i16 %tmp4, 1" %t1 &&
-// RUN: grep "lshr i16 %tmp5, 9" %t1
-// RUN: grep "and i32 %tmp, -8192" %t1
-// RUN: grep "and i16 %tmp5, -32513" %t1
-// RUN: grep "getelementptr (i32\* bitcast (.struct.STestB2\* @stb2 to i32\*), i32 1)" %t1
-// Test bitfield access
-
-
-struct STestB1 { int a:13; char b; unsigned short c:7;} stb1;
-struct STestB2 { short a[3]; int b:15} stb2;
-
-int f() {
- return stb1.a + stb1.b + stb1.c;
-}
-
-void g() {
- stb1.a = -40;
- stb1.b = 10;
- stb1.c = 15;
-}
-
-int h() {
- return stb2.a[1] + stb2.b;
-}
-
-void i(){
- stb2.a[2] = -40;
- stb2.b = 10;
-}
diff --git a/clang/test/CodeGen/boolassign.c b/clang/test/CodeGen/boolassign.c
deleted file mode 100644
index 7f76a9245900..000000000000
--- a/clang/test/CodeGen/boolassign.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-int testBoolAssign(void) {
-int ss;
-if ((ss = ss && ss)) {}
-}
diff --git a/clang/test/CodeGen/cast.c b/clang/test/CodeGen/cast.c
deleted file mode 100644
index dfd9bb87c3af..000000000000
--- a/clang/test/CodeGen/cast.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-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 c7df1b303397..000000000000
--- a/clang/test/CodeGen/cfstring.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm %s
-#define CFSTR __builtin___CFStringMakeConstantString
-
-void f() {
- CFSTR("Hello, World!");
-} \ No newline at end of file
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.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 5b2eb3f3d5eb..000000000000
--- a/clang/test/CodeGen/conditional-gnu-ext.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm %s
-// 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 ae4420711502..000000000000
--- a/clang/test/CodeGen/conditional.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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;
-}
diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c
deleted file mode 100644
index e3f110d64ed8..000000000000
--- a/clang/test/CodeGen/const-init.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang -emit-llvm %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;
-int c();
-void *d = c;
-intptr_t e = c;
diff --git a/clang/test/CodeGen/cxx-default-arg.cpp b/clang/test/CodeGen/cxx-default-arg.cpp
deleted file mode 100644
index 957b60a8d75a..000000000000
--- a/clang/test/CodeGen/cxx-default-arg.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-// 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/dostmt.c b/clang/test/CodeGen/dostmt.c
deleted file mode 100644
index b721974dc574..000000000000
--- a/clang/test/CodeGen/dostmt.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-int bar();
-int foo() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- i = bar();
- } while(0);
- return i;
-}
-
-
-int foo1() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- break;
- i = bar();
- } while(1);
- return i;
-}
-
-
-int foo2() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- continue;
- i = bar();
- } while(1);
- return i;
-}
-
-
-int foo3() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- break;
- } while(0);
- return i;
-}
-
-
-int foo4() {
- int i;
- i = 1 + 2;
- do {
- i = bar();
- if (i == 42)
- continue;
- } while(0);
- return i;
-}
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 b4384ee0c2ae..000000000000
--- a/clang/test/CodeGen/exprs.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-// 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());
-}
-
diff --git a/clang/test/CodeGen/extern-block-var.c b/clang/test/CodeGen/extern-block-var.c
deleted file mode 100644
index ea8df7bfc679..000000000000
--- a/clang/test/CodeGen/extern-block-var.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-int f() {
- extern int a;
- return a;
-}
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/functions.c b/clang/test/CodeGen/functions.c
deleted file mode 100644
index 09cb9786dac2..000000000000
--- a/clang/test/CodeGen/functions.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -emit-llvm
-int g();
-
-int foo(int i) {
- return g(i);
-}
-
-int g(int i) {
- return g(i);
-}
-
diff --git a/clang/test/CodeGen/global-with-initialiser.c b/clang/test/CodeGen/global-with-initialiser.c
deleted file mode 100644
index 2e4bdf8840ed..000000000000
--- a/clang/test/CodeGen/global-with-initialiser.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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 a5535b5853ad..000000000000
--- a/clang/test/CodeGen/globalinit.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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/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 fdb61882281d..000000000000
--- a/clang/test/CodeGen/int-to-pointer.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-void *test(int i)
-{
- return (void *)i;
-}
diff --git a/clang/test/CodeGen/mandel.c b/clang/test/CodeGen/mandel.c
deleted file mode 100644
index f9b59722163a..000000000000
--- a/clang/test/CodeGen/mandel.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-/* 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
-
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#include <complex.h>
-#elif defined(__APPLE__)
-#include <math.h>
-#else
-#include <tgmath.h>
-#endif
-
-#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-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 3313b127f015..000000000000
--- a/clang/test/CodeGen/ocu-vector.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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 33706aa9d88b..000000000000
--- a/clang/test/CodeGen/opaque-pointer.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: clang %s -emit-llvm
-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 6b4de9111285..000000000000
--- a/clang/test/CodeGen/pointer-arithmetic.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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-to-int.c b/clang/test/CodeGen/pointer-to-int.c
deleted file mode 100644
index 7599e0d4abea..000000000000
--- a/clang/test/CodeGen/pointer-to-int.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-int test(void* i)
-{
- return (int)i;
-}
diff --git a/clang/test/CodeGen/shared-string-literals.c b/clang/test/CodeGen/shared-string-literals.c
deleted file mode 100644
index 45b2f95a61e2..000000000000
--- a/clang/test/CodeGen/shared-string-literals.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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/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-literal.c b/clang/test/CodeGen/string-literal.c
deleted file mode 100644
index 8b39dfcdb1d5..000000000000
--- a/clang/test/CodeGen/string-literal.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-int main() {
- char a[10] = "abc";
-}
diff --git a/clang/test/CodeGen/struct-x86-darwin.c b/clang/test/CodeGen/struct-x86-darwin.c
deleted file mode 100644
index 3d3729dc9b9c..000000000000
--- a/clang/test/CodeGen/struct-x86-darwin.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: clang < %s -emit-llvm > %t1
-// 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
-// FIXME : Enable this test for x86-darwin only. At the moment clang hard codes
-// x86-darwin as the 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 1b476f823d5a..000000000000
--- a/clang/test/CodeGen/struct.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-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};
-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;}
diff --git a/clang/test/CodeGen/switch.c b/clang/test/CodeGen/switch.c
deleted file mode 100644
index a21505ef89cf..000000000000
--- a/clang/test/CodeGen/switch.c
+++ /dev/null
@@ -1,76 +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) {
-
- }
- }
-}
-
diff --git a/clang/test/CodeGen/trunc-array-initializer.c b/clang/test/CodeGen/trunc-array-initializer.c
deleted file mode 100644
index 6f4caf458813..000000000000
--- a/clang/test/CodeGen/trunc-array-initializer.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-int ary[2] = { 1, 2, 3 };
diff --git a/clang/test/CodeGen/typedef.c b/clang/test/CodeGen/typedef.c
deleted file mode 100644
index 291f0c89dba5..000000000000
--- a/clang/test/CodeGen/typedef.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -emit-llvm %s
-
-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.c b/clang/test/CodeGen/union.c
deleted file mode 100644
index b47e697adc51..000000000000
--- a/clang/test/CodeGen/union.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-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; }
-
diff --git a/clang/test/CodeGen/vector.c b/clang/test/CodeGen/vector.c
deleted file mode 100644
index 52ad19fc15f7..000000000000
--- a/clang/test/CodeGen/vector.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -emit-llvm %s
-typedef short __v4hi __attribute__ ((__vector_size__ (8)));
-
-void f()
-{
- __v4hi A = (__v4hi)0LL;
-}
diff --git a/clang/test/CodeGen/weak-global.c b/clang/test/CodeGen/weak-global.c
deleted file mode 100644
index 86e551c1ead5..000000000000
--- a/clang/test/CodeGen/weak-global.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -emit-llvm < %s | grep weak
-
-int i;
diff --git a/clang/test/CodeGen/whilestmt.c b/clang/test/CodeGen/whilestmt.c
deleted file mode 100644
index 8ded265d0c04..000000000000
--- a/clang/test/CodeGen/whilestmt.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// RUN: clang %s -emit-llvm
-
-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 36cb9b58147d..000000000000
--- a/clang/test/CodeGen/writable-strings.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang -emit-llvm -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 41fd7a72d81f..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/Lexer/11-27-2007-FloatLiterals.c b/clang/test/Lexer/11-27-2007-FloatLiterals.c
deleted file mode 100644
index 3f938576a7fa..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 30e6d92eee22..000000000000
--- a/clang/test/Lexer/block_cmt_end.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- RUN: clang -E %s | grep bar &&
- RUN: clang -E %s | grep foo &&
- RUN: clang -E %s | not grep abc &&
- RUN: clang -E %s | not grep xyz &&
- RUN: clang -fsyntax-only -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 84d30467b949..000000000000
--- a/clang/test/Lexer/c90.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -std=c90 -fsyntax-only %s -verify
-
-enum { cast_hex = (long) (
- 0x0p-1 /* expected-error {{invalid suffix 'p' on integer constant}} */
- ) };
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.cpp b/clang/test/Lexer/digraph.cpp
deleted file mode 100644
index 07c085a1d55d..000000000000
--- a/clang/test/Lexer/digraph.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -fsyntax-only %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 235ee51ef014..000000000000
--- a/clang/test/Lexer/escape_newline.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang -E %s | grep -- ' ->' &&
-// RUN: clang -E %s 2>&1 | grep 'backslash and newline separated by space' &&
-// RUN: clang -E %s 2>&1 | grep 'trigraph converted'
-
-// This is an ugly way to spell a -> token.
- -??/
->
diff --git a/clang/test/Lexer/number.c b/clang/test/Lexer/number.c
deleted file mode 100644
index 4e12cc7edce3..000000000000
--- a/clang/test/Lexer/number.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-float X = 1.17549435e-38F;
-
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/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 35f9025934a2..000000000000
--- a/clang/test/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-LEVEL = ../../..
-include $(LEVEL)/Makefile.common
-
-TESTDIRS = CodeGen Lexer Preprocessor Parser Sema Analysis Serialization
-
-# Only run rewriter tests on darwin.
-ifeq ($(OS),Darwin)
-TESTDIRS += Rewriter Analysis-Apple
-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' \))))
-
-Output/%.testresults: %
- @ $(PROGRESS)
- @ PATH=$$PATH:$(ToolDir):$(LLVM_SRC_ROOT)/test/Scripts VG=$(VG) ./TestRunner.sh $< > $@ || $(REPORTFAIL)
-
-all::
- @ mkdir -p $(addprefix Output/, $(TESTDIRS))
- @ rm -f $(TESTS)
- @ echo '--- Running clang tests ---'
- @ $(MAKE) $(TESTS)
- @ $(DONE)
-
-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 c988ccb977e3..000000000000
--- a/clang/test/Misc/diag-checker.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -parse-ast -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 6a19acaaed64..000000000000
--- a/clang/test/Parser/asm.c
+++ /dev/null
@@ -1,10 +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'}}
-}
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/builtin_classify_type.c b/clang/test/Parser/builtin_classify_type.c
deleted file mode 100644
index 6bed9ec666ba..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{{variable length array declared outside of any function}}
- static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{variable length array declared outside of any function}}
-
- 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 62f79dbdf173..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 1e06e981e4c6..000000000000
--- a/clang/test/Parser/cxx-casting.cpp
+++ /dev/null
@@ -1,31 +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);
-}
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/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 693f12e2ffe9..000000000000
--- a/clang/test/Parser/objc-foreach-error-1.m
+++ /dev/null
@@ -1,25 +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'}} \
- // expected-error {{cannot find interface declaration for 'NSConstantString'}}
- { LOOP(); }
-}
-@end
-
diff --git a/clang/test/Parser/objc-init.m b/clang/test/Parser/objc-init.m
deleted file mode 100644
index ce7acaf92534..000000000000
--- a/clang/test/Parser/objc-init.m
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-// rdar://5707001
-
-@interface NSNumber;
-- () METH;
-@end
-
-void test1() {
- id objects[] = {[NSNumber METH]};
-}
-
-void test2(NSNumber x) {
- id objects[] = {[x METH]};
- return 0;
-}
-
-
diff --git a/clang/test/Parser/objc-messaging-1.m b/clang/test/Parser/objc-messaging-1.m
deleted file mode 100644
index 3f6168f6b2ad..000000000000
--- a/clang/test/Parser/objc-messaging-1.m
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: clang %s -parse-noop
-int main ()
-{
- int i,j;
- struct S *p;
- [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];
-}
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 af4f92610cac..000000000000
--- a/clang/test/Parser/objc-quirks.m
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-int @"s" = 5; // expected-error {{unknown}}
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 ef4b94348d0d..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 statment without a @catch and @finally clause}}
- return proc();
- }
-}
-
-
-void bar()
-{
- @try {}// expected-error {{@try statment without a @catch and @finally clause}}
- @"s"; // expected-warning {{result unused}}
-}
-
-void baz()
-{
- @try {}// expected-error {{@try statment 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/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 b7270b572a9f..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/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/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/expr_comma.c b/clang/test/Preprocessor/expr_comma.c
deleted file mode 100644
index 55072723f6bc..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 82bfca36b8f2..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/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/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 095de82bbb70..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 0fcd90d68d1f..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 065c73e93908..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 4fbef7407cfd..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 af9f516f11ce..000000000000
--- a/clang/test/Preprocessor/undef-error.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: not clang %s -pedantic-errors -E
-// PR2045
-
-#define b
-#undef a b
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 0274ff836254..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 298248519d26..000000000000
--- a/clang/test/Rewriter/objc-super-test.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: clang -rewrite-objc %s -o=-
-
-@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 c2aa3486549e..000000000000
--- a/clang/test/Rewriter/objc-synchronized-1.m
+++ /dev/null
@@ -1,16 +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();
-}
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-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 14966dccb364..000000000000
--- a/clang/test/Rewriter/rewrite-try-catch.m
+++ /dev/null
@@ -1,23 +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;
-}
-}
-
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/DoubleMethod.m b/clang/test/Sema/DoubleMethod.m
deleted file mode 100644
index 70c7ed55f1e2..000000000000
--- a/clang/test/Sema/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/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/alias-test-1.m b/clang/test/Sema/alias-test-1.m
deleted file mode 100644
index fdaccf3f8bcc..000000000000
--- a/clang/test/Sema/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/Sema/alias-test-2.m b/clang/test/Sema/alias-test-2.m
deleted file mode 100644
index 0a17846685cd..000000000000
--- a/clang/test/Sema/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/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/argument-checking.m b/clang/test/Sema/argument-checking.m
deleted file mode 100644
index 820a2f09c794..000000000000
--- a/clang/test/Sema/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/Sema/array-constraint.c b/clang/test/Sema/array-constraint.c
deleted file mode 100644
index 3ed5215accb1..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 {{variable length array declared outside of any function}}
-
-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 56be42c695f0..000000000000
--- a/clang/test/Sema/array-init.c
+++ /dev/null
@@ -1,210 +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 constant}}
-int ary2[] = { x, y, z }; // expected-error{{initializer element is not 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-error{{at least one initializer value required to size array}} 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-warning{{braces around scalar initializer}}
-int u2 = {{3}}; //expected-warning{{braces around scalar initializer}}
-
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
deleted file mode 100644
index 360af015ce81..000000000000
--- a/clang/test/Sema/asm.c
+++ /dev/null
@@ -1,27 +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}}
-}
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/attributes.c b/clang/test/Sema/attributes.c
deleted file mode 100644
index f018c3356fc4..000000000000
--- a/clang/test/Sema/attributes.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/builtins.c b/clang/test/Sema/builtins.c
deleted file mode 100644
index 58cb92f5134b..000000000000
--- a/clang/test/Sema/builtins.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify -pedantic
-
-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/category-1.m b/clang/test/Sema/category-1.m
deleted file mode 100644
index 40993e8762f6..000000000000
--- a/clang/test/Sema/category-1.m
+++ /dev/null
@@ -1,38 +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', referenced by 'Category1'}}
-@end
-
-@interface MyClass1 (Category1) // expected-error {{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-error {{duplicate interface declaration for category 'MyClass1(Category4)'}}
-@interface MyClass1 (Category7) @end // expected-error {{duplicate interface declaration for category 'MyClass1(Category7)'}}
-@interface MyClass1 (Category8) @end // expected-error {{duplicate interface declaration for category 'MyClass1(Category8)'}}
-
-
-@protocol p3 @end
-
-@interface MyClass1 (Category) <p2, p3> @end // expected-warning {{cannot find protocol definition for 'p2', referenced by 'Category'}}
-
-@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'}}
-
-
diff --git a/clang/test/Sema/check-dup-decl-methods-1.m b/clang/test/Sema/check-dup-decl-methods-1.m
deleted file mode 100644
index 36a98a24a462..000000000000
--- a/clang/test/Sema/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/Sema/check-dup-objc-decls-1.m b/clang/test/Sema/check-dup-objc-decls-1.m
deleted file mode 100644
index e3902bdcca32..000000000000
--- a/clang/test/Sema/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/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/class-conforming-protocol-1.m b/clang/test/Sema/class-conforming-protocol-1.m
deleted file mode 100644
index 6afee0d3d4d7..000000000000
--- a/clang/test/Sema/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/Sema/class-def-test-1.m b/clang/test/Sema/class-def-test-1.m
deleted file mode 100644
index 72702d9d18bc..000000000000
--- a/clang/test/Sema/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', referenced by '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/Sema/class-impl-1.m b/clang/test/Sema/class-impl-1.m
deleted file mode 100644
index dedce58d2c0f..000000000000
--- a/clang/test/Sema/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/Sema/class-names.cpp b/clang/test/Sema/class-names.cpp
deleted file mode 100644
index b78d6964e260..000000000000
--- a/clang/test/Sema/class-names.cpp
+++ /dev/null
@@ -1,50 +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;
diff --git a/clang/test/Sema/class-proto-1.m b/clang/test/Sema/class-proto-1.m
deleted file mode 100644
index f38eaea4c196..000000000000
--- a/clang/test/Sema/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', referenced by 'E1'}}
-
-@protocol p2 @end
-
-
-@interface I2 <p1,p2> @end
-
-@interface E2 <p1,p2,p3> @end // expected-warning {{cannot find protocol definition for 'p3', referenced by 'E2'}}
-
-@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/Sema/cocoa.m b/clang/test/Sema/cocoa.m
deleted file mode 100644
index 7cb1b5295c5b..000000000000
--- a/clang/test/Sema/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/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 d7244d113bbf..000000000000
--- a/clang/test/Sema/complex-int.c
+++ /dev/null
@@ -1,43 +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);
-}
-
diff --git a/clang/test/Sema/compound-literal.c b/clang/test/Sema/compound-literal.c
deleted file mode 100644
index 83657245f501..000000000000
--- a/clang/test/Sema/compound-literal.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-struct foo { int a, b; };
-
-static struct foo t = (struct foo){0,0}; // -expected-error {{initializer element is not constant}}
-static struct foo t2 = {0,0};
-static struct foo t3 = t2; // -expected-error {{initializer element is not constant}}
-static int *p = (int []){2,4};
-static int x = (int){1}; // -expected-error {{initializer element is not constant}} -expected-warning{{braces around scalar initializer}}
-
-static int *p2 = (int []){2,x}; // -expected-error {{initializer element is not constant}}
-static int *p3 = (int []){2,"x"}; // -expected-warning {{incompatible pointer to integer conversion initializing 'char [2]', expected 'int'}}
-
-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 });
-}
-
-
diff --git a/clang/test/Sema/conditional-expr.c b/clang/test/Sema/conditional-expr.c
deleted file mode 100644
index a21914c6d5cc..000000000000
--- a/clang/test/Sema/conditional-expr.c
+++ /dev/null
@@ -1,38 +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;
-}
-
diff --git a/clang/test/Sema/conditional.c b/clang/test/Sema/conditional.c
deleted file mode 100644
index 3af0fe57b430..000000000000
--- a/clang/test/Sema/conditional.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-const char* test1 = 1 ? "i" : 1 == 1 ? "v" : "r";
-
diff --git a/clang/test/Sema/conflicting-ivar-test-1.m b/clang/test/Sema/conflicting-ivar-test-1.m
deleted file mode 100644
index 6f24e8cb3aa6..000000000000
--- a/clang/test/Sema/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/Sema/cxx-namespace.cpp b/clang/test/Sema/cxx-namespace.cpp
deleted file mode 100644
index df0fa253ef5c..000000000000
--- a/clang/test/Sema/cxx-namespace.cpp
+++ /dev/null
@@ -1,53 +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 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/Sema/cxx-references.cpp b/clang/test/Sema/cxx-references.cpp
deleted file mode 100644
index 3637573b445e..000000000000
--- a/clang/test/Sema/cxx-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/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/default1.cpp b/clang/test/Sema/default1.cpp
deleted file mode 100644
index fe019c847a70..000000000000
--- a/clang/test/Sema/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/Sema/default2.cpp b/clang/test/Sema/default2.cpp
deleted file mode 100644
index d3e999c34c6d..000000000000
--- a/clang/test/Sema/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/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/enhanced-proto-2.m b/clang/test/Sema/enhanced-proto-2.m
deleted file mode 100644
index 82e23c4b63fc..000000000000
--- a/clang/test/Sema/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/Sema/enum.c b/clang/test/Sema/enum.c
deleted file mode 100644
index 890b6a505b72..000000000000
--- a/clang/test/Sema/enum.c
+++ /dev/null
@@ -1,30 +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;
-}
diff --git a/clang/test/Sema/expr-address-of.c b/clang/test/Sema/expr-address-of.c
deleted file mode 100644
index 46ba5dae4dd2..000000000000
--- a/clang/test/Sema/expr-address-of.c
+++ /dev/null
@@ -1,33 +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}}
-}
-
diff --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c
deleted file mode 100644
index 01758772874e..000000000000
--- a/clang/test/Sema/exprs.c
+++ /dev/null
@@ -1,11 +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}}
-}
-
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 c1e690a3b80e..000000000000
--- a/clang/test/Sema/format-strings.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-#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}}
- 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}}
-}
-
-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 {{should not be a wide string}}
- vasprintf(&b,L"bar %d",ap); // 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 *'}}
-} \ No newline at end of file
diff --git a/clang/test/Sema/forward-class-1.m b/clang/test/Sema/forward-class-1.m
deleted file mode 100644
index 2b9369ba5f8a..000000000000
--- a/clang/test/Sema/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/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/id_builtin.m b/clang/test/Sema/id_builtin.m
deleted file mode 100644
index d7c916146fd1..000000000000
--- a/clang/test/Sema/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/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/incompatible-protocol-qualified-types.m b/clang/test/Sema/incompatible-protocol-qualified-types.m
deleted file mode 100644
index ad8c45e5e0a8..000000000000
--- a/clang/test/Sema/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/Sema/incomplete-decl.c b/clang/test/Sema/incomplete-decl.c
deleted file mode 100644
index 047c24266e38..000000000000
--- a/clang/test/Sema/incomplete-decl.c
+++ /dev/null
@@ -1,19 +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'}}
-}
diff --git a/clang/test/Sema/inherit.cpp b/clang/test/Sema/inherit.cpp
deleted file mode 100644
index f1f96f14e859..000000000000
--- a/clang/test/Sema/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/Sema/init.c b/clang/test/Sema/init.c
deleted file mode 100644
index 9085dbcf0dcd..000000000000
--- a/clang/test/Sema/init.c
+++ /dev/null
@@ -1,32 +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 }
-};
-
diff --git a/clang/test/Sema/invalid-decl.c b/clang/test/Sema/invalid-decl.c
deleted file mode 100644
index 2fa4758bbe93..000000000000
--- a/clang/test/Sema/invalid-decl.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: clang %s -fsyntax-only -verify
-
-void test() {
- char = 4; // expected-error {{expected identifier}} expected-error{{declarator requires an identifier}}
-
-}
-
-
diff --git a/clang/test/Sema/invalid-objc-decls-1.m b/clang/test/Sema/invalid-objc-decls-1.m
deleted file mode 100644
index fa18079d0755..000000000000
--- a/clang/test/Sema/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/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/ivar-sem-check-1.m b/clang/test/Sema/ivar-sem-check-1.m
deleted file mode 100644
index 4e810a29a812..000000000000
--- a/clang/test/Sema/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/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/message.m b/clang/test/Sema/message.m
deleted file mode 100644
index 9c9289b6b858..000000000000
--- a/clang/test/Sema/message.m
+++ /dev/null
@@ -1,63 +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
-
diff --git a/clang/test/Sema/method-def-1.m b/clang/test/Sema/method-def-1.m
deleted file mode 100644
index 2d5f92fcbc1e..000000000000
--- a/clang/test/Sema/method-def-1.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: clang -fsyntax-only %s
-
-@interface foo
-- (int)meth;
-@end
-
-@implementation foo
-- (int) meth { return [self meth]; }
-@end
-
diff --git a/clang/test/Sema/method-def-2.m b/clang/test/Sema/method-def-2.m
deleted file mode 100644
index d31a2b58b9d6..000000000000
--- a/clang/test/Sema/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/Sema/method-encoding-2.m b/clang/test/Sema/method-encoding-2.m
deleted file mode 100644
index 08a579b0a878..000000000000
--- a/clang/test/Sema/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/Sema/method-not-defined.m b/clang/test/Sema/method-not-defined.m
deleted file mode 100644
index 62a8be72e7dc..000000000000
--- a/clang/test/Sema/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/Sema/method-undef-category-warn-1.m b/clang/test/Sema/method-undef-category-warn-1.m
deleted file mode 100644
index 792c24d748f5..000000000000
--- a/clang/test/Sema/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/Sema/method-undefined-warn-1.m b/clang/test/Sema/method-undefined-warn-1.m
deleted file mode 100644
index 9e646f82f73a..000000000000
--- a/clang/test/Sema/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/Sema/missing-method-context.m b/clang/test/Sema/missing-method-context.m
deleted file mode 100644
index 20437b70ec16..000000000000
--- a/clang/test/Sema/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/Sema/missing-string-interface.m b/clang/test/Sema/missing-string-interface.m
deleted file mode 100644
index f96fb4c2e4a5..000000000000
--- a/clang/test/Sema/missing-string-interface.m
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-@class NSString;
-
-// GCC considers this an error, so clang will...
-NSString *s = @"123"; // expected-error: {{cannot find interface declaration for 'NSConstantString'}}
-
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/objc-bad-receiver-1.m b/clang/test/Sema/objc-bad-receiver-1.m
deleted file mode 100644
index 8376a5ced7ac..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-1.m b/clang/test/Sema/objc-comptypes-1.m
deleted file mode 100644
index e47bc63565fc..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-2.m b/clang/test/Sema/objc-comptypes-2.m
deleted file mode 100644
index d063d95cc242..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-3.m b/clang/test/Sema/objc-comptypes-3.m
deleted file mode 100644
index 1e271c8340eb..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-4.m b/clang/test/Sema/objc-comptypes-4.m
deleted file mode 100644
index bda9050164be..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-5.m b/clang/test/Sema/objc-comptypes-5.m
deleted file mode 100644
index f12fa9ab5d44..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-6.m b/clang/test/Sema/objc-comptypes-6.m
deleted file mode 100644
index 2edb181e83bc..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-comptypes-7.m b/clang/test/Sema/objc-comptypes-7.m
deleted file mode 100644
index 6e5ff0282fdd..000000000000
--- a/clang/test/Sema/objc-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-error {{incompatible type 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-error {{incompatible type 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-error {{invalid operands to binary expression ('id<MyProtocol>' and 'int')}}
- if (i == obj_p) foo() ; // expected-error {{invalid operands to binary expression ('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/Sema/objc-comptypes-8.m b/clang/test/Sema/objc-comptypes-8.m
deleted file mode 100644
index c22e88c88050..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-ivar-lookup.m b/clang/test/Sema/objc-ivar-lookup.m
deleted file mode 100644
index e599e9da016a..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-legacy-implementation-1.m b/clang/test/Sema/objc-legacy-implementation-1.m
deleted file mode 100644
index 76434471d149..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-property-1.m b/clang/test/Sema/objc-property-1.m
deleted file mode 100644
index 3bc2e3386b00..000000000000
--- a/clang/test/Sema/objc-property-1.m
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-@interface I
-{
- int IVAR;
- int name;
-}
-@property int d1;
-@property id prop_id;
-@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)
-@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
-
-
-
diff --git a/clang/test/Sema/objc-property-2.m b/clang/test/Sema/objc-property-2.m
deleted file mode 100644
index 4472a8f6955d..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-property-3.m b/clang/test/Sema/objc-property-3.m
deleted file mode 100644
index b22059c23823..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-property-4.m b/clang/test/Sema/objc-property-4.m
deleted file mode 100644
index b5a8f8b1ccb3..000000000000
--- a/clang/test/Sema/objc-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/Sema/objc-property-5.m b/clang/test/Sema/objc-property-5.m
deleted file mode 100644
index c467e634dcce..000000000000
--- a/clang/test/Sema/objc-property-5.m
+++ /dev/null
@@ -1,31 +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
-
diff --git a/clang/test/Sema/objc-string.m b/clang/test/Sema/objc-string.m
deleted file mode 100644
index c73948292d81..000000000000
--- a/clang/test/Sema/objc-string.m
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-@interface NSConstantString;
-@end
-
-
-
-NSConstantString *s = @"123"; // simple
-NSConstantString *t = @"123" @"456"; // concat
-NSConstantString *u = @"123" @ blah; // expected-error: {{unexpected token}}
-
diff --git a/clang/test/Sema/objc-unused.m b/clang/test/Sema/objc-unused.m
deleted file mode 100644
index cbe15a1abb57..000000000000
--- a/clang/test/Sema/objc-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/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/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/protocol-expr-1.m b/clang/test/Sema/protocol-expr-1.m
deleted file mode 100644
index dff2866020d5..000000000000
--- a/clang/test/Sema/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/Sema/protocol-expr-neg-1.m b/clang/test/Sema/protocol-expr-neg-1.m
deleted file mode 100644
index 427e74417ab4..000000000000
--- a/clang/test/Sema/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/Sema/protocol-id-test-1.m b/clang/test/Sema/protocol-id-test-1.m
deleted file mode 100644
index 765500e10d81..000000000000
--- a/clang/test/Sema/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/Sema/protocol-id-test-2.m b/clang/test/Sema/protocol-id-test-2.m
deleted file mode 100644
index 525d2cca9e9d..000000000000
--- a/clang/test/Sema/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/Sema/protocol-id-test-3.m b/clang/test/Sema/protocol-id-test-3.m
deleted file mode 100644
index 8c2beee989c7..000000000000
--- a/clang/test/Sema/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/Sema/protocol-test-1.m b/clang/test/Sema/protocol-test-1.m
deleted file mode 100644
index 6fb28b533cf7..000000000000
--- a/clang/test/Sema/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/Sema/protocol-test-2.m b/clang/test/Sema/protocol-test-2.m
deleted file mode 100644
index f323745c5dfe..000000000000
--- a/clang/test/Sema/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', referenced by 'PROTO2'}}
-@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', referenced by 'PROTO4'}}
-@end
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/return-stack-addr.cpp b/clang/test/Sema/return-stack-addr.cpp
deleted file mode 100644
index c7d1a7f3d6b1..000000000000
--- a/clang/test/Sema/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/Sema/selector-1.m b/clang/test/Sema/selector-1.m
deleted file mode 100644
index 476568f6caa4..000000000000
--- a/clang/test/Sema/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/Sema/selector-overload.m b/clang/test/Sema/selector-overload.m
deleted file mode 100644
index 7bd25444c7e9..000000000000
--- a/clang/test/Sema/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/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/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 e710973700a6..000000000000
--- a/clang/test/Sema/static-init.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-static int f = 10;
-static int b = f; // expected-error {{initializer element is not constant}}
diff --git a/clang/test/Sema/static-ivar-ref-1.m b/clang/test/Sema/static-ivar-ref-1.m
deleted file mode 100644
index d01a7fb6da0c..000000000000
--- a/clang/test/Sema/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/Sema/stmt_exprs.c b/clang/test/Sema/stmt_exprs.c
deleted file mode 100644
index 8165cf03aa43..000000000000
--- a/clang/test/Sema/stmt_exprs.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: clang %s -fsyntax-only
-
-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));
-}
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 f759e37a1df5..000000000000
--- a/clang/test/Sema/struct-packed-align.c
+++ /dev/null
@@ -1,71 +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));
-};
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 0c390fe4144b..000000000000
--- a/clang/test/Sema/tentative-decls.c
+++ /dev/null
@@ -1,24 +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}}
-// FIXME: the following should not be an error (see related FIXME in Sema::MergeVarDecl).
-int i1; // expected-error{{redefinition of '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{{non-static declaration of 'i1' follows static declaration}}
-
-void func() {
- extern int i1; // expected-error{{previous definition is here}}
- static int i1; // expected-error{{static declaration of 'i1' follows non-static declaration}}
-}
diff --git a/clang/test/Sema/typecheck-binop.c b/clang/test/Sema/typecheck-binop.c
deleted file mode 100644
index 05b9ad9067e1..000000000000
--- a/clang/test/Sema/typecheck-binop.c
+++ /dev/null
@@ -1,20 +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}} */
-}
-
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-retain.c b/clang/test/Sema/typedef-retain.c
deleted file mode 100644
index 5e4c978c3a4a..000000000000
--- a/clang/test/Sema/typedef-retain.c
+++ /dev/null
@@ -1,26 +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 z() {
- typedef const a b;
- b r;
- r[0]=10; // expected-error {{read-only variable is not assignable}}
-}
-
-int e(const a y) {
- y[0] = 10; // expected-error {{read-only variable is not assignable}}
-}
-
diff --git a/clang/test/Sema/typedef-variable-type.c b/clang/test/Sema/typedef-variable-type.c
deleted file mode 100644
index 3abca4314e84..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{{variable length array declared outside of any function}}
diff --git a/clang/test/Sema/undef-protocol-methods-1.m b/clang/test/Sema/undef-protocol-methods-1.m
deleted file mode 100644
index 9ad3593c6c4d..000000000000
--- a/clang/test/Sema/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/Sema/undef-superclass-1.m b/clang/test/Sema/undef-superclass-1.m
deleted file mode 100644
index 7e12463654f3..000000000000
--- a/clang/test/Sema/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/Sema/undefined-protocol-type-1.m b/clang/test/Sema/undefined-protocol-type-1.m
deleted file mode 100644
index 117f418ab1c1..000000000000
--- a/clang/test/Sema/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/Sema/unused-expr.c b/clang/test/Sema/unused-expr.c
deleted file mode 100644
index 305c2be06b57..000000000000
--- a/clang/test/Sema/unused-expr.c
+++ /dev/null
@@ -1,37 +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; });
-}
-
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-method-1.m b/clang/test/Sema/va-method-1.m
deleted file mode 100644
index 077982abbf51..000000000000
--- a/clang/test/Sema/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/Sema/varargs.c b/clang/test/Sema/varargs.c
deleted file mode 100644
index f52921c5fca6..000000000000
--- a/clang/test/Sema/varargs.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: clang -fsyntax-only -verify %s
-
-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 6f681813bc9e..000000000000
--- a/clang/test/Sema/vector-assign.c
+++ /dev/null
@@ -1,39 +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; // expected-error {{incompatible type assigning 'v2f', expected 'v2s'}}
- v1 = v5;
-
- v2 = v1;
- v2 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2u'}}
- v2 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2u'}}
- 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; // expected-error {{incompatible type assigning 'v2s', expected 'v2f'}}
- v4 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v2f'}}
- v4 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2f'}}
- v4 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v2f'}}
-
- v5 = v1;
- v5 = v2;
- v5 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v4ss'}}
- v5 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v4ss'}}
-}
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 c1e0e20e63af..000000000000
--- a/clang/test/Sema/vla.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: clang %s -verify -fsyntax-only
-
-int test1() {
- typedef int x[test1()]; // vla
- static int y = sizeof(x); // expected-error {{not constant}}
-}
-
diff --git a/clang/test/Sema/void_arg.c b/clang/test/Sema/void_arg.c
deleted file mode 100644
index 275a1c486432..000000000000
--- a/clang/test/Sema/void_arg.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* RUN: clang -fsyntax-only %s 2>&1 | grep '6 diagnostics'
- */
-
-typedef void Void;
-
-void foo() {
- int X;
-
- X = sizeof(int (void a));
- X = sizeof(int (int, void));
- X = sizeof(int (void, ...));
-
- X = sizeof(int (Void a));
- X = sizeof(int (int, Void));
- X = sizeof(int (Void, ...));
-
- // Accept these.
- X = sizeof(int (void));
- X = sizeof(int (Void));
-}
-
-// this is ok.
-void bar(Void) {
-}
-
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 49a15a46f5bb..000000000000
--- a/clang/test/TestRunner.sh
+++ /dev/null
@@ -1,89 +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.
-# %llvmgcc - llvm-gcc command
-# %llvmgxx - llvm-g++ command
-# %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 "$VG" ]; then
- rm -f $OUTPUT.vg.*
- CLANG="valgrind --leak-check=full --quiet --log-file=$OUTPUT.vg.%p $CLANG"
-fi
-
-SCRIPT=$OUTPUT.script
-TEMPOUTPUT=$OUTPUT.tmp
-grep 'RUN:' $FILENAME | \
- sed -e "s|^.*RUN:\(.*\)$|\1|g" \
- -e "s|%s|$SUBST|g" \
- -e "s|%llvmgcc|llvm-gcc -emit-llvm|g" \
- -e "s|%llvmgxx|llvm-g++ -emit-llvm|g" \
- -e "s|%prcontext|prcontext.tcl|g" \
- -e "s|%t|$TEMPOUTPUT|g" \
- -e "s|clang|$CLANG|g" > $SCRIPT
-
-grep -q XFAIL $FILENAME && (printf "XFAILED '$TESTNAME': "; grep XFAIL $FILENAME)
-
-/bin/sh $SCRIPT > $OUTPUT 2>&1
-SCRIPT_STATUS=$?
-
-if [ -n "$VG" ]; then
- VG_STATUS=`cat $OUTPUT.vg.* | wc -l`
-else
- VG_STATUS=0
-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:"
- 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/utils/ccc b/clang/utils/ccc
deleted file mode 100755
index fd909f914949..000000000000
--- a/clang/utils/ccc
+++ /dev/null
@@ -1,213 +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 sys
-import subprocess
-
-def error(message):
- print >> sys.stderr, 'ccc: ' + message
- sys.exit(1)
-
-def quote(arg):
- if '"' in arg:
- return repr(arg)
- return arg
-
-def run(args):
- print ' '.join(map(quote, args))
- code = subprocess.call(args)
- if code > 255:
- code = 1
- if code:
- sys.exit(code)
-
-def preprocess(args):
- command = 'clang -E'.split()
- run(command + args)
-
-def compile(args):
- command = 'clang -emit-llvm-bc'.split()
- run(command + args)
-
-def link(args):
- command = 'llvm-ld -native -disable-internalize'.split()
- 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)
- print path
- 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 == "mi":
- return "objective-c-cpp-output"
- else:
- return "unknown"
-
-def main(args):
- action = 'link'
- output = ''
- compile_opts = []
- link_opts = []
- files = []
- save_temps = 0
- language = ''
-
- i = 0
- while i < len(args):
- arg = args[i]
-
- # Modes ccc supports
- if arg == '-E':
- action = 'preprocess'
- if arg == '-c':
- action = 'compile'
- if arg.startswith('-print-prog-name'):
- action = 'print-prog-name'
- if arg == '-save-temps':
- save_temps = 1
-
- # Options with no arguments that should pass through
- if arg in ['-v']:
- compile_opts.append(arg)
- link_opts.append(arg)
-
- # Options with one argument that should be ignored
- if arg in ['--param', '-u']:
- 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 arg[:5] in ['-std=']:
- compile_opts.append(arg)
-
- # Options with one argument that should pass through
- if arg in ['-include', '-isysroot', '-arch']:
- compile_opts.append(arg)
- compile_opts.append(args[i+1])
- i += 1
-
- # Prefix matches for the link mode
- if arg[:2] in ['-l', '-L', '-O', '-F']:
- if arg == '-O': arg = '-O1'
- if arg == '-Os': arg = '-O2'
- link_opts.append(arg)
-
- # Options with one argument that should pass through
- if arg in ['-framework', '-isysroot', '-arch']:
- link_opts.append(arg)
- link_opts.append(args[i+1])
- i += 1
-
- # 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
- if poutput:
- args = ['-x', language, '-o', poutput, file] + compile_opts
- else:
- args = ['-x', language, 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 = ['-x', language, '-o', coutput, file] + compile_opts
- compile(args)
- language = ''
-
- if action == 'link':
- for i, file in enumerate(files):
- ext = extension(file)
- if ext != "o" and ext != "a":
- out = changeextension(file, "o")
- args = ['-o', out, file] + compile_opts
- compile(args)
- files[i] = out
- if not output:
- output = 'a.out'
- args = ['-o', output] + link_opts + files
- link(args)
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/clang/utils/ccc-analyzer b/clang/utils/ccc-analyzer
deleted file mode 100755
index d19955381e62..000000000000
--- a/clang/utils/ccc-analyzer
+++ /dev/null
@@ -1,266 +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.
-#
-##===----------------------------------------------------------------------===##
-#
-# A reduced version of the 'ccc' script that is designed to handle off
-# actual compilation to gcc, but run the code passed to gcc through the
-# static analyzer.
-#
-##===----------------------------------------------------------------------===##
-
-import sys
-import subprocess
-import os
-
-def error(message):
- print >> sys.stderr, 'ccc: ' + message
- sys.exit(1)
-
-def quote(arg):
- if '"' in arg:
- return repr(arg)
- return arg
-
-def run(args):
- # We MUST print to stderr. Some clients use the stdout output of
- # gcc for various purposes.
- print >> sys.stderr, ' '.join(map(quote, args))
- print >> sys.stderr
- code = subprocess.call(args)
- if code > 255:
- code = 1
- if code:
- sys.exit(code)
-
-def compile(args):
- # We MUST print to stderr. Some clients use the stdout output of
- # gcc for various purposes.
- print >> sys.stderr, '\n'
- command = 'gcc'.split()
- run(command + args)
-
-def remove_pch_extension(path):
- i = path.rfind('.gch')
- if i < 0:
- return path
- return path[:i]
-
-def analyze(clang, args,language,output,files,verbose,htmldir):
- if language.find("c++") > 0:
- return
-
- print_args = []
-
- if verbose:
- # We MUST print to stderr. Some clients use the stdout output of
- # gcc for various purposes.
- print >> sys.stderr, ' '.join(['\n[LOCATION]:', os.getcwd(), '\n' ])
- i = 0
- while i < len(args):
- print_args.append(''.join([ '\'', args[i], '\'' ]))
- i += 1
-
- if language.find("header") > 0:
- target = remove_pch_extension(output)
- command = 'cp'.split()
- args = command + files + target.split()
- else:
- command = clang.split() + '-checker-cfref'.split()
- args = command + args;
-
- if htmldir is not None:
- args.append('-o')
- print_args.append('-o')
- args.append(htmldir)
- print_args.append(htmldir)
-
- if verbose:
- # We MUST print to stderr. Some clients use the stdout output of
- # gcc for various purposes.
- print >> sys.stderr, ' '.join(command+print_args)
- print >> sys.stderr, '\n'
-
- subprocess.call(args)
-
-def link(args):
- command = 'gcc'.split()
- 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)
- print path
- 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 == "mi":
- return "objective-c-cpp-output"
- else:
- return "unknown"
-
-def main(args):
- old_args = args
- action = 'link'
- output = ''
- compile_opts = [ ]
- link_opts = [ ]
- files = []
- save_temps = 0
- language = ''
-
- verbose = 0
- clang = "clang"
-
-
- if os.environ.get('CCC_ANALYZER_VERBOSE') is not None:
- verbose =1
-
- clang_env = os.environ.get('CLANG')
-
- if clang_env is not None:
- clang = clang_env
-
- htmldir = os.environ.get('CCC_ANALYZER_HTML')
-
- i = 0
- while i < len(args):
- arg = args[i]
-
- # Modes ccc supports
- if arg == '-E':
- action = 'preprocess'
- if arg == '-c':
- action = 'compile'
- if arg.startswith('-print-prog-name'):
- action = 'print-prog-name'
- if arg == '-save-temps':
- save_temps = 1
-
- # Options with no arguments that should pass through
- if arg in ['-v']:
- compile_opts.append(arg)
- link_opts.append(arg)
-
- # Options with one argument that should be ignored
- if arg in ['--param', '-u']:
- 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 arg[:5] in ['-std=']:
- 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 argument that should pass through to compiler
- if arg in [ '-nostdinc', '-fobjc-gc-only', '-fobjc-gc' ]:
- compile_opts.append(arg)
-
- # Options with one argument that should pass through to linker
- if arg == '-framework':
- 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
-
- # Prefix matches for the link mode
- if arg[:2] in ['-l', '-L', '-O', '-F']:
- if arg == '-O': arg = '-O1'
- if arg == '-Os': arg = '-O2'
- link_opts.append(arg)
-
- # 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:
- compile(args)
-
- 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
- analyze_args = [ file ]
- if language != 'unknown':
- analyze_args = analyze_args + [ '-x', language ]
- analyze_args = analyze_args + compile_opts
- analyze(clang, analyze_args, language, output, files, verbose, htmldir)
- compile(args)
-
-
- if action == 'link':
- link(args)
-# analyze(link_opts)
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/clang/utils/scan-build b/clang/utils/scan-build
deleted file mode 100755
index 1514db3970a9..000000000000
--- a/clang/utils/scan-build
+++ /dev/null
@@ -1,677 +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 File::Temp qw/ :mktemp /;
-use FindBin qw($RealBin);
-use Digest::MD5;
-use File::Basename;
-
-my $Verbose = 0; # Verbose output from this script.
-my $Prog = "scan-build";
-
-##----------------------------------------------------------------------------##
-# GetHTMLRunDir - Construct an HTML directory name for the current run.
-##----------------------------------------------------------------------------##
-
-sub GetHTMLRunDir {
-
- die "Not enough arguments." if (@_ == 0);
-
- my $Dir = shift @_;
-
- # Get current date and time.
-
- my @CurrentTime = localtime();
-
- my $year = $CurrentTime[5] + 1900;
- my $day = $CurrentTime[3];
- my $month = $CurrentTime[4] + 1;
-
- my $DateString = "$year-$month-$day";
-
- # Determine the run number.
-
- my $RunNumber;
-
- if (-d $Dir) {
-
- if (! -r $Dir) {
- die "error: '$Dir' exists but is not readable.\n";
- }
-
- # Iterate over all files in the specified directory.
-
- my $max = 0;
-
- opendir(DIR, $Dir);
- my @FILES= readdir(DIR);
- closedir(DIR);
-
- foreach my $f (@FILES) {
-
- 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) {
- die "error: '$Dir' exists but is not a directory.\n";
- }
-
- # $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.
-
- return "$Dir/$DateString-$RunNumber";
-}
-
-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) {
- print "$Prog: 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;
- die "Cannot read $FName" 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 die "Cannot open $FName.";
- 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 =~ /^$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);
- `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.
- `rm -f $Dir/$FName`;
- return;
- }
-
- $AlreadyScanned{$digest} = 1;
-
- # At this point the report file is not world readable. Make it happen.
- `chmod 644 $Dir/$FName`;
-
- # Scan the report file for tags.
- open(IN, "$Dir/$FName") or die "$Prog: Cannot open '$Dir/$FName'\n";
-
- my $BugDesc = "";
- my $BugFile = "";
- my $BugPathLength = 1;
- my $BugLine = 0;
-
- while (<IN>) {
-
- if (/<!-- BUGDESC (.*) -->$/) {
- $BugDesc = $1;
- }
- elsif (/<!-- BUGFILE (.*) -->$/) {
- $BugFile = $1;
- UpdatePrefix($BugFile);
- }
- elsif (/<!-- BUGPATHLENGTH (.*) -->$/) {
- $BugPathLength = $1;
- }
- elsif (/<!-- BUGLINE (.*) -->$/) {
- $BugLine = $1;
- }
- }
-
- close(IN);
-
- push @$Index,[ $FName, $BugDesc, $BugFile, $BugLine, $BugPathLength ];
-}
-
-##----------------------------------------------------------------------------##
-# CopyJS - Copy JavaScript code to target directory.
-##----------------------------------------------------------------------------##
-
-sub CopyJS {
-
- my $Dir = shift;
-
- die "$Prog: Cannot find 'sorttable.js'.\n"
- if (! -r "$RealBin/sorttable.js");
-
- `cp $RealBin/sorttable.js $Dir`;
-
- die "$Prog: Could not copy 'sorttable.js' to '$Dir'."
- if (! -r "$Dir/sorttable.js");
-}
-
-##----------------------------------------------------------------------------##
-# Postprocess - Postprocess the results of an analysis scan.
-##----------------------------------------------------------------------------##
-
-sub Postprocess {
-
- my $Dir = shift;
- my $BaseDir = shift;
-
- die "No directory specified." if (!defined($Dir));
- die "No base directory specified." if (!defined($BaseDir));
-
- if (! -d $Dir) {
- return;
- }
-
- opendir(DIR, $Dir);
- my @files = grep(/^report-.*\.html$/,readdir(DIR));
- closedir(DIR);
-
- if (scalar(@files) == 0) {
- print "$Prog: Removing directory '$Dir' because it contains no reports.\n";
- `rm -fR $Dir`;
- return;
- }
-
- # Scan each report file and build an index.
-
- my @Index;
-
- foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); }
-
- # Generate an index.html file.
-
- my $FName = "$Dir/index.html";
-
- open(OUT, ">$FName") or die "$Prog: Cannot create file '$FName'\n";
-
- # Print out the header.
-
-print OUT <<ENDTEXT;
-<html>
-<head>
-<style type="text/css">
- body { color:#000000; background-color:#ffffff }
- body { font-family: Helvetica, sans-serif; font-size:9pt }
- h1 { font-size:12pt }
- table.sortable 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.sortable { border: 1px #000000 solid }
- table.sortable { border-collapse: collapse; border-spacing: 0px }
- 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>
-<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>
-</head>
-<body>
-ENDTEXT
-
- # Print out the summary table.
-
- my %Totals;
-
- for my $row ( @Index ) {
-
- #my $bug_type = lc($row->[1]);
- my $bug_type = ($row->[1]);
-
- if (!defined($Totals{$bug_type})) {
- $Totals{$bug_type} = 1;
- }
- else {
- $Totals{$bug_type}++;
- }
- }
-
-print OUT <<ENDTEXT;
-<h3>Summary</h3>
-<table class="sortable">
-<tr>
- <td>Bug Type</td>
- <td>Quantity</td>
- <td "sorttable_nosort">Display?</td>
-</tr>
-ENDTEXT
-
- for my $key ( sort { $a cmp $b } keys %Totals ) {
- my $x = lc($key);
- $x =~ s/\s[,]/_/g;
- print OUT "<tr><td>$key</td><td>$Totals{$key}</td><td><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></td></tr>\n";
- }
-
- # Print out the table of errors.
-
-print OUT <<ENDTEXT;
-</table>
-<h3>Reports</h3>
-<table class="sortable">
-<tr>
- <td>Bug Type</td>
- <td>File</td>
- <td>Line</td>
- <td>Path Length</td>
- <td "sorttable_nosort"></td>
-</tr>
-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->[1] cmp $b->[1] } @Index ) {
-
- my $x = lc($row->[1]);
- $x =~ s/\s[,]/_/g;
-
- print OUT "<tr class=\"bt_$x\">\n";
-
- my $ReportFile = $row->[0];
-
- print OUT " <td class=\"DESC\">";
- #print OUT lc($row->[1]);
- print OUT $row->[1];
- print OUT "</td>\n";
-
- # Update the file prefix.
-
- my $fname = $row->[2];
- if (defined($regex)) {
- $fname =~ s/$regex//;
- UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix)
- }
-
- print OUT "<td>$fname</td>\n";
-
- # Print the rest of the columns.
-
- for my $j ( 3 .. $#{$row} ) {
- print OUT "<td>$row->[$j]</td>\n"
- }
-
- # Emit the "View" link.
-
- print OUT " <td class=\"View\"><a href=\"$ReportFile#EndPath\">View</a></td>\n";
-
- # End the row.
- print OUT "</tr>\n";
- }
-
- print OUT "</table>\n</body></html>\n";
- close(OUT);
-
- CopyJS($Dir);
-
- # Make sure $Dir and $BaseDir is world readable/executable.
- `chmod 755 $Dir`;
- `chmod 755 $BaseDir`;
-}
-
-##----------------------------------------------------------------------------##
-# 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];
-
- if ($Cmd eq "gcc" or $Cmd eq "cc" or $Cmd eq "llvm-gcc") {
- shift @$Args;
- unshift @$Args, "ccc-analyzer"
- }
- elsif ($IgnoreErrors) {
- if ($Cmd eq "make" or $Cmd eq "gmake") {
- AddIfNotPresent($Args,"-k");
- }
- elsif ($Cmd eq "xcodebuild") {
- AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
- }
- }
-
- # Disable distributed builds for xcodebuild.
- if ($Cmd eq "xcodebuild") {
- AddIfNotPresent($Args,"-nodistribute");
- }
-
- system(@$Args);
-}
-
-##----------------------------------------------------------------------------##
-# DisplayHelp - Utility function to display all help options.
-##----------------------------------------------------------------------------##
-
-sub DisplayHelp {
-
-print <<ENDTEXT;
-USAGE: $Prog [options] <build command> [build options]
-
-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.
-
- -v - Verbose output from $Prog and the analyzer.
- A second "-v" increases verbosity.
-
- -V - View analysis results in a web browser when the build
- --view completes.
-
-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
-}
-
-##----------------------------------------------------------------------------##
-# 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.
-
-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 ($arg eq "-o") {
- shift @ARGV;
-
- if (!@ARGV) {
- die "$Prog: '-o' option requires a target directory name.\n";
- }
-
- $HtmlDir = shift @ARGV;
- next;
- }
-
- if ($arg eq "-k" or $arg eq "--keep-going") {
- shift @ARGV;
- $IgnoreErrors = 1;
- next;
- }
-
- if ($arg eq "-v") {
- shift @ARGV;
- $Verbose++;
- next;
- }
-
- if ($arg eq "-V" or $arg eq "--view") {
- shift @ARGV;
- $ViewResults = 1;
- next;
- }
-
- die "$Prog: unrecognized option '$arg'\n" if ($arg =~ /^-/);
-
- last;
-}
-
-if (!@ARGV) {
- print STDERR "$Prog: No build command specified.\n\n";
- DisplayHelp();
- exit 1;
-}
-
-# Determine the output directory for the HTML reports.
-
-if (!defined($HtmlDir)) {
-
- $HtmlDir = mkdtemp("/tmp/$Prog-XXXXXX");
-
- if (!defined($HtmlDir)) {
- die "error: Cannot create HTML directory in /tmp.\n";
- }
-
- if (!$Verbose) {
- print "$Prog: Using '$HtmlDir' as base HTML report directory.\n";
- }
-}
-
-my $BaseDir = $HtmlDir;
-$HtmlDir = GetHTMLRunDir($HtmlDir);
-
-# Set the appropriate environment variables.
-
-SetHtmlEnv(\@ARGV, $HtmlDir);
-
-my $Cmd = "$RealBin/ccc-analyzer";
-
-die "$Prog: Executable 'ccc-analyzer' does not exist at '$Cmd'\n"
- if (! -x $Cmd);
-
-my $Clang = "$RealBin/clang";
-
-if (! -x $Clang) {
- print "$Prog: 'clang' executable not found in '$RealBin'. Using 'clang' from path.\n";
- $Clang = "clang";
-}
-
-$ENV{'CC'} = $Cmd;
-$ENV{'CLANG'} = $Clang;
-
-if ($Verbose >= 2) {
- $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
-}
-
-# Run the build.
-
-RunBuildCommand(\@ARGV, $IgnoreErrors);
-
-# Postprocess the HTML directory.
-
-Postprocess($HtmlDir, $BaseDir);
-
-if ($ViewResults and -r "$HtmlDir/index.html") {
- # Only works on Mac OS X (for now).
- print "Viewing analysis results: '$HtmlDir/index.html'\n";
- `open $HtmlDir/index.html`
-}
diff --git a/clang/utils/sorttable.js b/clang/utils/sorttable.js
deleted file mode 100644
index 25bccb2b6b91..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/win32/clangAST/clangAST.vcproj b/clang/win32/clangAST/clangAST.vcproj
deleted file mode 100644
index 1517f9648df4..000000000000
--- a/clang/win32/clangAST/clangAST.vcproj
+++ /dev/null
@@ -1,301 +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"
- 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"
- 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\DeclObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\DeclSerialization.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\Expr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\AST\ExprCXX.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\DeclObjC.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\Expr.h"
- >
- </File>
- <File
- RelativePath="..\..\include\clang\AST\ExprCXX.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 d7d4c153f219..000000000000
--- a/clang/win32/clangAnalysis/clangAnalysis.vcproj
+++ /dev/null
@@ -1,305 +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"
- 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"
- 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\BasicObjCFoundationChecks.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\DeadStores.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\GRSimpleVals.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\GRTransferFuncs.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\LiveVariables.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\PathDiagnostic.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\ProgramPoint.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\RValues.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\SymbolManager.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\UninitializedValues.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Analysis\ValueState.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 e611e30ffbab..000000000000
--- a/clang/win32/clangBasic/clangBasic.vcproj
+++ /dev/null
@@ -1,234 +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"
- 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"
- 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 d7ca5694fe0f..000000000000
--- a/clang/win32/clangCodeGen/clangCodeGen.vcproj
+++ /dev/null
@@ -1,241 +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"
- 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"
- 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\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\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\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 b0e940d25662..000000000000
--- a/clang/win32/clangDriver/clangDriver.vcproj
+++ /dev/null
@@ -1,270 +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"
- 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"
- 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\ASTConsumers.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\clang.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\DiagChecker.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\HTMLDiagnostics.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\HTMLPrint.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\PrintParserCallbacks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\PrintPreprocessedOutput.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\RewriteMacros.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\RewriteObjC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\SerializationTest.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\TextDiagnosticBuffer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\TextDiagnosticPrinter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\Driver\TextDiagnostics.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\Driver\ASTConsumers.h"
- >
- </File>
- <File
- RelativePath="..\..\Driver\clang.h"
- >
- </File>
- <File
- RelativePath="..\..\Driver\TextDiagnosticBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\Driver\TextDiagnosticPrinter.h"
- >
- </File>
- <File
- RelativePath="..\..\Driver\TextDiagnostics.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 c2e8d35ca169..000000000000
--- a/clang/win32/clangLex/clangLex.vcproj
+++ /dev/null
@@ -1,269 +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"
- 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"
- 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\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/clangParse/clangParse.vcproj b/clang/win32/clangParse/clangParse.vcproj
deleted file mode 100644
index 23ce529597a3..000000000000
--- a/clang/win32/clangParse/clangParse.vcproj
+++ /dev/null
@@ -1,229 +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"
- 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"
- 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\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\Parser.cpp"
- >
- </File>
- <File
- RelativePath="..\..\lib\Parse\ParseStmt.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 a1e1e9dcacdf..000000000000
--- a/clang/win32/clangRewrite/clangRewrite.vcproj
+++ /dev/null
@@ -1,185 +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"
- 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"
- 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 c7e9200405da..000000000000
--- a/clang/win32/clangSema/clangSema.vcproj
+++ /dev/null
@@ -1,221 +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"
- 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"
- 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\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\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="..\..\include\clang\Sema\ASTStreamer.h"
- >
- </File>
- <File
- RelativePath="..\..\lib\Sema\Sema.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/clang/www/CheckerNotes.html b/clang/www/CheckerNotes.html
deleted file mode 100644
index 40d8535fa866..000000000000
--- a/clang/www/CheckerNotes.html
+++ /dev/null
@@ -1,242 +0,0 @@
-<html>
-<head>
- <title>Information on using the Static Analyzer ("LLVM Checker")</title>
- <style type="text/css">
- body { color:#000000; background-color:#ffffff }
- body { font-family: Helvetica, sans-serif; font-size:9pt }
- h1 { font-size:12pt }
- 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; width:80%;}
- 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>
-
-<h1>Information on using the Static Analyzer ("LLVM Checker")</h1>
-
-<p>
-This documents provides some notes on using the LLVM/clang static analyzer to
-find bugs in C and Objective-C programs.
-
-<p>This document is arranged into the following sections:</p>
-
-<ul>
- <li><a href="#Contents">Downloadable Package Contents</a></li>
- <li><a href="#BasicUsage">Basic Usage</a></li>
- <li><a href="#Output">Output of the Analyzer</a></li>
- <li><a href="#RecommendedUsageGuidelines">Recommended Usage Guidelines</a></li>
- <li><a href="#Debugging">Debugging the Analyzer</a>
-</ul>
-
-<h2 id="ReleaseContents">Package Contents</h2>
-
-<p>The static analyzer is released as a single tarball:
-<tt>checker-XXX.tar.gz</tt>, where <b>XXX</b> is the release tag. The tarball
-expands to the following files:</p>
-
-<table>
-<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>
-
-<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>, andin 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 are a complete list of 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 <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
- "-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>
-
-<p>These options can also be viewed by running <tt>scan-build</tt> with no
-arguments:</p>
-
-<pre>
- $ <b>scan-build</b>
-
- USAGE: scan-build [options] &lt;build command&gt; [build options]
-
- 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.
- <b>...</b>
-</pre>
-
-<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>
-
-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.
-
-<h3>Pass -k to <tt>scan-build</tt></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 <tt>scan-build</tt></h3>
-
-<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
-comprehendible logs, don't perform a parallel build.
-
-<h2 id="Debugging">Debugging the Analyzer</h2>
-
-This section provides information on debugging the analyzer, and troubleshooting
-it when you have problems analyzing a particular project.
-
-<h3>How it Works</h3>
-
-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>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).
-
-<h3>Filing Bugs</h3>
-
-We encourage users to file bug reports for any problems that they encounter.
-Apple-internal users should file bugs in Radar against the <b>llvm - clang</b>
-component. External-Apple users should file bugs in <a
-href="http://llvm.org/bugs/enter_bug.cgi?product=clang">LLVM's Bugzilla against
-clang</a>.
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 0fb5043ea1b0..000000000000
--- a/clang/www/comparison.html
+++ /dev/null
@@ -1,195 +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. clang's support for C++ in
- particular is nowhere near what GCC supports.</li>
- <li>GCC's codegen is much more mature than clang's right now. clang is
- only capable of codegen for small and simple projects and does not yet
- support debug info. GCC also 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, but its current PCH mechanism is close. However, GCC's current
- PCH support is architecturally only able to read the dump back into
- the exact same executable as the one that produced it.</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, 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 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 slower and uses more memory than GCC, which 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. For more details, please see the Pork page.</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 14de736a4a38..000000000000
--- a/clang/www/content.css
+++ /dev/null
@@ -1,10 +0,0 @@
-html, body {
- padding:0px;
-}
-
-/* Slides */
-IMG.img_slide {
- display: block;
- margin-left: auto;
- margin-right: auto
-}
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/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 477032fb44e0..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>
-
-<!--*************************************************************************-->
-<h1><a name="enduser">End-User Features</a></h1>
-<!--*************************************************************************-->
-
-
-<!--=======================================================================-->
-<h2><a name="performance">Fast compiles and Low Memory Use</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-
-<!--=======================================================================-->
-<h2><a name="expressivediags">Expressive Diagnostics</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-<!--=======================================================================-->
-<h2><a name="gcccompat">GCC Compatibility</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-
-<!--*************************************************************************-->
-<h1><a name="applications">Utility and Applications</a></h1>
-<!--*************************************************************************-->
-
-<!--=======================================================================-->
-<h2><a name="libraryarch">Library Based Architecture</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-<!--=======================================================================-->
-<h2><a name="diverseclients">Support Diverse Clients</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-<!--=======================================================================-->
-<h2><a name="ideintegration">Integration with IDEs</h2>
-<!--=======================================================================-->
-
-<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>
-
-
-<!--=======================================================================-->
-<h2><a name="license">Use the LLVM 'BSD' License</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-
-
-<!--*************************************************************************-->
-<h1><a name="design">Internal Design and Implementation</a></h1>
-<!--*************************************************************************-->
-
-<!--=======================================================================-->
-<h2><a name="real">A real-world, production quality compiler</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-<!--=======================================================================-->
-<h2><a name="simplecode">A simple and hackable code base</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-<!--=======================================================================-->
-<h2><a name="unifiedparser">A single unified parser for C, Objective C, C++,
-and Objective C++</a></h2>
-<!--=======================================================================-->
-
-<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>
-
-<!--=======================================================================-->
-<h2><a name="conformance">Conformance with C/C++/ObjC and their
- variants</a></h2>
-<!--=======================================================================-->
-
-<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 3a29e2e5bad2..000000000000
--- a/clang/www/get_involved.html
+++ /dev/null
@@ -1,130 +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,
-<a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2007-December/000613.html">
-the script attached to this post</a> 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="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2007-December/000613.html">
-the attachment to this post</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 things that can be done. Right now we support
-some small things like references and bool. We also support parsing of
-namespaces, but don't build ASTs for it. It would be straight-forward to
-implement support for representing namespaces, then add support for things like
-foo::bar::baz. Likewise, lots of other little pieces can be picked off and
-implemented.</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>
-
-</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 fee467b71410..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>
-
-<h3><a name="build">Building clang / working with the code</a></h3>
-
-<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 llvm/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/Driver/clang.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 | llvm-as | opt -std-compile-opts |
- llvm-dis</tt> (print out optimized llvm code)</li>
- <li><tt>clang file.c -emit-llvm | 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>
-
-<h3>Examples of using clang</h3>
-
-<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>
-
-
-<h4>Preprocessing:</h4>
-
-<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>
-
-
-<h4>Type checking:</h4>
-
-<pre class="code">
-$ <b>clang -fsyntax-only ~/t.c</b>
-</pre>
-
-
-<h4>GCC options:</h4>
-
-<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>
-
-
-<h4>Pretty printing from the AST:</h4>
-
-<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>
-
-
-<h4>Code generation with LLVM:</h4>
-
-<pre class="code">
-$ <b>clang ~/t.c -emit-llvm | 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 | 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 | llvm-as | opt -std-compile-opts | llc -march=x86 -mcpu=yonah</b>
-..
-_foo:
- mulps %xmm0, %xmm1
- addps %xmm0, %xmm1
- movaps %xmm1, %xmm0
- ret
-</pre>
-
-<h3>GCC "Emulation" Driver</h3>
-
-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>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 ad342b5611c7..000000000000
--- a/clang/www/index.html
+++ /dev/null
@@ -1,119 +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><a name="goals">Features and Goals</a></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. C++ support 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">geting 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/menu.css b/clang/www/menu.css
deleted file mode 100644
index 0ecc74e4b1fd..000000000000
--- a/clang/www/menu.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/***************/
-/* page layout */
-/***************/
-
-[id=menu] {
- position:fixed;
-}
-[id=content] {
- /* ***** EDIT THIS VALUE IF CONTENT OVERLAPS MENU ***** */
- padding-left:16ex;
-}
-
-/**************/
-/* 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 1f9380928f93..000000000000
--- a/clang/www/menu.html.incl
+++ /dev/null
@@ -1,23 +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="http://clang.llvm.org/docs/InternalsManual.html">Clang&nbsp;Internals</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>
- </div>
-</div>